关键字:
KingbaseES、Vacuum、事务、金仓数据库
什么是Vacuum?
Vacuum是KES的一种磁盘空间和事务号资源回收的手段,用户可以通过SQL手动触发vacuum工作也可以由KES的autovacuum进程自动执行。
为什么需要Vacuum?
要想了解vacuum的作用就不得进一步了解KES的事务机制。简单来讲,在KES中通过MVCC实现了事务的并发控制,随着数据库系统的运行会积累大量的历史数据,一方面历史数据占用的事务号信息、日志空间的占用属于资源的浪费;另一方面随着历史数据的增加,检索时需要扫描的历史数据占比上升,会出现检索性能逐渐降低。故此,我们需要引入一种 机制来回收事务号和日志空间,清理历史数据以提升无效扫描。在KES中,此机制就是vacuum。
Vacuum内部机制
根据上面的介绍,我们对vacuum形成了初步印象,下面进一步说明vacuum的内部机制方便深入了解KES。Vacuum主要包括三个部分:1. 删除历史元组;2.回收事务号(常称为冻结事务号);3. 其他内部文件更新。下面通过示例展示vacuum前后的数据变化。
test=# create global temp table gt10(a int) on commit preserve rows; CREATE TABLE test=# insert into gt10 values(100); INSERT 0 1 test=# update gt10 set a=20; UPDATE 1 test=# update gt10 set a=30; UPDATE 1 test=# update gt10 set a=40; UPDATE 1 test=# select xmin, xmax, * from gt10; xmin | xmax | a ------+------+---- 1209 | 0 | 40 (1 row) test=# select lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid from heap_page_items(get_raw_page('gt10', 0)); tuple | t_xmin | t_xmax | t_cid | t_ctid -------+--------+--------+-------+-------- 1 | 1206 | 1207 | 0 | (0,2) 2 | 1207 | 1208 | 0 | (0,3) 3 | 1208 | 1209 | 0 | (0,4) 4 | 1209 | 0 | 0 | (0,4) (4 rows) |
首先创建一张数据表(此处选择临时表避免了autovacuum),可以看到在对数据进行了多次更新后,物理上实际存储了4条数据,但是实际可见的仅一条数据,其他3条均为历史数据。
test=# vacuum gt10; WARNING: skipping the data of global temporary table "gt10" in other backends, and skipping the freezing xids stage VACUUM test=# select lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid from heap_page_items(get_raw_page('gt10', 0)); tuple | t_xmin | t_xmax | t_cid | t_ctid -------+--------+--------+-------+-------- 1 | | | | 2 | | | | 3 | | | | 4 | 1209 | 0 | 0 | (0,4) (4 rows) |
当执行vacuum后,3条历史数据被清除。
对于回收事务号,含义是当事务号申请达到某一阈值后,会对历史元组中的事务号id进行回收,即被回收事务号的元组均为可见元组,不再需要通过快照和事务日志等判断可见性,因此后续可以安全使用被冻结的事务号。
总结
本文介绍了KES中vacuum的作用以及内部机制,有利于深入了解KES产品,能够从底层原理理解KES产品的外在表现,也有助于了解该机制下KES与其他数据库产品的独特优势。
需要注意的是,在后续的产品升级中,通过vacuum对事务号进行回收变得不再迫切,为符合用户日益增长的业务规模和数据量的需要以及更有的性能表现,KES后续会扩展事务号的范围,届时事务号的回收或许将称为历史。