Postgres 18 async I/O: لمّا قاعدة البيانات بقت شغلها parallel حقيقي
لو الـ DB بتاعتك بتاخد ثانيتين في query تحت read-heavy workload، النسخة 18 بتغيّر المعادلة بالظبط. async I/O أصلي على Linux عبر io_uring، وskip scan بيقلّل عدد الـ index passes، وتحسينات موثّقة في vacuum وbackup. القرار مش "اعمل upgrade على طول"، القرار بالظبط: إمتى الأرقام دي بتفرق في شغلك، وإمتى الترحيل overkill مش مبرّر.
المشكلة باختصار
في النسخ الأقدم من Postgres، القراءات من الديسك كانت synchronous بالكامل. يعني كل page fetch بيقفل الـ worker process لحد ما الـ I/O يرجع من الـ storage. على NVMe محلي سريع، ده مش مشكلة كبيرة في OLTP. لكن على cold cache، أو storage متوسط، أو analytics queries بتمر على جداول كبيرة، بتخسر زمن ملحوظ في الانتظار.
Postgres 18 نزل رسميًا في 25 سبتمبر 2025 وبيجيب AIO كـ subsystem جديد في الـ core. على Linux بيستخدم io_uring، وعلى بقية الأنظمة بيستخدم worker processes. النتيجة الموثّقة في release notes الرسمية: تحسّن throughput يوصل لـ 3× على sequential scans، و2–2.5× على bitmap heap scans في الـ benchmarks الداخلية.
ليه async I/O بيفرق بالظبط
الفكرة إن Postgres دلوقتي يقدر يبعث عدة I/O requests في نفس الوقت، ويستفيد من الوقت ده في حساب execution plan steps تانية بدل ما يقعد ينتظر. ده معناه استغلال أفضل للـ CPU، وتقليل محسوس لوقت الـ wait على workloads فيها scans ثقيلة.
Skip Scan كمان ميزة جديدة مهمة. لو عندك index على (tenant_id, created_at) وبتعمل query بـ created_at لوحده، Postgres 18 هيقدر يستخدم الـ index ده بكفاءة بدل ما يعمل sequential scan على الجدول كله. في اختبارات EDB المنشورة، الفرق وصل لـ 180× في حالات محددة (جدول 10M rows، تصفية على column ثاني).
الخطوات قبل ما تهاجر
- اتأكد إن الـ kernel عندك >= 5.1 لو عايز io_uring (Ubuntu 22.04+ أو RHEL 9 بيوفّروا ده افتراضيًا).
- اعمل full backup، واتأكد من restore test حقيقي قبل الترحيل. مش snapshot بس.
- استخدم pg_upgrade مع
--linkلترحيل سريع، لكن متنساش--checkالأول. - اضبط
io_methodفي postgresql.conf — القيمة الافتراضيةworker؛ غيّرها لـio_uringلو Linux حديث. - راقب الأرقام الجديدة في pg_stat_io اللي اتوسّع في 18 بأعمدة إضافية عن read/write timings.
# ترحيل نموذجي من 17 إلى 18 مع فحص أولي
pg_upgrade \
--old-datadir=/var/lib/postgresql/17/main \
--new-datadir=/var/lib/postgresql/18/main \
--old-bindir=/usr/lib/postgresql/17/bin \
--new-bindir=/usr/lib/postgresql/18/bin \
--link --check
# بعد نجاح الترحيل، فعّل io_uring
echo "io_method = 'io_uring'" >> /etc/postgresql/18/main/postgresql.conf
echo "io_max_concurrency = 32" >> /etc/postgresql/18/main/postgresql.conf
systemctl restart postgresql@18-main
trade-offs صريحة
بتكسب throughput ملحوظ على analytics وreporting workloads. بتكسب كمان UUIDv7 مدعوم أصليًا في gen_random_uuid_v7()، وvirtual generated columns كـ default بدل stored، وOAuth 2.0 authentication كـ طريقة رسمية بدل الاعتماد الكامل على pg_hba.conf.
الثمن: الافتراض إن عندك monitoring ناضج. io_method = io_uring محتاج tuning حقيقي على io_max_concurrency، ولو سبته افتراضي على workload ثقيل ممكن تشوف نتائج عكسية على بعض الـ queries. overhead استهلاك الذاكرة في pg_stat_io بيزيد تقريبًا 10–15%. وبعض الـ extensions القديمة محتاجة rebuild كامل.
متى لا تهاجر لـ Postgres 18
لو شغلك OLTP بحت مع queries قصيرة جدًا تحت 10ms، التحسّن هيكون هامشي ومش يبرر downtime الترحيل. لو بتستخدم managed service (RDS, Cloud SQL, Supabase) ولسّه ما وصلش لـ 18 عندهم كـ GA، استنى النسخة المدعومة بدل ما تدير بنفسك. لو عندك extensions حساسة زي TimescaleDB أو Citus، اتأكد أولاً من توافقها الكامل مع 18 قبل أي خطوة — بعضها لسه بيتحدّث.
الخطوة التالية
شغّل pg_upgrade --check على staging environment النهارده، ولاحظ تحذيرات التوافق بدقة. لو نضيفة، اعمل benchmark before/after على 3 queries بتعتبرها critical فعلاً. لو الفرق أقل من 20%، أجّل الترحيل. لو أكتر، جدوله في أقرب نافذة صيانة.
المصادر
- PostgreSQL 18 Release Announcement (postgresql.org/about/news/2025/09)
- PostgreSQL 18 Release Notes (postgresql.org/docs/18/release-18.html)
- EDB — Skip Scan in PostgreSQL 18 Benchmarks (enterprisedb.com/blog)
- AIO Subsystem Design Wiki (wiki.postgresql.org/wiki/AIO)
- Crunchy Data — What's New in Postgres 18 (crunchydata.com/blog)