锁大家应该都知道,不多BB,直接开讲
为什么需要锁:
到淘宝上买东西,库存只剩一件的时候,两个人同时买,到底如何解决谁买到的的问题?
1:我们先从库存表中取出物品数量
2:插入订单
3:付款后插入付款表
4:然后更新商品数量
在这个过程中,使用锁可以对有限的资源进行保护,解决隔离和并发的矛盾;
锁的概念:
锁是计算机协调多个进程或线程并发访问某一资源的机制
在数据库中数据也是一种供许多用户共享的资源,如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素;
锁对数据库而言显得尤其重要,也更加复杂
Mysql中的锁
Mysql的锁机制比较简单
其最显著的特点是不同的存储引擎支持不同的锁机制
比如:
MyISAM和Memory存储引擎采用的是表级锁(table-level locking)
InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但是默认情况下采用的是行级锁
表级锁:开销小,加锁快;不会出现死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低.
行级锁:开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度也最高.
页面锁:开销和加锁时间介于表锁和行锁之间,会出现死锁,锁定粒度也介于表锁和行锁之间,并发度一般.
仅从锁的角度来说:
表级锁更适合于以查询为主,只有 少量按索引条件更新数据的应用,如OLAP系统
行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事物处理(OLTP)系统
很难笼统的说那种锁更好,只能就具体应用的特点来说那种锁更合适.
MyISAM的表锁
Mysq的表级锁有两种模式
表共享读锁(table read lock)
表独占写锁(table write lock)
请求锁模式 是否兼容 当前锁模式 |
NONE | 读锁 | 写锁 |
读锁 | 是 | 是 | 否 |
写锁 | 是 | 否 | 否 |
自己的理解:读的时候可以读,读的时候不能写,写的时候不能读,写的时候不能写;
读锁是共享锁;写锁是独占锁;
绕口令[捂脸]
MyISAM的共享读锁
给表添加读锁
lock table [tableName] read;
解锁
unlock tables;
当表添加读锁后在同一个Session会话中执行Insert or update会报错,而其他的Session会进入等待状态,一直到那个Session释放锁
当表添加读锁后在同一个Session会话中对其他表执行insert or Update会报错,查询其他表也会报错,在另外的Session对其他表进行操作不会报错,成功;
有兴趣,大家自己试一试,我觉得没啥用,了解一下就可以,就没有Demo了
还有一个坑就是,加锁的时候锁的表名是可以做别名的,如果没有做别名,那么只能查锁的那个表名,查询时不能采用别名,如果想用,请在锁的时候加上;
lock table test read;
select * from test;//不会报错
select a.* from test as a;//会报错
lock table test as a read //做别名
MyISAM的独占写锁
给表添加写锁
lock table [tableName] write;
解锁
unlock tables;
当表添加写锁后,在自身会话中可以insert or update or delete,其他表中查询会进入等待
当表添加写锁后,在自身会话中无法对其他表进行insert or update or delete
别名的坑是同样的,就不写例子了
MyISAM的表锁
总结:
对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求
对MyISAM表的读操作,不会阻塞当前Session对表的读操作,当对表修改会报错
一个Session使用 LOCK TABLE命令给表F添加读锁,这个Session可以查询锁定表中的记录,但更新或访问其他表都会提示报错;
另一个Session可以查询表中的记录,但更新会出现锁等待
对MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作
对MyISAM表的写操作,当前Session可以对本表做CRUD,但对其他表操作会报错
InnoDB的行锁
在Mysql中的InnoDB存储引擎支持行锁
行锁:
共享锁又称:读锁,当某一个事物对某几行上锁时,允许其他事物对这几行进行读操作,但不允许进行写操作,也不允许其他事物给这几行上排它锁,但允许上读锁;
排它锁又称:写锁:当一个事物对某几行上读锁时,不允许其他事物写,但允许读,更不允许其他事物给这几行上任何锁,包括读锁;
添加行读锁
select * from [tableName] where 条件 lock in share mode;
添加行写锁
select * from [tableName] where 条件 for update;
行锁添加之前需要开启事物
开启事物
Begin
当执行commit 或者rollback的时候会释放行锁
InnoDB添加表锁和MyISAM一致
但是有一点是,当开启事物的时候表锁会被释放
物理结构修改:
面试题:系统运行一段时间,数据量已经很大,这时候系统升级有张表A需要增加字段,并发量白天晚上都很大,请问则么修改表结构?
面试考点:修改表结构会导致表锁,数据量大,修改数据很长,导致大量用户无法访问!
看着比较复杂
物理结构修改工具 pt-online-schema-change
作者:彼岸舞
时间:2020\07\07
内容关于:Mysql
本文来源于网络,只做技术分享,一概不负任何责任