背景

前几天碰到这样一个场景,在KingbaseES数据库当作数据同步节点。其特点是接收过来的数据量巨大,其更新超级频繁,最大的数据库达到6TB。这还不是主要的,主要导致问题发生原因是同步数据库有很多重复数据,为了保证准确性,现在做法的每条数据独立一个事务去完成,这就导致保证同步速度的情况事务age被大量并快速消耗。至于为什么会freeze age,这个就不在这里解释了。大家可以自行百度。

报错信息:

ERROR:  database is not accepting commands to avoid wraparound data loss in database "xxxx"
HINT: Stop the kingbase and vacuum that database in single-user mode.
You might also need to commit or roll back old prepared transactions.

数据库年龄:

SELECT datname, age(datfrozenxid) FROM pg_database order by age(datfrozenxid) desc;

表年龄:

SELECT n.nspname as "Schema", c.relname as "Name", c.relfrozenxid

FROM pg_catalog.pg_class c

LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace

WHERE c.relkind IN ('r','')

AND n.nspname <> 'information_schema' AND n.nspname !~ '^pg_toast'

AND pg_catalog.pg_table_is_visible(c.oid)

ORDER BY c.relfrozenxid::text::bigint DESC;

当时查看两个数据库年龄10几亿,其中最大的一张表年龄23亿。难怪数据库告警,事务使用已经超过20亿,没有及时freeze操作。

解决方法

解决此问题的方法是:

​ 按照年龄从大到小排序,vacuum 该数据库下每张表。

​ 每张表的年龄都降下来后,再vacuum该数据库,把数据库年龄也降下来。需要说明的是为了保证解决问题效率,把最大的表vacuum freeze 年龄降下来后就可以登录数据库了,这时候可以在数据库里进行freeze 其他表和数据库的操作。

但是我们知道freeze 是极其消耗IO的动作,对于最大的那张表2965GB的feeze操作至少跑了一晚上,具体花费多旧难以估计。因为第二天来到现场已经跑完了。

之后再vacuum其他表和最终vacuum数据库花了大半天时间,至此问题解决。

最后我们要分析问题产生的原因,和怎么规避此次问题。

参数解答

首先了解一个概念很重要:在自动触发(由于表的年龄大于autovacuum_freeze_max_age) 或 手动执行vacuum freeze,或autovacuum触发、手工执行VACUUM时表的年龄大于等于vacuum_freeze_table_age时。以上几种情况的vacuum都将会进入FREEZE模式(扫描全表,并执行freeze)。

有效记录的年龄大于vacuum_freeze_min_age的,将该有效记录设置为freeze状态。普通vacuum(不带freeze的),并且表的年龄小于vacuum_freeze_table_age,不会执行FREEZE,所以不受这个参数影响。

很显然造成age众多,回收不及时的主要原因是业务同步数据作为每条数据库一个事务而处理,造成表age增长远远超过了vacuum freeze的速度。在无法改变此业务逻辑的前提下。

我们可以尝试修改一下参数:

autovacuum_freeze_max_age=150000000 当表的年龄超过autovacuum_freeze_max_age,即使关闭autovacuum,数据库实例依旧会强行触发vacuum freeze。

vacuum_freeze_table_age =100000000 当表的pg_class.relfrozenxid年龄大于等于vacuum_freeze_table_age,VACUUM会扫描全表,并执行freeze。

autovacuum_max_workers=5 实际测试发现调大整个参数会导致autovacuum进程过多io消耗满,所以就放弃了。(这还是用了磁盘阵列)

autovacuum_vacuum_scale_factor=0.05 该参数阈值更早的触发vacuum时机。当表的垃圾版本(dead tuples)超过 autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor*reltuples ,触发vacuum。

但注意没有到达vacuum_freeze_table_age 是不会触发freeze操作的。

为了避免多张表同一时间进行vacuum ,因为据观察,每张表的age年龄增长几乎都是同步的。

我们可以对年龄增长过快的表单独设置表级别不同的vacuum,freeze 的参数,如下所示,以错开vacuum导致的IO高峰。

autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (float4)

autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (整数)

autovacuum_freeze_table_age,toast.autovacuum_freeze_table_age(整数)

autovacuum_vacuum_cost_delay =0

结论

然而对于每个参数具体建议值,官方并没有给出最佳建议,毕竟业务场景是多变的。我们只能保守的尝试调整对应参数,再观察每个表对应的age增长情况以及监控IO走势。我们的处理原则是,让autovacuum进场尽量少休息多干活,并且错开每张表的vacuum高峰期,最终保证IO不要负载过高搞崩溃系统。

