Categories
Database Backup

**

برای مدیران پایگاه داده (DBAs) و مهندسان DevOps که PostgreSQL را در محیط عملیاتی (Production) مدیریت می‌کنند، دستیابی به هدف نقطه بازیابی (RPO) نزدیک به صفر، یک الزام اصلی است. در قلب قابلیت‌های بازیابی فاجعه و بازیابی در نقطه زمانی (PITR) در PostgreSQL، قابلیت Write-Ahead Logging یا همان WAL قرار دارد. در حالی که WAL با ثبت تراکنش‌ها پیش از نوشتن در فایل‌های داده، انطباق با ACID را تضمین می‌کند، آرشیو کردن WAL مکانیزمی است که این لاگ‌ها را برای پشتیبان‌گیری طولانی‌مدت و همانندسازی (Replication) حفظ می‌کند.

با این حال، پیکربندی آرشیو WAL یک عملیات «تنظیم کن و فراموش کن» نیست. پیکربندی‌های نادرست، شکست‌های خاموش و سوءتفاهم‌های معماری می‌توانند منجر به از دست رفتن فاجعه‌بار داده‌ها، سناریوهای مغز-شکافته (Split-brain) یا قطعی کامل پایگاه داده شوند.

در این راهنمای جامع، ما معماری آرشیو WAL در PostgreSQL را بررسی می‌کنیم، رایج‌ترین دام‌هایی که منجر به از دست رفتن داده‌ها می‌شوند را شناسایی کرده و بهترین شیوه‌های سطح عملیاتی را برای اطمینان از تاب‌آوری پایگاه داده شما ترسیم می‌کنیم.

درک معماری WAL در PostgreSQL

پیش از غوطه‌ور شدن در دام‌ها، درک نحوه مدیریت لاگ‌های تراکنش توسط PostgreSQL حیاتی است.

PostgreSQL تمام تغییرات را در بخش‌های WAL (که به طور پیش‌فرض فایل‌های ۱۶ مگابایتی هستند) در دایرکتوری pg_wal (که در نسخه‌های پیش از ۱۰ با نام pg_xlog شناخته می‌شد) می‌نویسد. هر تراکنش به صورت متوالی ثبت شده و با یک شماره توالی لاگ (LSN) مشخص می‌شود.

هنگامی که یک بخش WAL پر می‌شود، PostgreSQL به بخش جدیدی سوئیچ می‌کند. برای جلوگیری از رشد بی‌نهایت دایرکتوری pg_wal، PostgreSQL بخش‌های قدیمی WAL را پس از اینکه دیگر برای بازیابی از خرابی یا همانندسازی مورد نیاز نباشند، بازیافت یا حذف می‌کند.

آرشیو کردن WAL این فرآیند بازیافت را قطع می‌کند. هنگامی که archive_mode فعال باشد، PostgreSQL یک archive_command تعریف‌شده توسط کاربر (یا در نسخه‌های ۱۵ به بعد، یک archive_library) را اجرا می‌کند تا بخش تکمیل‌شده WAL را پیش از حذف یا بازنویسی، به یک مکان ثانویه و امن کپی کند.

برای انجام بازیابی در نقطه زمانی (PITR)، شما به دو مؤلفه نیاز دارید:
۱. یک پشتیبان پایه (Base Backup) معتبر.
۲. زنجیره‌ای پیوسته از فایل‌های WAL آرشیو شده از زمان پشتیبان پایه تا زمان بازیابی مورد نظر شما.

اگر آن زنجیره WAL شکسته شود، PITR شما با شکست مواجه خواهد شد.

پیکربندی آرشیو WAL برای محیط عملیاتی

برای فعال‌سازی آرشیو WAL، باید فایل postgresql.conf خود را تغییر دهید. یک پیکربندی پایه مستلزم تنظیم wal_level، فعال‌سازی archive_mode و تعریف archive_command است.

# postgresql.conf
wal_level = replica             # 'replica' یا 'logical' برای آرشیو کردن مورد نیاز است
archive_mode = on               # فرآیند آرشیو را فعال می‌کند
archive_command = 'test ! -f /mnt/nfs/archive/%f && cp %p /mnt/nfs/archive/%f'
archive_timeout = 600           # هر ۱۰ دقیقه یک سوئیچ WAL را اجبار می‌کند

در archive_command:
* %p نشان‌دهنده مسیر کامل فایل WAL برای آرشیو است.
* %f نشان‌دهنده نام فایل WAL است.

