晚上11点左右,朋友电话我,说他们公司pg有点问题,登录上去看了pg(9.2.4)日志报错如下(配置文件中有开autovacuum):
2016-08-05 23:47:32.839 cst,,,41181,,57a4b514.a0dd,2,,2016-08-05 23:47:32 cst,,0,warning,01000,"database with oid 16384 must be vacuumed within 999409 transactions",,"to avoid a database shutdown, execute a database-wide vacuum in that database.
you might also need to commit or roll back old prepared transactions.",,,,,,,""
如是进入到单用户执行如下操作:
pg_ctl -m f stop -d $pgdata
postgres --single lockdb -d $pgdata
backend> vacuum full;
操作到vacuum full报错如下:
warning: database "lockdb" must be vacuumed within 999238 transactions
hint: to avoid a database shutdown, execute a database-wide vacuum in that database.
you might also need to commit or roll back old prepared transactions.
error: row is too big: size 235728, maximum size 8160
statement: vacuum full;
改用vacuum freeze报错如下:
backend> vacuum freeze;
\error: failed to re-find parent key in index "user_checkin_user_id_idx" for deletion target page 902154
statement: vacuum freeze;
如是打算dump user_checkin表,后删除索引,报错如下:
pg_dump: dumping the contents of table "user_checkin" failed: pqgetresult() failed.
pg_dump: error message from server: error: invalid memory alloc request size 18446744073709551613
pg_dump: the command was: copy public.user_checkin (id, user_id, active_date, last_login_date, update_date, update_flag, product_code, kernel_code, product_ver, product_ver_num, opt_update_num) to stdout;
当时pg的数据库大概470g左右,其中索引user_checkin表索引就占了130g。如是和朋友商量后,删除索引和重建索引,时间太长,打算清空user_checkin表,清空user_checkin表后,pg数据大小100g左右,然后在执行上面的vacuum操作,pg数据大小为86g,重启pg后,一切正常。