بخش اول: ورود به جهان قدرتمند PostgreSQL
بخش دوم : مکانیزم های حرفه‌ای مدیریت ذخیره سازی و تضمین مقیاس پذیری پستگرس
بخش سوم : تحلیل و بهینه‌سازی اجرای کوئری در PostgreSQL
بخش چهارم: استراتژی‌های پشتیبان‌گیری و بازیابی اطلاعات
بخش پنجم: راهکارهای دسترس‌پذیری بالا و مقیاس‌پذیری
بخش ششم: پایش، مانیتورینگ و عیب‌یابی در PostgreSQL
کارگاه‌ها و مثال‌های کاربردی

از OID تا RelFileNode – چگونه PostgreSQL فایل فیزیکی جداول را جایگزین می‌کند؟ 🎥

تا اینجا با ساختار فیزیکی ذخیره فایل‌ها در PostgreSQL آشنا شده‌ایم و می‌دانیم که:

  • هر شیء اصلی دیتابیس (مثل جدول یا ایندکس) در سطح فیزیکی به یک فایل روی دیسک نگاشت می‌شود.
  • این فایل در مسیر زیر قرار می‌گیرد:
$PGDATA/base/<database_oid>/<file_identifier>
  • معمولاً هنگام ایجاد یک جدول، OID آن جدول در کاتالوگ سیستم، همان شناسه فایل فیزیکی آن هم هست.
    یعنی در نگاه اول به نظر می‌رسد:
pg_class.oid  ==  filename on disk

اما این فقط در ابتدای عمر جدول درست است.


❗ نکته مهم: همیشه OID برابر نام فایل نیست

در بسیاری از عملیات‌ها PostgreSQL فایل فیزیکی جدول را عوض می‌کند، اما هویت منطقی جدول تغییر نمی‌کند.

در اینجا یک مفهوم کلیدی وارد می‌شود:

🧠 RelFileNode چیست؟

ستونی در جدول سیستمی pg_class که مشخص می‌کند:

فایل فیزیکی فعلی این جدول روی دیسک چیست؟

بنابراین:

مفهومنقشتغییر می‌کند؟
OIDهویت منطقی جدول در کاتالوگ❌ تقریباً هرگز
relfilenodeشناسه فایل فیزیکی فعلی✅ گاهی تغییر می‌کند

پس اگر PostgreSQL فایل جدول را بازنویسی کند:

  • OID ثابت می‌ماند
  • relfilenode عوض می‌شود
  • فایل فیزیکی جدید ساخته می‌شود

بنابراین برای پیدا کردن فایل واقعی جدول روی دیسک، همیشه باید relfilenode را بررسی کنیم، نه OID.


۱. هویت منطقی vs هویت فیزیکی جدول

هر جدول دو هویت دارد:

🧩 هویت منطقی
pg_class.oid

شناسه دائمی جدول در کاتالوگ سیستم

این شناسه:

  • در کل عمر جدول ثابت است
  • برای وابستگی‌ها استفاده می‌شود

💾 هویت فیزیکی
pg_class.relfilenode

شناسه فایل واقعی روی دیسک

این شناسه:

  • می‌تواند تغییر کند
  • نشان می‌دهد جدول الان در کدام فایل ذخیره شده

۲. عملیات‌هایی که فایل فیزیکی را عوض می‌کنند

چند دستور مهم باعث بازنویسی کامل جدول می‌شوند:

  • TRUNCATE
  • VACUUM FULL
  • CLUSTER
  • برخی عملیات REINDEX

در همه این‌ها:

فایل جدید ساخته می‌شود
relfilenode عوض می‌شود
OID ثابت می‌ماند

۳. آماده‌سازی محیط آزمایش

CREATE DATABASE relfilenode_workshop;
\c relfilenode_workshop

CREATE TABLE employees (
    id serial PRIMARY KEY,
    name text,
    salary numeric,
    updated_at timestamp default now()
);

۴. مشاهده وضعیت اولیه جدول

SELECT oid, relfilenode, relname
FROM pg_class
WHERE relname='employees';

SELECT pg_relation_filepath('employees');

در ابتدای ایجاد جدول معمولاً:

