1.问题
Greenplum集群segment后台日志报错
2.回收库龄
master上执行
vacuumdb -F -d cxy
vacuumdb -F -d template1
vacuumdb -F -d rptdb
3.回收完成后检查
仍然发现segment还是有库龄报警警告信息发出
4.检查
4.1 在master上检查库年龄
SELECT datname, datfrozenxid ,age(datfrozenxid) FROM pg_database ORDER BY 3 DESC ;
4.2 在master上查看主要库的表龄
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;
发现没有年龄15亿左右的表,就很奇怪,但是很多temp表存在,年龄2千万左右在,暂时不管。
查看各segment库龄:
SELECT gp_segment_id,datname, age(datfrozenxid) FROM gp_dist_random('pg_database') ORDER BY 3 DESC;
先去segment端查看具体情况。
5.在segment上检查
本地GP集群下有32个segment,连接单一segment方式
PGOPTIONS="-c gp_session_role=utility" psql -h gz2rptdbs06 -p 6003 -U gpadmin -d gprptdb;
查看库下的表龄排序:
发现segment库龄主要由最上面这个temp表导致。
查询相关资料:
postgresql中在使用临时表时,如果数据库发生crash,临时表不会被自动清除,而临时表在的XID不能回收循环,vacuum freeze无法在临时表上执行。而在GP这种分布式数据库中,会出现更复杂情况,比如某些段清理了,某些段没有清理临时表。
本数据库确实发生过crash,而且临时表在部分应用中一直使用。正常临时表在会话结束后会自动释放,不会出现这么高的age。所以判断段中出现的高age临时表为非正常使用临时表,需进行drop处理。
6.在master上查看存在哪些临时表
select b.nspname,a.relname from pg_class a ,pg_namespace b
where a.relnamespace=b.oid
and b.nspname ~ 'pg_temp'
and a.relkind='r' order by age(a.relfrozenxid) desc;
如果不处理的话,久而久之,库龄会达到最大年龄,数据库就不能正常连接使用了。
在部分segment中,发现template1中也存在高age临时表,如下图:
查询资料该表为gp在recover产生的临时表,目前数据库正常无revocer进程,可以删除。
7.结果
部分segment下删除最大age临时表前后对比
后续会逐步清理其他高age临时表。降低库龄。
参考文章:
PostgreSQL: Temporary tables prevent autovacuum, leading to XID wraparound
Thread: Temporary tables prevent autovacuum, leading to XID wraparound : Postgres Professional
Vacuuming old tables in a database to reduce its age
https://developer.aliyun.com/article/8922