MVCC هو السرّ وراء قدرة PostgreSQL على خدمة قرّاء وكتّاب كثيرين في آنٍ واحد بسلاسة. هذا مفهوم متقدّم لكنّه أساسيّ لفهم أداء PostgreSQL وسلوكه. تبني هذه الصفحة على مخطّطات PostgreSQL وتفترض إلمامًا بأساسيات المعاملات (Transactions).
المشكلة: القراءة والكتابة في آنٍ واحد
تخيّل معاملةً تقرأ صفًّا بينما معاملة أخرى تعدّله في اللحظة نفسها. في نظام يعتمد على الأقفال (Locks) الصارمة، سيضطرّ أحدهما للانتظار: القارئ يحجب الكاتب أو العكس. مع آلاف المعاملات المتزامنة، يصبح هذا الانتظار عنق زجاجة يخنق الأداء.
الحلّ: نسخ متعدّدة من الصفّ
MVCC اختصار لـ Multi-Version Concurrency Control (التحكّم بالتزامن متعدّد النسخ). فكرته:
بدل تعديل الصفّ في مكانه وقفل القرّاء، يحتفظ PostgreSQL بعدّة نسخ من الصفّ؛ كل معاملة ترى «لقطة (Snapshot)» متّسقة من البيانات كما كانت عند بدئها.
النتيجة المباشرة والمهمّة: القرّاء لا يحجبون الكتّاب، والكتّاب لا يحجبون القرّاء. حين يُعدَّل صفّ، تُنشأ نسخة جديدة، وتبقى النسخة القديمة متاحة للمعاملات التي بدأت قبل التعديل. لكلّ معاملة رؤية متّسقة دون انتظار.
التكلفة: الصفوف الميّتة و VACUUM
لا شيء بلا ثمن. لأنّ التعديل يُنشئ نسخة جديدة ويُبقي القديمة، تتراكم صفوف ميّتة (Dead Tuples) — نسخ قديمة لم تعد أي معاملة بحاجة إليها. تراكمها يُسمّى الانتفاخ (Bloat) ويهدر مساحة وأداءً.
لذلك يوفّر PostgreSQL عملية VACUUM التي تنظّف الصفوف الميّتة وتستعيد المساحة. فهم هذه العلاقة ضروري: أداء PostgreSQL الجيّد يتطلّب إبقاء VACUUM يعمل بكفاءة. (سنفرد صفحةً لـ VACUUM وأهمّيته.)
لماذا يهمّك هذا؟
- يفسّر لماذا لا تتباطأ قراءات PostgreSQL رغم الكتابة المتزامنة الكثيفة.
- يفسّر ظهور الانتفاخ وحاجتك المستمرّة إلى VACUUM وضبطه.
- يمهّد لفهم مستويات العزل (Isolation Levels) وسلوك المعاملات المتزامنة.
الخطوات التالية
بعد استيعاب MVCC، ستتعمّق في VACUUM ولماذا يهمّ، ثم في ضبط الأداء وقراءة خطط التنفيذ عبر EXPLAIN ANALYZE. راجع أساس المعاملات في المعاملات في SQL، والسياق الأوسع في مخطّطات PostgreSQL.