首页 > 数据库 > MySQL > 正文

史上最具体MySQL全局锁和表锁

2024-07-24 12:32:06
字体:
来源:转载
供稿:网友
      根据加锁的范围,MySQL里面的锁大致可以分成全局锁,表级锁,行锁。本文主要讲述MySQL全局锁和表锁。
  
1. 全局锁
 
      全局锁就是对整个数据库实例加锁。MySQL 提供了一个加全局读锁的方法,命令是Flush tables with read lock (FTWRL)。
 
1.1 全局锁使用场景
  
     全局锁的典型使用场景是,做全库逻辑备份(mysqldump)。重新做主从时候
     也就是把整库每个表都 select 出来存成文本。
      以前有一种做法,是通过 FTWRL 确保不会有其他线程对数据库做更新,然后对整个库做备份。注意,在备份过程中整个库完全处于只读状态。
 
1.2 不加锁产生的问题
 
比如手机卡,购买套餐信息
 
这里分为两张表 u_acount (用于余额表),u_pricing (资费套餐表)
步骤:
1. u_account 表中数据 用户A 余额:300
    u_pricing 表中数据 用户A 套餐:空
2. 发起备份,备份过程中先备份u_account表,备份完了这个表,这个时候u_account 用户余额是300
3. 这个时候套用户购买了一个资费套餐100,餐购买完成,写入到u_print套餐表购买成功,备份期间的数据。
4. 备份完成
 
可以看到备份的结果是,u_account 表中的数据没有变, u_pricing 表中的数据 已近购买了资费套餐100.
 
1.3 为什么需要全局读锁(FTWRL)
  
可能有的人在疑惑,官方自带的逻辑备份工具是 mysqldump。当 mysqldump 使用参数--single-transaction的时候,导数据之前就会启动一个事务,来确保拿到一致性快照视图。而由于 MVCC 的支持,这个过程中数据是可以正常更新的。
 
1.4 全局锁两种方法
 
一、FLUSH TABLES WRITE READ LOCK
二、set global readonly=true
  
既然要全库只读,为什么不使用 set global readonly=true 的方式呢?确实 readonly 方式也可以让全库进入只读状态,但我还是会建议你用 FTWRL 方式,主要有几个原因:
 
一是,在有些系统中,readonly 的值会被用来做其他逻辑,比如用来判断一个库是主库还是备库。因此,修改 global 变量的方式影响面更大,我不建议你使用。
 
二是,在异常处理机制上有差异。如果执行FTWRL 命令之后由于客户端发生异常断开,那么 MySQL 会自动释放这个全局锁,整个库回到可以正常更新的状态。而将整个库设置为 readonly 之后,如果客户端发生异常,则数据库就会一直保持 readonly 状态,这样会导致整个库长时间处于不可写状态,风险较高。
 
三是,readonly 对super用户权限无效
 
注 :业务的更新不只是增删改数据(DML),还有可能是加字段等修改表结构的操作(DDL)。不论是哪种方法,一个库被全局锁上以后,你要对里面任何一个表做加字段操作,都是会被锁住的。

(编辑:武林网)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表