Mysql元数据锁、行锁、MySQL事务介绍、InnoDB架构
元数据锁
行锁的意义和场景
记录锁和间隙锁
死锁原理和场景
事务的概念和四大特征ACID
Redolog的作用
元数据锁
MDL(MeteDataLock 5.5版本映入)元数据:也是一个表锁, 即表结构。当对表结构炒作的时候加DML的写锁,当DML(Data Manipluation Language 数据操作语言即insert、update、delete)操作的时候加DML读锁,该锁是MySQL自动加(就是防止在操作表数据的时候,表结构不能变化)。
begin; -- 开启事务,其他会话将无法对该表结构产生影响
select * from mylock; -- 此处select,mysql自动 加DML读锁
commit; -- 提交事务 或者 roolback 释放锁
行级锁
行写锁(读写和写锁互斥)
单纯的select 不加锁!select * from table where 。。。。 lock in share mode
-- 行写锁(加写锁,不影响其他数据读取)
-- select ... 查询不加锁,select ... 是lock in share mode 读锁。
select * from mylock where id =1 for update;
记录锁
防止幻读(T1、T2读取一个字段,T2插入一条数据,T1再次查询后以前的不一致了)!
锁的是某一行的记录。主键指定,比如 where id=3 时表示该条记录查询是,无法操作DML
间隙锁(gap locks)
锁定记录前、记录中、记录后的行,在RR隔离级(可重复读)也是Mysql的默认隔离级。锁的时候两行之间的间隙(两行数据的缝)
start transaction;
-- 产生一个 1,2,3 ;4,5,6的间隙锁
update gap_lock set number = 80 where id >1 and id <4;
Next-Key锁
意向锁
两阶段锁
行锁加锁、解锁
-- 查看行锁状态
show status like 'innodb_row_loc%'
-- 返回结果
'Innodb_row_lock_current_waits', '0'
'Innodb_row_lock_time ', '50602' -- 如果改行数字过大,表示并发有问题出现了很多锁定状态
'Innodb_row_lock_time_avg', '50602'
'Innodb_row_lock_time_max', '50602'
'Innodb_row_lock_waits', '1'
-- 事务加锁
begin;
select * from users where id =1 lock in share mode -- 对改行加读锁
rollback;
-- 此时另外一个会话来更新该条记录,将阻塞
update users set name = 'zdddd' where id=1
-- 超时抛出异常:21:52:49 update users set name = 'zdddd' where id=1 Error Code: 2013.
Lost connection to MySQL server during query 30.005 sec
-- 在where中使用为添加索引的列作为查询条件时,加锁,将导致行锁升级为表锁
begin;
select * from dep where name ='部门4' lock in share mode;
rollback;
-- 在另外一个会话中,执行update,将出现阻塞(超时抛异常,释放该执行语句!)
update dep set name = '部门4444' where id = 1;
-- 如果在执行update的 where条件中的name为非索引列,该行锁将升级为表锁
-- 因为没有加索引的列,在执行时扫描全表,扫描全表将对表加锁
update dep set name='部门11aa' where name ='部分1111'
死锁
两个session互相等待对象释放资源之后,才能释放自己的资源,造成了死锁!Mysql发现死锁时自动结束其中一个,避免发生阻塞死锁!Deadlock found when trying to get lock;try restarting transaction!!!!
begin;-- 会话1
update a set name='11' where id =1;
update a set name='22' where id =2;
rollback;
begin; -- 会话2
update a set name ='222' where id = 2;
update a set name ='111' where id =1;
rollback;
事务
mysql事务在存储引擎实现,Innodb存储引擎,支持事务。要么都执行、要么都不执行。
事务四大特性ACID
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation):
事务之间互不影响,由mysql锁机制
MVCC机制来实现:多版本并发控制、优化读写性能、读不加锁、读写不冲突!
持久性(Durability)
显示的使用事务,begin、commit、rollback;
InnoDB架构
page 也叫脏页,因为和真实的数据文件是不一致的,还没有更新到数据文件中。这些数据会被先写入到redo-log-buffer中。
重做日志的落盘机制
redo-log Buffer 重做日志缓冲
重做日志保证了数据的可靠性,InnoDB采用了额Write Ahead Log(预写日志)策略,即当事务提交时,先写重做日志,然后再择时将脏页数据写入磁盘。如果发生宕机导致数据丢失,就通过重做日志进行数据恢复。
例如:insert into xxxx commit; Redo Log File 写成功则 Commit。
这个Redo-log在ib_logfile0、iblogfile1中(这两个大小默认8M,通过innodb_log_buffer_size控制大小)。
redo-log作用是实时保证在buffer pool中缓存的数据能够被保存下来,在mysql宕机后,重启后能够被记录到mysql的数据文件中(这个过程叫做redo-log落盘,这个机制是mysql默认的数据保存机制)。
在commit后数据将被真正写入到磁盘。