在row-based存储引擎中,如果需要update某个字段,tidb是以key+更新字段的方式append,还是以key+更新字段+其他字段 插入一条新完整的record?
我的印象是这种方式,一条新的记录append在sst 文件末尾,同时带上最新的时间戳TSO,表示是最新的可用MVCC版本,等到下次GC才会把旧的数据清理掉
谢谢你的回答。
不过,如果是更新字段+其他字段再append的话,如果其他字段很大,对性能应该也有影响的吧,tidb是怎么解决的呢?
就是KV的更新,往内存追加,然后再交换成immutable,再原样往level0刷盘,最后再后台compaction.
是的,字段很大的行,写性能是会有影响的,所以官方也建议我们频繁更新的字段不能太大
我有个想法,能不能只写入key + 更新字段,给这种record设个update状态,append进底层。在查询时根据lsn和update状态来合并其他字段?
这样需要维护不同字段的状态才行了,极端情况下一个表的几乎全部字段都有过更新,这些个字段还被更新过很多次,想想维护起来多麻烦。而且还要考虑MVCC多版本控制的事情,导致整个基础数据行的设计不够简单优雅了,大概率会引发其他意想不到的性能和管理的问题
那么tidb提供 bulk update的方式吗?假设有种场景,某字段需要更新的行很多,只能通过update语句一条条来更新吗?
tikv存储的是key:value,一行就是一个键值对,不可能从value中单独标记其中一个字段被更新过,所以更新其中一个字段,会产生一个新的完整的value。
mvcc实现主要有两个派:
以oracle,mysql,db2,dm为代表的基于undo实现的undo派;
以pgsql,kingbase,opengauss,tidb为代表的基于行复制的行复制派。
undo派适应性更广泛; 而行复制派在特定场景效率会更高(只是场景普适性稍差),不仅update只要是dml,tidb都会新写行进去,本质上是空间换效率的策略,因此产生了很多垃圾(过期的)数据,如何高效回收垃圾及回收过程避免与应用需求间的冲突是个持续迭代优化过程。
目前有部分数据库提供了两种mvcc的实现方式可供选配,如opengauss,在原本pg系的行复制实现的基础上,增加了类似oracle的undo的新的实现方式。
insert 一条版本号更高的新数据
此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。