RACのノードエビクション ― インターコネクトダウン(ネットワークハートビート断)はどのログを解析するのか

📚 連載:RAC障害のログ解析
1. RACインスタンスがダウン ― どのログを解析するのか(instance down 編)
2. RACのノードエビクション ― インターコネクトダウン(ネットワークハートビート断)はどのログを解析するのか(本記事)
3. RACのノードエビクション ― 投票ディスク到達不可(ディスクハートビート断)はどのログを解析するのか(ディスク型 evict 編)

前回(instance down 編)は、「インスタンス1がダウン」の第一報を instance down(インスタンスだけの停止)と切り分け、その記録が DB層のログ(生存ノードのアラートログと LMON トレース)に集中して現れることを実機で確認しました。
そのとき、クラスタ層の ocssd.trcNM層(clssnm*)が無反応で、動いていたのは GM層(clssgm*)だけでした。

今回はその対になる node evict(ノードがクラスタから切り離される障害)を、同じ2ノードRAC で再現します。
前回無反応だった NM層(clssnm*)に、今度は何が出るのか。ここが instance down と node evict を分ける境界線です。

なお、node evict には切り離しのきっかけがいくつかあります。代表的なのは、ノード間の専用ネットワーク(インターコネクト)が切れるネットワークハートビート断と、投票ディスクに到達できなくなるディスクハートビート断の2つです。
本記事は前者(ネットワークハートビート断)のケースを扱います。後者(ディスク型)は次回に回します。同じ node evict でも、どのハートビートが失われたかで ocssd.trc に残る証跡が変わるためです。

あわせて、前回「fence の文字=evict ではない」と確認した点が、今回は本物の fence(投票ディスクへの kill block 書き込み)としてどう出るのかも見ていきます。


1. シナリオ

2ノードRAC(node1 / node2)で、次の状況が起きています。

  • 監視から「DBインスタンス2(node2側)がダウン」のアラートが発報した
  • 前回同様、第一報だけでは instance down か node evict か区別できない
  • ただし今回の実体は、node2 のインターコネクト(ノード間の専用ネットワーク)が失われたことによる node evict である

インターコネクトは、RAC のノードどうしが「生存確認(ネットワークハートビート)」やキャッシュのやり取りに使う専用ネットワークです。
これが切れると、ノードは互いに「相手が消えた」と判断します。

放置すればデータが二重に更新される危険(スプリットブレイン)があるため、クラスタはどちらか一方を強制的に切り離して整合性を守ります。

これが node evict です。

今回は node2 のインターコネクト(NIC ens19)をダウンさせて、この node evict を実機で再現しました。

※ RAC のノードは、クライアント接続用のパブリックと、ノード間専用のプライベート(インターコネクト)の2系統のネットワークを持ちます。CSS のネットワークハートビートが流れるのはプライベート側だけです。そのため、node evict の引き金になるのはインターコネクト断であって、パブリック側が切れても evict にはなりません(その場合は VIP・SCAN・リスナーが生存ノードへフェイルオーバし、ノードはクラスタの管理下に残ります=別トピック)。本記事はプライベート(インターコネクト)側の障害を扱います。


2. 前提の仕組み ― 二階建てと、evict で登場するプロセス

RAC のログを読むには、どのプロセスがどの層に属し、何を管理しているかを押さえます。
前回の「クラスタ層/DB層の二階建て」に、evict で新しく主役になるプロセスを加えたのが次の表です。

プロセス役割主なログ
DB層LMONインスタンスのメンバーシップ監視と reconfiguration の実行DBアラートログ・LMONトレース
DB層SMON死んだインスタンスのインスタンスリカバリDBアラートログ
DB層PMONプロセス・インスタンスの終了処理DBアラートログ
クラスタ層CRS(crsdアプリ資源(ora.*=DB・VIP・リスナー等)の起動・停止・監視・フェイルオーバCRS alert.log
クラスタ層CSS(ocssdノードのメンバーシップ管理(ハートビート・node evict)とプロセスグループ管理ocssd.trc
クラスタ層GIPC(gipcdノード間通信(インターコネクト)の管理CRS alert.log
クラスタ層OHAS(ohasdクラスタの土台プロセス群(CSS/CRS/GIPC 等)自体を起動・監視(各ノードで最初に起動)

上段が「上物」(DB層)・下段が「土台」(クラスタ層)。ノード起動時はこの表を下から順に立ち上げます(ohasd → GIPC → CSS → CRS → DB。簡略表記で、実際は gpnpdmdnsd 等も CSS の前段に起動します)。

プロセス名は略語がそのまま役割を表しています。名前から役割を思い出せると、ログを読むときに迷いません。
(前回はプロセスの役割だけを説明し、名前の読み解きには踏み込みませんでした。名前がとっつきにくいのも確かなので、ここで表の各プロセスを一度ひも解いておきます。)

表と同じ「上物(DB層)→土台(クラスタ層)」の順に見ていきます。

DB層(末尾の MON は Monitor=監視)

  • LMONLock Monitor(グローバル資源=ロックの監視。reconfiguration を実行。頭文字は覚え方で、正式名は Global Enqueue Service Monitor)
  • SMONSystem Monitor(システム管理・インスタンスリカバリ)
  • PMONProcess Monitor(プロセスの死活監視・後始末)

クラスタ層(プロセス名末尾の d は daemon=常駐プロセス。ohasd は OHAS の、ocssd は CSS の daemon=表の ohasd と下の OHAS は同じものd が付くかどうかの違いだけです)

  • CRScrsd)… Cluster Ready Services(リソースを Ready=稼働状態に保つ)
  • CSSocssd)… Cluster Synchronization Services(同期=ノードのメンバーシップ管理)
  • GIPCgipcd)… Grid InterProcess Communication(プロセス間通信=インターコネクト)
  • OHASohasd)… Oracle High Availability Services(可用性の土台。各ノードで最初に起動し、上のプロセス群を立ち上げる)

