设为首页 加入收藏

TOP

MySQL 命令行工具之 mysqldump 深入研究(三)
2015-11-12 21:29:16 来源: 作者: 【 】 浏览:15
Tags:MySQL 命令 工具 mysqldump 深入 研究
ump 的备份是如何实现的,我们需要在 my.cnf 中的[mysqld] 参数段加入:


这样我们就可以通过观察 general.log 的输出,来了解 mysqldump 的备份是如何实现的。


1)--lock-tables 是如何实现的:


先执行:mysqldump -uroot -p --databases gs --lock-tables > gs_l.sql, 然后查看 general.log:


1> 第一步: SHOW CREATE DATABASE IF NOT EXISTS `gs`; 导出了建库语句;


2> 第二步:show tables; 获得数据库中所有表名,然后锁住:LOCK TABLES `tb1` READ /*!32311 LOCAL */,`user` READ /*!32311 LOCAL */


? ? ? ? ? ? ? ? 使用的是 lock table tb1 read local, tb2 read local, tb3 read local; 语句


3> 第三步:show create table 'tb1'; 导出了 tb1 的建表语句;


4> 第四步:show fields from `tb1`; SELECT /*!40001 SQL_NO_CACHE */ * FROM `tb1`; 导出了表中的数据;


......


5> 最后导出了 trigger, 最后的最后 unlock tables; 结束。


可以看到 --lock-tables 在导出一个数据库时,会在整个导出过程 lock read local 所有的表。该锁不会阻止其它session读和插入


2)--lock-all-tables 的实现:


先执行:mysqldump -uroot -p --databases gs --lock-all-tables > gs_l.sql, 在查看 general.log:


它的实现使用了 FLUSH TABLES; FLUSH TABLES WITH READ LOCK; 语句。在最后没有看到解锁语句。


它请求发起一个全局的读锁,会阻止对所有表的写入操作,以此来确保数据的一致性。备份完成后,该会话断开,会自动解锁。


3)--single-transaction 的实现:


先执行:?mysqldump -uroot -p --databases gs --single-transaction > gs_l.sql,在查看 general.log:


基本过程是:


1> 先改变事务隔离级别:SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ


2> 开始事务:START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */


3> unlock tables;


4> 导出建库语句; SHOW CREATE DATABASE IF NOT EXISTS `gs`


5> 打开一个 savepoint: SAVEPOINT sp;


6> 导出 表 tb1 的结构和数据;


7> ROLLBACK TO SAVEPOINT sp; 回滚到savepoint;


对其它表重复该过程;


8> 最后 realease savepoint p; 释放savepoint;


整个过程,没有任何锁。RR隔离级别保证在事务中只读取本事务之前的一致性的数据。 rollback to savepoint sp; 保证了对数据库中的数据没有影响。


4)--master-data 的实现:


先执行:mysqldump -uroot -p --databases gs --master-data=1 > gs_l.sql,在查看general.log:


发现了 --lock-all-tables一样,就多了一句:show master status;


5)--single-transaction 和 --master-data 结合使用:


先执行:mysqldump -uroot -p --databases gs --master-data=1 > gs_l.sql,在查看general.log:


发现 --single-transaction 单独使用 与 --single-transaction 和 --master-data 结合使用 的区别如下图:



--single-transaction 和 --master-data 结合使用时,在导出开始,会短暂的持有一个全局的读锁,锁定时:刷新数据到磁盘、设置隔离级别为RR、开始事务、输出 binary log 的位置和文件名,然后解锁。这样就保证了:show master status 输出的 binary log 的位置和文件名 和 后面 导出的数据是同一个时间点的(同一个lsn),所以才能使用该备份 和 利用 change master to 构造一个 slave,成功的连接上 master.


可以看到这里使用了两次 flush tables:


FLUSH /*! 40101 LOCAL */ TABLES


FLUSH TABLES WITH READ LOCK


其原因是 第一次 flush 是不需要锁表的,第一次将所有数据刷新到磁盘之后,第二次 FLUSH TABLES WITH READ LOCK 时就会只有很少量的数据需要刷新到磁盘,所以第一次 flush 是为了尽量的 减少 第二次? fush 持有锁的时间


11. mysqldump 与 锁


1)--lock-tables 会在整个导出过程 lock read local 所有的表。该锁不会阻止其它session读和插入,但是显然阻塞了update。


2)--lock-all-tables 它请求发起一个全局的读锁,会阻止对所有表的写入操作(insert,update,delete),以此来确保数据的一致性。备份完成后,该会话断开,会自动解锁。


?


3)--single-transaction 和 --master-data 结合使用时,也是在开始时,会短暂的请求一个全局的读锁,会阻止对所有表的写入操作。


4)--single-transaction 单独使用,不会有任何锁。但是测试表明: 它也需要对备份的表持有 metadata lock 的共享锁


而我们知道,一般的事务,持有的是 行锁,还有 metadata lock 的共享锁。所以实际上,mysqldump不论你使用哪些选项,都不会阻塞事务的执行。


因为它们对锁的申请,没有任何排它性。而不像DDL一样需要持有 metadata lock 上的独占锁(排它锁)。当然DDL也会阻塞mysqldump。


mysqldump 一定需要表上的 metadata lock 共享锁。然后,要么需要所有备份表上的local读锁(lock table tb1 read local),要么需要的是所有备份表上的全局读锁(FLUSH TABLES WITH READ LOCK;)。


首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇数据处理之PostgreSQL过程语言学习 下一篇mysqldump 逻辑备份的正确方法

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: