WIUNIX ACADEMY
autovacuum در PostgreSQL؛ تشخیص عقبافتادگی پاکسازی و خطر wraparound
میبینیم پاکسازی جدول چرا عقب افتاده، سن XID و multixact چه خطری دارن و قبل از نگهداری یک جدول موجود در PostgreSQL 18 چه چیزهایی رو باید بررسی کنیم.
محیطت رو انتخاب کنآموزش متناسب با محیط تو
کجا اجرا میکنی؟
سیستمعامل و نسخهٔ سرورت رو انتخاب کن تا مراحل، دستورها و راهحلهای همون محیط رو ببینی.
آموزش متناسب با مقادیر تو
تنظیمات این آموزش
مقادیر نمونه رو با مشخصات سرورت عوض کن تا متن و دستورها با هم تغییر کنن. رمز، کلید خصوصی و توکن اینجا وارد نکن. مقدارها فقط توی همین زبانه میمونن و به سرور یا لینک اشتراکگذاری فرستاده نمیشن. قبل از اجرا، DNS، گواهیها و تنظیمات دسترسی شبکه رو روی سرورت بررسی کن.
اگر آیپی، دامنه یا پورتهای نمونه با سرورت فرق دارن، بخش تنظیمات پایین رو باز کن. مقدارها رو عوض کن و «اعمال در آموزش» رو بزن؛ بعد دستورهای تازه رو کپی کن.
تنظیم مقادیر برای محیط من4 مقدار قابلتغییر
از اینجا شروع کن
آخر این آموزش چی خواهیم داشت؟
میبینیم پاکسازی جدول چرا عقب افتاده، سن XID و multixact چه خطری دارن و قبل از نگهداری یک جدول موجود در PostgreSQL 18 چه چیزهایی رو باید بررسی کنیم.
سیستمعاملها و نسخههای پوششدادهشده
مسیرهای مستند کلاینت مدیریت موجود در Ubuntu 26.10/26.04/24.04، Debian 13/12، خانوادهٔ RHEL/Rocky/AlmaLinux 10.2/9.8 و Arch/Manjaro rolling در ۲۰۲۶-۱۱-۰۵ بررسی شدن. سرور و کلاینت نسخهٔ اصلی ۱۸ لازم است؛ نصب یا آزمون عملی همهٔ توزیعها ادعا نمیشه.
- Ubuntu 26.10 — کلاینت موجود
- Ubuntu 26.04 — کلاینت موجود
- Ubuntu 24.04 — کلاینت موجود
- Debian 13 — کلاینت موجود
- Debian 12 — کلاینت موجود
- RHEL 10.2 — کلاینت موجود
- RHEL 9.8 — کلاینت موجود
- Rocky Linux 10.2 — کلاینت موجود
- Rocky Linux 9.8 — کلاینت موجود
- AlmaLinux 10.2 — کلاینت موجود
- AlmaLinux 9.8 — کلاینت موجود
- Arch Linux rolling — کلاینت موجود
- Manjaro rolling — کلاینت موجود
قبل از شروع
- یک دیتابیس PostgreSQL 18 موجود، هویت مقصد معلوم و اجازهٔ دیدن آمار با pg_read_all_stats.
- کلاینت نسخهٔ اصلی ۱۸، اتصال مستقیم با نشست ثابت و پروفایل libpq و احراز هویت محافظتشدهٔ موجود.
- برای بخش اختیاری نگهداری: تأیید مسئول جدول، مالکیت یا MAINTAIN، primary و بودجهٔ مناسب I/O/WAL و زمان اجرا.
اول بفهمیم عقبافتادگی از کجاست
وقتی تعداد ردیفهای مرده زیاد میشه، ممکنه پاکسازی از تغییرات برنامه عقب افتاده باشه. اما قدیمیشدن شناسهٔ تراکنش مسئلهٔ دیگهایه و حتی روی جدول کمتغییر هم رخ میده. اول این دو رو از هم جدا میکنیم، بعد میبینیم کدوم تراکنش یا مصرفکننده اجازه نمیده vacuum جلو بره.
فضای شناسهٔ تراکنش محدوده و بالاخره شمارهها دوباره استفاده میشن. اگر ردیفها با اطلاعات تراکنش خیلی قدیمی باقی بمونن، بعد از دورزدن شمارهها ممکنه قدیمی و جدید اشتباه تفسیر بشن؛ به این خطر wraparound میگیم. PostgreSQL با freeze، وضعیت تراکنشِ سازندهٔ نسخههای قدیمی ردیف رو طوری ثبت میکنه که برای تشخیص قدیمیبودنشان به آن شمارهٔ قدیمی وابسته نباشه. سنها رو میخونیم تا قبل از وضعیت اضطراری به این نگهداری رسیدگی کنیم.
روی یک کلاستر PostgreSQL 18 موجود کار میکنیم. بخش اصلی آموزش فقط وضعیت رو میخونه؛ آخرش هم یک کار نگهداری اختیاری برای یک جدول مشخص داریم. لازم نیست برای تمرین سرور بسازی یا عمداً کلاستر رو به wraparound نزدیک کنی. گزینهٔ سیستمعامل، مسیر کلاینت مدیریت رو مشخص میکنه و سرور میتونه روی میزبان دیگهای باشه.
قدم بعدی
کلاینتی رو پیدا کنیم که واقعاً نصب شده
از میزبان مدیریتی مورد تأیید تیم استفاده کن که کلاینت نسخهٔ اصلی ۱۸ از قبل روش نصبه. در Ubuntu و Debian بستهٔ postgresql-client-18 مسیر نسخهدار پایین رو میده؛ میانبُر عمومی Debian ممکنه کلاینت دیگهای رو انتخاب کنه. در خانوادهٔ RHEL، مسیر این آموزش برای بستهٔ postgresql18 از PGDG است، نه بستهٔ پیشفرض توزیع. در Arch و Manjaro کلاینت داخل postgresql-libs است و مسیرش شمارهٔ نسخه نداره؛ پس خروجی نسخه رو حتماً بخون.
اگر بسته یا فایل وجود نداره، همینجا توقف کن. کلاینت مناسب رو در یک تغییر برنامهریزیشده و با راهنمای مخزن رسمی آماده کن؛ وسط رخداد، مخزن اضافه نکن و سرور رو ارتقا نده. Manjaro شاخههای خودش رو داره: برای دنبالکردن این آموزش شاخه رو عوض نکن و بستهٔ Arch رو مستقیم روش نصب نکن.
میزبان لینوکسی مدیریت که تیم تأیید کرده
cat /etc/os-release
id
pacman -Q postgresql-libs
pacman -Qo /usr/bin/psql
test -x /usr/bin/psql
/usr/bin/psql --versionبستهٔ انتخابشده مالک فایل کلاینت است و نسخهٔ اصلی psql برابر ۱۸ دیده میشه؛ در غیر این صورت هنوز به دیتابیس وصل نشو.
اتصال مشاهده و نگهداری رو از هم جدا کنیم
از مسئول دیتابیس دو نام اتصال موجود libpq بگیر: یکی برای مشاهده با دسترسی pg_read_all_stats و یکی برای نگهداری همان دیتابیس. حساب دوم باید مالک جدول انتخابشده باشه یا مجوز MAINTAIN داشته باشه. برای راحتترشدن کار، حساب مشاهده رو به superuser تبدیل نکن.
این نام اتصال، یک پروفایل کلاینت است و ربطی به سرویس systemd نداره. رمز و کلید رو داخل فرم این صفحه یا تاریخچهٔ ترمینال نذار؛ از روش محافظتشدهٔ فعلی تیم استفاده کن. در اتصال TCP راه دور، بررسی نام میزبان با verify-full و CA مصوب رو حفظ کن. اگر اتصال محلی عمداً با peer تنظیم شده، با همان هویت سیستمعامل وصل شو؛ قواعد pg_hba رو به trust تغییر نده.
اینجا سرویس PostgreSQL رو روشن یا راهاندازی نمیکنیم. واحد کلاستر Debian، واحد نسخهدار PGDG و سرویس Arch مسیر یکسانی ندارن. اگر سیاست SELinux، AppArmor یا فایروال جلوی اتصال مصوب رو گرفته، علت رو با مسئول میزبان بررسی کن؛ خاموشکردن حفاظت یا عمومیکردن پورت دیتابیس راهحل این آموزش نیست.
قدم بعدی
یک نشست برای دیدن وضعیت باز کنیم
روی میزبان مدیریت، پروفایل مشاهده رو باز کن و این ترمینال رو تا پایان بررسی نگه دار. اتصال باید به یک نشست ثابت PostgreSQL برسه؛ آدرس pool با حالت transaction pooling برای این مسیر مناسب نیست.
میزبان لینوکسی مدیریت
/usr/bin/psql -X -v ON_ERROR_STOP=1 'service=academy_vacuum_observe'psql به مقصدی که برای مشاهده تعیین شده وصل میشه. اگر اتصال خطا داد، اول همان پروفایل و دسترسی مصوب رو درست کن.
قدم بعدی
مقصد و تنظیمات واقعی کلاستر رو تأیید کنیم
قبل از بررسی، نام دیتابیس و کاربر و نسخه رو بخون. کنترل پایین فقط سرور نسخهٔ اصلی ۱۸ و دسترسی آمار مصوب رو میپذیره؛ بعد، تراکنشهای این نشست رو فقطخواندنی میکنه. اگر سرور replica باشه، بعضی وضعیتها رو میتونی ببینی، اما مقصد اجرای دستی vacuum نیست.
autocommit رو روشن نگه دار و دور این کادرها یک تراکنش طولانی باز نکن؛ قرار نیست نشست تشخیص خودش به مانع پاکسازی تبدیل بشه. مقدارهای freeze و failsafe رو جدا ثبت کن. رسیدن به آستانهٔ شروع autovacuum با رسیدن به مرز توقف ناشی از wraparound یکی نیست.
همان نشست ثابت psql برای مشاهده
\conninfo
SELECT current_database(), current_user, version(), pg_is_in_recovery();
SELECT current_setting('server_version_num')::integer BETWEEN 180000 AND 189999
AND pg_has_role(current_user,'pg_read_all_stats','USAGE') AS ready \gset
\if :ready
\else
\echo 'STOP: require PostgreSQL 18 and approved pg_read_all_stats access.'
\quit
\endif
SET statement_timeout='15s';
SET lock_timeout='2s';
SET default_transaction_read_only=on;
SHOW autovacuum;
SHOW track_counts;
SHOW autovacuum_freeze_max_age;
SHOW autovacuum_multixact_freeze_max_age;
SHOW vacuum_failsafe_age;
SHOW vacuum_multixact_failsafe_age;هویت سرور با کلاستر موردنظر یکی است، دسترسی آمار داری و تنظیمات واقعی دیده میشن.
قدم بعدی
سن XID و multixact رو جدا ببینیم
از فهرست دیتابیسهای کلاستر شروع میکنیم. سن XID با تعداد شناسههای تراکنشِ مصرفشده سنجیده میشه، نه ثانیه یا تعداد ردیف؛ هر تراکنش فقطخواندنی الزاماً XID تازه مصرف نمیکنه. multixact هم فضای شناسهٔ جداگانهای داره که از جمله در قفل مشترک ردیفها استفاده میشه. روی کلاستری با تغییرات زیاد، فاصلهٔ باقیمانده ممکنه خیلی سریع مصرف بشه.
هر دو ستون رو با آستانهٔ مربوط به خودشون مقایسه کن و روندشون رو در فاصلهٔ معقول ببین. ترتیب جدول پایین بر اساس XID است؛ کمبودن آن ستون، خیال ما رو از multixact راحت نمیکنه. اگر دیتابیسی اتصال نمیپذیره، بررسیش رو به مسئول دیتابیس بسپار؛ برای ورود بهش کورکورانه ویژگیهای اتصال رو عوض نکن.
همان نشست ثابت psql برای مشاهده
SELECT clock_timestamp() AS captured_at, datname, datallowconn,
age(datfrozenxid) AS xid_age, mxid_age(datminmxid) AS mxid_age
FROM pg_database
ORDER BY age(datfrozenxid) DESC;برای هر دیتابیس دو سن مستقل و وضعیت اجازهٔ اتصال دیده میشه.