前言
锁机制是为了解决数据库的并行性和数据的一致性而产生的,通过为访问的数据加锁,可以使得被访问的数据不被修改,从而保证数据的有效性和一致性。
1、表级锁:MyISAM 引擎
(优点)开销小,加锁快,不会出现死锁现象;
(缺点)表级锁范围大,导致锁的冲突概率最高,并发性最低;
(使用)MyISAM执行查询(SELECT)前和执行更新操作(UPDATE、DELETE、INSERT)前会自动的给被查询的数据表加读锁 定和写锁定,是不需要用户使用(LOCK TABLE)命令显式锁定的。
2、行级锁:InnoDB 引擎
(优点)行级锁范围小,导致锁的冲突概率最小,并发性最好;
1. 回滚时少量更改即可。
2. 冲突低,可长时间锁定。
(缺点)锁定的开销大,加锁慢;会出现死锁;
1. 相比于页级锁和表级锁,开销大,占用内存大。
2. 某些应用场景下,对表的大部分使用行级锁,会比较慢。
(分类)
1. 共享锁(S)允许事物读取数据记录,并阻止其他事物获得相同数据记录的 排它锁。
2. 排它锁(X)允许事物更新数据记录,并阻止其他事物获得相同数据记录的 共享读锁和排他写锁。
(注意事项)
InnoDB的行级锁定是通过对索引项加锁实现的,否则InnoDB使用的是表级锁。
3、页级锁:DBD引擎(也支持表级锁定)
(状况)页面锁定的开销和加锁时间界于表级锁定和行级锁定之间;会出现死锁;锁定的粒度处于其他两者之间,并发度一般。
4、函数锁定:(不常见)
函数锁定使用GET_LOCK(name, time), RELEASE_LOCK(name)函数进行行锁定和释放操作;
5、适用范围:
表级锁:以查询为主,只有少量按索引条件更新数据的应用,如一些Web应用;
行级锁:适用有大量按索引条件并发更新少量不同的数据,同时又有并发查询的应用,如一些在线的事物处理系统;
函数锁定:当只需要锁定两个进程之间的通信时,最好采用函数锁定而不是LOCK/UNLOCK锁定。
6、利用锁进行性能优化
(出现情况)
读锁定与写锁定:当一个锁被释放后,锁定会先分配给写锁定队列,然后才是读锁定队列。也就是说,当数据库拥有大量的更新操锁时,查询很难获得读锁定,所以mysql的锁机制可能会造成死锁。
(解决方法)
1. 通过指定启动参数low-priority-update,使得MyISAM存储引擎给予读锁定请求优先权;
2. 通过执行命令SET LOW_PRIORITY_UPDATES=1,降低该进程的更新请求优先级;
3. 通过指定UPDATE、DELETE、INSERT等更新语句的LOW_PRIORITY属性,降低优先级。
4. 为适应更一般的情况,MySQL提供折中办法调节读写冲突,即给系统参数max_write_lock_count设置一个合适的值,当一个数据表的写锁定达到该值的时,MySQL就暂时的把写请求的优先级降低,这样就可以在执行一定数量的写锁定后执行读锁定,以解决读锁定等待严重的问题。