تحديث PostgreSQL 13

:warning: تحذير! إذا كانت قاعدة بياناتك ضخمة جدًا، فستحتاج إلى مساحة تخزين إضافية كبيرة (ضعف حجم قاعدة البيانات) ويجب أن تكون حذرًا للغاية عند إجراء هذا الترقية!

لقد قمنا مؤخرًا بإدخال تغييرات لترقية صورة Docker الخاصة بنا إلى PostgreSQL 13. سيتم ترقية أي مسؤول موقع يعيد بناء Discourse من سطر الأوامر إلى PostgreSQL 13 من الإصدار السابق PostgreSQL 12. لاحظ أنه إذا كنت قد امتنعت عن الترقية عندما حدث تحديث PostgreSQL 12 في مايو الماضي، فيمكنك تخطي ذلك التحديث والانتقال مباشرة إلى PostgreSQL 13.

إذا كنت قد امتنعت عن الترقية سابقًا، فقم بتغيير قالب PostgreSQL في ملف app.yml من templates/postgres.10.template.yml إلى templates/postgres.template.yml.

كما هو الحال مع أي ترقية، يُنصح بشدة بأخذ نسخة احتياطية قبل القيام بأي شيء.

التحديث

دليل التثبيت الرسمي (حاوية واحدة)

في إعادة البناء التالية، ستظهر هذه الرسالة في النهاية:

-------------------------------------------------------------------------------------
تمت ترقية POSTGRES بنجاح

يتم تخزين قاعدة البيانات القديمة 12 في /shared/postgres_data_old

لإكمال الترقية، أعد البناء مرة أخرى باستخدام الأمر:

./launcher rebuild app
-------------------------------------------------------------------------------------

هذا يعني أن كل شيء سار على ما يرام أثناء الترقية! كل ما عليك فعله هو إصدار أمر إعادة بناء جديد لاستعادة موقعك وجعله يعمل مرة أخرى.

تثبيت حاوية البيانات

إذا كنت تشغل إعدادًا يحتوي على حاوية بيانات مخصصة بناءً على العينة المقدمة في مستودع discourse_docker الخاص بنا، فيجب عليك التأكد من إيقاف تشغيل PostgreSQL بطريقة آمنة ونظيفة.

في الوقت الحالي، لدينا عمليات خلفية تقوم بتشغيل استعلامات تمتد لعدة دقائق، لذا فإن إيقاف تشغيل حاوية الويب سيساعد في إيقاف تشغيل حاوية البيانات بشكل آمن.

./launcher stop web_only
./launcher stop data
./launcher rebuild data
./launcher rebuild data
./launcher rebuild web_only

قبل إصدار أمر إعادة البناء الأول لحاوية البيانات، يمكنك تتبع سجل PostgreSQL لمعرفة ما إذا تم إيقاف تشغيله بشكل صحيح.

يجب أن يعطي تشغيل الأمر tail -f shared/data/log/var-log/postgres/current السجل التالي إذا كان الإيقاف نظيفًا:

2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

إجراء تحديث يدوي / بيئات مقيدة المساحة

:warning::warning::warning:
يجب عليك أخذ نسخة احتياطية من POSTGRES_DATA قبل محاولة هذا
:warning::warning::warning:

إذا كنت في بيئة مقيدة المساحة دون أي طريقة للحصول على مساحة إضافية، فيمكنك تجربة ما يلي:

./launcher stop app #(أو كلاهما web_only و data إذا كان هذا هو حالتك)
mkdir -p /var/discourse/shared/standalone/postgres_data_new
docker run --rm \
	-v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/12/data \
	-v /var/discourse/shared/standalone/postgres_data_new:/var/lib/postgresql/13/data \
	tianon/postgres-upgrade:12-to-13
mv /var/discourse/shared/standalone/postgres_data /var/discourse/shared/standalone/postgres_data_old
mv /var/discourse/shared/standalone/postgres_data_new /var/discourse/shared/standalone/postgres_data
./launcher rebuild app #(أو أولاً data ثم web_only إذا كان هذا هو حالتك)

في اختباراتي، تتطلب هذه العملية أقل من 1x حجم قاعدة بياناتك الحالي من المساحة الحرة.

تأجيل التحديث

إذا كنت بحاجة إلى تأجيل التحديث أثناء إعادة البناء التالية، فيمكنك تبديل قالب PostgreSQL في ملف app.yml الخاص بك عن طريق تغيير \"templates/postgres.template.yml\" إلى \"templates/postgres.12.template.yml\".

لا يُنصح بذلك، حيث قد ينسى بعض مسؤولي المواقع عكس التغيير لاحقًا.