KingbaseES应对表年龄增长过快导致事务回卷的更多相关文章

  1. springmvc 事务回滚说明

    Spring中的@Transactional(rollbackFor = Exception.class)属性详解 序言 今天我在写代码的时候,看到了.一个注解@Transactional(rollb ...

  2. 事务之二:spring事务(事务管理方式,事务5隔离级别,7个事务传播行为,spring事务回滚条件)

    事物管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的一致性. spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务管理使用TransactionTemplate或 ...

  3. Spring中的事务回滚机制

    初学者笔记 问题:在Java项目汇中,添加@Transactional注解,报错之后,事务回滚未生效,数据仍插入数据库中.经查看报错位置位于新增成功之后.空指针异常. 一.特性 先了解一下@Trans ...

  4. SQLServer数据库中开启CDC导致“事务日志空间被占满,原因为REPLICATION”的原因分析和解决办法

    本文出处:http://www.cnblogs.com/wy123/p/6646143.html SQLServer中开启CDC之后,在某些情况下会导致事务日志空间被占满的现象为:在执行增删改语句(产 ...

  5. SQLServer数据库中开启CDC导致事务日志空间被占满的原因

    SQLServer数据库中开启CDC导致事务日志空间被占满的原因 转载  2017-04-01   投稿:mrr    我要评论 这篇文章主要介绍了SQLServer数据库中开启CDC导致事务日志空间 ...

  6. 生产环境下,MySQL大事务操作导致的回滚解决方案

    如果mysql中有正在执行的大事务DML语句,此时不能直接将该进程kill,否则会引发回滚,非常消耗数据库资源和性能,生产环境下会导致重大生产事故. 如果事务操作的语句非常之多,并且没有办法等待那么久 ...

  7. ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave由于鼠标移动速度过快导致问题解决办法

    记录两个项目开发中遇到的问题,一个是ECharts外部调用保存为图片操作,一个是workflow工作流连接曲线onmouseenter和onmouseleave事件由于鼠标移动过快触发问题. 一.外部 ...

  8. sendto频率过快导致发送丢包

    编写一个转发模块,虽然没有要求一转多时要达到多少路(不采用组播的情况下,单纯的一路转成多路),但是本着物尽其用的原则,尽可能测试一下极限. 网络环境:1000M,直连,多网卡 系统:Linux ver ...

  9. 关于srping的AOP事务管理问题,自定义切面是否导致事务控制失效

    applicationContext.xml: <!-- 方法调用时间记录 --> <bean id="methodExecuteTime" class=&quo ...

随机推荐

  1. Windows-VS2017创建.NET项目

    首先新建->项目 选择如下, 注意要选择.NET Framework4.x 选择对应的项目类型 建议选上Web窗体(如果是用于实验的话) 完成后进行测试 如果出现 HTTP Error 403. ...

  2. Mybatis中@select注解联合查询

    前言 在项目中经常会使用到一些简单的联合查询获取对应的数据信息,我们常规都是会根据对应的mapper接口写对应的mapper.xml的来通过对应的业务方法来调用获取,针对这一点本人感觉有点繁琐,就对@ ...

  3. IP寻址与规划

    一.IP寻址和子网划分 IP地址的主机部分可被分为三种地址:网络地址.主机地址和定向广播地址. 网络地址是网络号中的第一个地址.它用来将网络内的其他所有网段唯一标识为一个网段或广播域.定向广播地址是网 ...

  4. freeswitch拨打分机号

    概述 电话语音服务中,有一种稍微复杂的场景,就是总机分机的落地场景,客户拨打总机号码之后,需要再拨打分机号转接到指定的话机. 分机号的拨打一般在总机接通之后,会有语音提示,总机收号之后转接分机. 分机 ...

  5. 常见的git命令和git->github错误

    相关命令 git remote git remote add origin xxx (xxx为仓库链接) 给这个链接取一个名字,为origin git pull git pull <远程主机名& ...

  6. 浏览器js调试

    经常忘记,还是需要记录一下啊 右键,检查元素 在元素DOM节点右击,复制CSS选择器 function sleep (time) { return new Promise((resolve) => ...

  7. elastic-job和spring cloud版本冲突2

    ***************************APPLICATION FAILED TO START*************************** Description: An at ...

  8. 【Python爬虫技巧】快速格式化请求头Request Headers

    你好,我是 @马哥python说 . 我们在写爬虫时,经常遇到这种问题,从目标网站把请求头复制下来,粘贴到爬虫代码里,需要一点一点修改格式,因为复制的是字符串string格式,请求头需要用字典dict ...

  9. C++学习记录1

    代码1:转义字符 点击查看代码 #include<iostream> using namespace std; void test01()//换行 { cout << &quo ...

  10. IP地址和端口号

    IP地址 IP地址:指互联网协议地址(Internet Protocol Address),俗称IP.IP地址用来给一个网络中的计算机设备做唯一的编号.加入我们吧"个人电脑"比作一 ...