对mysql的锁这块真的不是特别了解,学习完这一部分,有种豁然开朗的感觉。当然还是有待进一步提高。更加深入的学习。
锁问题
mysql锁的分类
1 表锁,开销小,加锁快,不会出现死锁,锁定粒度大 2 行锁,开销大,加锁慢,会出现死锁,锁粒度小 3 页面锁,介于两者之间,会出现死锁myisam 表锁,适合读多的程序innodb 行锁,适合写多和并发高的程序
查看表锁的状况
show status like 'table%';
| Table_locks_immediate | 504 || Table_locks_waited | 0 锁等待状态 || Table_open_cache_hits | 0 || Table_open_cache_misses | 0 || Table_open_cache_overflows | 0
表锁又分为:表共享读锁,表独占写锁。
加表锁语法:lock table xxx read;lock table xxx write;
解除表锁:unlock tables;
并发插入
myisam的表读写都是串行的。其实也支持并发插入通过concurent_insert 0 不允许 1 有空洞允许在表尾插入 2 允许表尾插入
myisam锁调度
读锁写锁是互斥的,读写操作是串行的。myisam的锁是写先行。当然也可以调整myisam的锁的行为
innodb和myisam的最大的不同
1 innodb支持事务2 采用了行锁
事务和acid属性
原子性。要么全部执行,要么全部不执行。一致性。事务开始和完成时数据保持一致性。隔离性。事务不受外部并发操作影响。持久性。当事务完成后,数据的修改是永久性的
并发事务带来的问题
更新丢失。多事务操作同一条记录。可以采用锁定。脏读。不可重复读。幻读。
事务隔离级别
实现方式 1 加锁 2 快照实现多版本控制未提交读已提交读可重复读可序列化
查看innodb事务状态
show status like '%innodb%';
innodb的行锁模式以及加锁方式
行锁 共享锁S,允许一个事务去读一行,阻止其他事务获取相同数据集的排它S锁 排他锁X,允许获得排它锁的事务更新数据,阻止其他事务获取相同的共享锁和排它锁表锁 意向共享锁IS 意向排它锁IX
innodb锁的特别注意的
1 在不通过索引条件查询的时候,innodb确实用的是表锁,不是行锁。2 mysql的行锁是针对索引加的锁,而不是针对记录,使用相同的索引键可能出现冲突。3 当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引,唯一索引,普通索引,innodb都是采用行锁来对数据加锁4 即使创建了索引,能偶否使用索引还是由mysql判断,如果代价高,innodb可能采用表锁。
间隙锁-范围加锁
恢复机制对innodb锁的影响
myslql是通过binlog记录执行增删改查操作的。 1 mysql恢复的是sql语句的集合 2 通过binglog先后顺序恢复
innodb什么时候使用表锁
1 事务需要更新大部分或者全部数据,表又打的时候2 实际多表,业务复杂,容易造成死锁,造成大量事务回滚的情况。
在使用mysql中如何尽量减少死锁的概率
尽量使用较低级别的隔离级别精心设计索引,并尽量使用索引反问数据,使加锁更加精确合理选择事务大小申请合适的事务级别如果不同的程序会并发存取多个表,应尽量约定以相同的顺序来访问表。批量处理数据时,先对数据排序,保证每个线程以固定的顺序来访问记录更新记录直接使用排它锁更新同一条记录可以采用READ COMMITED级别