Greenplum是基于Postgresql数据库的分布式数据库,而PG数据库在事务及多版本并发控制的实现方式上很特别,采用的是递增事务id的方法,事务id大的事务,认为比较新,反之事务id小,认为比较旧。
事务id的上限是21亿,正常使用时,事务id只增不减,到达一定程度时,就会触发数据库告警直至数据库只读,无法创建新事务
减少事务id的方法是执行提供的回收命令。
gp一共是21亿可以使用,使用超过5亿就告警,超过11亿就锁库
postgres=# show xid_warn_limit;
xid_warn_limit
----------------
500000000
(1 row)
postgres=# show xid_stop_limit;
xid_stop_limit
----------------
1000000000
(1 row)
这个两个参数是控制事务id剩余值多少时数据库会告警,或切换为只读的
注意:事务id的总值是21亿
xid_warn_limit 当距离stop的值不足5亿时,数据库会触发年龄告警
xid_stop_limit 当距离21亿总值的剩余值不足10亿时,数据库会切换为只读
简单来说,针对默认的设置:
年龄1-5亿:无年龄问题
年龄5-11亿:会触发年龄告警,但不影响数据库使用
年龄11-21亿:数据库为只读,不能创建新事务
查询表统计数据是出现异常提示:
WARNNING:database “XXX” must be vacuumed within 177009986 transactions
HINT: To avoid a database shutdown,execute a database-wide VACUUM in “XXX”
当数据库查询或者日志中出现上面告警时,说明需要对GP事务id进行清理
If these warnings are ignored, the system will shut down and refuse to start any new transactions ince there are fewer than 1 million transactions left until wraparound:
ERROR: database is not accepting commands to avoid wraparound data loss in database “XXXX”
当数据库查询或者日志中出现上面告警时,说明GP停止对外提供服务
SELECT gp_segment_id,datname, age(datfrozenxid) FROM gp_dist_random(‘pg_database’) ORDER BY 3 DESC;
例子:
比如这里查询当前年龄,最上面的值为2亿多,说明年龄在2亿左右
postgres=# SELECT gp_segment_id,datname, age(datfrozenxid) FROM gp_dist_random('pg_database') ORDER BY 3 DESC;
gp_segment_id | datname | age
---------------+--------------------------------------------+-----------
0 | test01 | 270797923
0 | test02 | 270797923
0 | test03 | 270797923
如果是11亿,告警锁库了
如果出现上面1 的告警,说明年龄已经到达警戒值,需要处理。
如果2 年龄超过5亿,说明即将告警,也需要处理
超过11亿,数据库就会锁库
在年龄到达告警值且未到锁库值的时候,此时数据库服务正常,就是命令会有warning输出
此时需要再master daedb用户下执行
nohup vacuumdb -F -a >/home/gpadmin/vacuumdb.log &
该命令执行时间可能很长,并且会消耗一定资源,如果过于影响客户使用,请选择执行时间,保证执行时间有5+ 小时
还有一种情况,就是数据库已经到达只读阈值, 数据库只读了,因为vacuumdb的命令也需要创建事务,所以直接运行命令会报错,无法进行回收
就需要先修改上面的参数阈值,使其能正常运行事务
gpstop -M fast -a
ps -ef|grep postgres 关闭确保进程都不在了,再继续
在master的daedb用户下执行:
gpstate -s|grep -E 'Address|Datadir'
该命令会将集群所有的数据目录及对应的主机名打印出来
另外有两台master,一般是在/gpmaster/gpseg-1 里,可以使用gpstate -f 查看
修改配置,找到所有节点的postgresql.conf,为其增加或修改参数
xid_stop_limit=800000000 #改为8亿,或者更小
全部修改完成之后,启动数据库:gpstart -a
启动完成以后,此时数据库就可以正常使用了
此时需要再master 数据库用户下执行
nohup vacuumdb -F -a >/home/gpadmin/vacuumdb.log &
改完还有个事,要将上面加的参数,全部注释掉 。有个简便方法,find 出来后替换
find /* -name 'postgresql.conf'|xargs sed -i 's/xid_stop_limit=500000000/#xid_stop_limit=500000000/g'
重启数据库生效:
gpstop -M fast -a
gpstart -a