前言

最近生产环境发生几次由于长事务导致表、库年龄没法回收的情况。我们要规避这种情况的发生,不要等发生了再去强制中断会话连接。当数据库中存在最老事务版本xmin,那么早于他的快照可以被标记为frozen,如果在最老事务之后产生的快照版本,不被标记为frozen。如果数据库中有活动的长事务,长事务不结束,其后产生的版本都不能被vacuum。那么如果这段时间数据库产生大量事务,就会消耗表,库的age。age达到21亿就会强行进入单用户模式vacuum freeze整个数据库才能保证数据库正常运行。最老事务不仅阻止age的frozen,还阻止表的死亡行回收,所以尽量要避免数据库中产生长事务。

查看长事务的sql:

1、select * from sys_stat_activity where state<>'idle' and pg_backend_pid() != pid and (backend_xid is not null or backend_xmin is not null ) and extract(epoch from (now() - xact_start)) > 3; <时间阈值,单位秒> ;

或 select datname,usename,query,xact_start,now()-xact_start xact_duration,query_start,now()-query_start query_duration,state from sys_stat_activity where state<>$$idle$$ and (backend_xid is not null or backend_xmin is not null) and now()-xact_start > interval $$30 min$$ order by xact_start;

2、select * from sys_prepared_statements where now()-prepare_time > interval $$30 min$$ order by prepare_time;

测试

1、需要准备一个产生事务的压测脚本
vi test.sql
select txid_current();
2、新建一个事务,不结束事务 test=# create table t1(id int);
CREATE TABLE
test=# begin;
BEGIN
test=# insert into t1 values (1);
INSERT 0 1
test=# select txid_current();
txid_current
--------------
1668525
(1 row) 3、新开个会话,新建t2表,写入一条记录,注意这条记录的版本是在最老事务之后产生的。 test=# create table t2 (id int);
CREATE TABLE
test=# insert into t2 values (100);
INSERT 0 1 4、执行压测脚本,目的是消耗大量事务号 kbbench -U SYSTEM -d test -M prepared -n -r -P 1 -f ./test.sql -c 16 -j 16 -T 10 5、然后,再新建另一个事务,不结束事务 test=# begin;
BEGIN
test=# insert into t1 values (2);
INSERT 0 1
test=# select txid_current();
txid_current
--------------
1788896
(1 row) 6、下面继续消耗大量事务 kbbench -U SYSTEM -d test -M prepared -n -r -P 1 -f ./test.sql -c 16 -j 16 -T 10 7、freeze t2这个表,我们看到年龄始终降不下来。因为前面说过:表的tuple如果是在最老事务之前产生的,它可以被标记为frozen,而在最老事务之后产生的tuple,必须保留版本,不能被标记为frozen。 test=# vacuum (freeze,verbose) t2;
INFO: aggressively vacuuming "public.t2"
INFO: "t2": found 0 removable, 1 nonremovable row versions in 1 out of 1 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 1668525
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 查看表年龄没有下降
test=# select age(relfrozenxid),relname,pg_size_pretty(pg_total_relation_size(oid)) from sys_class where relname='t2';
age | relname | pg_size_pretty
----------+---------+----------------
244389 | t2 | 40 kB
(1 row) 8、释放第一个事务,再次freeze t2。注意这个时候最老的事务是在t2的所有记录版本之后产生的。所以理论上执行vacuum freeze后,这个表的年龄应该可以降到0. test=# vacuum (freeze,verbose) t2;
INFO: aggressively vacuuming "public.t2"
INFO: "t2": found 0 removable, 1 nonremovable row versions in 1 out of 1 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 1788896
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
表年龄有下降
test=# select age(relfrozenxid),relname,pg_size_pretty(pg_total_relation_size(oid)) from sys_class where relname='t2';
age | relname | pg_size_pretty
---------+---------+----------------
124048 | t2 | 40 kB
(1 row) 但是,我们发现年龄没有降到0,但是第二次vacuum t2,oldest xmin: 1788896,因为第一个事务版本1668525被释放了。 释放第二个事务,再次freeze t2,这时候查看t2年龄已经降到0 TEST=# select age(relfrozenxid),relname,pg_size_pretty(pg_total_relation_size(oid)) from sys_class where relname='t2';
age | relname | pg_size_pretty
-----+---------+----------------
0 | t2 | 40 kB
(1 row)

总结

在实际生产环境中,无论主库备库,尽量避免长事务,作为DBA我们要充分和客户沟通,长事务可能对数据库系统带来的隐藏隐患。

而且在结束第一个事务后,t2表事务之后产生的是t1表的事务,也就是说t1表的事务存在也会阻止t2表的vacuum freeze进行。

