pfaffman
(Jay Pfaffman)
1
我有一个标准安装,它正尝试恢复数据库。迁移失败了。
ALTER TABLE
正在迁移数据库...
EXCEPTION: rake db:migrate
数据库迁移失败。
rake aborted!
StandardError: 发生了一个错误,此后所有迁移都已取消: (StandardError)
PG::DiskFull: ERROR: 无法写入文件 “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'
磁盘上有 90GB 的可用空间。在源磁盘上,postgres 目录只有 23GB。
为什么一个 23GB 的数据库在迁移过程中会因为磁盘空间不足而失败,而磁盘上还有 90GB 的空闲空间?
23G /var/discourse/shared/standalone/postgres_data/
pfaffman
(Jay Pfaffman)
2
-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/
pfaffman
(Jay Pfaffman)
3
数据库恢复后,postgres_data 为 24G。
迁移过程中,postgres_data 膨胀到 91G,导致磁盘填满,恢复失败。这发生在安装了上述 Discourse 版本的全新安装上。
这看起来一定是个错误,所以我正在重新分类。在尝试升级时我也遇到过这种情况。我曾以为升级的解决方案是迁移到新服务器,但现在看来那行不通。
我想接下来要做的是尝试找出是哪个查询或哪个表导致了这种情况。我不太确定该如何着手。
2 个赞
sam
(Sam Saffron)
4
我将此信息提交给支持部门,此消息直接来自文件系统,如果 PG 认为没有空间,那很可能是因为它没有为其分配足够的空间。
pfaffman
(Jay Pfaffman)
5
您对 24G 数据库在数据库迁移过程中如何扩展到 90G 有什么提示吗?
sam
(Sam Saffron)
6
不确定……我可能会运行 ncdu 或类似工具,并在情况发生时查看一下。
pfaffman
(Jay Pfaffman)
7
使用 du 和 df 我观察到 postgres_data 的大小从 25g 增长到 90g,磁盘空间几乎为零,然后才失败。
我想我需要在下次找到一种方法来跟踪哪个查询正在运行。
我至少在两个站点上都见过这种情况。一个是在升级时,另一个是在恢复时。两者开始时都有比数据库大小更多的可用空间。
Falco
(Falco)
8
一堆迁移会重写整个表,这可能会暂时使用更多空间,而且 PostgreSQL 不会积极地将空间返还给系统。
那个论坛启用了带嵌入(embeddings)的人工智能(AI)吗?
pfaffman
(Jay Pfaffman)
9
我当时就在想类似的事情……
这看起来像是一个可能的罪魁祸首…… 唉。没有。它甚至没有安装 AI 插件。
2 个赞
Falco
(Falco)
10
如果你想深究下去,你可以手动将其恢复到一个处于 2025 年 5 月提交状态的开发环境中,然后转到当前提交,逐个运行迁移,并打印出每次迁移前后的空格——当然是使用脚本
。
3 个赞
pfaffman
(Jay Pfaffman)
11
好的,我正在恢复一个生产站点。它正在迁移中。
这是已经运行了 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)
这来自这里:
这表明最新的迁移时间更晚,但我想那是因为该迁移来自刚刚添加的插件;。
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!?
但源表中的日历事件数量确实是那个数字. . . .
1 个赞