مهاجرت از طریق Logical Replication

برای انتشار مستمر داده‌ها میان دو کلاستر پایگاه داده می‌توان از Logical Replication استفاده نمود. عملیات Logical replication با استفاده از مدل Publisher/Subscriber انجام می‌شود. در این مدل، یک یا چند Subscriber به یک یا چند Publication بر روی یک سرور متصل می‌شوند. Subscriberها داده‌ها را از انتشارهای انتخاب‌شده بازیابی کرده و می‌توانند آن را مجدداً بازپخش کنند.

مزایای استفاده از این مدل به صورت زیر است:

  • همگام سازی بر خط داده‌ها بین دو پایگاه‌داده
  • راه اندازی ساده تنها با چند دستور SQL در مبدا و مقصد
  • پشتیبانی PostgreSQL از logical replication به صورت built-in

در کنار مزایای ذکر شده باید به محدودیت‌های این روش نیز توجه داشت:

  • عملیات logical replication تنها در PostgreSQLهای نسخه ۱۰ به بعد پشتیبانی می‌شود
  • از ستون‌های تولید‌شده (Generated Columns) در logical replication پشتیبانی نمی‌شود.
  • تغییرات ساختاری مانند افزودن ستون یا تغییر نوع داده (DDL) به‌صورت خودکار تکرار نمی‌شوند و نیاز است که ساختار دیتابیس بدون تغییر باشد یا تغییرات جداگانه اعمال شود.
  • برای جداولی که کلید اصلی ندارند، فقط عملیات INSERT تکرار می‌شود و UPDATE و DELETE باید به‌صورت دستی مدیریت شوند.
  • جداول موقتی (TEMPORARY) و بدون لاگ (UNLOGGED) انتقال داده نمی‌شوند.
  • داده‌های نوع Large Object پشتیبانی نمی‌شوند.
  • برای فعال‌سازی logical replication باید تنظیمات دیتابیس را تغییر داده و دیتابیس را مجدداً راه‌اندازی کرد.
  • انتقال متادیتاها و جداول built-in پستگرس امکان پذیر نیست.
  • انتقال sequenceها به صورت خودکار انجام نمی‌شود. در صورتی که وابستگی به sequenceها وجود داشته و انتقال sequenceها مورد نیاز است باید در مرحله‌ای‌ که عملیات نوشتن بر روی دیتابیس مبدا متوقف شده است sequenceها به صورت دستی توسط کاربر به پایگاه داده مقصد منتقل شوند.
  • تنها در صورتی داده‌های extentionهای پایگاه داده قابلیت انتقال با logical replication را دارند که extention مورد نظر در مبدا و مقصد با نسخه‌های سازگار نصب شده باشند و تمامی extention و typeها و اسکیما و جداول پیش از شروع فرآیند replication در مقصد ساخته شده باشند. در این صورت احتمال انتقال داده‌ها وجود دارد اما کماکان ممکن است داده‌هایی با ساختار پیچیده هنگام انتقال با مشکل مواجه شوند

نحوه‌ی پیکربندی Logical Replication

1. اتصال بین پایگاه داده مبدا و مقصد از اتصال شبکه‌ای بین سرور مبدا و مقصد مطمئن شوید و اطمینان حاصل کنید پایگاه‌داده مبدا توسط پایگاه‌داده مقصد دیده میشود.

2. پیکربندی سرور مبدا از اعمال تنظیمات زیر بر روی پایگاه داده مطمئن شوید. توجه داشته باشید که تغییر wal_level نیازمند راه اندازی مجدد دیتابیس است. wal_level = 'logical' max_replication_slots = 10 max_wal_senders = 10

برای اطمینان از تنظیم صحیح دستور زیر را اجرا کنید:

SELECT name, setting FROM pg_settings WHERE name IN ('wal_level', 'max_replication_slots', 'max_wal_senders');

3. ساخت Publication در سرور مبدا دستور زیر را برای انتشار تمام جداول موجود اجرا کنید:

CREATE PUBLICATION my_publication_name FOR ALL TABLES;

4. ساخت Subscription در پایگاه داده مقصد سپس در مقصد، Subscription را به شکل زیر ایجاد کنید:

CREATE SUBSCRIPTION my_subscription_name
CONNECTION 'host=<source_host> port=<port> dbname=<src_db> user=<user> password=<pwd>'
PUBLICATION my_publication_name
WITH (copy_data = true);

5. بررسی عملکرد Replication برای بررسی همگام بودن داده‌ها بین سرور منبع و مقصد، در پایگاه داده مبدا دستور زیر را اجرا کنید:

SELECT * FROM pg_stat_replication;

مقادیر sent_lsn, write_lsn و replay_lsn را بررسی کنید، اگر این مقادیر با یکدیگر برابر باشند بدین معنی است که پایگاه داده مقصد در همان موقعیت LSN است که پایگاه داده مبدا قرار دارد.

انتقال اپلیکیشن به پایگاه داده جدید

برای انتقال اپلیکیشن به پایگاه‌داده مقصد مراحل زیر را دنبال کنید:

  • صبر کنید که LSN مقصد به اندازه کافی به LSN مبدا نزدیک شود.
  • عملیات نوشتن را بر روی پایگاه داده مبدا متوقف کنید.
  • عملیات replication را بر روی پایگاده داده مقصد با دستور زیر متوقف کنید
DROP SUBSCRIPTION my_subscription_name;
  • کانفیگ اپلیکیشن را به پایگاه داده جدید تغییر داده و عملیات CRUD را بر روی پایگاه داده جدید آغاز کنید
  • دلخواه: با اجرای دستور زیر بر روی پایگاه داده جدید می‌توانید از پر شدن جداول مدیریتی پایگاه داده که باعث بهبود اجرای کوئری‌ها می‌شود اطمینان حاصل کنید:
ANALYZE;

حذف Logical Replication

برای پاک‌سازی دستور زیر را در پایگاه داده مقصد اجرا کنید:

DROP SUBSCRIPTION my_subscription_name;

برای پاک‌سازی دستور زیر را در پایگاه داده مبدا اجرا کنید:

DROP PUBLICATION my_publication_name;