すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB RDS:リアルタイムのディザスタリカバリのための数秒以内のフラッシュバック

最終更新日:Mar 19, 2024

このトピックでは、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アドレスホワイトリストの設定」をご参照ください。

スナップショットの作成

  1. ECSインスタンスに接続します。 詳細については、「接続方法の概要」をご参照ください。

  2. 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)" zfs 
  3. rc.localファイルを変更します。

    vi /etc/rc.local
    /sbin/modprobe zfs
    
    sudo chmod + x /etc/rc.local 
  4. テストZFS。 ZFSが期待どおりに実行されていることを確認したら、ECSインスタンスを再起動します。

    modprobe zfs
    
    zpoolリスト
    利用可能なプールはありません
    
    reboot 
  5. ECSインスタンスに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 * 
  6. 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 
  7. データファイルを格納するディレクトリを作成します。

    zfs create -o mountpoint=/zpdata01 -o recordsize=8K -o atime=off -o primarycache=metadata -o logbias=throughput -o secondarycache=none zp1/zpdata01
  8. アーカイブされた先行ログ記録 (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 /zpdata02 
  9. RDSインスタンスから同期されたデータを保存するために使用されるディレクトリを作成します。

    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_wal 
  10. RDSインスタンスから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アドレスホワイトリストの設定」をご参照ください。

    同步数据

  11. /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 
  12. 設定ファイルを変更します。

    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' 
  13. 作成したディレクトリの権限を変更します。

    sudo chmod 700 /zpdata02/pg12_1921_wal
    sudo chmod 700 /zpdata01/pg12_1921_data 
  14. ECSインスタンスでPostgreSQLデータベースを起動します。

    su - postgres
    /usr/pgsql-12/bin/pg_ctl start -D /zpdata01/pg12_1921_data 
    説明

    ECSインスタンスの設定が低いために次のエラーが報告された場合は、ECSインスタンスをアップグレードすることを推奨します。

    HINT: このエラーは通常、PostgreSQLによる共有メモリセグメントの要求が、使用可能なメモリ、スワップ領域、または膨大なページを超えたことを意味します。
  15. ECSインスタンスのPostgreSQLデータベースを自動的に起動するように設定します。

    vi /etc/rc.local
    
    su - postgres -c "/usr/pgsql-12/bin/pg_ctl start -D /zpdata01/pg12_1921_data" 
  16. ECSインスタンスのPostgreSQLデータベースを設定して、データファイルの保存に使用されるディレクトリのスナップショットを自動的に作成します。 アーカイブされたWALファイルの格納に使用されるディレクトリのスナップショットを作成する必要はありません。

    1. スナップショットの作成に使用する権限を設定するスクリプトを作成します。

      vi /etc/snap.sh
      
      STIME='date + % F % T'
      /usr/sbin/zfsスナップショットzp1/zpdata01 @$STIME
      
      chmod 500 /etc/snap.sh 
    2. スナップショットが期待どおりに作成できるかどうかを確認します。

      /etc/snap.sh
      
      # zfs list -tスナップショット
      名前使用AVAIL REFERマウント
      zp1/zpdata01 @ 2020-03-2117:06:47 144K - 770M -
    3. 自動的に起動するように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 -n 
    4. crontabファイルを設定します。

      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 {} \; 
  17. バックアップセットの有効性を確認します。 詳細については、『GitHub』をご参照ください。

  18. 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インスタンスを数秒で復元する

  1. 適切なスナップショットに基づいて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_データ 
  2. 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' 
  3. クローンZFSファイルシステムからsocketファイルとpidファイルを削除します。

    rm -f /test_recovery/pg12_1921_data/.s。*
    rm /test_recovery/pg12_1921_data/postmaster.pid 
  4. クローンZFSファイルシステムからデータを復元します。

    su - postgres
    /usr/pgsql-12/bin/pg_ctl start -D /test_recovery/pg12_1921_data 
  5. 復元されたデータを表示します。

    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