اگرچه پیکربندی بالا ساده به نظر می‌رسد، اما تکیه بر دستورات ساده شل در محیط‌های سازمانی خطرات قابل توجهی را به همراه دارد.

دام‌های رایج در آرشیو WAL

دام ۱: «موفقیت خاموش» در archive_command

PostgreSQL کاملاً به کد خروجی archive_command متکی است. اگر دستور مقدار 0 را برگرداند، PostgreSQL فرض می‌کند که فایل WAL با موفقیت آرشیو شده و اقدام به بازیافت فایل اصلی می‌کند.

یک اشتباه رایج، استفاده از دستوری است که حتی اگر داده‌ها به طور ایمن در حافظه پایدار ذخیره نشده باشند، مقدار 0 را برمی‌گرداند. برای مثال، یک دستور ساده cp ممکن است به محض رسیدن داده‌ها به کش صفحه سیستم‌عامل در سرور مقصد، موفقیت را گزارش کند. اگر سرور مقصد پیش از تخلیه کش روی دیسک دچار قطعی برق شود، فایل WAL از دست می‌رود، اما PostgreSQL نسخه محلی خود را حذف کرده است.

خطر: شکسته شدن زنجیره WAL و ناتوانی در انجام PITR که تنها در زمان وقوع فاجعه کشف می‌شود.

راهکار: اطمینان حاصل کنید که اسکریپت آرشیو شما نوشتن‌های همگام (Synchronous) را اعمال می‌کند. اگر از دستورات استاندارد شل استفاده می‌کنید، از ابزارهایی استفاده کنید که تخلیه داده روی دیسک را تضمین می‌کنند، یا یک اسکریپت واسط بنویسید که اندازه فایل و چک‌سام را پس از انتقال تأیید کند.

دام ۲: اتمام فضای پارتیشن pg_wal (تورم WAL)

اگر archive_command شکست بخورد (کد خروجی غیر صفر برگرداند)—به دلیل قطعی شبکه، مجوزهای نادرست یا پر شدن دیسک مقصد—PostgreSQL فایل WAL را در دایرکتوری pg_wal نگه می‌دارد و دستور را به طور نامحدود دوباره امتحان می‌کند.

اگرچه این کار با حذف نکردن WALهای آرشیو نشده از از دست رفتن داده‌ها جلوگیری می‌کند، اما خطر جدی برای در دسترس بودن ایجاد می‌کند. اگر دایرکتوری pg_wal روی پارتیشنی باشد که ۱۰۰٪ پر شود، PostgreSQL یک خطای PANIC صادر کرده و کرش می‌کند. پایگاه داده تا زمانی که فضا آزاد نشود، دوباره بالا نخواهد آمد.

خطر: قطعی کامل پایگاه داده به دلیل پر شدن پارتیشن pg_wal.

راهکار:
۱. همیشه pg_wal را روی یک پارتیشن دیسک اختصاصی قرار دهید.
۲. نظارت دقیق بر اندازه دایرکتوری pg_wal را پیاده‌سازی کنید.
۳. نمای pg_stat_archiver را برای شناسایی فوری دستورات آرشیو ناموفق پایش کنید.

دام ۳: پشتیبان‌های پایه ناقص

یک پشتیبان پایه بدون فایل‌های WAL تولید شده در حین فرآیند پشتیبان‌گیری، بی‌فایده است. اگر از اسنپ‌شات در سطح فایل‌سیستم استفاده می‌کنید یا از pg_basebackup بدون استریم کردن WALها (-X stream) استفاده می‌کنید، باید اطمینان حاصل کنید که فایل‌های WAL تولید شده بین شروع و پایان پشتیبان‌گیری با موفقیت آرشیو شده‌اند.

اگر آرشیوکننده شما کند باشد یا شکست بخورد و آن فایل‌های WAL خاص از دست بروند، پشتیبان پایه نمی‌تواند به وضعیت سازگار برسد.

خطر: پشتیبان‌های پایه خراب یا غیرقابل بازیابی.

راهکار: از pg_basebackup -X stream استفاده کنید تا فایل‌های WAL ضروری را درون خودِ بسته پشتیبان قرار دهید، یا از راهکارهای پشتیبان‌گیری سازمانی استفاده کنید که به طور خودکار وابستگی بین پشتیبان‌های پایه و بخش‌های WAL را مدیریت می‌کنند.

دام ۴: سردرگمی در تایم‌لاین و سناریوهای مغز-شکافته

