mysql的锁总结
表锁
行锁 :记录锁(record lock)、间隙锁(gap lock)、临间锁(next-key lock)。行锁是加在索引上的,没有索引是加不上行锁的
共享锁:又称读锁(lock in share mode),例如select,当上锁之后,另一个线程只可以读,不可以修改。
排他锁:又称写锁(for update),例如update,insert,delete,上锁之后,另一个线程不可以读和修改。
读锁(共享锁、S锁):多个事务同时读,不能写。
写锁(排他锁、互斥锁、X锁):一个事务能写能读,其他的事务都不行
mdl(meta data lock、元数据锁):查询事务一旦开始,不能修改表结构
意向锁:表锁,获取锁前先要获取意向锁,不能修改表结构。
一、意向共享锁(IS) 是指在给一个数据行加共享锁前必须获取该表的意向共享锁。
二、意向排它锁(IX) 是指在给一个数据行加排他锁前必须获取该表的意向排他锁。
乐观锁:无锁 version来控制
悲观锁:mysql都是悲观锁 上锁
聚簇索引:每个节点含有主键 和 每个叶子结点包含表中所有数据。
非聚簇索引:只包含索引,先查非聚簇索引,然后回表查聚簇索引。
select for update :
主键索引:只对聚簇索引加锁,直接查聚簇索引。
非主键索引:加两把锁,聚簇索引和非聚簇索引,先加锁普通索引(非聚簇索引),再加锁主键索引(聚簇索引)。
select * from table where id = 1 select * from table where id = 1 for update
SELECT 和 SELECT FOR UPDATE两个例子
总结:写锁的RC解决不了幻读,就不需要间隙锁,RR解决了幻读,就需要间隙锁
mysql可重复读隔离(RR)级别不是可以通过间隙锁解决幻读么,为什么又说RR级别无法解决幻读?
因为不加for update的读是不加锁的,用的是MVCC快照读。加了for update就会加排他行锁和间隙锁,并在这次事务结束解锁。
MVCC 的局限性: MVCC 保证了快照读的一致性视图,但写操作(当前读)必须基于最新数据,否则会导致更新丢失或逻辑错误
ACID如何保证?
A.原子性
C.持久性
Redo log
当我们想要修改DB上某一行数据的时候,
InnoDB是把数据从磁盘读取到内存的缓冲池上进行修改。数据在内存中被修改,与磁盘中相比就存在
了差异,我们称这种有差异的数据为脏页。InnoDB对脏页的处理不是每次生成脏页就将脏页刷新回磁
盘,这样会产生海量的IO操作,严重影响InnoDB的处理性能。
redo log的工作原理。说白了,redo log就是存储了数据被修改后的值。当我们
提交一个事务时,InnoDB会先去把要修改的数据写入日志,然后再去修改缓冲池里面的真正数据页。
I:隔离性
D:一致性:一些约束,唯一索引,错误检查器check一些字段