今天有个日志库遭遇 ERROR: database is not accepting commands to avoid wraparound data loss in database
,HINT: Stop the postmaster and use a standalone backend to VACUUM in "mydb".
,根据提示,数据库已经不接受事务,需要关闭后以单用户模式 vacuum full。 真是杯具啊,生产库遭受这样的错误,无疑是致命的打击,日志库有几百G数据,所有库 vacuum full
至少需要好几小时,显然这无法接受的,迅速将故障报给德哥,还好德哥反应快,很快搭建了套只有表结构的日志库,让业务继续跑起来,这样可以有充足的时间维护这个故障库,下面是处理过程。
日志分析
2011-09-28号时的日志 ( WARNING )
1 |
WARNING: database "mydb" must be vacuumed within 177009986 transactions |
备注: 这是故障的初级阶段,如果在这时发现问题,可以手工修复而不需要停库维护了;这时只需要在提示的库上用超级用户登陆进行全库 Vacuum 就可以了。
2011-09-29 号的日志 ( ERROR )
1 |
2011-09-29 09:42:33.273 CST,,,30165,,4e83cd09.75d5,1,,2011-09-29 09:42:33 CST,138/13556266,0,ERROR,54000,"database is not accepting commands to avoid wraparound data loss in database ""mydb""",,"Stop the postmaster and use a standalone backend to vacuum that database. |
备注:到了这个程度,根据提示,数据库需要停库以单用户模式进行 vacuum , 下面是单用户模式对数据库进行维护的例子。
关闭数据库
1 |
[postgres@pgb ~]$ pg_ctl stop -m fast -D $PGDATA |
单用户模式维护
单用户模式维护数据库 mydb
1 |
[postgres@pgb ~]$ postgres --single -D /database/pgdata1923_9.1/pg_root mydb |
备注:后来在这个日志库上对所有日志库进行以上操作,重启后数据库不再报以上ERROR,恢复正常。
原因分析
PostgreSQL 使用的是 MVCC 机制, 可以分配 2^32 ( 40 亿) 次方事务, 当事务号分配完后,将归0,PG是这样处理的: 在达到 20 亿事务后需要对整个数据库进行 vacuum。 这个操作一般 autovacuum 可以完成,不需要手工干预,当 autovacuum 由于某种原因不能对数据库表进行 vacuum时,会出现开头 “WARNING” 的提示信息,如果再不继续处理,接着会出现“ERROR” 信息,这时唯一处理的方法是:先停库 ,再以单用户模式 VACUUM FULL
。今天的故障原因猜测是有长时间未提交事务导致 autovacuum 表失败;
后期计划
后期计划将长时间事务进行监控;
参考资料
- http://www.postgresql.org/docs/9.0/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND
- http://blog.163.com/digoal@126/blog/static/163877040201041111516154/
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/database/236433.html