1、数据库锁
根据事务的隔离性,调整不同的锁粒度(对行,数据块或表进行加锁)
2、写时复制COW
原理:对于写操作单独复制一份B+树丛叶子节点到根节点的路径,修改后再切换复制节点的根节点指向。具体步骤如下:
- 拷贝:将从叶子到根节点路径上的所有节点拷贝一份
- 修改:基于拷贝的节点进行修改
- 提交:原子地切换根节点的指针,使之指向新的根节点(同时旧的节点会根据维护的引用计数情况是否为0,觉得是否进行垃圾回收)
优点:读操作不用加锁,极大提升了读取性能
缺点:每次写操作都需要拷贝从叶子到根结点路径上的所有节点,写操作成本高;另外,不支持多个写操作并发
3、多版本MVCC
原理:对每行数据维护多个版本,无论事务的执行时间有多长,MVCC总是能够提供与事务开始时刻相一致的数据。实际是增加了俩个隐式列:行被修改的”时间”和行被删除的”时间”(这个时间实际上是一个递增的唯一事务号)。对于每一次查询,会把当前事务的事务号同行存储的事务号进行对比,然后结合不同的事务隔离级别,来决定是否返回该行。
优点:
读取数据不需要加锁,每个读事务只获取自己的事务版本,大大提高了并发度;可以支持多个写事务并发
缺点:
需要额外存储多个版本数据;需对多个版本数据进行维护,定时删除不需要的版本,回收空间
根据这个原理,select/delete/update/insert语句的行为如下:
- select
进行select操作时需要满足,才能返回数据
1) 行的修改版本号小于等于该事务号
2) 行的删除版本号要么没定义,要么大于事务的版本号(表示数据在未来被其他事务删除) - delete
更改行的删除版本号为当前事务号 - update
将原来的行复制一份,更改行的修改版本号为当前事务号 - insert
设置行的修改版本号为当前事务号