هنگامی که یک سرور استندبای به سرور اصلی (Primary) ارتقا می‌یابد، PostgreSQL «شناسه تایم‌لاین» (بخش اول نام فایل WAL، مثلاً 0000000200000001000000A4) را افزایش می‌دهد. این کار از بازنویسی تاریخچه WAL سرور اصلی قدیمی توسط سرور اصلی جدید جلوگیری می‌کند.

با این حال، اگر سرور اصلی قدیمی به طور تصادفی و بدون حصارکشی مناسب (سناریوی مغز-شکافته) شروع به کار کند، ممکن است تلاش کند فایل‌های WAL را با استفاده از تایم‌لاین قدیمی به همان مکان آرشیو ارسال کند. اگر archive_command شما کورکورانه فایل‌ها را بازنویسی کند، می‌توانید مخزن آرشیو خود را خراب کنید.

خطر: بازنویسی فایل‌های WAL، خرابی آرشیوها و پایگاه‌های داده غیرقابل بازیابی.

راهکار: دستور archive_command شما هرگز نباید یک فایل موجود را بازنویسی کند. توجه کنید که در پیکربندی پایه قبلی، ما از test ! -f /mnt/nfs/archive/%f استفاده کردیم تا در صورت وجود فایل، دستور صراحتاً شکست بخورد.

کاهش خطرات از دست رفتن داده‌ها: بهترین شیوه‌های عملیاتی

برای تقویت استراتژی آرشیو PostgreSQL خود، بهترین شیوه‌های زیر را پیاده‌سازی کنید.

۱. نظارت بومی بر فرآیند آرشیو

PostgreSQL یک نمای داخلی به نام pg_stat_archiver ارائه می‌دهد که موفقیت و شکست فرآیند آرشیو شما را ردیابی می‌کند. شما باید این نما را در پشته نظارتی خود (مانند Prometheus، Datadog یا Zabbix) ادغام کنید.

SELECT 
    archived_count,
    last_archived_wal,
    last_archived_time,
    failed_count,
    last_failed_wal,
    last_failed_time,
    stats_reset
FROM pg_stat_archiver;

آستانه‌های هشدار برای پیکربندی:
* در صورت افزایش failed_count هشدار دهید.
* اگر اختلاف زمانی بین now() و last_archived_time از آستانه RPO شما (مثلاً ۱۵ دقیقه) فراتر رفت هشدار دهید، با در نظر گرفتن اینکه پایگاه‌های داده با ترافیک کم ممکن است به طور طبیعی تأخیر داشته باشند مگر اینکه archive_timeout تنظیم شده باشد.

۲. بهره‌گیری از archive_timeout

در پایگاه‌های داده با حجم نوشتن کم، ممکن است پر شدن یک فایل WAL ۱۶ مگابایتی ساعت‌ها طول بکشد. تا زمانی که پر نشود، آرشیو نمی‌شود. اگر سرور کرش کند و دیسک محلی از دست برود، شما ساعت‌ها تراکنش را از دست می‌دهید.

تنظیم archive_timeout = 600 (۱۰ دقیقه) PostgreSQL را مجبور می‌کند به یک فایل WAL جدید سوئیچ کرده و فایل فعلی را آرشیو کند، حتی اگر پر نشده باشد. این کار تضمین می‌کند که RPO شما از ۱۰ دقیقه فراتر نرود، که به قیمت استفاده کمی بیشتر از فضای ذخیره‌سازی به دلیل فایل‌های WAL نیمه‌پر تمام می‌شود.

۳. انتقال به archive_library (PostgreSQL 15+)

به طور تاریخی، archive_command برای هر فایل WAL یک فرآیند شل جدید ایجاد می‌کرد. در محیط‌های با توان عملیاتی بالا که صدها فایل WAL در دقیقه تولید می‌کنند، سربار ایجاد فرآیندهای شل به یک گلوگاه عملکردی تبدیل می‌شود.

PostgreSQL 15 پارامتر archive_library را معرفی کرد که اجازه می‌دهد آرشیو WAL توسط ماژول‌های C بارگذاری‌شده به صورت پویا مدیریت شود. این کار سربار ایجاد فرآیند شل را حذف کرده و مکانیزم آرشیو بسیار قوی‌تر و با عملکرد بالاتری را فراهم می‌کند. اگر از PostgreSQL 15 یا بالاتر استفاده می‌کنید، به دنبال ابزارهای پشتیبان‌گیری باشید که از ماژول‌های آرشیو سفارشی پشتیبانی می‌کنند.

۴. تست منظم بازیابی در نقطه زمانی (PITR)