補足:切り離しの引き金になる「インターコネクト」は何をしているネットワークか

本記事でダウンさせるインターコネクトが、そもそも何をしている専用ネットワークなのかを押さえておきます。
RAC は「別々のサーバー(別々の SGA)」が「1つの共有データベース」を触る構成です。同じデータブロックを複数のインスタンスがそれぞれのメモリにキャッシュするため、その整合を取る通信がインターコネクトを流れます。運んでいるのは主に3種類です。

  • ① データブロックそのもの(キャッシュフュージョン) … あるインスタンスが必要なブロックを、別のインスタンスのメモリから直接取り寄せる仕組み。ブロックの所在は GRD(グローバルリソースディレクトリ) が管理しており、欲しいブロックのマスター(担当インスタンス)に問い合わせる(全ノードに聞いて回るのではない)。
    別インスタンスが保持していればインターコネクト経由でメモリからメモリへ転送(ディスクを介さない)、どこも保持していなければ共有ディスクのデータファイルから読み込む
    この転送を担うのが LMS です。
  • ② ロック・資源の調整情報 … 「どのインスタンスがどのブロックをどのモードで持っているか」という GRD の台帳の調整。
    維持・再構成を担うのが LMON(=後述の reconfiguration で台帳を作り直すのはこれ)
  • ③ ネットワークハートビート … CSS がノードの生存を数秒おきに確認する軽量な通信(本記事の主役)

重要なのは、このネットワークが切れると、上の①(ブロックの受け渡し)と②(ロック調整)ができなくなることです。ブロックを送り合えず、ロックも調整できない(③のハートビートが途絶えることが、後述の切り離しの引き金になります)。
ここで怖いのは、インターコネクト(調整のネットワーク)が切れても、実データのある共有ストレージ(データファイル)は両ノードから見えたままだという点です。
つまり両ノードは、互いに調整できないのに、同じ共有ディスクへそれぞれ勝手に書ける状態になります。
このまま走らせると、両ノードがそれぞれ「自分の持っているデータが最新だ」と思い込んだまま、同じデータを別々に更新してしまい、本当にデータが壊れる危険があります(スプリットブレイン)。
だからクラスタは、被害が出る前に先回りして、ハートビート喪失を引き金に片方のノードを切り離し、1ノードに縮退させてデータベースの整合性を守ります
残った1ノードは、切り離した側のインスタンスリカバリを済ませ、以降はそのノードだけが単独でデータを扱うため、整合が保てます。
node evict は障害であると同時に、この保護動作でもあります。

そして今回の最重要ポイントは、前回と同じ CSS(ocssd)の「2つの層」 です。

プレフィックス管理対象evict との関係
NM層clssnm*ノードの在籍・ハートビートの監視evict の判定はここ。ここに出たら evict
GM層clssgm*プロセスグループのメンバー管理メンバーが消えれば動く。instance down でも動く

前回の instance down では NM層が無反応でした。
今回の node evict では、この NM層に評価から切り離しまでの一部始終が記録されるはずです。実機で確かめます。


3. 実機検証 ― コマンドとログを順に照合する

検証環境は Oracle Database 19c(19.28)の2ノードRAC。
DB名 rc19u、インスタンスは node1 側が rc19u1、node2 側が rc19u2 です。

node2 側でインターコネクト(ens19)をダウンさせ、node2 が切り離される様子を、生存ノード(node1) から観測しました。

[root@node2 ~]# date; ip link set ens19 down
2026年  7月 11日 土曜日 16:53:00 JST

以降、遮断の時刻 16:53:00 を基準に「どのログに・何秒後に・何が出たか」を見ていきます。
インターコネクト喪失から既定の待機時間(misscount、既定30秒)を過ぎると、クラスタは評価を確定させます。

Step 1. まず全体のリソース状況を確認する(crsctl stat res -t)

最初に、クラスタが管理するリソースの状態を一覧で確認します(評価が確定し、node2 が切り離された後の出力です)。

[grid@node1 ~]$ crsctl stat res -t
--------------------------------------------------------------------------------
Name           Target  State        Server                   State details
--------------------------------------------------------------------------------
...
ora.rc19u.db
      1        ONLINE  ONLINE       node1                    Open,STABLE
      2        ONLINE  OFFLINE                               STABLE
