Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

論理レプリケーションを使ったDB統合

Ken Kato
December 05, 2024

 論理レプリケーションを使ったDB統合

Ken Kato

December 05, 2024
Tweet

More Decks by Ken Kato

Other Decks in Technology

Transcript

  1. © 2024 Wantedly, Inc. 究極の適材適所により、 シゴトでココロオドルひとを ふやすために Wantedlyはパーパス‧共感を軸にした、⼈と会社との出会いを2012 年から創出。 はたらくすべての⼈が共感を通じて「であい」「つながり」「つなが

    りを深める」ためのビジネスSNS「Wantedly」を提供しています。 1⼈でも多くの⼈がワクワクしたり、熱中してシゴトと向き合えるよ うな世界を実現するために、国境を超えて「はたらくすべての⼈の イ ンフラ」を創っていきます。 Business 提供サービス 3
  2. © 2024 Wantedly, Inc. Business Wantedly Hire 次世代型 採用管理システム 採⽤プロセスの悩みを解決

    途中辞退を防ぐための業務を効率化 • 繰り返しフローで候補者管理を⾃動化 • 複数名の⾃動⽇程調整で80%時間を削減 多様化する採⽤プロセスに対応 • 最適な選考プロセスを⾃由⾃在に構築 • 多様なメンバーに適した権限 4 構造化⾯接で⾼精度の⾒極め可能 • 採⽤基準の標準化‧カスタマイズ • 各項⽬の評価を定量化
  3. © 2024 Wantedly, Inc. 物理レプリケーションと論理レプリケーションの違い 物理レプリケーション 論理レプリケーション 転送データ WAL (バイナリ形式)

    WALをデコードした、 SQLに似たデータ変更の情報 レプリケーション単位 DBクラスタ単位 DB単位、テーブル単位 レプリケーションされる操作 DML (INSERT、UPDATE、 DELETE、TRUNCATE)、DDL (CREATE、ALTER、DROP)、シ ステムカタログの変更 (スキー マ、ユーザー、権限など ) DML (INSERT、UPDATE、 DELETE、TRUNCATE) のいず れの組み合わせ 異なるメジャーバージョン間で のレプリケーション できない できる
  4. © 2024 Wantedly, Inc. ウォンテッドリーのアーキテクチャ サービスA サービスB サービスC PostgreSQL PostgreSQL

    PostgreSQL UI ウォンテッドリーではマイクロサービスアーキテクチャを採用しており、そのベストプラクティスに従って、サー ビス毎に分割された DB構成を取っている。しかし、一部他のサービスの DBを利用している箇所もある。
  5. © 2024 Wantedly, Inc. DB統合する背景 サービスA サービスB サービスC PostgreSQL PostgreSQL

    PostgreSQL UI サービスの統廃合やアーキテクチャの整理により、一部の DBは分割の必要性がなくなった。 コスト削減のため、DBを統合することにした。
  6. © 2024 Wantedly, Inc. 論理レプリケーションの登場人物 • Publisher ◦ WAL Sender

    プロセス: データをSubscriber側に送信する ◦ Publication: 対象テーブルや対象操作に関する情報を保持する ◦ Replication Slot : レプリケーションの進行状況を管理する • Subscriber ◦ Logical Replication Worker プロセス: Publisherからデータを受信し、それを適用する ◦ Subscription: Publicationの接続情報などを保持する ◦ Replication Origin: データの受信・適用状況を管理する publication replication slot replication origin subscription Publisher Subscriber walsender logical replication worker
  7. © 2024 Wantedly, Inc. 論理レプリケーション設定時の流れ 1. 対象テーブル、対象操作を指定し、 Publicationを作成する 4. Subscriptionを作成されると、Publisher側で

    Replication Slotが自動作成される (SubscriptionとReplication Slotは1対1) 2. DDL (CREATE, ALTER, DROP) はレプリケー ションされないので、あらかじめテーブルを作成し ておく必要がある 3. Publicationを指定し、Subscriptionを作成 する 4. Subscriptionが作成されると、同時に Replication Originも自動作成される (SubscriptionとReplication Originは1対1)
  8. © 2024 Wantedly, Inc. 作業の概要 pub1 pub2 sub2 Publisher Subscriber

    DB単位でレプリケーションし、 2つのDBを1つのDBクラスタに集約する。ダウンタイムを設けてアプリから DBへ の向き先を変更するが、ダウンタイム直前までデータの追加・削除・変更が行われるため、最新データをリア ルタイムでレプリケーションし続ける必要がある。 sub1
  9. © 2024 Wantedly, Inc. 手順 1. AWS上での設定 2. Publication作成 3.

    Subscription作成 4. アプリの接続先DB切り替え 5. Subscription, Publication削除
  10. © 2024 Wantedly, Inc. 手順① AWS上での設定 • セキュリティグループ ◦ DB間接続を許可するための設定をした

    • パラメータグループ ◦ Publisher、Subscriber 共通 ▪ rds.logical_replication = 1 ▪ max_replication_slots = 10 (デフォルトのまま) ◦ Publisher側 ▪ max_wal_senders = 10 (デフォルトのまま) ◦ subscriber側 ▪ max_logical_replicaion_workers = 4 (デフォルトのまま)
  11. © 2024 Wantedly, Inc. 手順② Publication作成 • Publication 作成 (pub1)

    => CREATE PUBLICATION pub1 FOR ALL TABLES; (pub2) => CREATE PUBLICATION pub2 FOR ALL TABLES; pub1 pub2 sub2 Publisher Subscriber sub1
  12. © 2024 Wantedly, Inc. 手順③ Subscription作成 • レプリケーション先の DB作成 (maindb)

    => CREATE DATABASE sub1; (maindb) => CREATE DATABASE sub2; • レプリケーション先のテーブル作成 pg_dump $PUB1_URL --schema-only > pg_dump1.sql pg_dump $PUB2_URL --schema-only > pg_dump2.sql psql $SUB1_URL < pg_dump1.sql psql $SUB2_URL < pg_dump2.sql • Subscription 作成 (sub1) => CREATE SUBSCRIPTION sub1 CONNECTION $SUB1_URL PUBLICATION pub1; (sub2) => CREATE SUBSCRIPTION sub2 CONNECTION $SUB1_URL PUBLICATION pub2; pub1 pub2 sub2 Publisher Subscriber sub1
  13. © 2024 Wantedly, Inc. 手順⑤ Subscription, Publication削除 • Subscription停止 (sub1)

    => ALTER SUBSCRIPTION sub1 DISABLE; (sub2) => ALTER SUBSCRIPTION sub2 DISABLE; • Subscription削除 (sub1) => DROP SUBSCRIPTION sub1; (sub2) => DROP SUBSCRIPTION sub2; • Publication削除 (pub1) => DROP PUBLICATION pub1; (pub2) => DROP PUBLICATION pub2; pub1 pub2 sub2 Publisher Subscriber sub1
  14. © 2024 Wantedly, Inc. 課題① シーケンスデータがレプリケーションされない id name 1 Sato

    2 Suzuki 3 Takahashi 4 Tanaka 5 Ito sequencename last_value table_id_seq 5 sequencename last_value table_id_seq 1 Publisher Subscriber 現在(最新はv17時点)だと、仕 様上の制約により、 シーケンスデータは レプリケーションされない
  15. © 2024 Wantedly, Inc. 課題① シーケンスデータがレプリケーションされない 開発環境でテストしている時、シーケンスデータがレプリケーションされていないことに気がついた。 レプリケーション完了後に、 Subscriber側でシーケンスの値を手動で設定するようにした。 •

    シーケンスデータを取得する psql $PUB1_DB_URL -c "SELECT sequencename, last_value FROM pg_sequences) t" -t > sequences.txt • setval関数でシーケンスの値を設定する psql $SUB1_DB_URL -c “SELECT setval($sequencename, $last_value)”
  16. © 2024 Wantedly, Inc. 課題② レプリケーションが止まっていることに気づけなかった pub1 pub2 sub2 Publisher

    Subscriber sub1 コスト節約のために論理レプリケーションを実行したまま、 Subscriberのインスタンスタイプを下げていたが、 リソース不足によりプロセスが起動していなかった、もしくは処理のためのリソースが不足していた可能性が ある。レプリケーションが途中で止まっており、最新のデータが同期されていなかった。
  17. © 2024 Wantedly, Inc. 課題② レプリケーションが止まっていることを検知できなかった DBを切り替える前にビューなどでレプリケーションが完了しているか確認しておくべきだった。 論理レプリケーションに関連するビューは以下の通り。 • Publisher側

    ◦ pg_stat_replication ▪ 現在のレプリケーションの状態 ◦ pg_publication ▪ Publicationに関する情報 ◦ pg_replication_slots ▪ Replication Slotに関する情報 • Subscriber側 ◦ pg_stat_subscription ▪ Subscriptionの現在の状況や進捗 ◦ pg_subscription ▪ Subscriptionに関する情報 ◦ pg_replication_origin_status ▪ Replication Originに関する情報
  18. © 2024 Wantedly, Inc. 課題② レプリケーションが止まっていることに気づけなかった どのビューのどの項目を見ればレプリケーションが完了していると言えるのか分からなかった。 見るべきポイントは以下の通り。 • Publisher側

    ◦ pg_stat_replicationのsent_lsn(最後に送信したLSN)とreplay_lsn(Subscriber側で最 後に適用されたLSN)の値が同じであること • Subscriber側 ◦ pg_stat_replication_originのremote_lsn(最後に受信したLSN)とlocal_lsn(ローカル で最後に適用された LSN)の値が同じであること • できれば確認しておきたい ◦ Publisher側のpg_stat_replicationのsent_lsn(最後に送信したLSN)とSubscriber側の pg_stat_subscriptionのreceived_lsn(最後に受信したLSN)の値が同じであること
  19. © 2024 Wantedly, Inc. 課題② レプリケーションが止まっていることに気づけなかった LSN (Log Sequence Number)

    とは WAL (Write Ahead Log) の位置を示すもの 喩えるならば • WAL = 本 • LSN = しおり WALはデータベースの変更内容が時系列順に記載されている「本」で、 LSNというしおりを挟んでおくことで、ど こから読み進めるべきか、あるいはどこまで読み終わったかが分かる。
  20. © 2024 Wantedly, Inc. 課題② レプリケーションが止まっていることに気づけなかった どのビューのどの項目を見ればレプリケーションが完了していると言えるのか分からなかった。 見るべきポイントは以下の通り。 • Publisher側

    ◦ pg_stat_replicationのsent_lsn(最後に送信したLSN)とreplay_lsn(Subscriber側で最 後に適用されたLSN)の値が同じであること • Subscriber側 ◦ pg_stat_replication_originのremote_lsn(最後に受信したLSN)とlocal_lsn(ローカル で最後に適用された LSN)の値が同じであること • できれば確認しておきたい ◦ Publisher側のpg_stat_replicationのsent_lsn(最後に送信したLSN)とSubscriber側の pg_stat_subscriptionのreceived_lsn(最後に受信したLSN)の値が同じであること
  21. © 2024 Wantedly, Inc. 課題③ レプリケーションを途中から再開できなかった • Publisher側 ◦ どこまでのWALを保持しておくかのカーソル

    -> Replication Slot • Subscriber側 ◦ どこまでのWALを受信・適用できたかのカーソル -> Replication Origin -> 「どの時点からロジカルレプリケーションを始めるか」という情報は、 Subscriber側のReplication Originが保持している。 subscription publication replication slot replication origin Publisher Subscriber walsender logical replication worker subscription
  22. © 2024 Wantedly, Inc. 課題③ レプリケーションを途中から再開できなかった 必要な条件 1. Publisher側で必要なWALが残っていること 2.

    Subscriber側のReplication Originが再開したいLSNよりも昔のLSNに設定されていること 1. Publisher側で必要なWALが残っていること 🔺 Publisher側のインスタンスをPITRすれば、必要なWALがディスク上に残っている可能性がある。 しかし、自動アーカイブを有効化していなかったため、必要な WALが消失している可能性がある。 2. Subscriber側のReplication Originが再開したいLSNよりも昔のLSNに設定されていること ❌ Subscriber側のReplication Originを再開したいLSNよりも昔のLSNに設定されていれば、 pg_replication_origin_advance関数を使って開始LSNを任意の地点に設定できる。 しかし、Subscriber側のReplication Originはすでに削除されていたので、レプリケーションの再開は難し いことが分かった。
  23. © 2024 Wantedly, Inc. 課題③ レプリケーションを途中から再開できなかった Subscriptionを削除しなければ、レプリケーションを途中から再開できた。 Subscriptionを削除すると、以下も自動削除される。 • Publisher側のReplication

    Slot • Subscriber側のReplication Origin ちゃんと動くことを確認した後に Subscriptionを削除すべきだった。 レプリケーションを止めたい場合は、 ALTER SUBSCRIPTION sub1 DISABLE; で一時的に無効化できる。
  24. © 2024 Wantedly, Inc. まとめ • 論理レプリケーションでは、レプリケーション単位や対象操作を柔軟に設定できる ◦ 今回紹介したDB統合など、物理レプリケーションではできなかったオペレーションが可能 •

    論理レプリケーションでは制限事項があるので、開発環境などでリハーサルしておくのが大事 ◦ DDL (CREATE, ALTER, DROP) がレプリケーションされない ◦ シーケンスデータがレプリケーションされない • 正しくレプリケーションされないことがあるので、レプリケーションが完了しているか確認する手順を含めて おく ◦ Publisher側では最後に送信した LSNと、最後に適用された LSNの値が同じことを確認する ◦ Subscriber側では最後に受信した LSNと、最後に適用された LSNの値が同じことを確認する • レプリケーションを途中から再開するのは難しいので、 Subscriptionの削除は慎重に行う
  25. © 2024 Wantedly, Inc. 参考 • 日本PostgrSQLユーザ会 PostgreSQL日本語ドキュメント ◦ https://www.postgresql.jp/document/16/html/logical-replication.html

    ◦ https://www.postgresql.jp/document/16/html/logicaldecoding.html • NTT Data Technology & Innovation ( PostgreSQL Conference 2022 鳥越淳さんの資料) ◦ https://www.slideshare.net/slideshow/postgresql-logical-replication-postgresql-conference-j apan-2022-nttdata/254219341 • SRA OSS Tech Blog ◦ https://www.sraoss.co.jp/tech-blog/pgsql/logical-replication-1/ ◦ https://www.sraoss.co.jp/tech-blog/pgsql/logical-replication-2/ ◦ https://www.sraoss.co.jp/tech-blog/pgsql/logical-replication-3/ • Fujitsu PostgreSQLインサイド ◦ https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-inde x/logical-replication-tutorial/ ◦ https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/engineer-bl og19/ • PGConf.Asia 2017 篠田典良さんの資料 ◦ https://www.pgconf.asia/JA/2017/wp-content/uploads/sites/2/2017/12/D2-A7-JA.pdf
  26. © 2024 Wantedly, Inc. 論理レプリケーションの全体的な流れ 2. WAL SenderプロセスがSubscriber側からの 要求を受けて、Publicationが保持しているレプ リケーション対象の情報と

    Replication Slotを元 に必要なWALを特定する 3. WAL Senderプロセスはデコードプラグインを 用いて、WALをデコードし、Subscriber側に送信 する 6. Subscriber側からの通知を受け、 Replication Slotの情報を更新する 1. Logical Replication Workerプロセスが、 Subscriptionが保持しているPublicationの接 続情報とReplication Originの進捗に基づき、 必要なデータをPublisher側に要求する 4. Logical Replication Workerプロセスがデー タを受信し、ローカル DBに適用する 5. データの適用が成功すると、 Replication Originが更新され、その情報を Publisher側に 共有する