oracle
バックアップはできたものの、実際にそのバックアップから戻すのは経験しないと意味がないと思っている。
っで、オラクルさんのRMANの操作でバックアップされるファイルは下記となる。
・データベースファイル
・制御ファイル
・アーカイブREDOログファイル(オリジナルな「REDOログファイル」ではない)
・初期化パラメータファイル
RMANでバックアップされたファイルを別のソフトウエア(ntbackup, rsyncら)で別の場所に持っていくのもいい。
といっても迅速に障害から復旧してたいのなら、なるべくはRMANの操作の中で復旧を終えたい。
っとなると制御ファイルやアーカイブREDOログファイルの複数ストレージ同時展開が望ましく、まさにASMの世界。
ここではハードウエアの構成にも寄るのだが、上記のそれぞれでファイルが読めなくなった際のRMANを使っての復旧を語る
データベースファイル(***.dbf)が読めない†
障害作成:
1
2
| C:\TEMP> echo 1 > null.dbf *1byteファイル。
C:\TEMP> ocopy null.dbf *強制的な上書きコピー
|
障害確認:
1
2
3
4
5
6
7
8
9
10
11
| SQL> select count(*) from demo10q1;
select count(*) from demo10q1
*
行1でエラーが発生しました。:
ORA-01115: ファイル(ブロック番号)からの読取りI/Oエラーが発生しました。
ORA-01110: データファイル5: 'D:\ORADATA\AERS\AERS.DBF'
ORA-27070: 非同期の読取り/書込みに失敗しました。
OSD-04006: ReadFile()に失敗しました。ファイルからの読取りができません
O/S-Error: (OS 38) ファイルの終わりです。
SQL>
|
確かに検索できなくなった
緊急措置:
1
2
3
4
5
| C:\TEMP> sqlplus sys as sysdba
SQL*Plus: Release 11.2.0.3.0 Production on 土 6月 15 16:56:44 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
アイドル・インスタンスに接続しました。
SQL>
|
どうやらORACLEは自動的に落ちたみたい。落ちていないのなら
shutdown abort
で落としてみる。
復旧活動:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| SQL> startup mount
ORACLEインスタンスが起動しました。
Total System Global Area 2.6724E+10 bytes
Fixed Size 2267824 bytes
Variable Size 2.5904E+10 bytes
Database Buffers 805306368 bytes
Redo Buffers 12099584 bytes
データベースがマウントされました。 *mountまでは行えた
SQL>
SQL>
SQL> recover database; *recoverを試みると
ORA-00283: エラーによってリカバリ・セッションは取り消されました。
ORA-01110: データファイル5: 'D:\ORADATA\AERS\AERS.DBF'
ORA-01157: データファイル5を識別/ロックできません -
DBWRトレース・ファイルを参照してください
ORA-01110: データファイル5: 'D:\ORADATA\AERS\AERS.DBF'
SQL>
|
この段階で一応データファイル5が見えないと原因を伝えているのだが、一応SQLでも確認するには
1
2
3
4
5
6
7
| | $ sqlplus SYS@AERS as sysdba
SQL> SELECT file# , error , online_status , change#, time FROM V$RECOVER_FILE;
FILE# ERROR ONLINE_STATUS CHANGE# TIME
5 FILE NOT FOUND ONLINE 0
SQL>
|
データファイルは見えない物の、まだONLINEとして認識されている模様
っで、このデータファイル5なるもののありかは、
1
2
3
4
5
6
7
8
9
10
11
12
| | SQL> SELECT name, file#, status, TS# FROM V$DATAFILE;
NAME FILE# STATUS TS#
D:\ORADATA\AERS\SYSTEM01.DBF 1 SYSTEM 0
D:\ORADATA\AERS\SYSAUX01.DBF 2 ONLINE 1
D:\ORADATA\AERS\UNDOTBS01.DBF 3 ONLINE 2
D:\ORADATA\AERS\USERS01.DBF 4 ONLINE 4
D:\ORADATA\AERS\AERS.DBF 5 ONLINE 6
D:\ORADATA\AERS\AERSIND.DBF 6 ONLINE 7
D:\ORADATA\AERS\AERSTBL.DBF 7 ONLINE 8
SQL>
|
となる。ちなみにTS#は表領域の番号でこれは
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| | SQL> SELECT TS#, name FROM V$TABLESPACE;
TS# NAME
0 SYSTEM
1 SYSAUX
2 UNDOTBS1
4 USERS
3 TEMP
6 AERS
7 AERSIND
8 AERSTBL
9 AERSTMP
SQL>
|
と各TS#がどんな表領域に当てられているかが分かる。っで、問題部分をOFFLINEへ。
1
2
3
| | SQL> ALTER DATABASE DATAFILE 'D:\ORADATA\AERS\AERS.DBF' OFFLINE;
データベースが変更されました。
SQL>
|
と指定して当該データファイルをOFFLINEにしてしまい、
次にバックアップから失われたファイルをリストアして、リカバリ処理を行う。
RMANにログインして、バックアップから指定のデータファイルを取り戻す。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| | $ RMAN TARGET /
ターゲット・データベース: AERS(DBID=2976312353、未オープン)に接続されました *startup mountのまま
RMAN>
RMAN> restore datafile 5;
restoreが開始されました(開始時間: 13-06-15)
リカバリ・カタログのかわりにターゲット・データベース制御ファイルを使用しています
チャネル: ORA_DISK_1が割り当てられました
チャネルORA_DISK_1: SID=63 デバイス・タイプ=DISK
チャネルORA_DISK_1: データファイル・バックアップ・セットのリストアを開始しています
チャネルORA_DISK_1: バックアップ・セットからリストアするデータファイルを指定しています
チャネルORA_DISK_1: データファイル00005をD:\ORADATA\AERS\AERS.DBFにリストアしています
チャネルORA_DISK_1: バックアップ・ピースE:\BACKUP\1EOC76DG_1_1から読取り中です
チャネルORA_DISK_1: ピース・ハンドル=E:\BACKUP\1EOC76DG_1_1 タグ=BACKUP_AERS.CHAPER_061513010009
チャネルORA_DISK_1: バックアップ・ピース1がリストアされました
チャネルORA_DISK_1: リストアが完了しました。経過時間: 00:16:18
restoreが完了しました(完了時間: 13-06-15)
RMAN>
|
リストアは、バックアップからのファイルの戻し操作のみで、バックアップ操作後に生じている内容の変更は加わっていない。
そのため、アーカイブREDOログファイルの適用と最新のREDOログの適用を行う
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| | RMAN>
RMAN> RECOVER DATAFILE 5;
recoverが開始されました(開始時間: 13-06-15)
チャネルORA_DISK_1の使用
チャネルORA_DISK_1: 増分データファイル・バックアップ・セットのリストアを開始しています
チャネルORA_DISK_1: バックアップ・セットからリストアするデータファイルを指定しています
データファイル00005のリストア先: D:\ORADATA\AERS\AERS.DBF
チャネルORA_DISK_1: バックアップ・ピースE:\BACKUP\1UOC8QRC_1_1から読取り中です
チャネルORA_DISK_1: ピース・ハンドル=E:\BACKUP\1UOC8QRC_1_1 タグ=BACKUP_AERS.CHAPER_061513035501
チャネルORA_DISK_1: バックアップ・ピース1がリストアされました
チャネルORA_DISK_1: リストアが完了しました。経過時間: 00:01:35
メディア・リカバリを開始しています
メディア・リカバリが完了しました。経過時間: 00:00:01
recoverが完了しました(完了時間: 13-06-15)
RMAN>
|
これでリストアは完了して、データベースを公開します。
1
2
3
4
5
6
7
8
9
| | SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE DATAFILE 'D:\ORADATA\AERS\AERS.DBF' ONLINE;
SQL> select count(*) from aers.demo10q1;
COUNT(*)
136191
SQL>
|
以上表領域の障害時復旧。
個別テーブルの復元†
データを削除(delete)、上書き(update)、追記(insert)もしくはテーブルそのものを削除(drop)の際、
戻したくなる時がある。
■削除したテーブルの復旧
管理者権限で
1
2
3
4
5
6
| | SQL> show parameter RECYCLEBIN
NAME TYPE VALUE
recyclebin string on
SQL>
|
となっていれば、テーブル復活の呪文が使える。
障害作成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| | SQL> create table sample(id int);
表が作成されました。
SQL> select table_name from user_tables where table_name='SAMPLE';
TABLE_NAME
SAMPLE
SQL>
SQL> drop table sample;
表が削除されました。
SQL> select table_name from user_tables where table_name='SAMPLE';
レコードが選択されませんでした。
SQL>
|
な感じでテーブルを削除
復旧活動:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| | SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
SAMPLE BIN$s/LmllkYRiWYyfOOCISP2Q==$0 TABLE 2013-06-15:21:36:06
SQL>
SQL> SELECT object_name as recycle_name, original_name, type FROM recyclebin;
RECYCLE_NAME ORIGINAL_NAME TYPE
BIN$s/LmllkYRiWYyfOOCISP2Q==$0 SAMPLE TABLE
SQL>
SQL> flashback table sample to before drop;
フラッシュバックが完了しました。
SQL>
SQL> select table_name from user_tables where table_name='SAMPLE';
TABLE_NAME
SAMPLE
SQL>
|
別名保存なら
flashback table "BIN$s/LmllkYRiWYyfOOCISP2Q==$0" to before drop rename to sample_old;
とする
*どうも時刻(DROP TIME)が標準時で困る...
■テーブルデータの復旧
「フラッシュバック(Flashback)」機能を使えば目的の時点まで戻せるそうな。
っでその「時点」の示し方は
- 指定時刻
- 特定SCN(System Commit Number)
SCNの値と時刻およびREDOファイルの関係は v$archived_log を参照すればいいみたい。だが管理者権限が必要
1
2
3
| | select
name, thread#, sequence#, status, first_time, next_time, first_change#, next_change#
from v$archived_log
|
なので、ユーザからはscnを特定してデータを取得するのは難しいかと。
まぁー一応、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| | SQL> select id,ora_rowscn from sample;
ID ORA_ROWSCN
100 9239715
1 9239715
2 9239715
4 9239715
SQL>
SQL> select ora_rowscn from sample group by ora_rowscn;
ORA_ROWSCN
9239715
SQL>
|
と得られるが、目的の操作時点のscnが不明なので使えない。
となると、時刻指定で振り返るしかなく、
1
2
3
4
5
6
7
8
| | SQL> select * from sample as of timestamp to_timestamp('20130615 20:30:00','YYYYMMDD HH24:MI:SS');
ID
100
1
SQL>
|
と指定時刻でのテーブル状況が分かる。
っで、この時点のテーブルを作るにはCREATE TABLE sample_old AS ....とすればいい。
あと、指定時刻がこのテーブルの存在以前であると
1
2
3
4
5
6
7
8
| | SQL> select * from sample as of timestamp to_timestamp('20130615 10:30:00','YYYYMMDD HH24:MI:SS');
select * from sample as of timestamp to_timestamp('20130615 10:30:00','YYYYMMDD HH24:MI:SS')
*
行1でエラーが発生しました。:
ORA-01466: データを読み込めません - 表定義が変更されました
SQL>
|
と当然ながらエラーとなる。
*ここでの時刻は正常に使えるみたい....