مهام اختيارية بعد التحديث

تحسين إحصائيات PostgreSQL

بعد التحديث، لن يكون لدى PostgreSQL الجديد إحصائيات الجداول جاهزة. يمكنك إنشاء هذه الإحصائيات باستخدام:

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
VACUUM VERBOSE ANALYZE;
\q
exit
exit

أو هذا الإصدار المكون من سطر واحد من الأمر أعلاه:

/var/discourse/launcher run app "echo 'vacuum verbose analyze;' | su postgres -c 'psql discourse'"

إعادة إنشاء الفهارس

الميزة الرئيسية لهذه الترقية هي توفير كبير في الملفات في أكبر جدول لدينا في كل مثيل، وهو جدول post_timings وفهارسه. بعد إجراء تحديث ناجح، ستحتاج إلى تشغيل أمر لإعادة بناء الفهارس والحصول على الفوائد.

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
REINDEX SCHEMA CONCURRENTLY public;
\q
exit
exit

إذا كان بإمكانك التحقق من حجم post_timings قبل وبعد REINDEX، فسيكون ذلك إحصائية رائعة لمشاركتها هنا!

يمكنك استخدام الاستعلام أدناه للتحقق من أكبر 20 كائن بيانات، وقم بتشغيله قبل إعادة الفهرسة وبعدها:

WITH RECURSIVE pg_inherit(inhrelid, inhparent) AS
    (select inhrelid, inhparent
    FROM pg_inherits
    UNION
    SELECT child.inhrelid, parent.inhparent
    FROM pg_inherit child, pg_inherits parent
    WHERE child.inhparent = parent.inhrelid),
pg_inherit_short AS (SELECT * FROM pg_inherit WHERE inhparent NOT IN (SELECT inhrelid FROM pg_inherit))
SELECT table_schema
    , TABLE_NAME
    , row_estimate
    , pg_size_pretty(total_bytes) AS total
    , pg_size_pretty(index_bytes) AS INDEX
    , pg_size_pretty(toast_bytes) AS toast
    , pg_size_pretty(table_bytes) AS TABLE
  FROM (
    SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes
    FROM (
         SELECT c.oid
              , nspname AS table_schema
              , relname AS TABLE_NAME
              , SUM(c.reltuples) OVER (partition BY parent) AS row_estimate
              , SUM(pg_total_relation_size(c.oid)) OVER (partition BY parent) AS total_bytes
              , SUM(pg_indexes_size(c.oid)) OVER (partition BY parent) AS index_bytes
              , SUM(pg_total_relation_size(reltoastrelid)) OVER (partition BY parent) AS toast_bytes
              , parent
          FROM (
                SELECT pg_class.oid
                    , reltuples
                    , relname
                    , relnamespace
                    , pg_class.reltoastrelid
                    , COALESCE(inhparent, pg_class.oid) parent
                FROM pg_class
                    LEFT JOIN pg_inherit_short ON inhrelid = oid
                WHERE relkind IN ('r', 'p')
             ) c
             LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
  ) a
  WHERE oid = parent
) a
ORDER BY total_bytes DESC LIMIT 20;

تنظيف البيانات القديمة

للتثبيت القياسي، يمكنك حذف البيانات القديمة بتنسيق PG12 باستخدام الأمر التالي:

cd /var/discourse
./launcher cleanup

إذا كانت لديك حاوية بيانات منفصلة، فستحتاج إلى إزالة نسخة النسخ الاحتياطي على النحو التالي:

rm -fr /var/discourse/shared/data/postgres_data_old/

الأسئلة الشائعة

لم يتم إيقاف تشغيل مجموعة المصدر بشكل نظيف

إذا حصلت على فشل في الترقية مع الرسالة أعلاه، فيمكنك تجربة نهج أبسط لإعادتها إلى حالة أفضل.

أعد تشغيل الحاوية القديمة باستخدام ./launcher start app. انتظر بضع دقائق حتى تعود للعمل.

الآن أوقف تشغيلها مرة أخرى باستخدام ./launcher stop app. بعد ذلك، تابع السجلات لمعرفة ما إذا كان الإيقاف نظيفًا:

tail -f shared/data/log/var-log/postgres/current
2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

إذا بدت السجلات مثل ما هو أعلاه، فيمكنك الآن محاولة الترقية مرة أخرى باستخدام ./launcher rebuild app.

قيم lc_collate لقاعدة بيانات “postgres” لا تتطابق

