暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

人大金仓KingbaseES 中truncate和oracle中truncate区别

lucky 2023-10-30
271

truncate命令在KingbaseES中本质上区别于oracle。因为oracle中,数据文件datafile可以被表所共享,每张表被分配各自的连续的extents。而在KingbaseES中,数据文件是独立的,不同表不存在共享数据文件的说法。

下面我们看一下KingbaseES数据库在内部怎么实现的truncate命令。

createtable t4 asselect*from t3;
insertinto t4 select*from t4;
insertinto t4 select*from t4;
insertinto t4 select*from t4;
insertinto t4 select*from t4;
insertinto t4 select*from t4;
selectcount(*) from t4;

vacuum t4;
select relfilenode from sys_class where relname='t4';
select pg_relation_filepath('t4');

[kingbase@localhost16052]$ ll 252980*-rw------- 1 kingbase kingbase 8192 Oct 19 10:47 252980-rw------- 1 kingbase kingbase 24576 Oct 19 10:47 252980_fsm-rw------- 1 kingbase kingbase 8192 Oct 19 10:47 252980_vm

下面开启事务执行

begin;
truncatetable t4;
selectcount(*) from t4;
select relfilenode from sys_class where relname='t4';

这时候 relfilenode变成了252983,大小是0的对象,而原来的relfilenode 250980 还在,大小不变。

[kingbase@localhost16052]$ ll 252980*-rw------- 1 kingbase kingbase 8192 Oct 19 10:47 252980-rw------- 1 kingbase kingbase 24576 Oct 19 10:47 252980_fsm-rw------- 1 kingbase kingbase 8192 Oct 19 10:47 252980_vm
You have mail in/var/spool/mail/kingbase
[kingbase@localhost16052]$ ll 252983*-rw------- 1 kingbase kingbase 0 Oct 19 10:48 252983

看看回滚会发生什么

test=# rollback;
ROLLBACK
test=# selectcount(*) from t4;
count
\-------160
(1row)

test=# select relfilenode from sys_class where relname='t4';
relfilenode
\-------------252980
(1row)
[kingbase@localhost16052]$ ll 252980*252983*
ls: cannot access 252983*: No such file or directory
-rw------- 1 kingbase kingbase 8192 Oct 19 10:49 252980-rw------- 1 kingbase kingbase 24576 Oct 19 10:49 252980_fsm-rw------- 1 kingbase kingbase 8192 Oct 19 10:49 252980_vm

可以看到

1,数据恢复成原来的,并且relfilenode变成了原来的252980.KingbaseES数据库的truncate可以回滚。而oracle中的truncate不能回滚。

2,因为回滚继续使用对象252980,那么252983就被删除了,因为事务已经结束了,252983也就用不到了。

下面不开启事务,truncate不运行在事务块里测试一下

truncatetable t4;
select relfilenode from sys_class where relname='t4';
relfilenode
\-------------252984

[kingbase@localhost16052]$ ll 252980*252983*252984*
ls: cannot access 252983*: No such file or directory
-rw------- 1 kingbase kingbase 0 Oct 19 10:58 252980-rw------- 1 kingbase kingbase 0 Oct 19 10:58 252984

[kingbase@localhost16052]$ ll 252980*252984*
ls: cannot access 252980*: No such file or directory
-rw------- 1 kingbase kingbase 0 Oct 19 10:58 252984

1,我先后查看两次relfilenode,可以看到最开始能查到truncate前的252980,但是无论怎样它的大小已经变成0,这时候可以判断已经没办法回滚了,当再次查询发现252980被删除了,只剩下252984

因为没法利用252980回滚了,所以可以被数据库删除掉了。最后只能查到最新的对象号252984

2,经过多次测试发现有时候老的对象号252980并不是立即被删除,我想应该和数据库有自己的删除机制有关。总之,这个老的对象号已经没有用了。

总结:

当truncate命令在事务块里可回滚。而truncate可回滚无疑对业务有一些帮助。根据KingbaseES和oracle对于truncate的内存原理不同,我们可以理解KingbaseES中truncate的代价很小,因为KingbaseES中的truncate不会存在存储空间重用的问题,也没有触发对象级检查点的操作,当进行truncate时候不会对业务产生太大影响,在业务运行期间我们可以使用truncate及时恢复一些存储空间。

需要注意的是如果truncate命令和另外的session对于正在truncate的表有操作(包括Select),那么很可能会有锁冲突,虽然这种可能性很小,但还是要注意。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论