Oracle RACでインターコネクトIPを変更する方法

# 1.はじめに
今回、Oracle RACが動いているDBサーバーがDC移転をすることとなり、その際インターコネクトIPのセグメントが変わる場合に特殊な対応が必要だっため記事にしました。

CRSにはインターコネクトのネットワークI/F名及びセグメント（サブネット）の情報を保持しており、インターコネクトIPが異なるサーバでは、CRSを起動することが出来ません。
CRSが起動しないと設定変更もできないため、予め移転先のネットワーク情報をCRSに設定した上で移転を行う方法がMOS上では案内されています。
[Oracle Clusterwareでプライベート・ネットワーク情報を変更する方法 (Doc ID 2878978.1)](https://support.oracle.com/epmos/faces/DocumentDisplay?id=2878978.1)

今回はCRSに新環境のネットワーク情報を設定しないまま移転してしまった後、設定変更をするという特殊な対応の事例の紹介となります。

動作検証は以下の手順を参考に作成したOCI Docker環境で実施していますので、異なる環境の場合は振る舞いが異なる場合があります。
[[Oracle Cloud] OCI Compute 上に Docker で Oracle Database 19c の 4 Node RAC 環境を構築する](https://qiita.com/hshida/items/40fdf5952ece39faec11)

※記載するコマンド結果等はインターコネクトIP部分に絞って記載しています。

## 1-1.環境
- Oracle Cloud Infrastructure Compute
- Oracle Linux 7.9
- Oracle Database 19c (19.3)
- Oracle Database 19c Grid Infrastructure（19.3）
- Docker

# 2.インターコネクトIP変更
## 2-1.変更前のネットワーク情報の確認
変更前のネットワーク情報を確認します。
今回、192.168.17.150から192.168.19.150にインターコネクトIPを変更します。
セグメントは192.168.17.0/24から192.168.19.0/24に変わります。

    [grid@racnode1 ~]$ ifconfig -a
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.17.150  netmask 255.255.255.0  broadcast 192.168.17.255
            ether 02:42:c0:a8:11:96  txqueuelen 0  (Ethernet)
            RX packets 41438473  bytes 64138559285 (59.7 GiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 35849429  bytes 35802279901 (33.3 GiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    [grid@racnode1 ~]$ ip addr show
    97: eth0@if98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:c0:a8:11:96 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.168.17.150/24 brd 192.168.17.255 scope global eth0
           valid_lft forever preferred_lft forever
    [grid@racnode1 ~]$ cat /etc/hosts
    192.168.17.150  racnode1-priv.example.com       racnode1-priv
    192.168.17.151  racnode2-priv.example.com       racnode2-priv

## 2-2.CRSの停止
インターコネクトIP変更前にRACの両ノードでCRSを停止しておきます。

    -bash-4.2# /u01/app/19.3.0/grid/bin/crsctl stop crs

## 2-3.docker networkの作成/割当て
dockerで192.168.19.0/24セグメントのネットワークを作成し、各ノードに割り当てます。

    [root@docker ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    719d1338369c        rac_priv1_nw        bridge              local
    [root@docker ~]# docker network create --subnet 192.168.19.0/24 rac_priv2_nw
    daf3a9c6ff2b31545eb453f013806eb370383228fc9abf1ccfdaa0f54075e462
    [root@docker ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    719d1338369c        rac_priv1_nw        bridge              local
    daf3a9c6ff2b        rac_priv2_nw        bridge              local
    [root@docker ~]# docker network connect --ip 192.168.19.150 rac_priv2_nw racnode1
    [root@docker ~]# docker network connect --ip 192.168.19.151 rac_priv2_nw racnode2
    [root@docker ~]# docker network disconnect rac_priv1_nw racnode1
    [root@docker ~]# docker network disconnect rac_priv1_nw racnode2

## 2-4.変更後のネットワーク情報の確認
dockerで上記のコマンドを実行すると、新しいネットワークI/F名（eth2）に追加したネットワークが割り当てられます。

    [grid@racnode1 ~]$ ifconfig -a
    eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.19.150  netmask 255.255.255.0  broadcast 192.168.19.255
            ether 02:42:c0:a8:13:96  txqueuelen 0  (Ethernet)
            RX packets 11  bytes 946 (946.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    [grid@racnode1 ~]$ ip addr show
    99: eth2@if100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:c0:a8:13:96 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.168.19.150/24 brd 192.168.19.255 scope global eth2
           valid_lft forever preferred_lft forever

今回は同じネットワークI/F（eth0）を使いたいため、dockerを再起動します。

    [root@docker ~]# systemctl daemon-reload
    [root@docker ~]# systemctl restart docker
    [root@docker ~]# systemctl enable docker

docker再起動後にネットワーク情報を再確認すると、eth0に変っていました。

    [grid@racnode1 ~]$ ifconfig -a
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.19.150  netmask 255.255.255.0  broadcast 192.168.19.255
            ether 02:42:c0:a8:13:96  txqueuelen 0  (Ethernet)
            RX packets 11  bytes 906 (906.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    [grid@racnode1 ~]$ ip addr show
    105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:c0:a8:13:96 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.168.19.150/24 brd 192.168.19.255 scope global eth0
           valid_lft forever preferred_lft forever

/etc/hostsも変更しておきます。

    [grid@racnode1 ~]$ sudo vi /etc/hosts
    [grid@racnode1 ~]$ cat /etc/hosts
    #192.168.17.150  racnode1-priv.example.com       racnode1-priv
    192.168.19.150  racnode1-priv.example.com       racnode1-priv
    #192.168.17.151  racnode2-priv.example.com       racnode2-priv
    192.168.19.151  racnode2-priv.example.com       racnode2-priv

## 2-5.CRSの起動
インターコネクトIPの異なる環境が作れたので、CRSを起動してみます。

    -bash-4.2# /u01/app/19.3.0/grid/bin/crsctl start crs -wait

この時、CRSのアラートログも別ターミナルでtailしておきます。

    [grid@racnode1 ~]$ cd /u01/app/grid/diag/crs/racnode1/crs/trace/
    [grid@racnode1 trace]$ tail -f alert.log

しばらくすると、以下のようなログが大量に出力されます。
eth0(:.*)?:192.168.17.0 が見つからないと怒られていますね。

    2024-05-30 06:04:07.340 [GIPCD(7483)]CRS-42216: No interfaces are configured on the local node for interface definition eth0(:.*)?:192.168.17.0: available interface definitions are [eth0(:.*)?:192.168.19.0][eth1(:.*)?:172.16.1.0].

とりあえずCRS起動に失敗しているため、起動コマンドは停止し、CRSの停止コマンドも実行しておきます。
必要に応じてプロセスをkillします。

    ^C
    -bash-4.2# /u01/app/19.3.0/grid/bin/crsctl stop crs -f

ここまでで、CRSに移転先のネットワーク情報を設定しないまま移転した場合にどうなるかを確認することができました。

# 3.CRSのネットワーク情報変更
## 3-1.変更前IPの割り当て
では、この状態でCRSを起動するにはeth0(:.*)?:192.168.17.0 が見つからないというメッセージをどうにかする必要がありそうです。
そのため、eth0（セグメントは192.168.19.0/24）に無理やり変更前IPの192.168.17.150を割り当ててみます。

    [grid@racnode1 ~]$ sudo ip addr add 192.168.17.150/24 dev eth0
    [grid@racnode1 ~]$ ifconfig -a
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.19.150  netmask 255.255.255.0  broadcast 192.168.19.255
            ether 02:42:c0:a8:13:96  txqueuelen 0  (Ethernet)
            RX packets 15  bytes 1146 (1.1 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    [grid@racnode1 ~]$ ip addr show
    111: eth0@if112: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:c0:a8:13:96 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.168.19.150/24 brd 192.168.19.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet 192.168.17.150/24 scope global eth0
           valid_lft forever preferred_lft forever

ifconfigは192.168.19.150のみですが、ip addr showではeth0に192.168.17.150/24も割り当てられています。
2号機は192.168.17.151/24で割り当てました。
この状態でのそれぞれのpingを確認してみます。

    [grid@racnode1 ~]$ ping 192.168.19.150
    PING 192.168.19.150 (192.168.19.150) 56(84) bytes of data.
    64 bytes from 192.168.19.150: icmp_seq=1 ttl=64 time=0.035 ms
    ^C
    --- 192.168.19.150 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.035/0.035/0.035/0.000 ms
    [grid@racnode1 ~]$ ping 192.168.19.151
    PING 192.168.19.151 (192.168.19.151) 56(84) bytes of data.
    64 bytes from 192.168.19.151: icmp_seq=1 ttl=64 time=0.112 ms
    ^C
    --- 192.168.19.151 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.112/0.112/0.112/0.000 ms
    [grid@racnode1 ~]$ ping 192.168.17.150
    PING 192.168.17.150 (192.168.17.150) 56(84) bytes of data.
    64 bytes from 192.168.17.150: icmp_seq=1 ttl=64 time=0.037 ms
    ^C
    --- 192.168.17.150 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.037/0.037/0.037/0.000 ms
    [grid@racnode1 ~]$ ping 192.168.17.151
    PING 192.168.17.151 (192.168.17.151) 56(84) bytes of data.
    ^C
    --- 192.168.17.151 ping statistics ---
    2 packets transmitted, 0 received, 100% packet loss, time 1008ms
    
    [grid@racnode1 ~]$

移転先環境の正しいセグメントのIPである192.168.19.150及び192.168.19.151にはそれぞれpingは通り、無理やり付与した192.168.17.0/24についてはセグメントが異なるため外部の通信ができません。
ノード1の192.168.17.150は自ノードであるためpingが通り、ノード2の192.168.17.151にはノード1からのpingは通らないという状態であることが分かります。

## 3-2.CRSの起動
この状態でCRSを起動してみます。

    -bash-4.2# /u01/app/19.3.0/grid/bin/crsctl start crs -wait
    ：
    CRS-4123: Oracle High Availability Services has been started.
    
CRSを起動することができました。
RAC間通信が出来なくても、CRSに登録されているネットワーク情報で自ノードに疎通ができればCRSは起動できるということがわかります。

## 3-3.CRSのネットワーク設定変更
CRSのインターコネクトのネットワーク情報はoifcfgコマンドで確認/設定を行います。
ここではもう移転前のネットワーク情報は不要なので削除していますが、globalオプションがあれば不要な設定が入っていても問題ありません。
移転前の環境で設定を入れることが可能な場合は、setifで移転後のネットワーク情報を追加し、インターコネクト情報が2重の状態で運用することが可能です。

    [grid@racnode1 ~]$ oifcfg getif
    eth1  172.16.1.0  global  public
    eth0  192.168.17.0  global  cluster_interconnect,asm
    [grid@racnode1 ~]$ oifcfg setif -global eth0/192.168.19.0:cluster_interconnect,asm
    [grid@racnode1 ~]$ oifcfg delif -global eth0/192.168.17.0
    [grid@racnode1 ~]$ oifcfg getif
    eth1  172.16.1.0  global  public
    eth0  192.168.19.0  global  cluster_interconnect,asm

## 3-4.ASMlistenerの設定変更
oifcfg以外でASMlistenerの設定変更も行います。

    [grid@racnode1 ~]$ srvctl config listener -asmlistener
    Name: ASMNET1LSNR_ASM
    Type: ASM Listener
    Owner: grid
    Subnet: 192.168.17.0
    Home: <CRS home>
    End points: TCP:1525
    Listener is enabled.
    Listener is individually enabled on nodes:
    Listener is individually disabled on nodes:
    [grid@racnode1 ~]$ srvctl update listener -listener ASMNET1LSNR_ASM -asm -remove -force
    [grid@racnode1 ~]$ srvctl add listener -asmlistener -l ASMNET1LSNR_ASM -subnet 192.168.19.0
    [grid@racnode1 ~]$ srvctl config listener -asmlistener
    Name: ASMNET1LSNR_ASM
    Type: ASM Listener
    Owner: grid
    Subnet: 192.168.19.0
    Home: <CRS home>
    End points: TCP:1525
    Listener is enabled.
    Listener is individually enabled on nodes:
    Listener is individually disabled on nodes:

## 3-5.asmnetworkの設定変更（19c以降）
19c以降はasmnetworkの設定変更も必要です。

    -bash-4.2# /u01/app/19.3.0/grid/bin/srvctl config asmnetwork -netnum 1
    ASM network 1 exists
    Subnet IPv4: 192.168.17.0//
    Subnet IPv6:
    Network is enabled
    Network is individually enabled on nodes:
    Network is individually disabled on nodes:
    -bash-4.2# /u01/app/19.3.0/grid/bin/srvctl remove asmnetwork -netnum 1 -force
    -bash-4.2# /u01/app/19.3.0/grid/bin/srvctl add asmnetwork -netnum 1 -subnet 192.168.19.0
    -bash-4.2# /u01/app/19.3.0/grid/bin/srvctl config asmnetwork -netnum 1
    ASM network 1 exists
    Subnet IPv4: 192.168.19.0//
    Subnet IPv6:
    Network is enabled
    Network is individually enabled on nodes:
    Network is individually disabled on nodes:

## 3-6.CRSの停止
oifcfg、ASMlistener、asmnetworkの設定変更を行ったらCRSを停止します。

    -bash-4.2# /u01/app/19.3.0/grid/bin/crsctl stop crs

## 3-7.一時的に付与した変更前IPの削除
3-1で割り当てた変更前のIPアドレスを削除します。
2号機も同様に削除します。

    [grid@racnode1 ~]$ sudo ip addr del 192.168.17.150/24 dev eth0
    [grid@racnode1 ~]$ ip addr show
    111: eth0@if112: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:c0:a8:13:96 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 192.168.19.150/24 brd 192.168.19.255 scope global eth0
           valid_lft forever preferred_lft forever

疎通確認を行い、IP削除前は疎通できた192.168.17.150に疎通が出来なくなっていることを確認します。

    [grid@racnode1 ~]$ ping 192.168.19.150
    PING 192.168.19.150 (192.168.19.150) 56(84) bytes of data.
    64 bytes from 192.168.19.150: icmp_seq=1 ttl=64 time=0.035 ms
    ^C
    --- 192.168.19.150 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.035/0.035/0.035/0.000 ms
    [grid@racnode1 ~]$ ping 192.168.17.150
    PING 192.168.17.150 (192.168.17.150) 56(84) bytes of data.
    ^C
    --- 192.168.17.150 ping statistics ---
    1 packets transmitted, 0 received, 100% packet loss, time 0ms
    
    [grid@racnode1 ~]$

## 3-8.CRSの起動
再度CRSを起動します。
CRSの設定変更は片ノードで設定することで両ノードに反映されます。
RAC間通信可能な変更後IPの情報をノード1で設定しましたが、この状態でノード1のCRSを起動することでノード2にも設定が伝播され、ノード2の起動もできるようになります。
そのため、ノード1の起動が確認できてからノード2を起動するようにします。

    -bash-4.2# /u01/app/19.3.0/grid/bin/crsctl start crs -wait
    ：
    CRS-4123: Oracle High Availability Services has been started.

## 3-9.CRSのステータス確認
CRSのステータスを確認します。
設定変更したasmnetworkが起動していませんでした。

    [grid@racnode1 ~]$ crsctl stat res -t
    --------------------------------------------------------------------------------
    Name           Target  State        Server                   State details
    --------------------------------------------------------------------------------
    Local Resources
    --------------------------------------------------------------------------------
    ora.LISTENER.lsnr
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    ora.chad
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    ora.net1.network
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    ora.ons
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    --------------------------------------------------------------------------------
    Cluster Resources
    --------------------------------------------------------------------------------
    ora.ASMNET1LSNR_ASM.lsnr(ora.asmgroup)
          1        ONLINE  ONLINE       racnode1                 STABLE
          2        ONLINE  ONLINE       racnode2                 STABLE
          3        ONLINE  OFFLINE                               STABLE
    ora.DATA.dg(ora.asmgroup)
          1        ONLINE  ONLINE       racnode1                 STABLE
          2        ONLINE  ONLINE       racnode2                 STABLE
          3        OFFLINE OFFLINE                               STABLE
    ora.LISTENER_SCAN1.lsnr
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.asm(ora.asmgroup)
          1        ONLINE  ONLINE       racnode1                 Started,STABLE
          2        ONLINE  ONLINE       racnode2                 Started,STABLE
          3        OFFLINE OFFLINE                               STABLE
    ora.asmnet1.asmnetwork(ora.asmgroup)
          1        OFFLINE OFFLINE                               STABLE
          2        OFFLINE OFFLINE                               STABLE
          3        OFFLINE OFFLINE                               STABLE
    ora.cvu
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.orcl.db
          1        ONLINE  ONLINE       racnode1                 Open,HOME=/u01/app/o
                                                                 racle/product/19.3.0
                                                                 /dbhome_1,STABLE
          2        ONLINE  ONLINE       racnode2                 Open,HOME=/u01/app/o
                                                                 racle/product/19.3.0
                                                                 /dbhome_1,STABLE
    ora.qosmserver
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.racnode1.vip
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.racnode2.vip
          1        ONLINE  ONLINE       racnode2                 STABLE
    ora.scan1.vip
          1        ONLINE  ONLINE       racnode1                 STABLE
    --------------------------------------------------------------------------------
    [grid@racnode1 ~]$

asmnetworkを起動します。

    [grid@racnode1 ~]$ srvctl start asmnetwork
    [grid@racnode1 ~]$ crsctl stat res -t
    --------------------------------------------------------------------------------
    Name           Target  State        Server                   State details
    --------------------------------------------------------------------------------
    Local Resources
    --------------------------------------------------------------------------------
    ora.LISTENER.lsnr
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    ora.chad
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    ora.net1.network
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    ora.ons
                   ONLINE  ONLINE       racnode1                 STABLE
                   ONLINE  ONLINE       racnode2                 STABLE
    --------------------------------------------------------------------------------
    Cluster Resources
    --------------------------------------------------------------------------------
    ora.ASMNET1LSNR_ASM.lsnr(ora.asmgroup)
          1        ONLINE  ONLINE       racnode1                 STABLE
          2        ONLINE  ONLINE       racnode2                 STABLE
          3        ONLINE  OFFLINE                               STABLE
    ora.DATA.dg(ora.asmgroup)
          1        ONLINE  ONLINE       racnode1                 STABLE
          2        ONLINE  ONLINE       racnode2                 STABLE
          3        OFFLINE OFFLINE                               STABLE
    ora.LISTENER_SCAN1.lsnr
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.asm(ora.asmgroup)
          1        ONLINE  ONLINE       racnode1                 Started,STABLE
          2        ONLINE  ONLINE       racnode2                 Started,STABLE
          3        OFFLINE OFFLINE                               STABLE
    ora.asmnet1.asmnetwork(ora.asmgroup)
          1        ONLINE  ONLINE       racnode1                 STABLE
          2        ONLINE  ONLINE       racnode2                 STABLE
          3        ONLINE  OFFLINE                               STABLE
    ora.cvu
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.orcl.db
          1        ONLINE  ONLINE       racnode1                 Open,HOME=/u01/app/o
                                                                 racle/product/19.3.0
                                                                 /dbhome_1,STABLE
          2        ONLINE  ONLINE       racnode2                 Open,HOME=/u01/app/o
                                                                 racle/product/19.3.0
                                                                 /dbhome_1,STABLE
    ora.qosmserver
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.racnode1.vip
          1        ONLINE  ONLINE       racnode1                 STABLE
    ora.racnode2.vip
          1        ONLINE  ONLINE       racnode2                 STABLE
    ora.scan1.vip
          1        ONLINE  ONLINE       racnode1                 STABLE
    --------------------------------------------------------------------------------
    [grid@racnode1 ~]$

CRSリソースが全て正常起動したことが確認できました。

# 4.まとめ
インターコネクトIPが異なる環境にOracle RACを持って行く場合、事前に新しい環境のネットワーク情報をCRSに登録しておくことが推奨されます。

新環境のネットワーク情報を設定しない状態で新環境に持って行った場合は、そのままではCRSが起動できず、ネットワーク情報の設定変更もできない状態となります。
その場合は当記事の手順で一時的に旧環境で利用していたIPを割り当てることでCRSを起動することができ、ネットワーク設定変更を行うことが可能となります。
一時的に割り当てるIPは自身のサーバに疎通が出来ればよく、RAC間通信は必須ではないということもわかりました。

ご参考になれば幸いです。