扩展:锁优化---全局锁介绍及案例分析

全局锁 Global Read lock
a. 介绍
全局读锁。
加锁方法: FTWRL,flush tables with read lock. (flush tables:把当前系统当中已经打开的表关掉)
表关掉之后,加上锁,阻塞所有事务的提交commit
解锁方法: unlock tables;

FTWRL出现场景:
mysqldump --master-data
xtrabackup(8.0之前早期版本)等备份时。
8.0之后:
属于类型: MDL(matedatalock)层面锁
影响情况: 加锁期间,阻塞所有事务写入,阻塞所有已有事务commit。
MDL,等待时间受 lock_wait_timeout=31536000

场景: 业务反馈所有写入做不了.查询的相关
mysql> show processlist;
mysql> select * from performance_schema.metadata_locks\G
mysql> select * from sys.schema_table_lock_waits;

一个经典故障:5.7 xtrabackup/mysqldump备份时数据库出现hang状态,所有修改查询都不能进行

session1: 模拟一个大的查询或事务
mysql> select id,sleep(100)  from city where id<100  for update ;

session2: 模拟备份时的FTWRL 
mysql> flush tables with read lock;
-- 此时发现命令被阻塞

session3: 发起查询,发现被阻塞
mysql> select * from world.city where id=500 for update;

解决问题的步骤:   

1.查看进程的详细信息
show processlist;

2.查看MDL锁信息
select * from performance_schema.metadata_locks\G

查看  PENDING 被阻塞    GRANTED 阻塞者的owner_therad_ID号
penging:   61 63 64   
GRANTED:   62

3.# 通过SQL线程号找到 SQL语句,分析语句是谁堵塞了谁
select * from performance_schema.events_statements_history;(历史上运行的)   

select * from performance_schema.events_statements_current;(正在运行的)
PENDING:
61:SQL_TEXT: flush tables with read lock
63:SQL_TEXT: select * from world.city where id=1 for update
64:SQL_TEXT: insert into student values(1,'asan')
GRANTED:
62:SQL_TEXT: select id,sleep(100)  from city where id<100  for update(模拟执行了个大事务)

4.查看源头GRANTED:62能不能停(通过therad_ID找到processlist_Id)   找到是哪个用户或人员相连接做的操作,对相关人员询问

mysql>select * from performance_schema.threads where thread_id=62\G
             THREAD_ID: 62
               NAME: thread/sql/one_connection
               TYPE: FOREGROUND
     PROCESSLIST_ID: 22
   PROCESSLIST_USER: root
   PROCESSLIST_HOST: localhost
     PROCESSLIST_DB: world
PROCESSLIST_COMMAND: Query
   PROCESSLIST_TIME: 2130
  PROCESSLIST_STATE: User sleep
   PROCESSLIST_INFO: select id,sleep(100)  from city where id<100  for update
   PARENT_THREAD_ID: NULL
               ROLE: NULL
       INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: Socket
       THREAD_OS_ID: 3098
     RESOURCE_GROUP: USR_default
1 row in set (0.00 sec)

5.如果要立即解决问题,让项目跑起来,通过找到备份(THREAD_ID为61)的连接线程PROCESSLIST_ID为21
mysql> select * from performance_schema.threads where thread_id=61\G
*************************** 1. row ***************************
          THREAD_ID: 61
               NAME: thread/sql/one_connection
               TYPE: FOREGROUND
     PROCESSLIST_ID: 21
   PROCESSLIST_USER: root
   PROCESSLIST_HOST: localhost
     PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Query
   PROCESSLIST_TIME: 2581
  PROCESSLIST_STATE: Waiting for global read lock
   PROCESSLIST_INFO: flush tables with read lock
   PARENT_THREAD_ID: 1
               ROLE: NULL
       INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: Socket
       THREAD_OS_ID: 6362
     RESOURCE_GROUP: USR_default
1 row in set (0.00 sec)

6.杀掉进程21

结论: 备份时,一定要选择业务不繁忙期间,否则有可能会阻塞正常业务。

案例2: 
5.7版本  innobackupex备份全库,进程死了,mysql里就是全库读锁,后边insert 全阻塞了
解决步骤和案例1类似

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值