第28天SQL进阶-查询优化- performance_schema系列实战三:锁问题排查(行级锁)(SQL 小虚竹)
Posted 小虚竹
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第28天SQL进阶-查询优化- performance_schema系列实战三:锁问题排查(行级锁)(SQL 小虚竹)相关的知识,希望对你有一定的参考价值。
回城传送–》《32天SQL筑基》
文章目录
零、前言
今天是学习 SQL 打卡的第 28 天,每天我会提供一篇文章供群成员阅读( 不需要订阅付钱 )。
希望大家先自己思考,如果实在没有想法,再看下面的解题思路,自己再实现一遍。在小虚竹JAVA社区 中对应的 【打卡贴】打卡,今天的任务就算完成了,养成每天学习打卡的好习惯。
虚竹哥会组织大家一起学习同一篇文章,所以有什么问题都可以在群里问,群里的小伙伴可以迅速地帮到你,一个人可以走得很快,一群人可以走得很远,有一起学习交流的战友,是多么幸运的事情。
我的学习策略很简单,题海策略+ 费曼学习法。如果能把这些题都认认真真自己实现一遍,那意味着 SQL 已经筑基成功了。后面的进阶学习,可以继续跟着我,一起走向架构师之路。
今天的学习内容是:SQL进阶-查询优化- performance_schema系列实战二:锁问题排查(行级锁)
一、什么是行级锁
行级锁是mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。
其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。
特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
二、什么时候适合加行级锁
行级锁适用于高并发环境下,对事务完整性要求较高的系统,如在线事务处理系统。
三、实战演练
通过一个示例演示如何找出谁持有行级锁。
3.1 数据准备(如果已有数据可跳过此操作)
使用sysbench准备初始化数据
创建测试数据库sysbenchdemo
create database sysbenchdemo;
准备测试数据:
sysbench /usr/share/sysbench/oltp_insert.lua \\
--mysql-host=localhost \\
--mysql-port=3306 \\
--mysql-socket=/tmp/mysql.sock \\
--mysql-user=root \\
--mysql-password=xiaoxuzhu \\
--mysql-db=sysbenchdemo \\
--db-driver=mysql \\
--tables=8 \\
--table-size=100000 \\
--time=180 prepare
3.2 开启第一个会话,显式开启一个事务
登录mysql数据库
use sysbenchdemo;
开启一个事务
begin;
执行update修改语句
update sbtest1 set pad='xxx' where id=1;
3.3 开启第二个会话,查询 performance_schema 库的data_locks表
登录mysql数据库
use performance_schema;
select * from data_locks;
从图上的结果可知:
第1行是对表sbtest1的表级锁,是IX锁;状态为GRANTED。
第2行是对表sbtest1的行记录锁,是行锁。状态为GRANTED 。
3.4 开启第三个会话,模拟两个DML锁等待
登录mysql数据库
use sysbenchdemo;
开启一个事务
begin;
执行update修改语句
update sbtest1 set pad='xxx' where id=1;
发现update语句被阻塞了。
3.5 返回第二个会话,查看data_locks表
select * from data_locks;
从图上结果来看,data_locks表中新增了线程ID为12608的两条锁记录。对表sbtest1的表级锁,是IX锁;状态为GRANTED。
和对表sbtest1的行记录锁,是行锁。状态为WAITING ,说明正在等待被授予。
可以使用sys.innodb_lock_waits视图查看锁等待信息。
select * from sys.innodb_lock_waits;
字段说明:
- wait_started:发生锁等待的开始时间
- wait_age:锁已经等待了多久了,是一个时间格式的值
- wait_age_secs:锁已经等待了** s,是一个整型的数值,此字段是mysql5.7.9版本中新增
- locked_table:锁等待的表名称
- locked_index:锁等待的索引名称
- locked_type:锁等待的类型
- waiting_trx_id:锁等待的事务id
- waiting_trx_started:锁等待的开始时间
- waiting_trx_age:发生锁等待的事务的总的等待时间
- waiting_trx_rows_locked:发生锁等待事务已经锁定的行数(如果是复杂的事务会累计)
- waiting_trx_rows_modified:发生锁等待事务已经修改的行数(如果是复杂的事务会累计)
- waiting_pid:发生锁等待事务的processlist id 号
- waiting_query:发生锁等待事务的sql语句文本
- waiting_lock_id:发生锁等待的锁id
- waiting_lock_mode:发生锁等待的锁模式
- blocking_trx_id:持有锁的事务id
- blocking_pid:持有锁的事务的processlist id号
- blocking_query:持有锁的事务的sql文本
- blocking_lock_id:持有锁的锁id
- blocking_lock_mode:持有锁的锁模式
- blocking_trx_started:持有锁的事务的开始时间
- blocking_trx_age:持有锁的事务需要修改的行数
- sql_kill_blocking_query:执行KILL 语句来杀死持有锁的查询语句(而不是终止会话)此字段MySQL5.7.9新增
- sql_kill_blocking_connection:执行KILL 语句来来终止持有锁的语句的会话,此字段MySQL5.7.9新增
四、总结
通过本文学习,学会了什么是行级锁以及行级锁的适用场景,通过实战演练排查行级锁问题,从理论到实战的介绍,可以加深对行级锁的理解。
五、参考
应用示例荟萃 | performance_schema全方位介绍(中)
技术分享 | MySQL 的 MDL 锁解惑
SQL进阶-查询优化- performance_schema系列三:事件记录(SQL 小虚竹)
我是虚竹哥,我们明天见~
以上是关于第28天SQL进阶-查询优化- performance_schema系列实战三:锁问题排查(行级锁)(SQL 小虚竹)的主要内容,如果未能解决你的问题,请参考以下文章
第17天SQL进阶-查询优化- SHOW STATUS(SQL 小虚竹)
第17天SQL进阶-查询优化- SHOW STATUS(SQL 小虚竹)
第16天SQL进阶-查询优化一定要学EXPALIN (SQL 小虚竹)