我定义了一个
LOG
表。
然后我创建了很多子表,每分钟一个,其形式为:
create LOG_20231209_1500 .. inherits LOG;
create LOG_20231209_1501 .. inherits LOG;
create LOG_20231209_1502 .. inherits LOG;
...
多年后,LOG 上的
count(*)
返回了数十亿美元。子表数量为:357299
但是现在是时候进行备份了,并且我希望将每个表备份到自己的文件中。
不幸的是,使用以下命令:
pg_dump logdb -t LOG_20231209_1501 > LOG_20231209_1501.sql
引发以下错误:
pg_dump: error: query failed: ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.
pg_dump: error: query was: LOCK TABLE public.LOG_20231209_1501 IN ACCESS SHARE MODE
即使是有 3000 条记录的小表。 请注意,直接
select * from LOG_20231209_1501
会立即产生结果。另请注意,我在 postgres.conf 中配置了 max_locks_per_transaction=1024
,但没有成功。
当我转储时没有人使用数据库:我可以让 pg_dump 避免锁定表并理所当然地不进行任何修改吗?
PostgreSQL 版本是:14.8
正如评论中所建议的,部分问题的答案是将
max_locks_per_transaction
增加到(至少)查询中涉及的对象数量。就我而言,由于父表有 359299 个子表,因此我必须设置 max_locks_per_transaction=360000
并且 pg_dump
有效。
这仍然是部分答案,因为
pg_dump
仍然尝试锁定所有表以转储单个表的结构或数据;因此,即使简单的 COPY tab INTO 'file' CSV
是立即执行,也需要长达 1 分钟的时间才能执行;这使得使用 pg_dump
转储所有表变得不切实际。
我仍然相信正确的方法 - 如果可行的话 - 是让
pg_dump
完全避免锁定。