PostgreSQL維護年齡的處理


1、錯誤信息

WARNING: database “postgres” must be vacuumed within 3330803 transactions

最常見的方法是通過此消息,警告您正在進行事務處理:

WARNING: database “postgres” must be vacuumed within XXX 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.

或者更糟糕的是,以下消息表明您已經完成了 transaction wraparound,並且PostgreSQL正在嘗試防止數據丟失:

ERROR: database is not accepting commands to avoid wraparound data loss in database “template0” HINT: Stop the postmaster and use a standalone backend to vacuum that database. You might also need to commit or roll back old prepared transactions.

2、處理方法:

在適當的數據庫上執行建議的VACUUM; 這里我們使用默認數據庫postgres,因此用適當的數據庫名稱替換該名稱。

vacuumdb postgres

如果您收到上面提到的錯誤,並且數據庫不再接受  命令
以下是在單用戶模式下運行真空的步驟; 請注意,--single必須是命令行上的第一個命令:

# su - postgres /usr/pgsql-11/bin/postgres --single -D /var/lib/pgsql/11/data/ postgres PostgreSQL stand-alone backend 11.3 backend> vacuum freeze; 

3、原理

PG的版本號是uint32的,是重復使用的,所以每隔大約20億個事務后,必須要凍結,否則記錄會變成未來的,對當前事務”不可見”。
同一個數據庫中,存在的最舊和最新兩個事務之間的年齡最多是2^31,即20億

當表的年齡大於autovacuum_freeze_max_age時(默認是2億),autovacuum進程會自動對表進行freeze。

–查詢庫xid

SELECT datname, age(datfrozenxid) FROM pg_database;

或者:select max(age(datfrozenxid)) from pg_database;

— 來查詢每個表的xid使用程度

SELECT c.oid::regclass as table_name, greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age FROM pg_class c LEFT JOIN pg_class t ON c.reltoastrelid = t.oid WHERE c.relkind IN (‘r’, ‘m’) order by age desc;

這查詢按照最老的XID排序,查看大於1G而且是排名前20的表。

SELECT relname, age(relfrozenxid) as xid_age, pg_size_pretty(pg_table_size(oid)) as table_size FROM pg_class WHERE relkind = 'r' and pg_table_size(oid) > 1073741824 ORDER BY age(relfrozenxid) DESC LIMIT 20;

建議使用vacuum freeze [ table_name ] 來對指定的表進行xid 凍結清理。

執行vacuum freeze pg_database 。其他table 根據需要freeze

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM