このトピックでは、ApsaraDB RDS for PostgreSQLでサポートされているZettabyte File System (ZFS) のフラッシュバック技術について説明します。 Elastic Compute Service (ECS) インスタンスをApsaraDB RDS for PostgreSQLインスタンスのバックアップとして指定すると、ZFSによりECSインスタンスはRDSインスタンスからデータを同期し、cronツールを呼び出して一定間隔でスナップショットをすばやく作成できます。 RDSインスタンスに障害が発生した場合、ECSインスタンスのスナップショットを使用して、数秒以内にRDSインスタンスを復元できます。
背景情報
ZFSは、現在利用可能な他のファイルシステムにはない機能と利点を提供する動的ファイル管理システムです。 ZFSは、ストレージプールの概念を使用して、物理ストレージデバイスを管理します。 これにより、ZFSは物理ストレージデバイスをストレージプールに集約できます。 ストレージプールは、物理ストレージデバイスの特性を記述します。 これらの特性は、デバイスレイアウトおよびデータ冗長性を含む。 ストレージプールは、ファイルシステムを作成できる任意のデータストアとしても機能します。 ファイルシステムは、もはや個々の物理デバイスに制約されない。 さらに、個々の物理デバイスを備えたファイルシステムをストレージプール内で共有することができる。
ZFSは、コピーオンライト技術を使用してデータを管理します。 新しいデータを書き込むと、元のデータを含むブロックが保持されます。 これにより、ZFSはスナップショットの作成に必要なすべてのデータを保存できます。 データを使用して、数秒でスナップショットを作成できます。 さらに、ZFSを使用すると、ファイルに対する変更をファイルシステムとそのスナップショット間で共有できます。 これにより、ZFSスナップショットのストレージ使用量を最適化できます。
ZFSのこれらの機能により、最新のスナップショットを見つけることができます。 最新のスナップショットを使用して、障害や災害が発生した場合にデータを復元できます。
準備
適切なECSインスタンスを作成します。 詳細については、「作成方法」をご参照ください。 ECSインスタンスは、RDSインスタンスと同じゾーン、仮想プライベートクラウド (VPC) 、およびvSwitchを使用することを推奨します。 これにより、内部ネットワークを介したこれらのインスタンス間の高速通信が保証されます。 クロスリージョンディザスタリカバリが必要な場合は、Cloud Enterprise Network (CEN) インスタンスを作成します。 詳細については、「CENを使用したリージョン内ネットワーク通信の有効化」をご参照ください。
ホワイトリストを設定して、ECSインスタンスにRDSインスタンスへのアクセスを許可します。 詳細については、「IPアドレスホワイトリストの設定」をご参照ください。
スナップショットの作成
ECSインスタンスに接続します。 詳細については、「接続方法の概要」をご参照ください。
ZFSをインストールします。
wget http://download.zfsonlinux.org/epel/zfs-release.el7_7.noarch.rpm sudo rpm -ivh zfs-release.el7_7.noarch.rpm sudo yumインストールhttps://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm sudo yum install -y "kernel-devel-uname-r == $(uname-r)" zfsrc.localファイルを変更します。
vi /etc/rc.local /sbin/modprobe zfs sudo chmod + x /etc/rc.localテストZFS。 ZFSが期待どおりに実行されていることを確認したら、ECSインスタンスを再起動します。
modprobe zfs zpoolリスト 利用可能なプールはありません rebootECSインスタンスにPostgreSQL 12をインストールします。
sudo yumインストールhttps://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install postgresql12 *ECSインスタンスのディスクに次のパラメーターを設定します。
# パーティションの整列。 /dev/vdb1パスは、新しいディスクが作成される場所です。 parted -a optimal -s /dev/vdb1 mklabel gpt mkpart primary 1MiB 100% FREE # ZFSストレージプールを設定します。 zpool create zp1 -f -o ashift=13 vdc1 # canmountパラメーターを設定します。 zfs set canmount=off zp1データファイルを格納するディレクトリを作成します。
zfs create -o mountpoint=/zpdata01 -o recordsize=8K -o atime=off -o primarycache=metadata -o logbias=throughput -o secondarycache=none zp1/zpdata01アーカイブされた先行ログ記録 (WAL) ファイルを格納するために使用されるディレクトリを作成します。
zfs create -o mountpoint=/zpdata02 -o recordsize=8K -o atime=off -o primarycache=metadata -o logbias=throughput -o secondarycache=none -o compression=on zp1/zpdata02 zfs set compression=on zp1/zpdata02 zfsリスト 名前使用AVAIL REFERマウント zp1 1.29M 1.42T 192K /zp1 zp1/zpdata01 192K 1.42T 192K /zpdata01 zp1/zpdata02 192K 1.42T 192K /zpdata02RDSインスタンスから同期されたデータを保存するために使用されるディレクトリを作成します。
mkdir /zpdata01/pg12_1921_data mkdir /zpdata02/pg12_1921_wal sudo chown -R postgres:postgres /zpdata01/pg12_1921_data sudo chown -R postgres:postgres /zpdata02/pg12_1921_walRDSインスタンスからECSインスタンスにデータを同期します。
su - postgres export PGPASSWORD=<RDSインスタンスの特権アカウントのパスワード> nohup pg_basebackup -D /zpdata01/pg12_1921_data -F p -R -c fast -X stream -h <RDSインスタンスへの接続に使用されるエンドポイント> -p <RDSインスタンスへの接続に使用されるポート> -U <RDSインスタンスの特権アカウントのユーザー名> >. log. 1 &説明ECSインスタンスにRDSインスタンスへのアクセスを許可するホワイトリストが設定されていることを確認します。 詳細については、「IPアドレスホワイトリストの設定」をご参照ください。

/zpdata01/pg12_1921_data/postgresql.confファイルで次のパラメーターをコメントアウトします。
#3月13日金曜日09:55:03 CST 2020 # ssl_key_file='server.key' # huge_pages=try # auto_explain.sample_rate=1 # zhparser.multi_zall=off # shared_preload_libraries='pg_stat_statements,auth_delay,auto_explain,zhparser,timescaledb,pg_pathman' # promote_trigger_file='/data/postgresql.trigger' # ssl=オフ # rds_max_log_files=20 # pg_pathman.enable_auto_partition=on # shared_buffers=32768MB # zhparser.punctuation_ignore=off # pg_pathman.override_copy=on # port=1922 # pg_stat_statements.max=5000 # auth_delay.ms=3s # auto_explain.log_nested_statements=off # track_io_timing=on # zhparser.multi_zmain=off # auto_explain.log_analyze=off # archive_mode=on # ssl_cert_file='server.crt' # zhparser.multi_short=off # zhparser.dict_in_memory=off # auto_explain.log_format=テキスト # auto_explain.log_min_duration=-1 # rds.rds_max_non_super_conns=12800 # pg_pathman.enable=on # archive_command='/bin/date' # auto_explain.log_verbose=off # log_line_prefix='\1\n\t % p\t % r\t % u\t % d\t % t\t % e\t % T\t % S\t % S\t % U\t % E\t\t\t\t' # pg_pathman.enable_runtimemergeappend=on # zhparser.extra_dicts='dict_extra.xdb' # auto_explain.log_buffers=off # pg_stat_statements.track=top # jit_provider='llvmjit' # pg_pathman.enable_partitionrouter=off # pg_stat_statements.track_utility=off # pg_stat_statements.save=off # zhparser.dicts_type='EXTRA' # auto_explain.log_timing=on # pg_pathman.enable_runtimeappend=on # zhparser.seg_with_duality=off # rds.rds_max_super_conns=100 # pg_pathman.enable_partitionfilter=on # log_destination='stderr,csvlog' # zhparser.multi_duality=off # pg_pathman.insert_into_fdw='postgres' # pg_pathman.enable_bounds_cache=on # rds.rds_max_non_super_wal_snd=32 # auto_explain.log_triggers=off # rds_sync_replication_timeout=0設定ファイルを変更します。
vi /zpdata01/pg12_1921_data/postgresql.auto.conf primary_conninfo = 'user=<RDSインスタンスの特権アカウントのユーザー名> password=''<RDSインスタンスの特権アカウントのパスワード>'' host=''<RDSインスタンスへの接続に使用されるエンドポイント>'' port=<RDSインスタンスへの接続に使用されるポート> ationapplic_name=hello_rds_pg12' port=1922 shared_buffers=32GB log_destination='csvlog' archive_mode=常に archive_command='test! -f /zpdata02/pg12_1921_wal/% f && cp % p /zpdata02/pg12_1921_wal/% f'作成したディレクトリの権限を変更します。
sudo chmod 700 /zpdata02/pg12_1921_wal sudo chmod 700 /zpdata01/pg12_1921_dataECSインスタンスでPostgreSQLデータベースを起動します。
su - postgres /usr/pgsql-12/bin/pg_ctl start -D /zpdata01/pg12_1921_data説明ECSインスタンスの設定が低いために次のエラーが報告された場合は、ECSインスタンスをアップグレードすることを推奨します。
HINT: このエラーは通常、PostgreSQLによる共有メモリセグメントの要求が、使用可能なメモリ、スワップ領域、または膨大なページを超えたことを意味します。ECSインスタンスのPostgreSQLデータベースを自動的に起動するように設定します。
vi /etc/rc.local su - postgres -c "/usr/pgsql-12/bin/pg_ctl start -D /zpdata01/pg12_1921_data"ECSインスタンスのPostgreSQLデータベースを設定して、データファイルの保存に使用されるディレクトリのスナップショットを自動的に作成します。 アーカイブされたWALファイルの格納に使用されるディレクトリのスナップショットを作成する必要はありません。
スナップショットの作成に使用する権限を設定するスクリプトを作成します。
vi /etc/snap.sh STIME='date + % F % T' /usr/sbin/zfsスナップショットzp1/zpdata01 @$STIME chmod 500 /etc/snap.shスナップショットが期待どおりに作成できるかどうかを確認します。
/etc/snap.sh # zfs list -tスナップショット 名前使用AVAIL REFERマウント zp1/zpdata01 @ 2020-03-2117:06:47 144K - 770M -自動的に起動するようにcrondデーモンプロセスを設定します。
systemctl start crond systemctl enable cond systemctlステータスcrond ● crond.service-コマンドスケジューラ Loaded: loaded (/usr/lib/systemd/system/crond.service; 有効; ベンダープリセット: 有効) アクティブ: アクティブ (実行中) 以来土2020-03-21 16:16:08 CST; 53分前 メインPID: 2526 (crond) CGroup: /system.slice/crond.service └ ─ 2526 /usr/sbin/crond -ncrontabファイルを設定します。
crontab -e 1 1 * * * /etc/snap.sh crontab -l -uユーザー名 1 1 * * * /etc/snap.sh
説明ディスク使用量とビジネス要件に基づいて、スナップショットまたはアーカイブの自動削除を設定できます。 スナップショットまたはアーカイブを手動で削除するには、次の手順に従います。
スナップショットを手動で削除する: zfs list -tスナップショット zNAME中古AVAIL REFERマウント zp1/zpdata01 @ 2020-03-2117:06:47 144K - 770M- zp1/zpdata01 @ 2020-03-2117:17:01 0B - 786M- zfs destroy zp1/zpdata01 @ 2020-03-2117:06:47 zfs list -tスナップショット 名前使用AVAIL REFERマウント zp1/zpdata01 @ 2020-03-2117:17:01 0B - 786M- アーカイブを手動で削除する: find /zpdata02/pg12_1921_wal/ -タイプf -mtime + 7 -exec rm -f {} \;RDSとECSインスタンス間のデータ同期のレイテンシを取得します。
postgres=> sent_delayとしてpg_size_pretty(pg_wal_lsn_diff(pg_current_wal_flush_lsn(),sent_lsn)) を選択し、pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_flush_lsn(),replay_lsn)), replay_dealy,* pg_stat_replicationから; -[レコード1 ]---- + ------------------------------ sent_delay | 0バイト replay_dealy | 0バイト pid | 84098 usesysid | 886185 usename | 担当者 application_name | hello_rds_pg12 client_addr | 192.168.0.173 client_hostname | client_port | 60402 backend_start | 2020-03-21 16:59:01.890775 + 08 backend_xmin | state | ストリーミング sent_lsn | 11D/97002068 write_lsn | 11D/97002068 flush_lsn | 11D/97002068 replay_lsn | 11D/97002068 write_lag | flush_lag | replay_lag | sync_priority | 0 sync_state | async reply_time | 2020-03-21 17:01:17.198139 + 08
上記の手順を完了すると、ECSインスタンスに一定の間隔でスナップショットが作成されます。 作成したスナップショットを使用して、RDSインスタンスを数秒で復元し、リアルタイムのディザスタリカバリを行うことができます。
RDSインスタンスを数秒で復元する
適切なスナップショットに基づいてZFSファイルシステムをクローンします。
zfs list -tスナップショット 名前使用AVAIL REFERマウント zp1/zpdata01 @ 2020-03-2117:17:01 312K - 786M- zfs clone -o mountpoint=/test_recovery zp1/zpdata01 @ 2020-03-2117:17:01 zp1/zpdata_test cd /test_recovery ll 合計17 drwx ----- 20 postgres postgres 35 3月21日16:59 pg12_1921_データRDSインスタンスのデータの復元に使用するパラメーターを設定します。
説明ECSインスタンスが十分なメモリ容量を提供できない場合は、小さな共有バッファを設定できます。
vi /test_recovery/pg12_1921_data/postgresql.auto.conf port=1923 shared_buffers=32GB log_destination='csvlog' recovery_end_command = 'cp /zpdata02/pg12_1921_wal/% f % p' recovery_target_time = '2020-03-21 17:28:37.670338 08' recovery_target_timeline = 'latest' recovery_target_action = 'pause'クローンZFSファイルシステムからsocketファイルとpidファイルを削除します。
rm -f /test_recovery/pg12_1921_data/.s。* rm /test_recovery/pg12_1921_data/postmaster.pidクローンZFSファイルシステムからデータを復元します。
su - postgres /usr/pgsql-12/bin/pg_ctl start -D /test_recovery/pg12_1921_data復元されたデータを表示します。
psql -h /test_recovery/pg12_1921_data -p 1923 -U <RDSインスタンスの特権アカウントのユーザー名> postgres psql (12.1) ヘルプを「ヘルプ」と入力します。 postgres=> \dt
説明復元されたデータが正しいことを確認したら、pgdumpツールを使用して復元されたデータをRDSインスタンスにコピーできます。
ECSインスタンスから復元されたデータを削除する
復元が完了したら、次のコマンドを実行して、復元されたデータをECSインスタンスのtest_recoveryディレクトリから削除します。
su - postgres
/usr/pgsql-12/bin/pg_ctl stop -m fast -D /test_recovery/pg12_1921_data
sudo zfs destroy zp1/zpdata_test