يحدث هذا الخطأ إذا كنت تستخدم مناطق غير افتراضية لقاعدة بياناتك. تم الإبلاغ عن أنك تحتاج إلى 3 متغيرات لكي ينجح الأمر. تأكد من أن قسم env: في ملف app.yml الخاص بك يحتوي على الأسطر الثلاثة:

  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

تغيير en_US.UTF-8 إلى منطقتك المحلية.

كل إعادة بناء تقوم بالترقية مرة أخرى أي حلقة ترقية

عندما يحدث هذا، ستحتوي سجلات الترقية على

mv: cannot move '/shared/postgres_data' to '/shared/postgres_data_old/postgres_data': Directory not empty
mv: cannot move '/shared/postgres_data_new' to '/shared/postgres_data/postgres_data_new': Directory not empty

هذا يعني أن هناك ملفات لا تزال موجودة من الترقية الأخيرة. انقلها إلى مكان آخر قبل المتابعة.

اقتراحات سكريبتات اكتمال الترقية - هل أحتاج إلى فعل أي شيء؟

بمجرد اكتمال الترقية، سترى مخرجات من رسالة pg_upgrade تقول:

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster's data files:
    ./delete_old_cluster.sh

يمكنك تجاهل هذه الرسالة بأمان.

لقد قمت بتخطي تحديث PostgreSQL 12، فماذا أفعل الآن؟

يمكنك اتباع التعليمات القياسية في أعلى هذا الدليل وستقوم بالترقية من نسختك إلى 13 دون مشاكل.

إذا كنت تتبع تعليمات البيئة المقيدة للمساحة، فقم بتعديل أرقام الإصدار وفقًا لذلك.

38 إعجابًا
PostgreSQL Details
Discourse 2.7.0.beta2 Release Notes
Forum offline due to failed rebuilds on Tests-Pass
Nginx upstream timed out (110: Connection timed out)
Firewall issue with running multiple containers after upgrade
Help! Problem with firewall/permissions and postgre?
PostgreSQL 13 update from PostgreSQL 10 fails
PostgreSQL 13 update from PostgreSQL 10 fails
Unrecognized error type (ActiveRecord::StatementInvalid: PG::ProgramLimitExceeded
Recover from filesystem backup: can't rebuild nor start
Rebuild error: Errno::ENOENT: No such file or directory @ rb_sysopen - /e tc/postgresql/13/main/pg_hba.conf
Discourse broken after upgrade
Upgrade Failed from 2.7.0.beta1 to 2.7.0.beta3
Invalid location error after update
Upgrade failed!
Upgrade failed: PostgreSQL version 13 ... not compatible with ... version 10.12
Improved Bookmarks with Reminders
Importing old database to latest version
Errors encountered when uploading images
What else do I need to take care of when self hosting?
Rebuild freezing when attempting to stop container
Backup failed due to PG/SQL errors
Restore Failing - Check Free Disk Space
Supported postgresql versions
Wrong Error Message for too short replies for Reply-by-Email
Upgrade Postgres with REALLY limited space
Upgrade Postgres with REALLY limited space
Postgres has 100% CPU for large databases, Discourse 2.7.7
Upgrade failing with FAILED TO BOOTSTRAP
Stuck in an update loop after PostgreSQL 13 update
Problem with rebuild Discourse at Docker
After Rebuild got error: postgres:10/main, Causes CPU to go high
Call AdminDashboardGeneralData.refresh_stats at boot?
ERROR: You are running an old version of the Discourse image
Failed to upgrade to v2.9.0beta3
Failed to upgrade to v2.9.0beta3
SMTP Settings in app.yml reset?
Upgrade container - keeping config and data
Site down after failed update: permission denied to create extension "unaccent"
Rebuild fails on db:migrate w/PG12
Update from 2.9.0 beta2 to beta4 failed (my site is down)
Performance optimisation tips
Upgrading from 2.4 to 2.9. Need slight assistance on what order to run the final commands & reboot in
Problem when updating Discourse Forum
Troubleshooting severe performance issues with latest Discourse?
Slow Profile Loads with 100GB+ database
Use Nginx Proxy Manager to manage multiple sites with Discourse
Horizontal loading slider
Upgrading Discourse from 2.6.0.beta2
PostgreSQL 15 update
Got a lot of "Failed to backfill 'Reader' badge" errors
Trouble updating discourse after some time - UPGRADE OF POSTGRES FAILED
Database size/maintenance
Upgrade gone sideways [deprecated Guest Gate plugin]
Upgrade Issues: Failed Upgrade due to Duplicate Key, Failed Snapshot Restore
2.7.0.beta2 upgrade failed with ERROR: duplicate key
Problem, rebuild to latest version
Urgent, upgraded build failed UniqueViolation