SCANの名前解決をDNSで行う場合とhostsファイルで行う場合の挙動の違いについて

タイトルの通り。サーバー側はLinux環境の3ノードRACを想定し、以下のように3つのSCANが起動しているものとする。

[grid@rac19db1 ~]$ crsctl stat res ora.scan1.vip ora.scan2.vip ora.scan3.vip -t
--------------------------------------------------------------------------------
Name           Target  State        Server                   State details       
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.scan1.vip
      1        ONLINE  ONLINE       rac19db1                 STABLE
ora.scan2.vip
      1        ONLINE  ONLINE       rac19db2                 STABLE
ora.scan3.vip
      1        ONLINE  ONLINE       rac19db3                 STABLE
--------------------------------------------------------------------------------

[grid@rac19db1 ~]$ srvctl config scan
SCAN名: rac19db-scan.dn.home、ネットワーク: 1
サブネットIPv4: 192.168.100.0/255.255.255.0/ens192, static
サブネットIPv6: 
SCAN 1 IPv4 VIP: 192.168.100.114
SCAN VIPは有効です。
SCAN 2 IPv4 VIP: 192.168.100.116
SCAN VIPは有効です。
SCAN 3 IPv4 VIP: 192.168.100.115
SCAN VIPは有効です。

今回主に着目するのはクライアント側でSCANの名前解決をするときの動作について。

DNSで名前解決する場合

DNSで名前解決している場合、DNSラウンドロビンの結果ホスト名は以下のように順不同で返却される。

[oracle@oracli admin]$ getent hosts rac19db-scan.dn.home
192.168.100.115 rac19db-scan.dn.home
192.168.100.116 rac19db-scan.dn.home
192.168.100.114 rac19db-scan.dn.home
[oracle@oracli admin]$ getent hosts rac19db-scan.dn.home
192.168.100.115 rac19db-scan.dn.home
192.168.100.114 rac19db-scan.dn.home
192.168.100.116 rac19db-scan.dn.home
[oracle@oracli admin]$ getent hosts rac19db-scan.dn.home
192.168.100.116 rac19db-scan.dn.home
192.168.100.115 rac19db-scan.dn.home
192.168.100.114 rac19db-scan.dn.home

Oracleが公開している情報によると、この名前解決の結果を受けてクライアントは接続記述子を以下のように自動的に展開する。

Oracle Databaseのネットワーク接続 Oracle Database Technology Night #52 より引用
https://speakerdeck.com/oracle4engineer/oracle-database-oracle-net-services

実際にtnspingを簡易接続形式で何度か実行してみると、SCANがどのように展開されているのかがわかる。

[oracle@oracli admin]$ tnsping rac19db-scan.dn.home

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 01-3月 -2025 19:27:18

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

パラメータ・ファイルを使用しました:
/u01/app/oracle/product/19.0.0/client_1/network/admin/sqlnet.ora

エイリアスを解決するためにEZCONNECTアダプタを使用しました。
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.116)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.114)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.115)(PORT=1521)))に接続の試行中
OK (0ミリ秒)
[oracle@oracli admin]$ tnsping rac19db-scan.dn.home

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 01-3月 -2025 19:27:20

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

パラメータ・ファイルを使用しました:
/u01/app/oracle/product/19.0.0/client_1/network/admin/sqlnet.ora

エイリアスを解決するためにEZCONNECTアダプタを使用しました。
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.114)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.115)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.116)(PORT=1521)))に接続の試行中
OK (0ミリ秒)
[oracle@oracli admin]$ tnsping rac19db-scan.dn.home

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 01-3月 -2025 19:27:23

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

パラメータ・ファイルを使用しました:
/u01/app/oracle/product/19.0.0/client_1/network/admin/sqlnet.ora

エイリアスを解決するためにEZCONNECTアダプタを使用しました。
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.115)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.116)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.114)(PORT=1521)))に接続の試行中
OK (0ミリ秒)

