天天看點

postgresql vacuum row is too big

晚上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後,一切正常。