Amazon Elastic Block Store (EBS) スナップショットは、ポイントインタイムスナップショットを取得することにより、EBS ボリューム上のデータを Amazon S3 にバックアップする機能を提供します。Amazon EC2 で Oracle Database を実行し、EBS ボリュームを使用する場合、バックアップ要件を満たすために EBS スナップショットを使用している可能性があります。2019 年 5 月より前は、データベースをバックアップモードにして、データベースファイルを含む各 EBS ボリュームのスナップショットを個別に作成する必要がありました。このアプローチには、主に 3 つの欠点がありました。
- データベースと対話する必要があった
- 複数の API を呼び出して、ボリュームの個別のスナップショットを作成する必要があった
- バックアップモードでは、データベースブロックは最初に変更されたときにログバッファに完全にコピーされ、これにより、特定のワークロードでより多くの REDO が生成され、データベースのパフォーマンスに影響が出る可能性がある
AWS は、1 回の API 呼び出しと最小限の I/O の一時停止で、EC2 インスタンスにアタッチされたすべての EBS ボリュームにわたってクラッシュ整合性のあるスナップショットを作成できる新しい機能を 2019 年 5 月にリリースしました。詳細については、「Amazon EC2 インスタンス上の複数の Amazon EBS ボリュームにわたってクラッシュ整合性のあるスナップショットを取得する」を参照してください。
この機能と Oracle Database 12c で導入された Storage Snapshot Optimization 機能を組み合わせることにより、データベースをバックアップモードにする必要がなくなります。この投稿では、このプロセスを順を追って説明し、(パフォーマンスの観点から) この新しい機能の利点について議論し、いくつかのユースケースについても説明します。
Oracle Database 12c Storage Snapshot Optimization 機能を活用するには、データベースが 12c 以上である必要があります。これにより、サードパーティーのテクノロジーを使用して、データベースをバックアップモードにせずにデータベースのストレージスナップショットを取得できます。そのスナップショットを使用して、データベースの全部または一部をリカバリできます。詳細については、Oracle ウェブサイトの「Storage Snapshot Optimization」を参照してください。
エンタープライズグレードのオンプレミスストレージアレイと Storage Snapshot Optimization 機能を備えた Oracle Database 12c を使用する Oracle のお客様は、ポイントインタイムリカバリやクローン作成など、大幅に改善されたバックアップおよびリストア操作の恩恵を受けています。新しい EBS マルチボリュームのクラッシュ整合性のあるスナップショット機能により、オンプレミスで長年使用してきた同様のスキルを使用して、AWS の全体的なエクスペリエンスを向上させることができます。
データベース (またはテーブルスペース) をバックアップモードにしないことの主な利点は、生成される REDO が少なくなることです。REDO の生成を少なくすると、チェックポイントの頻度と REDO サイズが減少します。これにより、バックアップ中のログ書き込みとデータベースライター I/O の両方が減少し、リカバリ中にログを適用する必要がある場合のデータベースリカバリ時間も短縮されます。
テスト環境
テスト環境には次の要素が含まれていました。
- EC2 インスタンスで作成された Oracle Database バージョン 19c インスタンス (ルートボリュームは 50 GB)
- 2 つのディスクグループ (
DATA
および RECO
) を持つ ASM インスタンス
- ディスクグループ
DATA
は、ASM ディスク (各 5 GB) として表示される 9 つの EBS ボリュームで構成され、データファイルが含まれます
- ディスクグループ
RECO
は、ASM ディスク (それぞれ 30 GB) として提示される 4 つの EBS ボリュームで構成され、REDO ログファイル、アーカイブログファイル、および制御ファイルが含まれます
- 各ブロックに 2 行のみが含まれる 19 GB のテーブル。次のコードを使用してテーブルを作成し、入力します。
$ cat create_table.sql
create table BDT (
id number(15)
,c1 varchar2(10)
)tablespace BDT;
insert /*+ APPEND */ into BDT select rownum
,'xxxxxxxxxx'
from dual connect by level <= 1;
alter table BDT minimize records_per_block;
truncate table BDT;
alter session set WORKAREA_SIZE_POLICY=MANUAL;
alter session set SORT_AREA_SIZE=1073741824;
insert /*+ APPEND */ into BDT select rownum
,'xxxxxxxxxx'
from dual connect by level <= 5000000;
- 次のコードを使用して作成できる、最初のクラッシュ整合性のあるマルチボリュームスナップショット:
$ cat ./cli_create_multivol_table_created.sh
aws ec2 create-snapshots \
--instance-specification InstanceId=<your_instance_id>,ExcludeBootVolume=true \
--description "table created" \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key="Name",Value="table created"}]'
この投稿のテスト中に、テーブルで更新アクティビティを生成し、更新アクティビティ後にデータベースをリカバリする必要性をシミュレートします。
クラッシュ整合性のあるスナップショットと Oracle Storage Snapshot Optimization の使用
最初のテストでは、クラッシュ整合性のあるスナップショット機能と Oracle Storage Snapshot Optimization を使用します。次の手順を実行します。
- 次のコードを使用して、19 GB のテーブルの列を更新します。
$ cat update_table.sh
sqlplus / as sysdba << EOF
execute dbms_workload_repository.create_snapshot;
update bdt.bdt set c1 = 'BDT';
commit;
execute dbms_workload_repository.create_snapshot;
EOF
生成される REDO の量は約 42 GB です。次のコードを参照してください。
Statistic Total per Second per Trans
-------------------------------- ------------------ -------------- -------------
redo size 2,629,050,100 7,429,507.5 1.8778929E+08
- 次のコードを使用して、別のクラッシュ整合性のあるマルチボリュームスナップショットを作成します。
$ cat ./cli_create_multivol_table_updated.sh
aws ec2 create-snapshots \
--instance-specification InstanceId=<your_instance_id>,ExcludeBootVolume=true \
--description "table updated" \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key="Name",Value="table updated"}]
ユースケースのシミュレーション
データベースをリカバリする必要性をシミュレートするには、次の手順を実行します。
- 次のコードを使用して、EC2 インスタンスを停止し、すべての EBS ボリューム (ルートボリュームを除く) をデタッチします。
$ cat ./cli_detach_non_root.sh
# detach volumes from DATA
for datavol in `aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=attachment.instance-id,Values=<your_instance_id> Name=size,Values=5`
do
aws ec2 detach-volume --instance-id <your_instance_id> --volume-id $datavol
done
# detach volumes from RECO
for datavol in `aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=attachment.instance-id,Values=<your_instance_id> Name=size,Values=30`
do
aws ec2 detach-volume --instance-id <your_instance_id> --volume-id $datavol
done
- 初期のクラッシュ整合性のあるマルチボリュームスナップショットからボリュームを作成し (DATA ディスクグループのみ)、次のコードを使用して EC2 インスタンスにアタッチします。
$ cat ./cli_create_data_volumes_test1.sh
# create DATA Volumes
for datasnaps in `aws ec2 describe-snapshots --query 'Snapshots[*].[SnapshotId]' --output text --filters Name=tag:Name,Values="table created" Name=volume-size,Values=5`
do
aws ec2 create-volume --availability-zone eu-west-3a --snapshot-id $datasnaps --tag-specifications 'ResourceType=volume,Tags=[{Key="Name",Value="Volume from table created snapshot"}]'
done
$ cat ./cli_attach_data_volumes_test1.sh
# Attach volumes for DATA
for voldev in 1:/dev/sdf 2:/dev/sdg 3:/dev/sdh 4:/dev/sdi 5:/dev/sdj 6:/dev/sdk 7:/dev/sdl 8:/dev/sdm 9:/dev/sdn
do
themax=`echo $voldev | cut -f1 -d:`
thedev=`echo $voldev | cut -f2 -d:`
volid=`aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=tag:Name,Values="Volume from table created snapshot" --max-items $themax | grep -v None | tail -1`
aws ec2 attach-volume --device $thedev --instance-id <your_instance_id> --volume-id $volid
done
- 更新後に取得したクラッシュ整合性のあるマルチボリュームスナップショットからボリュームを作成し (
RECO
ディスクグループのみ)、次のコードを使用して EC2 インスタンスにアタッチします。
$ cat ./cli_create_reco_volumes_test1.sh
# create RECO Volumes
for recosnaps in `aws ec2 describe-snapshots --query 'Snapshots[*].[SnapshotId]' --output text --filters Name=tag:Name,Values="table updated" Name=volume-size,Values=30`
do
aws ec2 create-volume --availability-zone eu-west-3a --snapshot-id $recosnaps --tag-specifications 'ResourceType=volume,Tags=[{Key="Name",Value="Volume from table updated snapshot"}]'
done
$ cat ./cli_attach_reco_volumes_test1.sh
# Attach volumes for RECO
for voldev in 1:/dev/sdo 2:/dev/sdp 3:/dev/sdq 4:/dev/sdr
do
themax=`echo $voldev | cut -f1 -d:`
thedev=`echo $voldev | cut -f2 -d:`
volid=`aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=tag:Name,Values="Volume from table updated snapshot" --max-items $themax | grep -v None | tail -1`
aws ec2 attach-volume --device $thedev --instance-id <your_instance_id> --volume-id $volid
done
RECO
ディスクグループには、REDO ログファイル、制御ファイル、およびアーカイブ REDO ログファイルが含まれます。データベースをリカバリするために必要なすべての情報が含まれています。
データベースのリカバリ
データベースをリカバリするには、次の手順を実行します。
- EC2 インスタンスタイプを起動します。
- データベースを起動します。次のコードを参照してください。
SQL> startup
ORACLE instance started.
Total System Global Area 4999608360 bytes
Fixed Size 8906792 bytes
Variable Size 822083584 bytes
Database Buffers 4110417920 bytes
Redo Buffers 58200064 bytes
Database mounted.
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '+DATA/BDT19/DATAFILE/system.257.1010589259'
- 初期スナップショットの時間を取得します (スナップショット全体で一意であることがわかります)。次のコードを参照してください。
$ cat ./cli_describe_snapshots.sh
aws ec2 describe-snapshots --query 'Snapshots[*].[StartTime]' --output text --filters Name=tag:Name,Values="table created" Name=volume-size,Values=5 | uniq
$ sh ./cli_describe_snapshots.sh
2019-11-23T10:43:10.964Z
- Storage Snapshot Optimization を使用してデータベースをリカバリします (以前の出力に基づいてスナップショット時間を適宜更新し、数秒追加します)。次のコードを参照してください。
$ cat ./recover_opti.sh
sqlplus / as sysdba << EOF
alter session set nls_date_format='YYYY/MM/DD HH24:MI:SS';
RECOVER database SNAPSHOT TIME '2019/11/23 10:43:50';
alter database open;
EOF
$ time sh ./recover_opti.sh
SQL*Plus: Release 19.0.0.0.0 - Production on Sat Nov 23 11:37:12 2019
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL>
Session altered.
SQL> Media recovery complete.
SQL>
Database altered.
SQL> Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
real 6m31.077s
user 0m0.007s
sys 0m0.021s
リカバリにかかる時間は約 6 分です。
データベースのリストア
データベースをテスト前の状態にリストアするには、次の手順を実行します。
- EC2 インスタンスを停止し、ルートのものを除くすべての EBS ボリュームをデタッチします。以前に使用したのと同じスクリプトを使用できます。
- 最初のクラッシュ整合性のあるマルチボリュームスナップショット (
DATA
および RECO
ディスクグループ用) からボリュームを作成し、EC2 インスタンスにアタッチします。次のコードを参照してください。
$ cat ./cli_create_reset_volumes.sh
# create DATA Volumes
for datasnaps in `aws ec2 describe-snapshots --query 'Snapshots[*].[SnapshotId]' --output text --filters Name=tag:Name,Values="table created" Name=volume-size,Values=5`
do
aws ec2 create-volume --availability-zone eu-west-3a --snapshot-id $datasnaps --tag-specifications 'ResourceType=volume,Tags=[{Key="Name",Value="Volume to reset from table created snapshot"}]'
done
# create RECO Volumes
for recosnaps in `aws ec2 describe-snapshots --query 'Snapshots[*].[SnapshotId]' --output text --filters Name=tag:Name,Values="table created" Name=volume-size,Values=30`
do
aws ec2 create-volume --availability-zone eu-west-3a --snapshot-id $recosnaps --tag-specifications 'ResourceType=volume,Tags=[{Key="Name",Value="Volume to reset from table created snapshot"}]'
done
$ cat ./cli_attach_reset_volumes.sh
for voldev in 1:/dev/sdf 2:/dev/sdg 3:/dev/sdh 4:/dev/sdi 5:/dev/sdj 6:/dev/sdk 7:/dev/sdl 8:/dev/sdm 9:/dev/sdn 10:/dev/sdo 11:/dev/sdp 12:/dev/sdq 13:/dev/sdr
do
themax=`echo $voldev | cut -f1 -d:`
thedev=`echo $voldev | cut -f2 -d:`
volid=`aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=tag:Name,Values="Volume to reset from table created snapshot" --max-items $themax | grep -v None | tail -1`
aws ec2 attach-volume --device $thedev --instance-id <your_instance_id> --volume-id $volid
done
- EC2 インスタンスタイプを起動します。
- データベースを起動します。
ホストが単にクラッシュしたかのように、データベースインスタンスが起動し、インスタンスのリカバリのみを行います。これは、クラッシュ整合性のあるスナップショットの優れた使用例です。スナップショットの時点でのすべてのボリュームを単純にリストアおよびリカバリします。
バックアップの開始/終了手順を使用する
2 番目のテストでは、バックアップの開始/終了手順を使用します。次の手順を実行します。
- データベースをバックアップモードにします。次のコードを参照してください。
SQL> alter database begin backup;
Database altered.
- 次のコードを使用して、
DATA
ディスクグループに属するすべての EBS ボリュームでループするスナップショットを作成します。
$ cat ./cli_create_data_snapshots_test2.sh
# Snap DATA volumes
for datavol in `aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=attachment.instance-id,Values=<your_instance_id> Name=size,Values=5`
do
aws ec2 create-snapshot --description "DATA snap begin backup" --tag-specifications 'ResourceType=snapshot,Tags=[{Key="Name",Value="DATA snap begin backup"}]' --volume-id $datavol
done
- 次のコードを使用して、19 GB テーブルの列を更新します (最初のテストと同じスクリプトを使用)。
$ cat ./update_table.sh
sqlplus / as sysdba << EOF
execute dbms_workload_repository.create_snapshot;
update bdt.bdt set c1 = 'BDT';
commit;
execute dbms_workload_repository.create_snapshot;
EOF
生成される REDO の量は約 42 GB です。次のコードを参照してください。
Statistic Total per Second per Trans
-------------------------------- ------------------ -------------- -------------
redo size 42,000,569,896 40,984,442.6 3.0000407E+09
- データベースのバックアップモードを解除します。次のコードを参照してください。
SQL> alter database end backup;
Database altered.
- 次のコードを使用して、
RECO
ディスクグループに属するすべての EBS ボリュームでループするスナップショットを作成します。
$ cat ./cli_create_reco_snapshots_test2.sh
# Snap RECO volumes
for datavol in `aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=attachment.instance-id,Values=<your_instance_id> Name=size,Values=30`
do
aws ec2 create-snapshot --description "RECO snap end backup" --tag-specifications 'ResourceType=snapshot,Tags=[{Key="Name",Value="RECO snap end backup"}]' --volume-id $datavol
done
ユースケースのシミュレーション
データベースをリカバリする必要性をシミュレートするには、次の手順を実行します。
- EC2 インスタンスを停止し、ルートのものを除くすべての EBS ボリュームをデタッチします。以前に使用したのと同じコードを使用します。
DATA
ディスクグループに属する EBS ボリュームのスナップショットからボリュームを作成し (データベースがバックアップモードになっている間)、それらを EC2 インスタンスにアタッチします。次のコードを参照してください。
$ cat ./cli_create_data_volumes_test2.sh
# create DATA Volumes
for datasnaps in `aws ec2 describe-snapshots --query 'Snapshots[*].[SnapshotId]' --output text --filters Name=tag:Name,Values="DATA snap begin backup" Name=volume-size,Values=5`
do
aws ec2 create-volume --availability-zone eu-west-3a --snapshot-id $datasnaps --tag-specifications 'ResourceType=volume,Tags=[{Key="Name",Value="Volume from DATA snap begin backup"}]'
done
$ cat ./cli_attach_data_volumes_test2.sh
# Attach volumes for DATA
for voldev in 1:/dev/sdf 2:/dev/sdg 3:/dev/sdh 4:/dev/sdi 5:/dev/sdj 6:/dev/sdk 7:/dev/sdl 8:/dev/sdm 9:/dev/sdn
do
themax=`echo $voldev | cut -f1 -d:`
thedev=`echo $voldev | cut -f2 -d:`
volid=`aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=tag:Name,Values="Volume from DATA snap begin backup" --max-items $themax | grep -v None | tail -1`
aws ec2 attach-volume --device $thedev --instance-id <your_instance_id> --volume-id $volid
done
RECO
ディスクグループに属する EBS ボリュームのスナップショットからボリュームを作成し (データベースのバックアップモードが解除されている間)、それらを EC2 インスタンスにアタッチします。次のコードを参照してください。
$ cat ./cli_create_reco_volumes_test2.sh
# create RECO Volumes
for recosnaps in `aws ec2 describe-snapshots --query 'Snapshots[*].[SnapshotId]' --output text --filters Name=tag:Name,Values="RECO snap end backup" Name=volume-size,Values=30`
do
aws ec2 create-volume --availability-zone eu-west-3a --snapshot-id $recosnaps --tag-specifications 'ResourceType=volume,Tags=[{Key="Name",Value="Volume from RECO snap end backup"}]'
done
$ cat ./cli_attach_reco_volumes_test2.sh
# Attach volumes for RECO
for voldev in 1:/dev/sdo 2:/dev/sdp 3:/dev/sdq 4:/dev/sdr
do
themax=`echo $voldev | cut -f1 -d:`
thedev=`echo $voldev | cut -f2 -d:`
volid=`aws ec2 describe-volumes --query 'Volumes[*].[VolumeId]' --output text --filters Name=tag:Name,Values="Volume from RECO snap end backup" --max-items $themax | grep -v None | tail -1`
aws ec2 attach-volume --device $thedev --instance-id <your_instance_id> --volume-id $volid
done
データベースのリカバリ
データベースをリカバリするには、次の手順を実行します。
- EC2 インスタンスタイプを起動します。
- データベースを起動します。次のコードを参照してください。
SQL> startup
ORACLE instance started.
Total System Global Area 4999608360 bytes
Fixed Size 8906792 bytes
Variable Size 822083584 bytes
Database Buffers 4110417920 bytes
Redo Buffers 58200064 bytes
Database mounted.
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '+DATA/BDT19/DATAFILE/system.257.1010589259'
- データベースのリカバリを行います。次のコードを参照してください。
$ cat recover_non_opti.sh
sqlplus / as sysdba << EOF
RECOVER database;
AUTO
alter database open;
EOF
$ $ time sh ./recover_non_opti.sh
SQL*Plus: Release 19.0.0.0.0 - Production on Sat Nov 23 13:06:46 2019
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> ORA-00279: change 14646020 generated at 11/23/2019 12:15:13 needed for thread 1
ORA-00289: suggestion :
+RECO/BDT19/ARCHIVELOG/2019_11_23/thread_1_seq_507.323.1025094369
ORA-00280: change 14646020 for thread 1 is in sequence #507
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}.
. (truncating output for visibility)
.
Log applied.
Media recovery complete.
SQL>
Database altered.
SQL> Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
real 15m8.149s
user 0m0.025s
sys 0m0.025s
リカバリにかかる時間は約 15 分です。
追加のユースケース
次のユースケースでは、クラッシュ整合性のあるスナップショットを使用できます。
- ポイントインタイムリカバリ
- テスト環境の更新と作成の自動化 (ソースデータベースとの対話は一切なし)
- セキュリティのレイヤーの追加 (rman の使用や S3 へのバックアップなど、別のバックアップ戦略を使用する場合)
まとめ
この投稿では、データベースがバックアップモードでより多くの REDO ログを生成できることを示しました (同じ更新の場合)。クラッシュ整合性のあるスナップショットからのリカバリにかかる時間は、標準のバックアップ開始/バックアップ終了戦略からのリカバリに必要な時間よりもはるかに短いものでした。さらに、クラッシュ整合性のあるスナップショットを使用して、最初のテストの前と同じように (2 つのテスト間で) データベースを再構築できます (インスタンスリカバリのみを実行)。
以上のことから、Oracle Database インスタンスを Amazon EC2 で実行し、Amazon EBS ボリュームを使用する場合、上記の利点のためにクラッシュ整合性のあるスナップショット機能の使用を検討することをお勧めします。
著者について
Bertrand Drouvot 氏は、アマゾン ウェブ サービスのシニアデータベースエンジニアです。