پشتیبانی که تست نشده باشد، پشتیبان نیست؛ یک آرزو است. تنها راه برای تأیید اینکه آرشیو WAL شما به درستی کار می‌کند، زنجیره WAL شما شکسته نیست و پشتیبان‌های پایه شما سازگار هستند، انجام تست‌های روتین و خودکار PITR است.

یک نمونه موقت بالا بیاورید، پشتیبان پایه را بازیابی کنید، restore_command را برای دریافت از آرشیو خود پیکربندی کنید و به یک زمان خاص بازیابی کنید. تأیید کنید که پایگاه داده به وضعیت سازگار می‌رسد و برای اتصالات باز می‌شود.

پشتیبان‌گیری و بازیابی سازمانی با CloudSave

مدیریت اسکریپت‌های شل سفارشی برای archive_command، مدیریت حذف داده‌های تکراری WAL و اطمینان از ذخیره‌سازی امن و خارج از سایت برای لاگ‌های تراکنش، می‌تواند به سرعت به یک بار عملیاتی برای تیم‌های IT تبدیل شود.

اینجاست که CloudSave ارزش قابل توجهی برای محیط‌های سازمانی PostgreSQL فراهم می‌کند. CloudSave مستقیماً با APIهای پشتیبان‌گیری و آرشیو WAL بومی PostgreSQL ادغام می‌شود تا دام‌های دستی مورد بحث در بالا را حذف کند.

به جای نوشتن اسکریپت‌های bash شکننده، CloudSave یک ادغام قوی، مبتنی بر ایجنت یا بدون ایجنت ارائه می‌دهد که:
* تضمین تحویل: دستورات استاندارد شل را با انتقال‌های تأیید شده و دارای چک‌سام به فضای ذخیره‌سازی امن خارج از سایت یا ابری جایگزین می‌کند.
* جلوگیری از تورم WAL: به طور فعال دایرکتوری pg_wal را نظارت کرده و پیش از اتمام فضای پارتیشن به مدیران هشدار می‌دهد.
* خودکارسازی PITR: بازیابی در نقطه زمانی را از طریق یک رابط بصری ساده می‌کند. شما دقیقه‌ای که می‌خواهید به آن بازیابی کنید را انتخاب می‌کنید و CloudSave به طور خودکار پشتیبان پایه صحیح را بازیابی کرده و توالی دقیق فایل‌های WAL مورد نیاز برای رسیدن به آن وضعیت را استریم می‌کند.
* مدیریت تایم‌لاین‌ها: تاریخچه‌های تایم‌لاین PostgreSQL را به هوشمندی مدیریت می‌کند و اطمینان حاصل می‌کند که فیل‌اورها و سناریوهای مغز-شکافته مخزن پشتیبان شما را خراب نمی‌کنند.

با برون‌سپاری مدیریت سنگین WAL به CloudSave، مدیران پایگاه داده می‌توانند بر بهینه‌سازی کوئری و عملکرد پایگاه داده تمرکز کنند، با این اطمینان که SLAهای RPO و RTO آن‌ها توسط یک پلتفرم در سطح سازمانی محافظت می‌شود.

نتیجه‌گیری

آرشیو WAL در PostgreSQL ستون فقرات بازیابی فاجعه پایگاه داده است. اگرچه مفهوم کپی کردن یک فایل از یک دایرکتوری به دایرکتوری دیگر ساده به نظر می‌رسد، اما موارد خاص—شکست‌های خاموش، اتمام فضای دیسک و واگرایی تایم‌لاین—خطرات جدی برای یکپارچگی داده‌ها ایجاد می‌کنند.

با درک معماری pg_wal، اجتناب اکید از پیکربندی‌های مخرب archive_command، نظارت بر pg_stat_archiver و بهره‌گیری از پلتفرم‌های پشتیبان‌گیری سازمانی مانند CloudSave، می‌توانید یک زیرساخت تاب‌آور PostgreSQL بسازید که قادر است در برابر خرابی‌های سخت‌افزاری، خطاهای انسانی و قطعی‌های فاجعه‌بار بدون از دست دادن حتی یک تراکنش ثبت‌شده، دوام بیاورد.

دام‌های رایج آرشیو WAL در PostgreSQL که منجر به از دست رفتن داده‌ها می‌شوند را کشف کنید. بهترین شیوه‌های تخصصی DBA، نکات پیکربندی و نحوه اطمینان از بازیابی در نقطه زمانی (PITR) قابل اعتماد برای پایگاه‌های داده سازمانی را بیاموزید.