...
ora.node2.vip
      1        ONLINE  INTERMEDIATE node1                    FAILED OVER,STABLE

※ 上の見出し行のとおり、各リソースには Target(どうしたいか=クラスタが目指す状態)と State(今どうなっているか=実際の状態)の2列があります(左が Target・右が State)。ここで inst2 は Target=ONLINE/State=OFFLINE、つまりクラスタは動かしたいのに実際は落ちている状態です。前回の instance down(srvctl stop で意図的に停止)が Target=OFFLINE/State=OFFLINE(止めたいから止まっている)だったのと対照的で、evict は「止めた」のではなく「落とされた」ことが Target 列に表れます(node2 が復帰すれば Target=ONLINE に従って自動で戻ります)。

インスタンス2が OFFLINE、というだけなら前回の instance down と同じ見た目です。
違いは次の1行です。ora.node2.vipINTERMEDIATEFAILED OVER で node1 側に退避しています。
State の INTERMEDIATE は「起動しているが本来のノードにいない=フェイルオーバ中」という、ONLINE でも OFFLINE でもない半端な状態を表します。node2 の VIP が node1 へ移った、という node evict の現れです。

ここが instance down との最初の差です。

  • instance down … DB インスタンスだけが落ちる。node はクラスタの管理下に残るので、VIP・リスナーは動かない
  • node evict … ノードごと切り離される。node2 の VIP・リスナー・ASM などがまとめて node1 側へフェイルオーバする

crsctl stat res -t の全体出力で「DB だけでなく node2 側のリソースが軒並み OFFLINE/フェイルオーバしているか」を見ると、この時点で node evict の当たりが付きます。

Step 2. 生存ノード(node1)の CRSアラートログ ― 評価から切り離しまでのカウントダウン

次に、生存ノード(node1)の CRSアラートログを見ます。
前回はここに CRS-1735 が1行出るだけでした。今回はまったく異なります。

[grid@node1 ~]$ tail -50 /u01/app/grid/diag/crs/node1/crs/trace/alert.log
2026-07-11 16:53:07 [OCSSD(3393)]CRS-7503: Oracle Grid Infrastructure プロセス 'ocssd' が、ノード 'node1' と 'node2' の間で通信の問題を検出しました
2026-07-11 16:53:14 [OCSSD(3393)]CRS-1612: タイムアウト間隔の 50% で、ノード node2 (2) のネットワーク通信がありません。この状態が続く場合、クラスタからのこのノードの削除が 14.500 秒内に行われます
2026-07-11 16:53:21 [OCSSD(3393)]CRS-1611: タイムアウト間隔の 75% で、ノード node2 (2) のネットワーク通信がありません。この状態が続く場合、クラスタからのこのノードの削除が 7.500 秒内に行われます
2026-07-11 16:53:26 [OCSSD(3393)]CRS-1610: タイムアウト間隔の 90% で、ノード node2 (2) のネットワーク通信がありません。この状態が続く場合、クラスタからのこのノードの削除が 2.490 秒内に行われます
2026-07-11 16:53:29 [OCSSD(3393)]CRS-1607: ノード node2 はクラスタから削除されました (:CSSNM00007:)
2026-07-11 16:53:30 [OCSSD(3393)]CRS-1601: CSSD の再構成が完了しました

CRS-1612 → 1611 → 1610 のカウントダウンを経て、CRS-1607CRS-1601
遮断(16:53:00)から削除確定(16:53:29)まで、約30秒(misscount)です。

前回の instance down では、この一連のカウントダウンは1行も出ませんでした
「CRS アラートにノード削除のカウントダウンが出ている」時点で、instance down ではないと判断できます。ただし、なぜ node2 が切り離されたのか(ネットワークか、ディスクか)は、この上位ログだけでは分かりません。そこで次の ocssd.trc に降ります。

Step 3. 生存ノード(node1)の ocssd.trc・NM層 ― 前回無反応だった層に記録が出る(最重要)

ここが本記事の最重要ポイントです。
前回 instance down で無反応だった NM層(clssnm* に、今回は評価から切り離しまでが一続きで記録されています。

[grid@node1 ~]$ grep -nE "clssnmPollingThread|DHBValidateNCopy|CheckForNodeRemoval|CheckDskInfo|CompareNodeWeights|clssnmrEvictNode|clssnmvDiskEvict" \
  /u01/app/grid/diag/crs/node1/crs/trace/ocssd.trc
(関連行のみ抜粋)
16:53:14  clssnmPollingThread: node node2 (2) at 50% heartbeat fatal, removal in 14.500 seconds
16:53:14  clssnmvDHBValidateNCopy: node 2, node2, has a disk HB, but no network HB
16:53:26  clssnmPollingThread: node node2 (2) at 90% heartbeat fatal, removal in 2.490 seconds
16:53:28  clssnmCheckForNodeRemoval: Marking node node2 (2) for removal. reason: NHB loss
16:53:28  clssnmCheckDskInfo: Checking disk info...
16:53:29  clssnmCompareNodeWeights: UsePvtNw 1 UseGipcd 1 clustersz 2 ...
16:53:29  clssnmCheckDskInfo: My cohort: 1
16:53:29  (:CSSNM00007:)clssnmrEvictNode: Evicting node 2, node2, from the cluster in incarnation 678615583 ...
16:53:29  clssnmvDiskEvict: kill block write for node node2, file /dev/sdb ... evictionreason: NHB loss, my cohort winreason: the cohort is the only one with public network access

読み解きは次のとおりです。

  • clssnmPollingThread: ... 50% ... heartbeat fatal … ハートビート監視スレッドがカウントダウンを刻む(CRS-1612 の実体)
  • has a disk HB, but no network HB … node2 はディスクのハートビートは続いているが、ネットワークのハートビートだけが途絶えている。これがネットワーク型 evict の証跡です
  • clssnmCheckForNodeRemoval: ... reason: NHB loss … 削除理由は NHB loss(ネットワークハートビート喪失) と確定
  • clssnmCompareNodeWeights … どちら側のノードを残すかの重み比較(「コホート」の意味は下記 ※ 参照)
  • clssnmrEvictNode: Evicting node 2 … node2 の追放を実行
  • kill block write ... file /dev/sdb … 生存側が投票ディスクに kill block を書き込む/dev/sdb は本検証環境の投票ディスクのデバイス名。実環境では ASM ディスクやマルチパス等で名前は異なる)。切り離しの物理的な実行がこれです

ここに、ネットワーク型 evict の証跡である 「ディスクハートビートは続いている/ネットワークハートビートだけが途絶えている」 が出ています。
この1行で、今回はネットワークだけが死んだネットワーク型 evict だと断定できます。ディスクのハートビートが失われる(投票ディスクに到達できない)ディスク型 evict は証跡が変わりますが、それは次回、投票ディスク到達不可のケースとして検証します。

どちらのノードを残すかの決め方:インターコネクトが切れると、2つのノードは動いているのに互いを見失い、「相手が消えた」と判断します。両方を動かし続けるとスプリットブレインになるため、クラスタは片方だけを残して他方を evict します。ここで「互いに通信できるノードのまとまり」を コホート と呼びます(今回は互いに通信できないので、各ノードがそれぞれ1台だけのコホートです)。どちらのコホートを残すかは clssnmCompareNodeWeights重み(パブリックネットワークへの到達性など)で決めます(この重み比較は 12c 以降の挙動)。今回の存続理由(winreason)は the cohort is the only one with public network access(生存側だけがパブリック網に到達可能)でした。重みが同点なら、番号の小さいノードが残ります。なお、パブリック網への到達性はあくまでインターコネクト断で evict が発生したあと「どちらを残すか」を決める判断材料であって、冒頭のシナリオで触れたとおりパブリック側の断そのものが evict の引き金になるわけではありません

そして切り離しの物理的な仕組みは、共有ディスクへの書き込みです。
ネットワークが切れていても、生存側が投票ディスクに退場を指示する印(kill block)を書き込み、切り離される側がそれを読んで自らを止めます。ネットワーク経由でなく共有ディスク経由なので、通信が切れていても確実に相手を隔離できます。

Step 4. 生存ノード(node1)の ocssd.trc・GM層 ― 前回と同じ層。ただし範囲が広がる

NM層と同じ ocssd.trc の中で、GM層(clssgm*)も動いています。
これは前回の instance down でも動いていた層です。今回も同じ整理が走ります。

ログには grock DG_DATA grock DB+ASM のように出ます。これは DG_DATA(ディスクグループ)・DB+ASMCTSSGROUP(時刻同期)といったサブシステムごとの「グループ」で、各ノードのプロセスがそこに登録されています。メンバーが消えると、GM層がそのグループから取り除きます(clssgmRemoveMember)。

[grid@node1 ~]$ grep -nE "clssgmReconfigThread|clssgmRemoveMember|clssgmDestroyMember" \
  /u01/app/grid/diag/crs/node1/crs/trace/ocssd.trc | grep -E "16:53:(29|30)"
(関連行のみ抜粋)
16:53:29  clssgmReconfigThread: spawned
16:53:30  clssgmRemoveMember: grock DG_DATA, member ... node number 2, member count 1
16:53:30  clssgmRemoveMember: grock DG_RECO, member ... node number 2, member count 1
16:53:30  clssgmRemoveMember: grock DB+ASM, member ... node number 2, member count 1
16:53:30  clssgmDestroyMember: member ... node number 2

前回は、死んだインスタンス1が所属していたグループ(GR+DB_RC19U など)から、そのメンバーを取り除いていました。
今回も同じ clssgmRemoveMemberclssgmDestroyMember ですが、対象が抜けたノード(node2)が持っていた全グループDG_DATADG_RECODB+ASMCTSSGROUP など、ディスクグループや ASM、時刻同期まで)に広がっています。
インスタンスだけが停止した前回に対し、今回はノードごと切り離されたためです。

