يحصل PostgreSQL 14 على آخر تحديث له في 12 نوفمبر 2026. تذكر سياسة إصدارات PostgreSQL هذا التاريخ بوصفه الإصدار النهائي للنسخة 14، والقاعدة وراءه قصيرة: كل نسخة رئيسية تُدعم خمس سنوات، ثم تحصل على إصدار فرعي أخير وتخرج من الدعم. أي ثغرة أمنية تُكتشف في 14 بعد ذلك اليوم تبقى بلا إصلاح.
والجدول الزمني حوله ضيق. يقول إعلان PostgreSQL 19 RC 1 الصادر في 15 أكتوبر إن تحديث 12 نوفمبر "سيتضمن عددًا كبيرًا من الإصلاحات"، ويحدد الإتاحة العامة لـ PostgreSQL 19 في 19 نوفمبر 2026، أي بعد أسبوع من خروج 14 من الدعم. إن كنت ما زلت على 14 فعليك اختيار الوجهة الآن، قبل أن يكون لـ 19 أي سجل في الإنتاج.
قواعد البيانات المُدارة لديها هامش أوسع قليلًا. يبقي تقويم إصدارات Amazon RDS for PostgreSQL النسخة 14 في الدعم القياسي حتى 28 فبراير 2027، ويبدأ الدعم الممتد المدفوع في 1 مارس 2027. أما الحاوية التي تستضيفها بنفسك فلا مهلة لها. صورة postgres:14 التي سحبتها في 2022 ما زالت تشغّل الشيفرة نفسها التي جاءت بها.
لماذا ما زالت أنظمة كثيرة على 14
سطر Postgres هو أكثر سطر في ملف compose يتردد الناس في لمسه، ولهم الحق. تغيير وسم الصورة بين نسختين رئيسيتين لا يرقّي البيانات، لأن صيغة التخزين على القرص تتغير بين النسخ الرئيسية. صفحة الإصدارات تقولها صراحة: لا بد من dump/reload أو pg_upgrade. لذلك في نظام أُعدّ في 2021 أو 2022 تُعاد بناء صور التطبيق كل شهر بينما يبقى وسم قاعدة البيانات في مكانه.
لكن صورة Docker الرسمية تمضي قدمًا. ملف versions.json في مستودع docker-library/postgres، وهو قائمة النسخ التي يبنيها القائمون على الصورة، يغطي حاليًا من 14 إلى 19. أما PostgreSQL 13 الذي انتهى عمره في نوفمبر 2025 فلم يعد فيه.
الخطوة 1: اعثر على كل Postgres 14 تشغّله
أسماء الصور لا يُعتمد عليها. قد تشغّل الحاوية PostGIS أو TimescaleDB أو صورة من مورّد أو شيئًا بُني داخليًا، وكلها تحمل Postgres في داخلها. اسأل الملف التنفيذي نفسه:
for c in $(docker ps --format '{{.Names}}'); do
v=$(docker exec "$c" postgres --version 2>/dev/null) && echo "$c: $v"
done
هذا يرى الحاويات العاملة فقط، لذا ابحث أيضًا في ملفات compose على القرص عن الأنظمة المتوقفة أو الموجودة على خوادم أخرى:
grep -rnE 'image: *"?postgres' --include='*compose*.y*ml' /srv /opt 2>/dev/null
لكل نسخة 14، دوّن ثلاث معلومات قبل أي تخطيط، فكل واحدة منها تحدد خطوة لاحقة (الأمثلة تفترض حاوية اسمها pg14):
# data checksums: "version: 0" means off
docker exec -u postgres pg14 pg_controldata | grep -i checksum
# bootstrap superuser: empty output means "postgres"
docker exec pg14 printenv POSTGRES_USER
# where the data volume is mounted
docker inspect -f '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{"\n"}}{{end}}' pg14
الخطوة 2: اختر النسخة الهدف
توصيتنا PostgreSQL 18 وليس 19. النسخة 18 هي الخط المستقر الحالي (18.6 على صفحة الإصدارات اليوم) ومدعومة حتى 14 نوفمبر 2030. سيكون عمر 19.0 أسبوعًا واحدًا حين تنتهي 14، والترحيل الذي يفرضه تاريخ انتهاء الدعم ليس الوقت المناسب لتكون من أوائل المستخدمين. انتقل إلى 18 الآن وخطط لـ 19 في العام المقبل، بعد صدور بضعة إصدارات فرعية منه.
لا حاجة للمرور عبر 15 و16 و17. تقول وثائق pg_upgrade إنه يدعم الترقية "من 9.2.X وما بعدها"، وتؤكد صفحة الإصدارات أنه يمكن تخطي النسخ، مع توصية بقراءة ملاحظات إصدار كل نسخة بينهما. من 14 إلى 18 يعني ذلك ملاحظات 15 و16 و17 و18، بدءًا من قائمة عدم التوافق في أعلى كل منها.
الخطوة 3: خذ نسخة احتياطية سبق أن استعدتها
docker exec pg14 pg_dumpall -U app | gzip > pg14-$(date +%F).sql.gz
استعدها في حاوية مؤقتة وشغّل عليها بعض الاستعلامات. قبل ذلك هي مجرد ملف، وليست نسخة احتياطية.
الخيار أ: dump ثم restore
لقواعد البيانات حتى بضعة غيغابايتات هذا أبسط طريق، ويزيل تضخم الجداول في الطريق. شغّل حاوية postgres:18 بجانب القديمة بمجلد تخزين فارغ خاص بها، ثم مرّر البيانات:
docker exec pg14 pg_dumpall -U app | docker exec -i pg18 psql -U app -q
حين شغّلنا هذا طبع psql خطأين:
ERROR: role "app" already exists
ERROR: database "app" already exists
كلاهما غير ضار. أنشأت الحاوية الجديدة هذا الدور وقاعدة البيانات عند أول تشغيل، وبقية الـ dump تُحمَّل فيهما. ثمن هذه الطريقة هو التوقف: يجب إيقاف الكتابة طوال الـ dump والاستعادة، فيطول التوقف مع حجم البيانات.
الخيار ب: pg_upgrade مع الروابط الصلبة
لقواعد البيانات الأكبر، يعيد pg_upgrade --link إنشاء المخطط في العنقود الجديد ويربط ملفات البيانات بروابط صلبة بدل نسخها. تقول وثائق pg_upgrade إن وضع link "أسرع بكثير (بلا نسخ ملفات)" ويستهلك مساحة أقل. يحتاج ذلك إلى الملفات التنفيذية للنسختين في مكان واحد، وهو ما لا توفره الصورة الرسمية. ينشر مشروع tianon/docker-postgres-upgrade صورًا بوسوم OLD-to-NEW، منها 14-to-18. ملف README الخاص به يصفه بأنه إثبات مفهوم "للتعلم منه" وتكييفه، لا أداة جاهزة، وهذا ما رأيناه فعلًا.
رقّينا عنقودًا تجريبيًا بالنسخة 14.24 أُنشئ بـ POSTGRES_USER=app، وهي الطريقة التي تضبطها معظم ملفات compose، إلى 18.6. فشلت العملية ثلاث مرات قبل أن تنجح، ولا علاقة لأي من الثلاث بإعداداتنا الخاصة.
الخطأ 1: data checksums
old cluster does not use data checksums but the new one does
Failure, exiting
تذكر ملاحظات إصدار PostgreSQL 18 هذا ضمن حالات عدم التوافق: صار initdb يفعّل data checksums افتراضيًا، و"يتطلب pg_upgrade تطابق إعداد checksum في العنقودين". العنقود الذي أنشأته صورة postgres:14 تكون فيه checksums معطلة ما لم تطلبها. الحل إنشاء العنقود الجديد بخيار --no-data-checksums. إن أردت checksums ففعّلها لاحقًا بأداة pg_checksums على العنقود المتوقف، وتحذّر وثائقها من أن ذلك في عنقود كبير "قد يستغرق وقتًا طويلًا"، ولا يجوز لأي برنامج آخر الكتابة في مجلد البيانات أثناء تشغيلها.
الخطأ 2: اسم المستخدم الخارق
FATAL: role "postgres" does not exist
could not connect to source postmaster started with the command: ...
تشغّل الصورة المساعدة initdb بالمستخدم الخارق الافتراضي postgres وتتصل بالعنقود القديم بالاسم نفسه. إن كان ملف compose يضبط POSTGRES_USER=app فلا يوجد في العنقود القديم دور اسمه postgres. مرّر الاسم الحقيقي إلى initdb وإلى pg_upgrade معًا. بعد الإصلاحين، شغّل وضع الفحص أولًا، فهو لا يغيّر أي بيانات:
# old cluster stopped, its files moved to /srv/pg/14/docker
docker run --rm \
--mount type=bind,src=/srv/pg,dst=/var/lib/postgresql \
-e PGDATAOLD=/var/lib/postgresql/14/docker \
-e PGDATANEW=/var/lib/postgresql/18/docker \
-e POSTGRES_INITDB_ARGS='--no-data-checksums --username=app' \
tianon/postgres-upgrade:14-to-18 --check --username=app
حين يطبع *Clusters are compatible*، شغّل الأمر نفسه مع --link --username=app بدل --check --username=app.
الخطأ 3: التطبيق لم يعد يتصل
انتهت الترقية وبدأ postgres:18 على البيانات الجديدة. ثم تلقى عميل في حاوية أخرى هذا:
FATAL: no pg_hba.conf entry for host "172.26.0.3", user "app", database "app", no encryption
تضيف الصورة الرسمية سطرًا إلى pg_hba.conf يسمح بتسجيل الدخول بكلمة مرور من مضيفين آخرين، لكن فقط عندما تهيئ مجلد بيانات فارغًا. هنا شُغّل initdb داخل الصورة المساعدة، فصار pg_hba.conf الجديد يثق بالاتصالات المحلية وحدها. تنبّه وثائق pg_upgrade إلى هذا في خطوة "Restore pg_hba.conf" وتضيف أن postgresql.conf وpostgresql.auto.conf قد يحتاجان المعاملة نفسها. انسخ ملفاتك القديمة إن كنت عدّلتها. وإن كانت لديك الإعدادات الافتراضية للصورة فقط، فأعد السطر:
docker exec pg18 sh -c 'echo "host all all all scram-sha-256" >> "$PGDATA/pg_hba.conf"'
docker exec pg18 psql -U app -c 'SELECT pg_reload_conf()'
مسار التخزين تغيّر في صورة 18
ابتداءً من 18، تحفظ الصورة الرسمية البيانات في مجلد خاص بالنسخة، /var/lib/postgresql/18/docker، وتعرّف مجلد التخزين على /var/lib/postgresql. تقول وثائق الصورة إن نقاط الربط يجب أن تستهدف الموقع الجديد، ويشرح طلب الدمج رقم 1259 السبب: مع نقطة ربط واحدة للنسختين يعمل pg_upgrade --link دون عبور حدود نظام الملفات. عدّل تعريف الخدمة وفقًا لذلك:
db:
image: postgres:18
volumes:
- /srv/pg:/var/lib/postgresql # not /var/lib/postgresql/data
إن غيّرت الوسم فقط وأبقيت نقطة الربط القديمة، يرفض سكربت entrypoint في نسخة 18 التشغيل ويطبع:
Error: in 18+, these Docker images are configured to store database data in a
format which is compatible with "pg_ctlcluster" ...
هذا فشل آمن، لكن الأفضل أن تراه في تشغيل تجريبي لا في الثانية فجرًا.
بعد الترقية
بحسب ملاحظات الإصدار، يحتفظ pg_upgrade في PostgreSQL 18 بإحصاءات المُحسِّن، لكن تشغيلنا انتهى مع ذلك بعبارة "Some statistics are not transferred by pg_upgrade" واقترح أمرين من vacuumdb. شغّلهما، ثم ابحث عن كلمات مرور مخزنة بـ MD5:
docker exec pg18 vacuumdb -U app --all --analyze-in-stages --missing-stats-only
docker exec pg18 vacuumdb -U app --all --analyze-only
docker exec pg18 psql -U app -Atc "SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%'"
غيّرت ملاحظات إصدار PostgreSQL 14 التجزئة الافتراضية لكلمات المرور إلى SCRAM-SHA-256، لكن الأدوار المنقولة من 13 أو أقدم قد تحمل تجزئات MD5. يعتبر PostgreSQL 18 مصادقة MD5 مهملة ويقول إن دعمها سيُزال في نسخة رئيسية قادمة، فغيّر تلك الكلمات ما دمت في نافذة صيانة أصلًا.
أمران آخران. في وضع link لا يعود تشغيل العنقود القديم آمنًا بعد أن يعمل الجديد، كما تحذّر وثائق pg_upgrade، فخطة التراجع هي النسخة الاحتياطية من الخطوة 3 وليس المجلد القديم. واحتفظ بذلك المجلد حتى يعمل التطبيق دورة عمل كاملة على 18، ثم احذفه بسكربت delete_old_cluster.sh الذي يتركه pg_upgrade.
العادة نفسها التي تبقي Postgres محدّثًا تنطبق على كل صورة أساسية تشغّلها. كتبنا عنها لـ PHP في PHP2Shell: رقّع PHP الذي تحت WordPress، وعن جانب التخطيط لتاريخ نهاية دعم محدد في خطة الخروج من Exchange 2016/2019. وإن كنت ترتّب نظام compose على أي حال، فإن إرسال سجلات الحاويات إلى stdout إصلاح صغير يستحق أن يتم في الجولة نفسها.
الأسئلة الشائعة
هل ستتوقف قاعدة بيانات PostgreSQL 14 عن العمل في 12 نوفمبر 2026؟
لا. ستستمر في العمل. انتهاء العمر يعني أن المشروع يتوقف عن إصدار الإصلاحات، فالثغرات الأمنية وأخطاء تلف البيانات المكتشفة بعد آخر إصدار من 14 لن تُرقَّع.
هل يمكنني الترقية من 14 إلى 18 مباشرة؟
نعم. يدعم pg_upgrade أي نسخة مصدر من 9.2 فما بعد، ويعمل dump/restore بين أي نسختين. اقرأ أولًا ملاحظات إصدار 15 و16 و17 و18 بحثًا عن حالات عدم التوافق.
هل أنتظر PostgreSQL 19؟
نحن لن ننتظر. موعد 19 هو 19 نوفمبر 2026، أي بعد انتهاء دعم 14. الترقية إلى 18 الآن ثم إلى 19 لاحقًا عملان مخططان بدل عمل واحد متعجل.
هل يكفي تغيير وسم الصورة من 14 إلى 18؟
لا. يجب ترقية مجلد البيانات بـ pg_upgrade أو dump/restore. ومع نقطة ربط بالطريقة القديمة ترفض صورة 18 التشغيل وتحيلك إلى pg_upgrade.
المصادر: سياسة إصدارات PostgreSQL، إعلان PostgreSQL 19 RC 1، ملاحظات إصدار PostgreSQL 18، ملاحظات إصدار PostgreSQL 14، وثائق pg_upgrade، تقويم إصدارات Amazon RDS for PostgreSQL، وثائق صورة postgres وtianon/docker-postgres-upgrade. جُرّبت الأوامر في 1 نوفمبر 2026 على Docker مع postgres:14 (14.24) وpostgres:18 (18.6).



