技術ブログ
引き続き、今週金曜日の特濃JPOUG | Japan Oracle User Groupの準備をしつつ、いろいろ検証しております。その中で、あらためて論理破損の厄介さを痛感させられております。
論理破損は、様々な要因により発生し、引き起こされる破損の状況も様々です。 論理破損を引き起こす1つの要因に"Lost Write"というストレージの問題があります。 これは、pwrite()等の更新系のシステムコールが正常に完了したにも関わらず、 実際には物理的な記憶領域は更新されていないというような、更新が実質的に失われてしまうような問題を指します。
"Lost Write"が発生すると、物理的な記憶領域におけるブロックは更新前の状態のままとなります。 したがって、Oracle Databaseから見るとブロックの形式にはまったく問題はなく、単に格納されている行データが古いだけ。という形になります。すなわち、物理破損を検出する機構では、この種の論理破損は検出できない位置付けになります。
ddコマンドを使用して"Lost Write"をエミュレートしてみます。
SQL> create table tbl_lostwrite ( i number, s1 varchar(100)) pctfree 99 tablespace tbs2; 表が作成されました。 SQL> insert into tbl_lostwrite values(1, 'JPOUG'); 1行が作成されました。 SQL> commit; コミットが完了しました。 SQL> select dbms_rowid.rowid_block_number(rowid) "Block#" from TBL_lostwrite; Block# ---------- 133 SQL> ALTER SYSTEM FLUSH BUFFER_CACHE; システムが変更されました。
初期状態のデータファイルをバックアップしておき、そのあとUPDATEを実行します。
SQL> define dirpath=/u01/app/oracle/oradata/c101p/ SQL> host cp &dirpath/tbs2.dbf &dirpath/tbs2_old.dbf SQL> SQL> update tbl_lostwrite SET s1 = 'XXXXX' WHERE i = 1; 1行が更新されました。 SQL> commit; コミットが完了しました。 SQL> SELECT * FROM tbl_lostwrite; I S1 ---------- ---------------------------------------- 1 XXXXX SQL> ALTER SYSTEM FLUSH BUFFER_CACHE; システムが変更されました。
当然のことながら、UPDATE実行後のSELECTでは、UPDATEにより更新されたデータが返ってきています。
上記の通り、今回はUPDATEによる更新処理は正常に実行されています。ここで、更新処理が失われた状態を疑似的に作り出してみます。これは、UPDATEにより更新されたブロックを、過去の状態に戻することで実現できます。
SQL> host dd if=&dirpath/tbs2_old.dbf of=&dirpath/tbs2.dbf bs=8192 skip=133 seek=133 count=1 conv=notrunc oflag=direct 1+0 records in 1+0 records out 8192 bytes (8.2 kB) copied, 0.00016607 s, 49.3 MB/s SQL> SQL> SELECT * FROM tbl_lostwrite; I S1 ---------- ---------------------------------------- 1 JPOUG
すると、SELECT結果は、更新前の状態に戻ります。何もエラーが発生していない、すなわち、Oracle Databaseは"Lost Write"により引き起こされた論理破損に気づかないことに注意してください。
"Lost Write"による論理破損は、前回ご紹介した表と索引が不整合となっている論理破損と同様に、Oracle Databaseの機能を用いた破損検出がきわめて困難です。以下のように各種コマンドを実行しても、破損を検出できません。
RMAN> backup datafile 6; backupが開始されました(開始時間: 13-11-09) チャネル: ORA_DISK_1が割り当てられました チャネルORA_DISK_1: SID=44 デバイス・タイプ=DISK チャネルORA_DISK_1: フル・データファイル・バックアップ・セットを開始しています チャネルORA_DISK_1: バックアップ・セットにデータファイルを指定しています 入力データファイル・ファイル番号=00006 名前=/u01/app/oracle/oradata/c101p/tbs2.dbf チャネルORA_DISK_1: ピース1(13-11-09)を起動します チャネルORA_DISK_1: ピース1(13-11-09)が完了しました ピース・ハンドル=/u01/app/oracle/product/12.1.0.1/ee_1/dbs/0coognl4_1_1 タグ=TAG20131109T070507 コメント=NONE チャネルORA_DISK_1: バックアップ・セットが完了しました。経過時間: 00:00:01 backupが完了しました(完了時間: 13-11-09) RMAN> backup CHECK LOGICAL datafile 6; backupが開始されました(開始時間: 13-11-09) チャネルORA_DISK_1の使用 チャネルORA_DISK_1: フル・データファイル・バックアップ・セットを開始しています チャネルORA_DISK_1: バックアップ・セットにデータファイルを指定しています 入力データファイル・ファイル番号=00006 名前=/u01/app/oracle/oradata/c101p/tbs2.dbf チャネルORA_DISK_1: ピース1(13-11-09)を起動します チャネルORA_DISK_1: ピース1(13-11-09)が完了しました ピース・ハンドル=/u01/app/oracle/product/12.1.0.1/ee_1/dbs/0doognn8_1_1 タグ=TAG20131109T070616 コメント=NONE チャネルORA_DISK_1: バックアップ・セットが完了しました。経過時間: 00:00:01 backupが完了しました(完了時間: 13-11-09) RMAN> backup CHECK LOGICAL VALIDATE datafile 6; backupが開始されました(開始時間: 13-11-09) チャネルORA_DISK_1の使用 チャネルORA_DISK_1: フル・データファイル・バックアップ・セットを開始しています チャネルORA_DISK_1: バックアップ・セットにデータファイルを指定しています 入力データファイル・ファイル番号=00006 名前=/u01/app/oracle/oradata/c101p/tbs2.dbf チャネルORA_DISK_1: バックアップ・セットが完了しました。経過時間: 00:00:01 データファイル・リスト ================= ファイル ステータス マーク済破損 空のブロック 調査済ブロック 高SCN ---- ------ -------------- ------------ --------------- ---------- 6 OK 0 1145 1280 589437 ファイル名: /u01/app/oracle/oradata/c101p/tbs2.dbf ブロック・タイプ 失敗ブロック 処理済ブロック ---------- -------------- ---------------- データ 0 5 索引 0 0 その他 0 130 backupが完了しました(完了時間: 13-11-09) RMAN> VALIDATE datafile 6; validateが開始されました(開始時間: 13-11-09) チャネルORA_DISK_1の使用 チャネルORA_DISK_1: データファイルの検証を開始しています チャネルORA_DISK_1: 検証のためのデータファイルを指定しています 入力データファイル・ファイル番号=00006 名前=/u01/app/oracle/oradata/c101p/tbs2.dbf チャネルORA_DISK_1: 検証が完了しました。経過時間: 00:00:01 データファイル・リスト ================= ファイル ステータス マーク済破損 空のブロック 調査済ブロック 高SCN ---- ------ -------------- ------------ --------------- ---------- 6 OK 0 1145 1280 589437 ファイル名: /u01/app/oracle/oradata/c101p/tbs2.dbf ブロック・タイプ 失敗ブロック 処理済ブロック ---------- -------------- ---------------- データ 0 5 索引 0 0 その他 0 130 validateが完了しました(完了時間: 13-11-09) RMAN> exit Recovery Managerが完了しました。 [oracle@ol64n19 ~]$ sqlplus rywatabe/rywatabe SQL*Plus: Release 12.1.0.1.0 Production on 土 11月 9 07:06:54 2013 Copyright (c) 1982, 2013, Oracle. All rights reserved. 最終正常ログイン時間: ナレ 11キ・09 2013 06:50:54 +09:00 Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options に接続されました。 SQL> analyze table tbl_lostwrite validate structure cascade; 表が分析されました。 SQL> analyze table tbl_lostwrite validate structure cascade FAST; 表が分析されました。
なお、再度更新を実行しても、特にエラーは発生しません。
SQL> update tbl_lostwrite SET s1 = 'YYYYY' WHERE i = 1; 1行が更新されました。 SQL> commit; コミットが完了しました。