ここで押さえたいのは、GM層の整理は instance down でも node evict でも出るという点です。判定の決め手は、あくまで Step 3 の NM層 です。

Step 5. 生存ノード(node1)の DBアラートログ ― DB層は前回と同じ構造

ノードが切り離されると、その上の DB インスタンス(rc19u2)も止まります。すると生存側(node1)の DB は、前回の instance down と同じ構造(行の並び)の reconfiguration + インスタンスリカバリを行います。inc 番号・落ちたインスタンス番号・所要時間は当然異なりますが、アラートログへ出力されている内容は前回と同じです。

[oracle@node1 ~]$ grep -iE -B1 "Reconfiguration|Dead instances|looking for dead threads|instance recovery" \
  /u01/app/oracle/diag/rdbms/rc19u/rc19u1/trace/alert_rc19u1.log | tail
Reconfiguration started (old inc 8, new inc 10)
Dead instances (total 1) :
2026-07-11T16:53:31.308+09:00
Instance recovery: looking for dead threads
Beginning instance recovery of 1 threads
Reconfiguration complete (total time 0.2 secs)
Completed instance recovery at
 Thread 2 advanced to log sequence 76 (thread recovery)

Reconfiguration startedDead instanceslooking for dead threadsBeginning instance recoveryReconfiguration complete
前回の instance down で見たものと、行の並びまで同じです。

※ 世代番号(inc)は前回の 4 → 6 に続き、今回は 8 → 10 と、やはり +2 で進んでいました。前回同様、「+1 ずつ」ではありません。

ただし、この再構成が起きた時刻を見ると、Step 3 の切り離しとのつながりが分かります。
NM層の切り離し(clssnmrEvictNode)が 16:53:29 に完了し、その約 1.5 秒後の 16:53:31 に DB の reconfiguration が完了しています。
クラスタ層がノードを切り離す → その巻き添えで DB インスタンスが停止する → DB層が再構成する、というクラスタ層から DB層へ波及する流れが時刻に表れています。

つまり、生存側の DB 再構成ログ(reconfiguration・インスタンスリカバリ)だけを見ても、instance down と node evict は区別できません。生存側の DB は「インスタンスが1つ停止した」としか認識せず、その原因(evict か否か)までは記録しないためです(実機でも生存側の DB アラート・LMON トレースには evictkill は1行も出ず、dead instance detected だけでした)。

Step 6. 切り離された側(node2)は何を記録したか

ここまでは生存ノード(node1)の視点でした。
切り離された node2 自身のログも見ておきます。実際の障害では、どちらのノードのログが手元にあるかで見え方が変わるためです。

まず、node2 の CRSアラートログにはインターコネクト喪失の直接の記録が残ります。

[grid@node2 ~]$ grep "CRS-" /u01/app/grid/diag/crs/node2/crs/trace/alert.log
2026-07-11 16:53:03 [GIPCD(2991)]CRS-42216: ローカルノードにインターフェース定義 ens19(172.16.20.x) が構成されていません
...(0.5秒ごとに繰り返し)
2026-07-11 16:53:29 [OCSSD(3325)]CRS-1609: このノードは他のノードと通信できず、クラスタ整合性を保つため停止します (:CSSNM00008:)
2026-07-11 16:53:36 [OCSSD(3325)]CRS-8503: プロセス OCSSD で致命的な信号または例外コード 6 が発生しました
  • CRS-42216gipcd(インターコネクト管理)が「ens19(インターコネクト)のインターフェースが無い」と繰り返し記録します。落としたのはこの NIC です。切り離された側だけに出る、遮断の直接の証跡です
  • CRS-1609 … node2 は他ノードと通信できず(孤立を検知し)、自らクラスタを停止します。生存側が投票ディスクへ書いた kill block(Step 3)とほぼ同時刻(16:53:29)です。切り離しは「生存側が投票ディスク経由で止める」と「切り離される側が自己停止する」の二重で成立します
  • CRS-8503 ... 例外コード 6 … OCSSD が SIGABRT(例外コード6)で停止した記録です

DB側(切り離された rc19u2)のアラートログには、instance down にはなかった決定的な一行が出ます。

[oracle@node2 ~]$ awk '/2026-07-11T16:53/,/2026-07-11T16:54/' \
  /u01/app/oracle/diag/rdbms/rc19u/rc19u2/trace/alert_rc19u2.log
(関連行のみ抜粋)
2026-07-11T16:53:31 Errors in file rc19u2_lmon_8876.trc (incident=21769):
ORA-29740: インスタンス番号1、グループ・インカネーション10により除去されます
2026-07-11T16:53:36 PMON (ospid: 8574): terminating the instance due to ORA error 499
   Cause - Instance is being terminated due to fatal process death (... IPC0)
2026-07-11T16:53:38 Instance terminated by PMON, pid = 8574
  • ORA-29740 … 「インスタンス番号1(node1)、グループ・インカネーション10 により除去されます」。自分が evict されたことを、切り離された側の DB が記録しています。前回の instance down では、落ちた側は Instance terminated by USER(自分で止まった)でした。ここが明確に異なります
  • Instance terminated by PMON … クリーンに停止したのではなく、PMON によって終了させられます。実機では、evict に続いて重要プロセス(IPC0)が落ち、アラートログに terminating the instance due to ORA error 499(致命的なプロセス死を受けた内部エラー)が記録され、それを受けて PMON がインスタンスを止めていました。前回の terminated by USER(=意図的な停止)とは対照的です

