Postgresql:数据库不接受命令以避免环绕数据丢失

xar*_*das 5 database postgresql rdbms vacuum

创建/删除/更新查询时出错:

错误:数据库不接受命令以避免数据库"mydb"中的环绕数据丢失提示:停止postmaster并使用独立后端来清空该数据库.您可能还需要提交或回滚旧准备的事务.

因此,数据库被阻止,只能执行SELECT查询.

数据库的大小为350 GB.1个表(my_table)有大约10亿行.

系统:"x86_64-unknown-linux-gnu上的PostgreSQL 9.3.4,由gcc(GCC)4.4.7 20120313(Red Hat 4.4.7-4)编译,64位"

postgresq.conf的一些设置:

effective_io_concurrency = 15           # 1-1000; 0 disables prefetching
autovacuum_vacuum_cost_delay = -1

#vacuum_cost_delay = 0                  # 0-100 milliseconds
#vacuum_cost_page_hit = 1               # 0-10000 credits
#vacuum_cost_page_miss = 10             # 0-10000 credits
#vacuum_cost_page_dirty = 20            # 0-10000 credits
#vacuum_cost_limit = 200 
Run Code Online (Sandbox Code Playgroud)

我不使用准备好的交易.但是使用基本的存储过程(这意味着,自动转换,对吧?)每天50mln次.

Сurrently"自动清理:真空分析公共.MY_TABLE(防止环绕)"被perforing,这是近12小时数查询活动.

据我所知,没有真空吸尘器的问题,对吗?

如何解决这个问题并在将来防止这种情况?请帮忙 :)

故事的结尾(约一个月后) 现在我的大表被数千个表分区.每个小桌子都抽真空得快得多.Autovacuum配置设置得更接近默认值.如果需要,我可以再次设置得更加激进,但到目前为止数十亿行的数据库工作得很好.

因此,该主题的问题不应再出现.

ps现在我正在将Postgres-XL视为数据可扩展性的下一步.

Dmi*_*tri 8

问题不在于死元组,它是控制行可见性的事务ID.每个事务都获得一个顺序XID,因为它们是32位整数,它们最终会回绕.

有关更多详细信息,请参见此处:http://www.postgresql.org/docs/9.3/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND,但简短版本是需要VACUUM编辑所有表格(手动或与autovacuum)至少每20亿交易.没有吸尘的时间越长,所需的时间就越长.

要解决当前的问题,你不需要做一个- VACUUM ANALYZE只是VACUUM- 我不确定它有多大的速度差异,但它应该更快.

这是什么类型的硬件,你的maintenance_work_mem设置是什么?您可能想要(可能是暂时的)提高它以更快地完成VACUUM.

在未来,您基本上只需要更多VACUUM:或者增加autovacuum频率(例如:参阅https://dba.stackexchange.com/questions/21068/aggressive-autovacuum-on-postgresql),或者甚至安排手动VACUUM与cron.另请查看vacuum_freeze_min_age相关设置.

它是什么类型的数据,以及您正在运行什么类型的交易?这是一个非常大的表,它可以被分区(例如,按日期)吗?

编辑

您可能还希望启用log_autovacuum_min_duration(将其设置为较小的值),以查看数据库处于活动状态时autovacuum实际执行的操作,以及是否存在阻止其运行的锁定问题.

回应评论

你不具备运行VACUUM独立的,你现在可以运行它,除非将过多干预与其他数据库.只需要以超级用户身份执行,因此系统表也会被清理.

进行转储/恢复似乎很激烈,我无法想象它会比完成VACUUM更快.

从存储过程切换远将不会帮助:修改数据的任何疑问将产生的XID,这并不重要,如果你使用的交易明确,他们还在交易.

你是在正确的方式 - 获得autovacuum以跟上你的插入/更新是最好的解决方案(记录它的活动应该有助于了解现在出了什么问题).

根据您的表结构来判断,这可能是表分区的经典案例(http://www.postgresql.org/docs/9.3/static/ddl-partitioning.html) - 我认为它是所有插入的,我是正确的更新/删除?如果您总是写入一个小分区,则可以更积极地对其进行真空吸尘(可以为每个表配置autovacuum),并使用VACUUM FREEZE其他分区.