KingbaseES 最老事务阻止vacuum freeze的更多相关文章

  1. Postgresql vacuum freeze相关参数

    先看3个参数:autovacuum_freeze_max_age           | 500000vacuum_freeze_min_age               | 10vacuum_fr ...

  2. KingbaseES XA 分布式事务

    在分布式系统中,各个节点(或者事务参与方)之间在物理上相互独立,各节点之间无法确切地知道其它节点中的事务执行情况,所以多节点之间很难保证ACID,尤其是原子性.如果是单节点的事务,由于存在事务机制,可 ...

  3. KingbaseES应对表年龄增长过快导致事务回卷

    背景 前几天碰到这样一个场景,在KingbaseES数据库当作数据同步节点.其特点是接收过来的数据量巨大,其更新超级频繁,最大的数据库达到6TB.这还不是主要的,主要导致问题发生原因是同步数据库有很多 ...

  4. PostgreSQL Autovacuum和vacuum

    1 基础知识 重点: 如果您的数据库运行了很久,并且从来没有打开过autovacuum,那么请在打开autovacuum之前全库手动运行vacuum analyze(可能要非常久的时间)完全禁用aut ...

  5. 新特性:postgresql的vacuum漫谈

    文章出处:来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31556440/viewspace-2375109/ 前言 即便是从数据库特性,SQL功能性等方面,Pos ...

  6. KingbaseESV8R6如何针对表单独设置vacuum策略

    背景 书接上文 KingbaseES应对表年龄增长过快导致事务回卷 ,有些特殊业务场景不能靠全局的autovacuum方法,例如大型数据库系统,频繁做update的系统,还有上文提到的做实时数据同步的 ...

  7. PostgreSQL处理膨胀与事务回卷

    一.表膨胀查询与处理 1.创建扩展 create extension pgstattuple; 2.表膨胀查询 pgstattuple提供了pgstatetuple()和pgstatindex()两个 ...

  8. SQL Server中的事务日志管理(7/9):处理日志过度增长

    当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...

  9. GaussDB(DWS)磁盘维护:vacuum full执行慢怎么办?

    摘要:在数据库中用于维护数据库磁盘空间的工具是VACUUM,其重要的作用是删除那些已经标示为删除的数据并释放空间. vacuum的功能 回收空间 数据库总是不断地在执行删除,更新等操作.良好的空间管理 ...

  10. MySQL · 引擎特性 · InnoDB 事务子系统介绍

    http://mysql.taobao.org/monthly/2015/12/01/ 前言 在前面几期关于 InnoDB Redo 和 Undo 实现的铺垫后,本节我们从上层的角度来阐述 InnoD ...

随机推荐

  1. Swoole从入门到入土(3)——TCP服务器[基本配置项]

    在这一节的开篇,让我们先解决上一节的"配置"话题.对于server对象,有很多配置项决定了服务端的行为,可以用set的函数进行配置的设置. 1.函数set:用于设置运行时的各项参数 ...

  2. Java设计模式-组合模式Composite

    介绍 组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示"整体-部分"的层次关系. 组合模式依据树形结构来组合对 ...

  3. Vue+SpringBoot+ElementUI实战学生管理系统-8.班级管理模块

    1.章节介绍 前一篇介绍了专业管理模块,这一篇编写班级管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.实现效果 班级列表 修改班级 4.模块 ...

  4. 将字符串"a,b,c"以逗号分隔转换为数组并打印

    主要利用了String的split方法. package com.dylan.test; /** * @author xusucheng * @create 2017-12-22 **/ public ...

  5. Java 中拼接 String 的 N 种方式

    文章持续更新,可以关注公众号程序猿阿朗或访问未读代码博客. 本文 Github.com/niumoo/JavaNotes 已经收录,欢迎Star. 1. 前言 Java 提供了拼接 String 字符 ...

  6. 【Azure 应用服务】收集App Service 关于Availability Zone, Health check 以及 Traffic Manager的文档,并了解高可用(HA)和灾备(DR)

    问题描述 收集App Service 关于Availability Zone, Health check 以及 Traffic Manager的文档,并了解高可用(HA)和灾备(DR)的具体办法 问题 ...

  7. spring 注入参数时为list map写法用例

    导包基础:这了让服务器支持json 需要导入下面包 <dependency> <groupId>com.alibaba</groupId> <artifact ...

  8. EL1008E: Property or field 'timestamp' cannot be found on object of type 'java.util.HashMap' - maybe not public-请求springboot-后台报错

    一.问题由来 自己在使用node.js写的前端项目访问springBoot访问的后端项目的时候,springboot项目中报这个错,抛出这个异常. 详细的错误信息如下: Servlet.service ...

  9. [VueJsDev] 基础知识 - 常见编码集

    [VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html 常用编码集 ::: details 目录 目录 常用编码集 ...

  10. linux 环境 打包 失败,一次解决过程

    发现打包失败 测试发现 npm run build 打包失败 发现问题1 node_modules 库 没装 rm -rf node_modules 进行 npm install 安装失败 发现lin ...