金仓数据库KingbaseES Vacuum功能介绍

1. 什么是Vacuum?
Vacuum从字面意思来理解就是一个“吸尘器”,用于“清理尘埃”;KingbaseES数据库是一个多用户、高并发的环境,为了维护数据的一致性,KingbaseES使用多版本并发控制(MVCC)以及多种锁机制来实现这一目标。但是MVCC机制有利有弊,会为数据库带来不必要的开支。因此,对于多版本的维护,KingbaseES提供了Vacuum命令,进行数据库中的无效元组的清理;同时,为了防止事务回卷及事务号越界等问题,Vacuum同样可以通过冻结事务ID及回收事务ID等操作,来解决上述问题。
2. 多版本并发控制—MVCC
2.1 MVCC原理

MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,用更好的方式去解决处理读写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。
MVCC的实现原理主要依赖undo log多版本链条和ReadView机制来实现的。undo log是指一行数据被多个事务多次修改后,在每个事务修改完成后,KES会保留修改前的数据undo回滚日志,并且用两个隐藏字段trx_id和roll_pointer把这些undo日志串联起来形成一个历史记录版本链。与此同时,事务开启时会产生一个可视视图ReadView(不同隔离级别有不同的产生策略),在进行数据查询时,可以根据ReadView进行判断来决定读取哪个版本的数据。

2.2 MVCC的存储机制

2.2.1 元组

元组(tuple)是关系数据库中的基本概念,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,每列就是一个属性,在二维表中,元组也称为行。
file:///C:/Users/GBJ-0537/AppData/Local/Temp/ksohtml21312/wps1.jpg
元组除了具有存储用户信息的userdata外,还有许多控制信息,在本文主要介绍t_xmin,t_xmax,t_cid和t_tcid:
    ·t_xmin:保存插入该元组的事务txid;
    ·t_xmax:保存更新或删除该元组的事务txid;
    ·t_cid:保存命令标识,指在该事务中,执行当前命令之前还执行过几条sql命令;
    ·t_tcid:一个指针,保存指向自身或新元组的元组标识符。
2.2.2 插入操作

插入(insert):插入操作时,直接将新元组插入目标表页面即可。
删除操作(delete):只是将目标元组在逻辑上标为删除,实际上该元组依然存在于数据库的存储页面中。
2.2.4 更新操作

更新操作(Update):更新操作相当于delete+insert;相当于占用了两条元组的空间。
2.3 表膨胀和索引膨胀

在MVCC中,每个写操作都会创建一个新版本的数据项,同时保留旧版本。当事务读取数据项时,系统会选择其中一个版本来确保单个事务的隔离。比如更新操作,每更新一次就会产生一个新版本元组,而旧版本的元组也会占用空间,在多用户、高并发的环境下,如果不对这些旧版本的元组(也称死元组)进行清理,那么就会出现表膨胀和索引膨胀的现象。
file:///C:/Users/GBJ-0537/AppData/Local/Temp/ksohtml21312/wps5.jpg
file:///C:/Users/GBJ-0537/AppData/Local/Temp/ksohtml21312/wps6.jpg
对同一元组进行更新操作后,数据库会生成大量的新版本元组,同时旧版本也存储在数据库中,就会产生大量的死元组(dead_tuple),这时,Vacuum会对表进行扫描,获取大量的死元组信息,创建死元组列表,然后通过死元组列表删除其对应的索引元组,直至死元组清理完成。
file:///C:/Users/GBJ-0537/AppData/Local/Temp/ksohtml21312/wps7.jpg
索引和表也是类似,随着不断的增删改,也会膨胀,对于Btree索引,也会涉及到分裂、合并等,导致索引页的空洞。另外,如前面所说,索引页的复用与HEAP PAGE不一样,因为索引的内容是有序结构,只有符合顺序的ITEM才能插入对应的PAGE。不像HEAP TUPLE,只要有空间就可以插入。index page无论在任何位置,都不能从磁盘删除,索引变大以后,不可能变小,除非vacuum full。因此索引膨胀后,通常需要重建索引来缩小索引大小。
3. 数据库事务
3.1 事务

事务是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。数据库会给可能对数据库进行修改操作的事务分配一个事务号(t_xid),事务号是一个32位无符号整数,因此其空间上有2^32-1=42亿个事务号。但是42亿仍是有上限的,为了使事务号不溢出,Pg数据库将事务号进行循环使用;并将txid空间一分为二,对于某个特定的txid,其后21亿txid属于未来,均不可见;其前21亿个txid属于过去,均可见。
3.2 事务回卷

当程序运行一段时间后,当数据库年龄到达21亿以后,就会导致原来表上的数据的xmin均大于当前事务号,造成看不到以前的数据现象,这就违背了数据库一致性的原则,这也就是事务回卷现象,如果不对这种现象进行解决,就相当于是数据丢失,非常严重。
3.3 冻结事务ID(惰性冻结

当数据库年龄达到21亿后,会出现事务回滚现象,为了解决该问题,可以对事务ID进行冻结操作,进行事务号清理工作,以此降低数据库表的年龄。通常的操作时将事务号t_xid置为2,因为t_xid=2的事务在参与事务id比较时总比所有旧事务都旧,它对于其他事务都是可见的。
在冻结开始时,pg数据库会根据freezelimit_txid = oldestxmin-vacuum_free_min_age计算freezelimit_txid的值,其中vacuum_free_min_age可以理解为有个元组可以做freeze的最小间隔年龄;oldestxmin代表当前活跃的事务中的最小的事务标识;然后Vacuum会将xmin小于freezelimit_txid的元组进行冻结;
4. Vacuum工作步骤
Vacuum的处理流程:

1)从指定的表中获取每个表;
2)获取表的ShareUpdateExclusiveLock锁。此锁允许读取其他事务;
3)扫描所有页面以获取所有死元组,必要时冻结旧元组;
4)如果存在,则移除指向相应死亡元组的索引元组;
5)对表的每一页执行以下(6)、(7);
6)移除死元组并重新分配页面中的活元组;
7)更新目标表的相应FSM(空闲空间地图)和VM(可见性地图);
8)如果最后一页没有元组,则截断最后一页;
9)更新与目标表的真空处理相关的统计信息和系统目录;
10)更新与真空处理相关的统计数据和系统目录;
11)如果可能,删除不必要的文件和clog页面。
  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值