WIUNIX ACADEMY
بازیابی PostgreSQL تا پیش از حذف داده؛ تمرین با pgBackRest
صفحهٔ 2 از 3؛ مراحل قبلی و پیشنیازها را پیش از ادامه مرور کن.
آموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخه را انتخاب کن تا مراحل، دستورها و راهحلها برای همان محیط نمایش داده شوند.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر میکنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری میشوند و به سرور یا لینک اشتراکگذاری فرستاده نمیشوند. پیش از اجرا، DNS، گواهیها و سیاست شبکهٔ واقعی را بررسی کن.
آیپی، دامنه یا پورت مثالها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای بهروزشده را کپی کن.
تنظیم مقادیر برای محیط من7 مقدار قابلتغییر
قدم بعدی
پیش از حذف رکورد، نقطهٔ بازیابی را ثبت کنید
ابتدا با یک نام یکتا نقطهای در WAL ثبت میکنیم؛ سپس فقط همان ردیف آزمایشی را حذف میکنیم. پس از بستهشدن قطعهٔ فعلی WAL و شروع قطعهٔ بعدی، دوباره check را اجرا کنید تا رسیدن آرشیو لازم به مخزن بررسی شود.
نام هدف را در این تاریخچه فقط یک بار به کار ببرید. استفاده از یک نام مشخص، ابهام تاریخ و منطقهٔ زمانی را کم میکند، اما نام تکراری دوباره ابهام میسازد. اگر تمرین را تکرار میکنید، نام تازهای انتخاب کنید.
میزبان PostgreSQL مبدأ
'/usr/pgsql-18/bin/psql' -X -v ON_ERROR_STOP=1 -d 'academy_lab' <<'SQL'
SELECT pg_create_restore_point('academy_before_change');
DELETE FROM academy_pitr_probe.marker WHERE id = 1;
SELECT count(*) AS source_rows_after_delete FROM academy_pitr_probe.marker;
SELECT pg_switch_wal();
SQL
pgbackrest --stanza='academy' checkشمار ردیف آزمایشی در مبدأ صفر است و بررسی آرشیو با موفقیت پایان یافته است.
قدم بعدی
پوشهٔ بازیابی را فقط روی میزبان جدا بسازید
این پنل را با کاربر PostgreSQL روی میزبان بازیابی اجرا کنید، نه مبدأ. پوشهٔ مقصد باید تازه باشد؛ مسیر موجود، لینک یا محل اتصال دیتای اصلی قابلاستفاده نیست. والد آن باید متعلق به همین کاربر، قابلنوشتن برای او و بدون مجوز نوشتن برای گروه و دیگران باشد. خود پوشهٔ تمرین با مجوز خصوصی ساخته میشود.
این نسخهٔ تمرین، بکاپ دارای tablespace بیرون از پوشهٔ اصلی را نمیپذیرد؛ برای آن باید همهٔ مسیرها جداگانه نقشهبرداری و بررسی شوند. هیچ مدیر سرویسی هم نباید پوشهٔ تازه را خودکار راهاندازی کند. اگر والد مناسبی ندارید، مدیر میزبان یک پوشهٔ مختص این کار آماده کند؛ مجوز پوشههای مشترک را عوض نکنید.
میزبان جداگانهٔ بازیابی
parent=$(dirname -- '/var/lib/pgsql/academy-pitr-20261028')
test -d "$parent" && test ! -L "$parent" && test -O "$parent" && test -w "$parent" || exit 1
parent_mode=$(stat -c '%a' "$parent")
test $((8#$parent_mode & 8#022)) -eq 0 || exit 1
test ! -e '/var/lib/pgsql/academy-pitr-20261028' && test ! -L '/var/lib/pgsql/academy-pitr-20261028' || exit 1
umask 077
mkdir -- '/var/lib/pgsql/academy-pitr-20261028' || exit 1
mkdir -- '/var/lib/pgsql/academy-pitr-20261028/socket'
df -h '/var/lib/pgsql/academy-pitr-20261028'
'/usr/pgsql-18/bin/postgres' --version
pgbackrest --stanza='academy' infoپوشهٔ تازهٔ خصوصی روی میزبان جدا ساخته شده؛ نسخهٔ باینری و فضای آزاد را بررسی کردهاید.
قدم بعدی
همان بکاپ را تا نام هدف بازیابی کنید
دسترسی محافظتشده به مخزن باید از قبل روی میزبان بازیابی آماده باشد. برچسب بکاپ کامل را در ترمینال وارد کنید؛ این برچسب رمز نیست و مقدار خالی باعث توقف میشود. مسیر صریح مقصد و گزینهٔ reset-pg1-host مانع میشوند مسیر یا میزبان مبدأ برای نوشتن انتخاب شود.
از گزینههای force و delta برای عبور از خطا استفاده نکنید. بازیابی با target-action=pause آماده میشود تا پس از رسیدن به هدف بتوانید داده را ببینید و پیش از هر تصمیم برای خروج از حالت بازیابی، نتیجه را بررسی کنید.
میزبان جداگانهٔ بازیابی
printf 'Completed backup label: '
IFS= read -r backup_label
test -n "$backup_label" || exit 1
pgbackrest --stanza='academy' --reset-pg1-host --pg1-path='/var/lib/pgsql/academy-pitr-20261028/data' --set="$backup_label" --type=name --target='academy_before_change' --target-action=pause --archive-mode=off restoreفایلهای بکاپ در پوشهٔ تازه قرار گرفتهاند و تنظیمات، توقف بازپخش در هدف نامگذاریشده را درخواست میکنند.
قدم بعدی
پیش از راهاندازی، فایلهای بازیابیشده را بخوانید
فایل تنظیمات، includeها، فایل تنظیمات خودکار، HBA و لینکها را محلی بررسی کنید. ممکن است داخل آنها اطلاعات محرمانه باشد؛ محتوای کامل را در چت یا تیکت نگذارید. هر مسیر بیرونی، اتصال به مبدأ، کلید TLS یا دستور وابسته به محیط اصلی باید پیش از راهاندازی تعیین تکلیف شود.
پنل فقط فایلها را برای بررسی باز میکند و آنها را خودکار بازنویسی نمیکند. دستور restore_command و تنظیمات هدفی را که ابزار ساخته حفظ کنید. این تمرین فایلهای تنظیمات داخل پوشهٔ داده را فرض میکند؛ تنظیمات بیرونی بستهٔ توزیع، مسیر آمادهسازی دیگری میخواهد.
میزبان جداگانهٔ بازیابی
find '/var/lib/pgsql/academy-pitr-20261028/data' -maxdepth 2 -type l -ls
ls -l '/var/lib/pgsql/academy-pitr-20261028/data/recovery.signal' '/var/lib/pgsql/academy-pitr-20261028/data/postgresql.auto.conf'
nano '/var/lib/pgsql/academy-pitr-20261028/data/postgresql.conf'
nano '/var/lib/pgsql/academy-pitr-20261028/data/postgresql.auto.conf'
nano '/var/lib/pgsql/academy-pitr-20261028/data/pg_hba.conf'مسیر یا دستور ناخواستهٔ متصل به محیط اصلی باقی نمانده و تنظیمات لازم برای خواندن آرشیو و رسیدن به هدف حفظ شدهاند.
قدم بعدی
نسخهٔ جدا را راهاندازی و توقف در هدف را بررسی کنید
فقط پوشهٔ بازیابیشده را با سوکت خصوصی، اتصال TCP روی loopback، آرشیو خاموش و بدون اتصال streaming به مبدأ راهاندازی کنید. اگر سرور منتظر WAL میماند، لاگ خصوصی را بخوانید؛ نبودن یک فایل WAL مجوز خروج اجباری از حالت بازیابی نیست.
فایل HBA بررسیشده باید اتصال کاربر PostgreSQL از سوکت خصوصی را مجاز بداند. برای این کار قانون شبکه یا احراز هویت سرویس اصلی را تغییر ندهید. پس از اتصال، وضعیت recovery و paused و سپس محتوای جدول آزمایشی را ببینید.
میزبان جداگانهٔ بازیابی
'/usr/pgsql-18/bin/pg_ctl' -D '/var/lib/pgsql/academy-pitr-20261028/data' -l '/var/lib/pgsql/academy-pitr-20261028/recovery.log' -o "-c port=55432 -c listen_addresses=127.0.0.1 -c unix_socket_directories=/var/lib/pgsql/academy-pitr-20261028/socket -c archive_mode=off -c primary_conninfo=" start
'/usr/pgsql-18/bin/psql' -X -v ON_ERROR_STOP=1 -h '/var/lib/pgsql/academy-pitr-20261028/socket' -p '55432' -d 'academy_lab' -c "SELECT pg_is_in_recovery(), pg_get_wal_replay_pause_state(); SELECT * FROM academy_pitr_probe.marker;"سرور همچنان در recovery است، بازپخش روی paused قرار دارد و ردیف before-change در جدول دیده میشود.
قدم بعدی
اگر به نتیجه نرسیدید، زنجیرهٔ بکاپ تا WAL را بررسی کنید
نبودن ردیف مورد انتظار را از زمانبندی بکاپ شروع کنید: آیا بکاپ منتخب پیش از ثبت هدف تمام شده بود؟ نام هدف، دیتابیس و شناسهٔ کلاستر درستاند؟ اگر بازیابی منتظر مانده، نام دقیق فایل WAL لازم و وضعیت نگهداری آن در مخزن را بررسی کنید. دیدهشدن یک بکاپ در info، کاملبودن زنجیرهٔ WAL را تضمین نمیکند.
لاگ را خصوصی بخوانید و فقط اطلاعات لازم و پاکسازیشده را ثبت کنید. خطای ناسازگاری نسخه به باینری همنسخه نیاز دارد، نه ارتقای اجباری. تا وقتی وضعیت توقف و دادهٔ هدف را ثبت نکردهاید، بازپخش را ادامه ندهید.
میزبان جداگانهٔ بازیابی
tail -n 80 '/var/lib/pgsql/academy-pitr-20261028/recovery.log'
pgbackrest --stanza='academy' info
'/usr/pgsql-18/bin/psql' -X -h '/var/lib/pgsql/academy-pitr-20261028/socket' -p '55432' -d 'academy_lab' -c "SELECT pg_is_in_recovery(), pg_last_wal_replay_lsn(), pg_get_wal_replay_pause_state();"علت بر اساس بکاپ منتخب، نام هدف، شناسهٔ کلاستر و فایل WAL لازم مشخص شده؛ خروج اجباری از recovery انجام نشده است.