MySQL

2020-02-06  本文已影响0人  金泽祺

InnoDB vs MyISAM

日志

主从复制

基于SQL语句的复制:binlog小,但是有些语句无法被复制,存储过程,触发器
基于行的复制:可靠性高,任何情况都可以复制,binlog大
混合复制:两种方式都可以用

bin log vs redo log

事务提交时,先写 bin log,再写 redo log
将事务放入队列,第一个事务称为leader,其他事务称为follower。分成3个阶段:flush/sync/commit
fulsh阶段:先写bin log内存,再写redo log内存。flush等待一段时间之后才进入sync
sync阶段:bin log刷盘,可能刷一个事务也可能刷多个事务
commit阶段:leader根据顺序提交事务,可以使用innodb的group commit

redo log

undo log

提升性能的关键特性

插入缓冲 insert buffer

两次写 double write

自适应哈希索引 Adaptive Hash Index

索引

MySQL事务

事务的ACID属性

ACID实现

InnoDB通过 Force Log At Commit 来实现 持久性:commit时,必须将事务的所有日志写入redo log

事务回滚,通过undo log,insert 对应 delete, update 对应反向的 update来实现原子性

MVCC的实现就是靠undo log,通过undo读取之前的行版本信息: RR隔离级别下,总是读事务开始的行数据;RC隔离级别下,总是读最新的快照

并发事务处理的问题

事务隔离级别(读数据一致性):

MySQL MVCC 多版本并发控制

Spring事务的传播行为

传播行为 说明
PROPAGATION_REQUIRED 默认值。如果没有则新建事务,如果有则加入当前事务
PROPAGATION_REQUIRES_NEW 如果没有则新建事务,如果有则挂起当前事务
PROPAGATION_NESTED 如果没有则新建事务,如果有则新建当前事务的子事务
PROPAGATION_SUPPORTS 如果没有则非事务,如果有则加入当前事务
PROPAGATION_NOT_SUPPORTED 如果没有则非事务,如果有则挂起当前事务
PROPAGATION_NEVER 如果没有则非事务,如果有则抛出异常
PROPAGATION_MANDATORY 如果没有则抛出异常,如果有则加入当前事务

InnoDB锁机制

乐观锁

读取数据的时候不加锁,更新数据的时候会判断数据是否被修改。
一般通过版本号或CAS实现。

悲观锁

读取数据的时候会加锁。
表锁,行锁,共享锁,排他锁,都是悲观锁

表锁

行锁 Row Lock

要点:行锁通过给索引项加锁实现,而不是给记录加锁。只有通过索引检索才使用行锁,否则使用表锁。

INSERT,UPDATE,DELETE语句自动加排他锁。

SELECT语句需要手动加锁:

间隙锁 Gap Lock

要点1:唯一索引只有行锁,非唯一索引才有间隙锁
要点2:间隙锁锁住了左边和右边不存在的记录,比如{2, 4, 6},如果查询条件是4,那么间隙锁锁住的是左边[3, 4),右边[5,6)

Next-Key Lock

InnoDB会加Netx-Key Lock,包括行锁(Record Lock)和间隙锁(Gap Lock)。间隙锁会锁住后面没有的记录,可以用来解决幻读的问题。比如事务A一开始使用select ... for update读出3条记录,此时由于间隙锁的存在,事务B将不能插入ID为4的记录,所以就不存在幻读的问题。

上一篇下一篇

猜你喜欢

热点阅读