起源
最近在看一本开源的书,主要讲数据库Oceanbase的相关实现方式以及一些原理,但是其中讲关于事务中mvcc的实现比较薄弱,所以在网上搜了很多资料特地总结归纳一下
对mvcc的实现
原理就是对一行记录就行多个版本保存,不同的数据库还有不同的实现:
- Mysql:主要是通过行记录中的隐藏字段(隐藏主键 row_id、事务ID trx_id、回滚指针 roll_pointer)、undo log(版本链)、ReadView(一致性读视图)来实现的。
- PostgreSQL:基本一致,但是更为纯粹,不使用行锁,需要定时清理并发版本。
mvcc的理解
核心思想就是使用单调递增的xid去筛选一个可以被查看的区间,当并发时,比如读写场景,开启事务后,在rc场景下每一次读都会有一行ReadView,而在rr场景下同一事务下每一次读都是同一行ReadView,根据你当前能读到的xid顺序,获取你当前可以读到的行,多版本又由行内的链表字段句柄连接,所以每次读都需要读取所有的链表才能拿到你需要的那一行,所以当你的写入并发量大的时候,建议开启rc,其他一般场景下都使用默认的rr。
mvcc经典论文
《An Empirical Evaluation of In-Memory Multi-Version Concurrency Control》论文翻译