أساسيات PostgreSQL: داخل محرك التخزين

فريق جلتش
٦ أبريل ٢٠٢٦2 مشاهدة4 دقائق
أساسيات PostgreSQL: داخل محرك التخزين

"يقدم هذا المقال نظرة معمقة على المحرك التخزيني لقواعد بيانات PostgreSQL، متتبعًا خطى عمليتي الإدخال (INSERT) والاستعلام (SELECT). نستكشف المكونات الأساسية مثل WAL وshared_buffers وكيف تؤثر على الأداء والمتانة."

يُعد فهم العمليات الداخلية لمحركات قواعد البيانات أمرًا بالغ الأهمية لأي مطور يسعى لتحسين الأداء والمتانة. يتناول هذا المقال تفصيليًا المحرك التخزيني لـPostgreSQL، متتبعًا خطوة بخطوة مسار عمليتي الإدخال (INSERT) والاستعلام (SELECT) داخل هذه القاعدة البيانات القوية.

قبل الخوض في تفاصيل الاستعلامات، من الضروري استكشاف البنية المعمارية لـPostgreSQL التي تتضمن أربعة مكونات رئيسية تُصادف في كل عملية. هذه المكونات هي: shared_buffers، وهي ذاكرة التخزين المؤقت للصفحات في الذاكرة؛ و WAL (Write-Ahead Log)، وهو سجل تسلسلي إضافي على القرص يضمن بقاء البيانات في حال تعطل النظام؛ و heap file، حيث تُخزن الصفوف فعليًا في صفحات بحجم 8KB؛ و index files، وهي هياكل B+Tree منفصلة تُخزن أيضًا في صفحات بحجم 8KB وتشير إلى موقع الصفوف في الـ heap. تُكتب البيانات أولاً إلى WAL، ثم إلى shared_buffers، وفي النهاية إلى ملفات الـ heap والفهرس على القرص. أما عمليات القراءة فتتحقق من shared_buffers أولاً، وإذا لم تكن الصفحة موجودة، تُجلب من القرص.

عند تنفيذ أمر INSERT INTO orders، تبدأ PostgreSQL بعملية تحليل SQL وتخطيط الاستعلام، ثم ينتقل المنفذ مباشرة إلى التنفيذ. قبل أي تعديل في shared_buffers أو صفحات الـ heap، تُكتب سجلات WAL التي تصف عملية الإدخال هذه. هذا السلوك يضمن متانة البيانات؛ فإذا تعطل النظام قبل إتمام الكتابة إلى الـ heap، يمكن لـPostgreSQL إعادة تطبيق التغييرات من سجل WAL. تُضمن الكتابة إلى WAL على القرص عبر `fsync` قبل تأكيد المعاملة للتطبيق، مما يمثل مساهمًا كبيرًا في زمن استجابة الكتابة. يمكن التحكم في هذا السلوك عبر `synchronous_commit` الذي يقلل زمن الاستجابة بشكل كبير إذا تم تعيينه إلى `off`، مع قبول احتمال فقدان البيانات لمدة تصل إلى wal_writer_delay الافتراضي البالغ 200ms. بعد ذلك، تبحث PostgreSQL عن صفحة heap بها مساحة حرة كافية (باستخدام Free Space Map - FSM) وتُدرج الصف الجديد. ثم تُحدّث الفهارس الأولية والثانوية (مثل `order_id` و`user_id` و`created_at`)، وكل تحديث فهرس يعني عبور B+Tree آخر وتعديل صفحة إضافية وسجل WAL جديد، مما يجعل تكلفة الكتابة O(k) في عدد الفهارس. تُعد المفاتيح الأولية من نوع UUIDs العشوائية سبباً متكرراً لتقسيم الصفحات (page splits) في الـ B+Tree، مما يزيد من تضخيم الكتابة.

بالنسبة لمسار القراءة، في سيناريو مثل SELECT * FROM orders WHERE order_id = <some order id>، يخطط PostgreSQL لاستخدام مسح الفهرس (index scan) على B+Tree الخاص بـ`order_id`. يستغرق هذا عادةً 3-4 قراءات صفحات للوصول إلى العقدة الورقية، والتي تحتوي على ctid يشير إلى الموقع الفعلي للصف في الـ heap. ثم تُجلب صفحة الـ heap المقابلة. هذه البنية ثنائية الخطوات (بحث في الفهرس ثم جلب من الـ heap) هي التكلفة الأساسية. بعد جلب الصف، تتحقق PostgreSQL من إصدارات الصفوف المتعددة عبر MVCC (Multi-Version Concurrency Control) باستخدام حقلي `xmin` و`xmax`، مما يضمن أن القراء لا ينتظرون الكتاب.

في سيناريو SELECT * FROM orders WHERE user_id = $1، قد يختار المخطط (planner) مسح الفهرس الثانوي على `user_id`. تعتمد كفاءة هذا المسح على مدى انتقائية الاستعلام. إذا كانت النتائج كثيرة، قد يكون المسح التسلسلي للـ heap أسرع من الجلب العشوائي للعديد من صفحات الـ heap. تُضبط هذه التكلفة المقدرة بواسطة `random_page_cost`، الذي يبلغ افتراضيًا 4.0 لأقراص HDD ولكن يجب ضبطه إلى 1.1-1.5 لأقراص SSD لضمان اختيار الخطة المثلى. المفاجأة الأخرى في PostgreSQL هي أن تحديث الصفوف لا يتم في مكانها؛ بل يُنشئ إصدار جديد من الصف، بينما يُصبح الإصدار القديم dead tuple، مما يؤدي إلى ما يُعرف بـ heap bloat. تُستعاد هذه المساحة بواسطة عملية VACUUM الخلفية.

ماذا يعني هذا لعملك؟

إن فهم هذه الآليات الداخلية في PostgreSQL يمنحك ميزة كبيرة في تصميم قواعد بيانات عالية الأداء والموثوقية. فمن خلال معرفة كيفية تأثير اختيار المفاتيح الأولية على تقسيم الصفحات، أو دور `synchronous_commit` في زمن استجابة الكتابة، يمكنك اتخاذ قرارات هندسية مستنيرة تقلل من تضخم الـ heap وتحسن أوقات الاستجابة بشكل جذري. هذا التحليل العميق يمكّنك من ضبط تكوينات PostgreSQL بفعالية ومعالجة تحديات الأداء بذكاء لضمان استقرار وفعالية تطبيقاتك.

أعجبك المقال؟ شاركه

النشرة البريدية

كن أول من يعرف بمستقبل التقنية

أهم الأخبار والتحليلات التقنية مباشرة في بريدك.