因为在可重复读的隔离级别下 , 即使其他事务更新了表的数据 , 也不会影响备份数据库时的 Read View , 这就是事务四大特性中的隔离性 , 这样备份期间备份的数据一直是在开启事务时的数据 。
备份数据库的工具是 mysqldump , 在使用 mysqldump 时加上 –single-transaction
参数的时候 , 就会在备份数据库之前先开启事务 。这种方法只适用于支持「可重复读隔离级别的事务」的存储引擎 。
InnoDB 存储引擎默认的事务隔离级别正是可重复读 , 因此可以采用这种方式来备份数据库 。
但是 , 对于 MyISAM 这种不支持事务的引擎 , 在备份数据库时就要使用全局锁的方法 。
表级锁
MySQL 表级锁有哪些?具体怎么用的 。MySQL 里面表级别的锁有这几种:
- 表锁;
- 元数据锁(MDL);
- 意向锁;
- AUTO-INC 锁;
如果我们想对学生表(t_student)加表锁 , 可以使用下面的命令:
//表级别的共享锁 , 也就是读锁;lock tables t_student read;//表级别的独占锁 , 也就是写锁;lock tables t_stuent write;
需要注意的是 , 表锁除了会限制别的线程的读写外 , 也会限制本线程接下来的读写操作 。也就是说如果本线程对学生表加了「共享表锁」 , 那么本线程接下来如果要对学生表执行写操作的语句 , 是会被阻塞的 , 当然其他线程对学生表进行写操作时也会被阻塞 , 直到锁被释放 。
要释放表锁 , 可以使用下面这条命令 , 会释放当前会话的所有表锁:
unlock tables
另外 , 当会话退出后 , 也会释放所有表锁 。不过尽量避免在使用 InnoDB 引擎的表使用表锁 , 因为表锁的颗粒度太大 , 会影响并发性能 , InnoDB 牛逼的地方在于实现了颗粒度更细的行级锁 。
元数据锁再来说说元数据锁(MDL) 。
我们不需要显示的使用 MDL , 因为当我们对数据库表进行操作时 , 会自动给这个表加上 MDL:
- 对一张表进行 CRUD 操作时 , 加的是 MDL 读锁;
- 对一张表做结构变更操作的时候 , 加的是 MDL 写锁;
当有线程在执行 select 语句( 加 MDL 读锁)的期间 , 如果有其他线程要更改该表的结构( 申请 MDL 写锁) , 那么将会被阻塞 , 直到执行完 select 语句( 释放 MDL 读锁) 。
反之 , 当有线程对表结构进行变更( 加 MDL 写锁)的期间 , 如果有其他线程执行了 CRUD 操作( 申请 MDL 读锁) , 那么就会被阻塞 , 直到表结构变更完成( 释放 MDL 写锁) 。
MDL 不需要显示调用 , 那它是在什么时候释放的?MDL 是在事务提交后才会释放 , 这意味着事务执行期间 , MDL 是一直持有的 。
那如果数据库有一个长事务(所谓的长事务 , 就是开启了事务 , 但是一直还没提交) , 那在对表结构做变更操作的时候 , 可能会发生意想不到的事情 , 比如下面这个顺序的场景:
- 首先 , 线程 A 先启用了事务(但是一直不提交) , 然后执行一条 select 语句 , 此时就先对该表加上 MDL 读锁;
经验总结扩展阅读
- SpringCloud整合分布式事务Seata 1.4.1 支持微服务全局异常拦截
- vivoy52s竖屏锁定在哪里 vivoy52s竖屏怎么锁定
- 苹果账户锁定怎么解锁 怎么解锁苹果id账户
- llinux下mysql建库、新建用户、用户授权、修改用户密码
- 别惹农夫小炎子皮肤怎么解锁
- RedHat7.6安装mysql8步骤
- 别惹农夫药尊者皮肤怎么解锁
- 国内经济型连锁酒店有哪些 中国十大经济型连锁酒店品牌排行榜
- 再有人说synchronized是重量级锁,就把这篇文章扔给他看
- 究极无敌细节版 Mysql索引