فشل الاستعادة بسبب مساحة القرص أثناء الترحيل بسبب 70 مليون حدث تقويم

لدي تثبيت قياسي يحاول استعادة قاعدة بيانات. إنه يفشل في الترحيل.


ALTER TABLE
ترحيل قاعدة البيانات...
استثناء: rake db:migrate
فشل ترحيل قاعدة البيانات.
تم إيقاف rake!
StandardError: حدث خطأ، تم إلغاء هذا الترحيل وجميع الترحيلات اللاحقة: (StandardError)

PG::DiskFull: خطأ: لا يمكن الكتابة إلى الملف "base/pgsql_tmp/pgsql_tmp11009.51": لا يوجد مساحة متبقية على الجهاز
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in `exec'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb:109:in `async_exec'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.4/lib/active_record/connection_adapters/postgresql/database_state
ments.rb:167:in `perform_query'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.4/lib/active_record/connection_adapters/abstract/database_stateme
nts.rb:556:in `block (2 levels) in raw_execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-8.0.4/lib/active_record/connection_adapters/abstract_adapter.rb:1017:in `block in with_raw_connection'

يوجد 90 جيجابايت من البيانات الحرة على القرص. في قرص المصدر، يبلغ حجم دليل postgres حوالي 23 جيجابايت فقط.

كيف تفشل قاعدة بيانات بحجم 23 جيجابايت في الاستعادة أثناء ترحيل قاعدة البيانات مع وجود 90 جيجابايت حرة؟

المصدر – إصدار الخادم: 3.5.0.beta5-dev (التثبيت: b16fb6a60b3f1db475cbb91a51b7d4c734370083 — 7 مايو 2025)

إصدار الخادم الوجهة: 2026.2.0-latest (التثبيت: b39866eb8891648a54764755e2e36eb725bd6c73 — قبل 4 أيام)

23G     /var/discourse/shared/standalone/postgres_data/
-rw-r--r-- 1 discourse discourse  16G Feb 10 21:13 site-2026-02-10-174058-v20250507013646.sql
-rw-r--r-- 1 discourse discourse 2.9G Feb 10 21:11 site-2026-02-10-174058-v20250507013646.sql.gz
root@forum-data:/shared# # بعد الحذف
root@forum-data:/shared# du -hs postgres_data/; df -h .
24G     postgres_data/
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       154G   87G   68G  56% /shared
....
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       154G  154G  607M 100% /shared
overlay         154G  154G  607M 100% /
91G     postgres_data/
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       154G  154G   82M 100% /shared
overlay         154G  154G   82M 100% /
1.1G    postgres_data/
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       154G   65G   90G  42% /shared
overlay         154G   65G   90G  42% /
1.1G    postgres_data/
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       154G   65G   90G  42% /shared
overlay         154G   65G   90G  42% /
1.1G    postgres_data/
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       154G   65G   90G  42% /shared
overlay         154G   65G   90G  42% /
1.1G    postgres_data/
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1       154G   65G   90G  42% /shared
overlay         154G   65G   90G  42% /
1.1G    postgres_data/

بعد استعادة قاعدة البيانات، كان حجم postgres_data يبلغ 24 جيجابايت.

شيء ما في عملية الترحيل تسبب في تضخم postgres_data إلى 91 جيجابايت قبل أن تمتلئ القرص وتفشل عملية الاستعادة. هذا يحدث في تثبيت نظيف باستخدام إصدارات Discourse الموضحة أعلاه.

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

أعتقد أن الشيء التالي الذي يجب القيام به هو محاولة معرفة الاستعلام الذي يسبب هذا و/أو الجدول الذي يسببه. لست متأكدًا تمامًا من كيفية المتابعة في ذلك.

إعجابَين (2)

أنا أضع هذا في الدعم، هذه الرسالة تأتي مباشرة من نظام الملفات، إذا اعتقدت قاعدة البيانات (PG) أنه لا يوجد مساحة، فمن المحتمل أنه لا توجد مساحة لأنه لم يتم تخصيص مساحة كافية لها.

هل لديك أي تلميحات حول كيف يمكن لقاعدة بيانات بحجم 24 غيغابايت أن تتوسع إلى 90 غيغابايت أثناء ترحيل قاعدة البيانات؟

لست متأكدًا.. ربما أقوم بتشغيل ncdu أو شيء من هذا القبيل وألقي نظرة عندما تحدث المشكلة.

باستخدام du و df راقبت حجم postgres_data وهو ينمو من 25 جيجابايت إلى 90 جيجابايت والمساحة على القرص تذهب إلى الصفر (تقريباً) قبل أن يفشل.

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

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

مجموعة من عمليات الترحيل (migrations) تعيد كتابة الجداول بأكملها، مما قد يستهلك مساحة أكبر مؤقتًا، و PostgreSQL لا تعيد المساحة إلى النظام بشكل عدواني أيضًا.

هل هذا المنتدى مفعل به الذكاء الاصطناعي (AI) مع التضمينات (embeddings)؟

كنت أفكر في شيء من هذا القبيل. . .

يبدو هذا وكأنه سبب محتمل. . . . تنهيدة. لا. حتى أن المكون الإضافي للذكاء الاصطناعي غير مثبت.

إعجابَين (2)

إذا كنت ترغب في التعمق أكثر، يمكنك استعادته يدويًا إلى بيئة تطوير (dev environment) بتاريخ تثبيت مايو 2025، ثم الانتقال إلى التثبيت الحالي وتشغيل عمليات الترحيل (migrations) واحدة تلو الأخرى وطباعة المسافة قبل وبعد كل واحدة — بالطبع باستخدام برنامج نصي :stuck_out_tongue: .

3 إعجابات

حسنًا. أنا أقوم بالاستعادة على موقع إنتاج. إنه ينتقل.

إليك استعلام يعمل منذ 30 دقيقة:

discourse=# SELECT pid, usename, state, query, query_start
FROM pg_stat_activity
WHERE state = 'active';
 pid |  usename  | state  |                                                    query                                                     |          query_start
-----+-----------+--------+--------------------------------------------------------------------------------------------------------------+-------------------------------
 519 | postgres  | active | SELECT pid, usename, state, query, query_start                                                              +| 2026-02-14 17:58:35.473337+00
     |           |        | FROM pg_stat_activity                                                                                       +|
     |           |        | WHERE state = 'active';                                                                                      |
 308 | discourse | active | DELETE                                                                                                      +| 2026-02-14 17:26:08.12598+00
     |           |        |   FROM calendar_events ce                                                                                   +|
     |           |        | WHERE                                                                                                       +|
     |           |        |   ce.id IN (SELECT DISTINCT(ce3.id) FROM calendar_events ce2                                                +|
     |           |        |             LEFT JOIN calendar_events ce3 ON ce3.user_id = ce2.user_id AND ce3.description = ce2.description+|
     |           |        |             WHERE ce2.start_date >= (ce3.start_date - INTERVAL '1 days')                                    +|
     |           |        |               AND ce2.start_date <= (ce3.start_date + INTERVAL '1 days')                                    +|
     |           |        |               AND ce2.timezone IS NOT NULL                                                                  +|
     |           |        |               AND ce3.timezone IS NULL                                                                      +|
     |           |        |               AND ce3.id != ce2.id                                                                          +|
     |           |        |               AND ce2.post_id IS NULL                                                                       +|
     |           |        |               AND ce3.post_id IS NULL                                                                       +|
     |           |        |   )                                                                                                         +|
     |           |        |                                                                                                              |
(2 rows)

هذا من:

هذا يوضح أن أحدث ترحيل أحدث، ولكن أفترض أن ذلك لأن هذا الترحيل من إضافة (plugin) تمت إضافتها للتو؛.

discourse=# SELECT version FROM schema_migrations ORDER BY version DESC LIMIT 1;
    version
----------------
 20250507013646
(1 row)

هناك الكثير من أحداث التقويم!!! 69,724,384!

discourse=# select count(*) from calendar_events;
  count
----------
 69724384
(1 row)

لذا أفترض أن هذه هي المشكلة.

. . . ولكنهم لا يملكون حتى discourse_calendar مثبتًا على موقع المصدر!؟

ولكن لديهم هذا العدد من الأحداث في جدول calendar_events على جدول المصدر. . . .

إعجاب واحد (1)