oid = relfilenode

۵. درج داده و بررسی عدم تغییر فایل

INSERT INTO employees(name,salary)
SELECT 'emp'||i, random()*100000
FROM generate_series(1,100000) i;

دوباره relfilenode را بررسی کنید.

نتیجه:

✔ تغییری نمی‌کند
✔ فقط داده به فایل موجود اضافه می‌شود


⚔️ DELETE vs TRUNCATE (از دید فیزیکی)

🗑 DELETE

دستور DELETE برای حذف سطرهای مشخص یا همه سطرهای جدول بر اساس شرط (یا بدون شرط) استفاده می‌شود.
این دستور رکوردها را فیزیکی حذف نمی‌کند، بلکه آن‌ها را طبق MVCC به‌صورت «حذف‌شده» علامت‌گذاری می‌کند.

در نتیجه:

  • فایل جدول همان باقی می‌ماند
  • فضای دیسک بلافاصله آزاد نمی‌شود
  • امکان استفاده از WHERE وجود دارد
  • برای حذف تدریجی یا انتخابی مناسب است
DELETE FROM employees;

نتیجه:

  • داده‌ها invisible می‌شوند (MVCC)
  • فایل همان است
  • relfilenode تغییر نمی‌کند
  • حجم جدول کم نمی‌شود

چرا؟

چون PostgreSQL فقط رکوردها را dead mark می‌کند.


⚡ TRUNCATE

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

  • بسیار سریع اجرا می‌شود
  • فضای دیسک فوراً آزاد می‌شود
  • عملیات مبتنی بر MVCC انجام نمی‌دهد
  • قابل rollback است (اگر داخل تراکنش باشد)
  • قفل انحصاری (ACCESS EXCLUSIVE) روی جدول می‌گیرد
TRUNCATE employees;

نتیجه فوری:

✔ فایل جدید ساخته می‌شود
✔ relfilenode تغییر می‌کند
✔ جدول کاملاً خالی
✔ فضای دیسک آزاد

این عملیات در واقع:

drop file + create new empty file

اما هویت منطقی جدول حفظ می‌شود.


📊 مقایسه DELETE و TRUNCATE

ویژگیDELETETRUNCATE
حذف منطقیبلهخیر
MVCCداردندارد
فایل جدیدخیربله
relfilenodeثابتتغییر
سرعتکندتربسیار سریع

🧾 رفتار ایندکس‌ها هنگام تعویض فایل جدول

نکته مهم:

وقتی فایل جدول عوض شود، ایندکس‌ها هم باید بازسازی شوند.

بنابراین در TRUNCATE و VACUUM FULL:

relfilenode جدول تغییر می‌کند
relfilenode ایندکس‌ها هم تغییر می‌کند

🔄 VACUUM FULL و بازنویسی کامل جدول

هدف VACUUM FULL:

  • حذف bloat
  • بازسازی فیزیکی جدول
  • برگرداندن فضا به سیستم عامل

مراحل داخلی:

  1. ساخت فایل جدید
  2. کپی فقط رکوردهای زنده
  3. تعویض pointer جدول
  4. حذف فایل قدیمی

در نتیجه:

✔ relfilenode جدید
✔ جدول فشرده
✔ بدون dead tuple


اجرای آزمایش

ایجاد bloat:

UPDATE employees
SET salary = salary * 1.1;

اجرای VACUUM FULL:

VACUUM FULL employees;

سپس:

SELECT oid, relfilenode
FROM pg_class
WHERE relname='employees';

مشاهده می‌کنید:

relfilenode تغییر کرده

🧠 جمع‌بندی

PostgreSQL بین هویت منطقی و هویت فیزیکی تفکیک کامل دارد.

این طراحی مزایای بزرگی دارد:

✔ امکان بازنویسی جدول بدون شکستن وابستگی‌ها
✔ امکان بهینه‌سازی ذخیره‌سازی
✔ امکان حذف bloat
✔ حفظ integrity سیستم


محتوای ویدئویی

 محتوای ویدئویی کارگاه در بخش زیر قابل مشاهده است.

فروشگاه
جستجو
دوره ها

لطفا کلمات کلیدی را وارد کنید