首页 > 其他分享 >极客--全局锁和表锁、行锁

极客--全局锁和表锁、行锁

时间:2022-09-19 20:37:13浏览次数:57  
标签:事务 极客 MDL 行锁 -- 更新 死锁 线程 表锁

根据加锁的范围,Mysql里面的锁大致可以分成全局锁、表级锁和行锁

全局锁

  • Flush tables with read lock。当你需要整个库处于只读状态的时候,可以使用这个命令,之后其他线程以下语句会被阻塞;数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。

  • 全局锁的典型使用场景,做全库逻辑备份:官方自带的逻辑备份工具是 mysqldump。当 mysqldump 使用参数–single-transaction 的时候,导数据之前就会启动一个事务,来确保拿到一致性视图。而由于 MVCC 的支持,这个过程中数据是可以正常更新的。

  • 一致性读是好,但前提是引擎要支持这个隔离级别,single-transaction方法只适用于所有表使用事务引擎的库,set global readonly=true的方式也会让库进入只读状态

  • 有些系统中,readonly的值会被用来做其他逻辑,比如判断库是主库还是从库

  • 异常机制下有差异,如果执行FTWRL命令之后由于客户端发生异常断开,那么Mysql会自动释放这个全局锁,整个库回到正常更新状态。而将整个库设置为readonlu之后,由于客户端发生异常,则数据库一直保持readonlu状态,这样导致整个库长时间处于不可写状态

  • 业务的更新不只是增删改数据(DML),还有可能是加字段等修改表结构的操作(DDL)。

表级锁

Mysql表级锁分为两种:一种表锁,一种元数据锁

  • 表锁的语法是lock tables ...read/write。lock tables语法除了会限制别的线程的读写外,也限定了本线程接下来的操作对象。

  • 还没有更细粒度的锁的时候,表锁是最常用处理并发的方式,而对于Innodb这种行锁引擎,一般不使用lock tables命令来控制并发,毕竟锁住整个表的影响面还是太大

  • 另一种表级锁是MDL,MDL不需要显示使用,在访问一个表的时候,会自动加上。MDL的作用保证读写正确性,增删改查的时候MDL加读锁,当要对标结构变更的时候,加MDL写锁

    • 读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。
    • 读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。因此,如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。
  • 如果某个表查询语句频繁,而且客户端重试机制,也就是说超时会再起一个新的session请求的话,这个库线程很快就会满,事务MDL锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而是等整个事务提交后释放

  • 一个变更热点表,虽然数据量不大,但是上面请求很频繁,而你不得不加个字段

  • alter tabel设定等待时间,如果在这个时间里面拿到MDL写锁最好,拿不到阻塞后面的业务语句,先放弃。之后开发人员或者DBA重复这个过程

  • MDL会直到事务提交才提交释放,在表结构变更的时候,你一定要小心不要导致锁住线上查询和更新

  • Online DDL过程是这样

    1. 拿MDL写锁
    2. 降级MDL读锁
    3. 真正做DDL
    4. 升级MDL写锁
    5. 释放MDL锁

行锁

  • Innodb支持行锁
  • 行锁就是针对数据表行记录的锁,比如事务A更新一行,而这时候事务B也要更新同一行,必须等A更新完B才能更新
从两阶段锁说起
  • 在Innodb事务,行锁是需要的时候加上,但不是不需要了立刻释放,而是等到事务结束时才释放,这个就是两阶段锁协议

死锁与死锁检测

  • 当并发系统不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源,就会导致这几个线程进入无线等待的状态--死锁
    image
  • 第一个策略出现死锁后,超过50s才能超时退出,但是超时时间设置太短,会出现误伤
  • 主动死锁检测,而且innodb_deadlock_detect的默认值发现并进行处理,但也是有额外负担
  • 假设有 1000 个并发线程要同时更新同一行,那么死锁检测操作就是 100 万这个量级的。虽然最终检测的结果是没有死锁,但是这期间要消耗大量的 CPU 资源。因此,你就会看到 CPU 利用率很高,但是每秒却执行不了几个事务。
怎么解决热点行更新导致性能问题?
  • 一种头痛医头的方法,就是如果你能确保这个业务一定不会出现死锁,可以临时把死锁检测关掉
  • 另一种思路是控制并发度,根据上面的分析,同一行时只有10个线程更新,那么死锁的检测成本很低,就不会出现这种问题,减少死锁的主要方向,就是控制相同资源的并发事务量

标签:事务,极客,MDL,行锁,--,更新,死锁,线程,表锁
From: https://www.cnblogs.com/dodogod/p/16706656.html

相关文章

  • 实验1:SDN拓扑实践
    实验1:SDN拓扑实践使用Mininet可视化工具,生成下图所示的拓扑,并保存拓扑文件名为学号.py。使用Mininet的命令行生成如下拓扑:a)3台交换机,每个交换机连接1台主机,3台交换......
  • Markdown语法
    Markdown学习标题一级标题:#+空格+标题名称回车二级标题:##+空格+标题名称回车三级标题:###+空格+标题名称回车四级标题:####+空格+标题名称回车快捷键:C......
  • DataInputStream,DataOutputStream
    packagecom.gao.IO;importjava.io.*;publicclassTest09{publicstaticvoidmain(String[]args)throwsIOException{//DataOutputStream:将内存......
  • Selenium测试时富文本编辑区输入方法
    用Selenium+python编写自动测试脚本,因为页面中内容编辑使用ckEditor富文本编辑,不知道如何输入内容。方法一:执行JS脚本,ckEditor编辑区内容输入成功,校验提示内容为空通过上......
  • 集群分发脚本
    在root用户下的bin目录下创建xsync文件vimxsync在文件中编写如下代码#!/bin/bash#1获取输入参数个数,如果没有参数,直接退出pcount=$#if((pcount==0));thenecho......
  • 笔记本电脑(ThinkPad E480)安装Ubuntu18.04系统 | 笔记本电脑安装双系统 Windows + Ubu
    1、制作系统U盘由于之前做好了启动盘,之后有机会在做详细说明。参考文章2、安装Ubuntu系统联想(ThinkPadE480)按是开机后图标转圈时然后按F1进入BIOS:选择StartUp==>Bo......
  • foobar2000 v1.6.12 汉化版
    foobar2000v1.6.12汉化版-----------------------【软件截图】----------------------    -----------------------【软件介绍】----------------------fooba......
  • Hadoop遇到的问题总结
    Xshell使用的时候,使用右侧数字键盘时数字的时候,数字变成英文字母了。  解决方法:解决办法:点击文件-属性(快捷键alt+P)然后在VT模式中的数字键盘模式修改......
  • 将秒数转换为时间格式(12小时制,如果小时数大于23,则转换成天数)(分支结构嵌套/双分支结构)
    #include<stdio.h>main(){inta,d=0;scanf("%d",&a);while(a>86399){a=a-86400;d++;if(a<86399){......
  • python+ mplfinance实现全功能动态交互式K线图
    在网上找的资料,但没有数据,于是根据代码自己造了一些,发现跑起来太卡了,放弃#coding=utf-8#inter_candle.pyimportpandasaspdimportnumpyasnpimportmatplotli......