グループ・インカネーション10 は、Step 5 で生存側 node1 が記録した new inc 10 と一致します。両ノードのログが、同じ世代番号で1本につながります。

さらに、切り離された node2 自身の ocssd.trc(NM層)にも、孤立を検知して自己停止する瞬間が残っています。

[grid@node2 ~]$ grep -nE "CheckDskInfo|DiskKillCheck" \
  /u01/app/grid/diag/crs/node2/crs/trace/ocssd*.trc | grep -E "16:53:(29|30)"
(関連行のみ抜粋)
16:53:29 (:CSSNM00008:)clssnmCheckDskInfo: Aborting local node to avoid splitbrain. Cohort led by node 2 (node2) loses to cohort led by node 1 (node1) ... winreason: the cohort is the only one with public network access
16:53:30 (:CSSNM00238:)clssnmvDiskKillCheck: evicted by node node1, number 1 ... evictionreason: NHB loss
  • clssnmCheckDskInfo: Aborting local node ... loses … node2 は重み比較で存続対象から外れ(残るのはパブリック網に到達可能な node1)、スプリットブレインを避けるため自らを停止します。これが CRS-1609(自己停止)の実体です
  • clssnmvDiskKillCheck: evicted by node ... number 1 … node2 は生存側 node1 が書いた kill block を読み、「1番のノードに evict された」と確認します。Step 3 で node1 が書いた kill block の受け取り側がこれです

node2 は、まず自ノードの停止を確定し(16:53:29)、続いて node1 の kill block を読んで裏を取ります(16:53:30)。生存側が書き、切り離される側が読む——切り離しが二重で確実に成立していることが、両ノードの実ログでつながりました。

※ node2 の CSS は 16:53:36 に停止(CRS-8503)し、その際に ocssd.trc はローテートしました。上の 16:53:29〜16:53:30 の記録は、退避された世代 ocssd_56.trc に残っていたものです(そのため世代をまたいで拾えるよう ocssd*.trc で検索しています)。切り離された側のログは、このようにプロセス停止で途中から欠落するのが、実障害でログを読むときのポイントです。

Step 7. 切り離しは Reboot-less ― OS は起動したまま、どう復旧するか

node2 は evict されましたが、OS は再起動していません
切り離しは GI スタック(CSS など)だけを止め、OS ごと落とすわけではないためです。これは Reboot-less Node Fencing(リブートレス・ノード・フェンシング。Reboot-less fencing とも) と呼ばれる、Oracle Clusterware 11.2.0.2 以降の挙動です。従来は障害ノードを OS ごと強制リブートしていましたが、可能な限り OS は再起動せず、GI スタックだけを止めて起動し直します。各ノードの GI 全体を監視する ohasd は動き続け、止まった CSS を再起動しようとし続けます。

[root@node2 ~]# crsctl stat res -t -init
...
ora.cssd
      1        ONLINE  OFFLINE      node2                    INTERCONNECT FAILURE
                                                             ,STARTING
...
[root@node2 ~]# ps -ef | grep ohasd.bin | grep -v grep
root   2198   1  ... /u01/app/19.0.0/grid/bin/ohasd.bin reboot

ora.cssdINTERCONNECT FAILURE で OFFLINE のまま、ohasd.bin は稼働継続(OS 再起動していない)です。
node2 は、次のサイクルに入っています。

ohasd が CSS を再起動
   │
   ▼
インターコネクトが切れたまま → クラスタへの再参加に失敗
   │
   ▼
CSS 自己停止(CRS-1609)
   │
   └─ ohasd がまた再起動 →(先頭に戻る・インターコネクトが戻るまで繰り返し)

それでは、復旧していきましょう。第一手は、切断したインターコネクト(ens19)をもとに戻します。ところが、リンクを上げただけでは疎通が戻りませんでした

# ① リンクを up に戻す
[root@node2 ~]# ip link set ens19 up

# ② IP アドレスは戻っている(が noprefixroute 付き・関連行のみ抜粋)
[root@node2 ~]# ip addr show ens19
    inet 172.16.20.22/24 brd 172.16.20.255 scope global noprefixroute ens19

# ③ リンク UP・IP あり。なのに node1 のインターコネクトへ届かない
[root@node2 ~]# ping -c 3 172.16.20.21
connect: Network is unreachable

リンク(インターフェース)は UP、IP アドレスも戻っているのに ping が届かないのは、172.16.20.0/24 への経路(route)が消えているからです。
IP に付いている noprefixroute が「このアドレスのサブネット経路をカーネルに自動生成させない」設定で、経路は OS の NetworkManager が管理しています。

そのため ip link ... up では経路が戻りません。

そこで、NetworkManager に接続プロファイルを再適用させます。

