暂无图片
暂无图片
暂无图片
暂无图片
暂无图片
mysql锁机制 学习笔记 行锁表锁定位
229
10页
3次
2022-09-23
免费下载
https://zhuanlan.zhihu.com/p/75595737
1 MySQL 的三种锁
1.1 表锁
开销小,加锁快
不会出现死锁
锁定粒度大,发生锁冲突的概率最高,并发度最低
1.2 行锁
开销大,加锁慢
会出现死锁
锁定粒度小,发生锁冲突的概率最低,并发度最高
1.3 页锁
开销和加锁时间介于表锁和行锁之间
会出现死锁
锁定粒度介于表锁和行锁之间,并发度一般
1.4 引擎与锁
MyISAM MEMORY 支持表锁
BDB 支持页锁,也支持表锁
Innodb 既支持行锁,也支持表锁,默认行锁
1.5 查询表锁争用情况
检查 table_locks_waited table_locks_immediate 状态变量分析
table_locks_immediate : 可以立即获取锁的次数
table_locks_waited : 不能立即获取锁,需要等待锁的次数
mysql> show status like '%table%';
+-----------------------------------------+---------+
| Variable_name | Value |
+-----------------------------------------+---------+
| Com_alter_table | 0 |
| Com_alter_tablespace | 0 |
| Com_create_table | 0 |
| Com_drop_table | 0 |
| Com_lock_tables | 0 |
| Com_rename_table | 0 |
| Com_show_create_table | 0 |
| Com_show_open_tables | 0 |
| Com_show_table_status | 0 |
| Com_show_tables | 0 |
| Com_unlock_tables | 0 |
| Created_tmp_disk_tables | 0 |
| Created_tmp_tables | 0 |
| Innodb_undo_tablespaces_total | 2 |
| Innodb_undo_tablespaces_implicit | 2 |
| Innodb_undo_tablespaces_explicit | 0 |
| Innodb_undo_tablespaces_active | 2 |
| Open_table_definitions | 617 |
| Open_tables | 5860 |
| Opened_table_definitions | 0 |
| Opened_tables | 0 |
| Performance_schema_table_handles_lost | 0 |
| Performance_schema_table_instances_lost | 0 |
| Performance_schema_table_lock_stat_lost | 0 |
| Replica_open_temp_tables | 0 |
| Slave_open_temp_tables | 0 |
| Table_locks_immediate | 4099671 |
| Table_locks_waited | 0 |
| Table_open_cache_hits | 0 |
| Table_open_cache_misses | 0 |
| Table_open_cache_overflows | 0 |
+-----------------------------------------+---------+
31 rows in set (3.13 sec)
table_locks_waited 的值越高,则说明存在严重的表级锁的争用情况
2 表锁模式(MyISAM)
ySQL 的表锁有两种模式
表共享读锁(Table Read Lock
表独占写锁(Table Write Lock
2.1 表锁兼容性
锁模式的兼容如下表
| 是否兼容 | 请求 none | 请求读锁 | 请求写锁 |
|:----|:----|:----|:----|
| 当前处于读锁 | | | |
| 当前处于写锁 | | | |
可见,对M yISAM 表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;
对M yISAM 表的写操作,则会阻塞其他用户对同一表的读和写请求;
yISAM 表的读和写操作之间,以及写和写操作之间是串行的!(当某一线程获得对一个表的写锁后,只有持有
锁的线程可以对表进行更新操作.其他线程的读、写操作都会等待,直到锁被释放为止)
2.2 如何加表锁
对于 MyISAM 引擎
执行 select ,会自动给涉及的所有表加 读
执行更新(update,delete,insert)会自动给涉及到的表加 写
不需要用户直接显式用 lock table 命令
对于给 MyISAM 显式加锁,一般是为了在一定程度上模拟事务操作,实现对某一个时间点多个表一致性读取
2.2.1 实例
订单表 - orders 记录各订单的总金额 total
订单明细表 - order_detail 记录各订单每一产品的金额小计 subtotal
假设我们需要检查这两个表的金额合计是否相符,可能就需要执行如下两条 SQL
这时,如果不先给这两个表加锁,就可能产生错误的结果;
因为第一条语句执行过程中,order_detail 表可能已经发生了改变.
因此,正确写法应该如下
2.2.2 注意点
上面的例子在 LOCK TABLES 时加了‘local’选项,其作用就是在满足 MyISAM 表并发插入条件的情况下,允
许其他用户在表尾插入记录
在用 LOCK TABLES 给表显式加表锁时,必须同时取得所有涉及表的锁,并且 MySQL 支持锁升级; 也就是说,
在执行 LOCK TABLES 后,只能访问显式加锁的这些表,不能访问未加锁的表; 同时,如果加的是读锁,那
么只能执行查询操作,而不能执行更新操作 其实,在自动加锁的情况下也基本如此,MySQL 会一次获得 SQL
语句所需要的全部锁.这也正是 MyISAM 表不会出现死锁(Deadlock Free)的原因
| session1 | session2 |
|:----|:----|
| 获得表 film_text 的读锁 lock table film_text read; | | | select * from
film_text | select * from film_text |
| 不能查询没有锁定的表 :select * from film | 可查询/更新未锁定的表: select * from film
|
| 插入或更新锁定表会提示错误 update...from film_text | 更新锁定表会等待 update...from
film_text |
| 释放锁 unlock tables | 等待 | | | 获得锁,更新成功 |
2.3 tips
当使用 lock tables ,不仅需要一次锁定用到的所有表
且同一表在 SQL 语句中出现多少次,就要通过与 SQL 语句中别名锁多少次
lock table actor read
会提示错误
select a.first_name.....
需要对别名分别锁定
lock table actor as a read,actor as b read;
3 MyISAM 的并发锁
在一定条件下,MyISAM 也支持并发插入和读取
3.1 系统变量 : concurrent_insert
其并发插入的行为,其值分别可以为
0 不允许并发插入,所有插入对表加互斥
1 只要表中无空洞,就允许并发插入. MyISAM 允许在一个读表的同时,一个进程表尾插入记录(MySQL
的默认设)
2 无论 MyISAM 表中有无空洞,强制在表尾并发插入记录 若无读线程,新行插入空洞
可以 MyISAM 的并发插入性,来解决应用中对同表查询和插入的锁争用
例如, concurrent_insert 系统变量设为 2,总是允许并发插入;
同时,通过定在系统空闲执行 OPTIONMIZE TABLE 语句来整理空碎片到因删除记录而产生的中
空洞
删除操作不会重整整个表,只是记为删除,在表中空洞
MyISAM 倾向于在可能时满这些空洞,插入时就会重用这些,无空洞新行插到表尾
3.2 MyISAM 的锁
MyISAM 的读和写锁互斥,读操作串行的
一个进程请求某个 MyISAM 表的读锁,同时一个进程也请求同表的写锁,MySQL 如何处理呢? 写进程先获得
!!! 不仅如此,即使读进程先请求先到锁等待队列,写请求后到,写锁也会插到读请求之前!!!
这是因为 MySQL 认为写请求一般读请求重要
这也正是 MyISAM 表不合有大量更新 / 查询操作应用的原因
大量的更新操作会成查询操作很难获得读锁,而可能永远阻塞
幸好,我们可以通过一些设置来调节 MyISAM 度行为
low-priority-updates 使 MyISAM 引擎默认给读请求以权利
执行命令 SET LOW_PRIORITY_UPDATES=1 使该接发出的更新请求先级
INSERTUPDATEDELETE 语句的 LOW_PRIORITY 低该语句的先级
虽然上面 3 法都是要么更新先,要么查询先,但是可以用其来解决查询相对重要的应用(如用户
录系统)中,读锁等待严重的问
另外MySQL 也提了一种中的来调节读写冲突;
即给系统 max_write_lock_count 一个合的值;
当一个表的读锁到这个值后,MySQL 便暂写请求的先级低,给读进程一定获得锁的
of 10
免费下载
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文档的来源(墨天轮),文档链接,文档作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。