KingbaseESV8R6垃圾回收受到参数old_snapshot_threshold的影响

垃圾回收影响因素

影响垃圾回收的因素有很多,垃圾回收不及时,最直接导致表膨胀,详情查看文档《KingbaseESV8R6 垃圾回收原理以及如何预防膨胀》。

vacuum回收垃圾的tuple时,判断哪些dead tuple可以被回收的规则是判断当前数据库中backend_xid和backend_xmin最小的值,凡是超过这个最小值的事务产生的垃圾都不能回收。所以在数据库中如果存在长时间不结束的事务是很危险的操作。

如果配置了old_snapshot_threshold.

则需要记录每分钟最大的backend_xid(没有则取最小未分配事务号) list(而非backend_xmin),vacuum时用于判断。

vacuum时,在1. old_snapshot_threshold最老的记录 与 2.当前系统最小的backend_xmin, backend_xid中取最大值,超过这个值的则垃圾不能回收。

使用old_snapshot_threshold可以避免长时间持有xmin的事务的sql导致其后产生的垃圾无法回收的问题。

测试

1.持有xid时,vacuum无法回收。

session a:
test=# begin;
BEGIN
test=# select txid_current();  -- 持有xid后的垃圾无法回收
 txid_current 
--------------
     115627
(1 row)


session b:
test=# delete from e1;
DELETE 10000
超过old_snapshot_threshold阈值后,仍然无法回收垃圾tuple
test=# vacuum verbose e1;
INFO:  vacuuming "public.e1"
INFO:  "e1": found 0 removable, 10000 nonremovable row versions in 45 out of 45 pages
DETAIL:  10000 dead row versions cannot be removed yet, oldest xmin: 115627
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
session a 提交后可回收。
  1. 长时间持有xmin,但是不持有xid时,可以回收其垃圾(必须配置 old_snapshot_threshold > 0)
session a:  
test=# select pg_sleep(1000);

session b:  
test=# insert into e1 values (1);
INSERT 0 1
test=# delete from e1;
DELETE 1
test=# insert into e1 values (1);
INSERT 0 1
test=# delete from e1;
DELETE 1
时间超过old_snapshot_threshold后,可以回收  
test=# vacuum verbose e1;
INFO:  vacuuming "public.e1"
INFO:  index "idx_e1" now contains 0 row versions in 30 pages
DETAIL:  0 index row versions were removed.
27 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  "e1": found 0 removable, 0 nonremovable row versions in 0 out of 45 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 115633
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 45 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM

总结

虽然设置参数old_snapshot_threshold可以解决垃圾无法回收问题,那只对于持有xmin的快照事务,而持有xid的事务这个参数是不生效的。

开启快照过旧,对性能有影响。

因为每次获取快照都要更新SNAPSHOT TOO OLD需要用到的数据结构列表。同时get buffer page时,每次都要判断,是否满足快照过旧。

posted @ 2022-08-13 09:54  KINGBASE研究院  阅读(92)  评论(0编辑  收藏  举报