# ④ NetworkManager に接続プロファイルを再適用する
[root@node2 ~]# nmcli device reapply ens19

# ⑤ 172.16.20.0/24 への経路が復活する
[root@node2 ~]# ip route show | grep 172.16
172.16.20.0/24 dev ens19 proto kernel scope link src 172.16.20.22 metric 101

# ⑥ 疎通が戻る(node2 はこのままクラスタへ自動復帰)
[root@node2 ~]# ping -c 3 172.16.20.21
64 bytes from 172.16.20.21: icmp_seq=1 ttl=64 time=0.248 ms

nmcli device reapply で経路が復活し、ping が通りました。

用語の注意: 本記事で何度も出る NM層 は、CSS(ocssd)の中でノードの在籍・ハートビートを扱う層(clssnm*)を指す呼び名です。ここで出てきた OS の NetworkManager(nmcli とは、頭の「NM」が同じだけでまったくの別物です。NM層=Oracle(クラスタ)側・NetworkManager=OS 側、と押さえてください。

ここで注目したいのは、インターコネクトを直しただけで、node2 が自動的にクラスタへ復帰したことです。
疎通が戻ったあと、srvctl start などの起動操作は一切していません。

それでも生存側(node1)から見ると、rc19u2 が元どおり ONLINE・Open に戻っています。

# node1 から。srvctl start は打っていないのに rc19u2 が復帰(関連行のみ抜粋)
[grid@node1 ~]$ crsctl stat res -t
--------------------------------------------------------------------------------
Name           Target  State        Server                   State details
--------------------------------------------------------------------------------
...
ora.rc19u.db
      1        ONLINE  ONLINE       node1                    Open,STABLE
      2        ONLINE  ONLINE       node2                    Open,STABLE

これは、Step 1 で見た Target が ONLINE のままだったからです。
クラスタは「動かしたい(Target=ONLINE)」という方針を保ち続けていたので、node2 の疎通が戻ると即座に起動を試み、そのまま Open まで戻しました。
前回の instance down(srvctl stop で Target=OFFLINE)であれば、こうは自動で戻りません(手動で srvctl start が要ります)。
Target 列は、そのリソースの"目標状態"(どの状態であるべきか)であり、復旧が自動か手動かを分けるのはこの列です。


4. instance down と node evict の比較 ― 「どの層で見分けるか」

前回と今回を、ログの種類ごとに、生存側/落ちた側の観測点を並べて比較していきましょう。

表の「生存側/落ちた側」は物理ノードでなく"役割"を指します。どちらのノードがどの役割になるかは、前回と今回で入れ替わります。

  • 前回(instance down):node1 が停止 → 生存側=node2
  • 今回(node evict):node2 を切り離し → 生存側=node1

違いは限られた場所にしか出ないことが分かります。

見る場所観測点instance down(前回)node evict(今回)見分けに使えるか
crsctl stat res -t全体Target=OFFLINE/State=OFFLINE(srvctl stop・VIP は動かない)Target=ONLINE/State=OFFLINEVIP フェイルオーバ使える
DBアラート+LMONトレース生存側Reconfiguration・インスタンスリカバリ(Total dlm rcfg time構造は同左(inc・所要時間・落ちたインスタンス番号だけ違う)使えない(前回と同じ)
DBアラート落ちた側Instance terminated by USER(自分で停止)ORA-29740Instance terminated by PMON(除去される)使える
ocssd.trc NM層clssnm*生存側無反応sending status msg to nodes: 1,2 継続)evict の出力no network HBEvicting node→kill block)★決め手
落ちた側ノードは残る=evict 特有の記録なし自己停止CSSNM00008)→ kill block 読み(CSSNM00238使える
ocssd.trc GM層(clssgm*生存側死んだインスタンスのグループ整理抜けたノードのグループ整理△(範囲が違うだけ)
落ちた側ノードは残る=特筆なし―(自己停止で ocssd ごと途絶。GM層の整理も途中で終わる)
CRSアラート生存側CRS-1735(メンバーレベルの fence)1行のみCRS-1612/1610/1607 カウントダウン → ノード削除使える
落ちた側ノードは残る=記録なしCRS-42216(NIC喪失)→ CRS-1609(自己停止)使える
復旧(元に戻すとき)落ちた側手動起動が要る(srvctl start・Target=OFFLINE)原因を取り除けば自動復帰(インターコネクト回復・Target=ONLINE のまま)―(見分けでなく復旧手順の違い)

端的にいうと、こうです。

生存側の DB 再構成(reconfiguration・インスタンスリカバリ)だけを見ても、instance down と node evict は区別できない。
区別できるのは、ocssd.trc の NM層(clssnm*)と、CRS アラートのカウントダウン、そして切り離された側の ORA-29740 である。

前回「NM層に出たら evict」と予告した基準が、今回の実機で埋まりました。


5. よくある Q&A

Q1. node evict の「ネットワーク型」と「ディスク型」はどこで見分けますか?
ocssd.trc(NM層)の clssnmvDHBValidateNCopy の行です。
今回の has a disk HB, but no network HB(ディスクは続いている/ネットワークだけ途絶えた)はネットワーク型です。
ディスクのハートビートが失われる(投票ディスクに到達できない)ケースはディスク型で、証跡が変わります(次回検証)。

Q2. 切り離しは、生存側が止めるのですか、切り離される側が自分で止まるのですか?
両方です。
生存側は投票ディスクに kill block を書いて相手を隔離し(clssnmvDiskEvict)、切り離された側も孤立を検知して自己停止します(CRS-1609)。
今回はどちらも 16:53:29 とほぼ同時刻でした。ネットワークが切れていても投票ディスク経由で確実に隔離できる、という二重の仕組みです。

Q3. evict されたノードは OS ごと再起動するのですか?
今回はしていません(Reboot-less Node Fencing)。
GI スタック(CSS など)だけが停止し、OS と ohasd は動き続けます。
ohasd は CSS の再起動を試み続けるため、原因(インターコネクト断)が残っている間は「再起動 → 再参加失敗 → 自己停止」を繰り返します。

Q4. ORA-29740 は必ず evict のときに出ますか?
evict された(除去された)インスタンス側に出ます。
ORA-29740: ... により除去されます は「他インスタンスの判断で自分が除去された」という記録で、前回の instance down(Instance terminated by USER =自分で停止)にはありません。
切り離された側の DB アラートを確認できるなら、これが決定的な手がかりになります。

Q5. 前回の CRS-1735(fence)は、今回どうなりましたか?
今回も CRS アラートに CRS-1735 は出ます(メンバーレベルの fence)。
ただし node evict の本体は、そちらではなく CRS-1607(ノード削除)と ocssd.trcclssnmrEvictNode(NM層)です。前回同様、CRS-1735 の字面だけで evict と判断しない点は変わりません。


6. まとめ

まず見る順番(診断フロー)

「インスタンス2がダウン」の第一報から node evict を見分けるには、次の順で見ます。

「インスタンスがダウン」のアラート
        │
        ▼  ① 全体のリソース状況を確認
  crsctl stat res -t
    インスタンスだけ OFFLINE? それとも node 側リソースもフェイルオーバ?
        │
        ▼  ② 生存ノードの CRSアラートログ
  CRS-1612/1611/1610(50/75/90%)のカウントダウン → CRS-1607 削除
    出ていれば instance down ではない
        │
        ▼  ③ ocssd.trc を「層」で読む(最重要)
  clssnm*(NM層)に評価〜切り離しあり → node evict で確定
    no network HB → ネットワーク型(本記事)/ディスクHB喪失 → ディスク型(次回)
        │
        ▼  補足
  DBアラートの reconfiguration は instance down と同じ構造(見分けには使えない)
  切り離された側があるなら ORA-29740 / terminated by PMON を確認

実際の時系列 ― 30秒間に両ノードで何が起きたか

Step 1〜6 で個別に見た記録を、時刻を軸に両ノードで並べると、node evict の一部始終が1本につながります(遮断 16:53:00 起点。時刻は本検証環境の実測値)。

時刻生存側 node1(残る側)落ちた側 node2(evict される側)
16:53:00ens19(インターコネクト)をダウン ← 遮断
16:53:03〜CRSアラート CRS-42216(NIC喪失)を繰り返し記録
16:53:07CRSアラート CRS-7503(通信異常を検知)
16:53:14ocssd.trc「disk HB あり/network HB なし」・CRS-1612(50%)カウントダウン開始ディスクHBは継続(ネットワークHBだけ断)
16:53:21〜16:53:26CRS-1611(75%)→ CRS-1610(90%)同上
16:53:28NM層:削除を決定(reason: NHB loss
16:53:29NM層:重み比較 → Evicting node 2投票ディスクへ kill block 書込CRS-1607 ノード削除孤立と判断し自ら停止CSSNM00008CRS-1609
16:53:30CRS-1601 CSS 再構成完了生存側の kill block を読むCSSNM00238
16:53:31DB:reconfiguration + インスタンスリカバリ完了(inc 8→10)DB:ORA-29740(「インスタンス1に除去された」)
16:53:36IPC0 プロセス死(アラートログ ORA error 499)→ PMON がインスタンス停止/CRS-8503(CSS 停止)=ログ途絶

決定的なのは 16:53:29 です。生存側 node1 が node2 の切り離しを確定し、投票ディスクへ kill block を書き込みます。ほぼ同時に、落ちた側 node2 も自ノードの孤立を検知して自己停止します(CRS-1609)。この2つが揃って切り離しが確定します。

押さえておくポイントは3つです。

  1. 判定の決め手は ocssd.trc の NM層(clssnm*
    前回無反応だったこの層に、no network HBEvicting nodekill block write まで一続きで出ます。
  2. DB層(reconfiguration)は instance down と区別できない。切り分けを DB アラートだけで終えない。
  3. 切り離された側は ORA-29740 で「除去された」と記録する。生存側と切り離された側で、記録の意味が逆になる。

前回の instance down と今回の node evict を並べたことで、「どの層に出たかで見分ける」という切り分けの基準が完成しました。