DNSから戻される結果を反映してか、順不同で展開されている。ただ、細かく見ると FAILOVER や LOAD_BALANCE のオプションは指定されていない。Oracleの資料の通り、自動展開されるのはあくまでも ADDRESS 属性の部分のみであり、FAILOVER や LOAD_BALANCE の指定は変更されないという印象。

この場合、接続時ロードバランスや接続時フェイルオーバーがどのように動くのか?が気になるところだが、SCANリスナーのリスナーログを見ながら観察する限りロードバランスはされておらず、上から順につなげているように見えた。

DNS側でラウンドロビンの結果が返ってくるので、LOAD_BALANCE属性の有無は大きな影響にはならないように見えるが、確実にロードバランス・フェイルオーバーを働かせるのであれば、以下のようにtnsnames.oraに対して明示的な設定をした方が確実と思われる。

XXXXX =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (LOAD_BALANCE = yes)
      (FAILOVER = yes)
      (ADDRESS = (PROTOCOL = TCP)(HOST = rac19db-scan.dn.home)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = db19)
    )
  )

hostsファイルで名前解決する場合

前提として、クライアントのhostsファイルには以下のように一つのホスト名に対して複数のIPアドレスを設定している。

192.168.100.114 rac19db-scan rac19db-scan.dn.home
192.168.100.115 rac19db-scan rac19db-scan.dn.home
192.168.100.116 rac19db-scan rac19db-scan.dn.home

/etc/host.conf にはデフォルトで multi on の設定があるため、名前解決時も複数のホスト名が返されるが、DNSと異なりIPアドレスの順番は毎回変わらず同じ(hostsファイルに書いた順)になる。

[oracle@oracli admin]$ getent hosts rac19db-scan.dn.home
192.168.100.114 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
192.168.100.115 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
192.168.100.116 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
[oracle@oracli admin]$ getent hosts rac19db-scan.dn.home
192.168.100.114 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
192.168.100.115 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
192.168.100.116 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
[oracle@oracli admin]$ getent hosts rac19db-scan.dn.home
192.168.100.114 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
192.168.100.115 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home
192.168.100.116 rac19db-scan rac19db-scan.dn.home rac19db-scan.dn.home rac19db-scan.dn.home

DNSの時と同じようにtnspingを簡易接続形式で実行してみると、3つのIPアドレスに展開はされるものの、やはりIPアドレスの順番は毎回変わらず同じとなる。

[oracle@oracli admin]$ tnsping rac19db-scan.dn.home

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 01-3月 -2025 20:04:10

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

パラメータ・ファイルを使用しました:
/u01/app/oracle/product/19.0.0/client_1/network/admin/sqlnet.ora

エイリアスを解決するためにEZCONNECTアダプタを使用しました。
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.114)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.115)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.116)(PORT=1521)))に接続の試行中
OK (0ミリ秒)
[oracle@oracli admin]$ tnsping rac19db-scan.dn.home

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 01-3月 -2025 20:04:14

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

パラメータ・ファイルを使用しました:
/u01/app/oracle/product/19.0.0/client_1/network/admin/sqlnet.ora

エイリアスを解決するためにEZCONNECTアダプタを使用しました。
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.114)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.115)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.116)(PORT=1521)))に接続の試行中
OK (0ミリ秒)
[oracle@oracli admin]$ tnsping rac19db-scan.dn.home

TNS Ping Utility for Linux: Version 19.0.0.0.0 - Production on 01-3月 -2025 20:04:19

Copyright (c) 1997, 2019, Oracle.  All rights reserved.

パラメータ・ファイルを使用しました:
/u01/app/oracle/product/19.0.0/client_1/network/admin/sqlnet.ora

エイリアスを解決するためにEZCONNECTアダプタを使用しました。
(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.114)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.115)(PORT=1521))(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.116)(PORT=1521)))に接続の試行中
OK (0ミリ秒)

したがって、この場合は接続記述子にLOAD_BALANCE属性を明示的に指定しなければ、毎回同じIPアドレスにつなげに行くことになるだろう。

コメント