RAC One Node の検証 その4
<RAC One Node の検証 その4>
ペンネーム : ダーリン
さてさて、RAC One Node の検証も 4 回目を迎えました。RAC の
ようで、でもちょっと違う微妙な構成にも徐々になれてきたでしょ
うか。
なかなか環境が手元にないと簡単な検証を行うにも困ってしまいま
すね。RAC One Node をちょっと触ってみたいけど環境がなくて…
という読者の方は、このメルマガで少しでも雰囲気を味わっていた
だければ幸いです。
前回、Omotion 中の Oracle インスタンスのアラートログから以下
のメッセージを拾い上げました。”transactional” ということはも
しかすると Omotion の処理時間が延びてしまう可能性があるとい
うことでしょうか。
今週はこの “transactional” について少し見ていきます。
————————————————
Shutting down instance (transactional)
————————————————
これは、( Omotion 中に )「データベースインスタンスを transactional
モードで停止します。」という意味です。
Oracle ではデータベースインスタンスを停止する場合には以下の
オプションがあります。
・NORMAL
・IMMEDIATE
・TRANSACTIONAL
・ABORT
また、SHUTDOWN 時に TRANSACTIONAL オプションが指定された場合
の動作については、マニュアルに以下のような説明があります。
・文が発行された後は、新しい接続や新しいトランザクションの 開始は許可されません。 ・すべてのトランザクションが完了すると、まだインスタンスに 接続されているすべてのクライアントが切断されます。 ・この時点で、インスタンスはSHUTDOWN IMMEDIATE文を発行した 場合と同じように停止します。 ・次にデータベースを起動するときに、インスタンス・リカバリ 手順は必要ありません。
つまり、全てのトランザクションが完了しないと SHUTDOWN 処理自
体が終了しないということになります。よって、TRANSACTION モー
ドを使って処理が行われている Omotion もこれに従わざるをえま
せん。
今回のシリーズ 2 回目で少しふれましたが Omotion は主にサーバ
のメンテナンスなどのシーンで使われるはずです。
ということは、、、、
– メンテナンス目的の計画停止の際に Omotion を発行して、
– インスタンスを移動し、
– 切り替えが終わったらサーバを停止して、、、、
– と思ったら、まだインスタンスが切り替わっていなぁ~い!!
ということになってしまうかもしれません。
ところで読者のみなさんの環境ではサーバメンテナンスでインスタ
ンスを停止する場合は、どのようにしているでしょうか。
いくらトランザクション中だと言っても、いつまでもそれが終了す
るまで待機することはないですよね?
通常は、IMMEDIATE モードでSHUTDOWN させ、実行中のトランザク
ション処理についてもロールバックさせるなどの対応をされている
のではないでしょうか。
Omotion といえどもやはりいつまでもトランザクションの終了を待
ちたくはありません。で、どうするかというと、、、
Omotion 実行時の入力項目を今一度確認するとこんな設定項目があ
ります。
———————————————————–
Specify maximum time in minutes for migration to complete
(max 30) [30]: 2 <<<< (2)
———————————————————–
これは、「移行終了までの最大時間 [ 分 ](最大 30)」という
ことで、どうやら上限を設定することができるようです。
デフォルトが 30 分とのことですが、ちょっと我慢強くないので
2 分で再度確認してみます。
また、前回のテストスクリプトではインサートごとにコミットし
ているのでトランザクションの時間は非常に短かいため、設定値
2 分に対しては影響がありません。よって、今回はコミットまで
の時間がちょっと長くなるように改修 ( 下記「テストスクリプト
改修版」参照 ) して検証してみます。
改修ポイントは COMMIT の間隔を設定するようにしたところです。
検証では 4 分 ( 240 秒 ) に設定しています。
これで、「移行終了までの最大時間」までにトランザクションが
終了しなかった場合にどうなるのかを確認できます。
では今回もテストスクリプト改修版を実行しながら Omotion !!
$ Omotion
(今回は oel55sv02 側 から oel55sv01 側への Omotion です。 )
まず、Omotion の標準出力に以下のようなメッセージが表示されました。
----------------------------------------------------------- RAC One Node databases on this cluster: Omotion Started... Starting target instance on oel55sv01... Migrating sessions... Stopping source instance on oel55sv02... Timeout exceeded, aborting instance... <<< select idate 2 , cnt 3 , csid 4 , to_char(trunc(dtime/60),'FM999') || ':' 5 || to_char(mod(dtime,60),'FM00') dtime 6 from ora3_test order by idate IDATE CNT CSID DTIME ------------------- ----- ----- ---------- 2010/08/03 00:04:55 1 RON_2 0:04 2010/08/03 00:05:00 2 RON_2 0:09 2010/08/03 00:05:05 3 RON_2 0:14 2010/08/03 00:05:10 4 RON_2 0:19 : : : : : : 2010/08/03 00:07:50 36 RON_2 2:59 2010/08/03 00:07:55 37 RON_2 3:04 2010/08/03 00:08:00 38 RON_2 3:09 2010/08/03 00:11:25 1 RON_1 6:34 <<< データ欠損!? 2010/08/03 00:11:30 2 RON_1 6:39 2010/08/03 00:11:35 3 RON_1 6:44 2010/08/03 00:11:40 4 RON_1 6:49 2010/08/03 00:11:45 5 RON_1 6:54 2010/08/03 00:11:50 6 RON_1 6:59 : : : : : : ----------------------------------------------------------- IDATE INSERT 時刻 CNT 接続した状態での INSERT の累計回数。再接続でクリア CSID 接続先の SID DTIME スクリプト開始後からの経過時間
上記の 00:11:25 の接続先 SID が変わったタイミングでデータが
欠損してしまいました。
アラートログを確認して時系列と挙動を確認してみましょう。
まずは、移行元のインスタンス( oel55sv02 側)です。
----------------------------------------------------------- Tue Aug 03 00:08:52 2010 Shutting down instance (transactional) Stopping background process SMCO Shutting down instance: further logons disabled Tue Aug 03 00:08:57 2010 Setting Resource Manager plan DEFAULT_MAINTENANCE_PLAN via parameter Stopping background process QMNC Tue Aug 03 00:08:57 2010 Stopping background process CJQ0 Stopping background process MMNL Stopping background process MMON Tue Aug 03 00:10:54 2010 License high water mark = 7 USER (ospid: 708): terminating the instance Instance terminated by USER, pid = 708 -----------------------------------------------------------
00:08:52 に TRANSACTIONAL モードでインスタンスの停止が始まっ
ています。
で、00:10:54 にいきなり停止?(terminating the instance)
確かに、Omotion で指定した待機時間 ( 2 分 ) とほぼ同じ時間
待機している様子がみえます。
では、移行先のインスタンス ( oel55sv01 側 ) の方も確認して
おきましょう。
----------------------------------------------------------- Tue Aug 03 00:10:58 2010 Reconfiguration started (old inc 140, new inc 142) List of instances: 1 (myinst: 1) Global Resource Directory frozen * dead instance detected - domain 0 invalid = TRUE Communication channels reestablished Tue Aug 03 00:10:59 2010 Instance recovery: looking for dead threads Reconfiguration complete Beginning instance recovery of 1 threads Started redo scan Completed redo scan read 25 KB redo, 26 data blocks need recovery Started redo application at Thread 2: logseq 7, block 15237 Recovery of Online Redo Log: Thread 2 Group 4 Seq 7 Reading mem 0 Mem# 0: +DATA/ron/onlinelog/group_4.270.723224611 Mem# 1: +DATA/ron/onlinelog/group_4.271.723224633 Completed redo application of 0.01MB Tue Aug 03 00:11:10 2010 Completed instance recovery at Thread 2: logseq 7, block 15287, scn 4924815 26 data blocks read, 26 data blocks written, 25 redo k-bytes read Thread 2 advanced to log sequence 8 (thread recovery) -----------------------------------------------------------
ほぼ同じタイミングで 00:10:58 から Reconfigration が始まって
います。
通常の RAC 構成のノードが停止した時と同じようにマスタノード
の再設定などが行われているようです。
おっと、途中でこんなメッセージが。
———————————————————–
Beginning instance recovery of 1 threads
———————————————————–
インスタンスリカバリ…..
TRANSACTIONAL では、インスタンスリカバリは不要なはずです。
SHUTDOWN の他のモードも含めてよくよく見てみると、インスタン
スリカバリが必要になるのは、やはり、SHUTDOWN ABORT….
どうやら、Omotion の待機時間を超えてトランザクションが終了し
ない場合は ABORT 相当の処理が実行されるようですねぇ。移行元
のインスタンスがいきなり停止しているように見えた理由も納得が
いきます。
ちなみに、テストスクリプト内では 5 秒ごとにデータを INSERT
して、4 分ごとに COMMIT を発行するようにしているので、移行
元のインスタンスが停止する直前の 00:10:50 までは INSERT さ
れていたはずです。
ここで 移行元のインスタンス ( oel55sv02 側 ) で ABORT 相当の
処理が実施されたため移行先のインスタンス ( oel55sv01 側 ) で
インスタンスリカバリが実行され、直前の COMMIT タイミング時点
まで ( 00:08:00 時点 ) ロールバックされたと考えられます。
・Omotion ではトランザクションモードで移行元のインスタンスを 停止している。 ・トランザクションモードでインスタンスを停止する場合は、実行 中のトランザクションが終了するまで停止処理は待機する。 ・アプリケーションからのトランザクションが継続していると Omotion は制限時間まで待機する。(デフォルトは 30 分) 制限時間に達すると、ABORT 相当の処理で移行元のインスタンス は停止する。 ・ABORT 相当の処理が行われると、実行中のトランザクションはロー ルバックされ、該当処理のデータは更新されない。
よって、運用上 Omotion を実行する場合は実際のトランザクション
にかかる時間を十分に把握したうえで Omotion の待機時間を設定す
る必要があります。(そうしないと、途中まで進行した処理がロー
ルバックされてしまう可能性があります。)
あるいは、計画メンテナンスなどの作業が控えている状況において
は、延々とトランザクションの終了を待ち続けるわけにもいかない
でしょうから、事前に全ての処理を停止しておいてもらう様に周知
しておく方が望ましいでしょう。
このあたりは通常の運用と同じ考慮が必要ということです。
次回は、Omotion は使わずにガッツリとインスタンスを落としてみ
ます。つまり障害時のシミュレートです。
どんな挙動を示すのでしょうか
==
補足1「テストスクリプト改修版」
------------------------------- #/bin/sh CNT=0 # sqlplus ora3/ora3@ron <<_EOF_ truncate table ora3_test2; truncate table ora3_start; insert into ora3_start (sdate) values (sysdate); commit; exit _EOF_ # while [ ${CNT} -lt 2 ]; do sqlplus ora3/ora3@ron <<_EOF_ DECLARE v_start_date date := NULL; v_sysdate date := NULL; v_time_min number := 0; v_time_sec number := 0; v_insert_interval number := 5; v_commit_interval number := 240; v_sleep number := 5; v_count number := 0; v_instance_name varchar2(5) := NULL; BEGIN select sdate into v_start_date from ora3_start; v_sysdate := sysdate; v_time_min := to_number(to_char(v_sysdate,'mi')); v_time_sec := to_number(to_char(v_sysdate,'ss')); v_sleep := v_insert_interval - mod(v_time_min*60+v_time_sec,v_insert_interval); DBMS_LOCK.SLEEP(v_sleep); LOOP v_sysdate := sysdate; v_time_min := to_number(to_char(v_sysdate,'mi')); v_time_sec := to_number(to_char(v_sysdate,'ss')); v_count := v_count + 1; insert into ora3_test (idate,cnt,csid,dtime) values (v_sysdate,v_count,sys_context('userenv','instance_name'),(v_sysdate - v_start_date)*60*60 *24); IF (mod(v_time_min*60+v_time_sec,v_commit_interval) < v_insert_interval) THEN COMMIT; END IF; v_sysdate := sysdate; v_time_min := to_number(to_char(v_sysdate,'mi&')); v_time_sec := to_number(to_char(v_sysdate,'ss')); v_sleep := v_insert_interval - mod(v_time_min*60+v_time_sec,v_insert_interval); DBMS_LOCK.SLEEP(v_sleep); END LOOP; END; / exit _EOF_ echo "Exit at:" `date '+%Y/%m%d %H%M%S'` CNT=`expr ${CNT} + 1` sleep 1 done exit -------------------------------
補足2「テストテーブル」
------------------------------- create table ora3_start (sdate date); create table ora3_test (idate date,cnt number,csid char(10),dtime number); -------------------------------