【转】mysqldump原理探究
作者:胡儿胡儿
来源:CSDN
原文:https://blog.csdn.net/cug_jiang126com/article/details/49824471
————————————————————————————————————————————
在mysqldump过程中,之前其实一直不是很理解为什么加了--single-transaction就能保证innodb的数据是完全一致的,而myisam引擎无法保证,必须加--lock-all-tables,前段时间抽空详细地查看了整个mysqldump过程。
理解master-data和--dump-slave
--master-data=2表示在dump过程中记录主库的binlog和pos点,并在dump文件中注释掉这一行;
--master-data=1表示在dump过程中记录主库的binlog和pos点,并在dump文件中不注释掉这一行,即恢复时会执行;
--dump-slave=2表示在dump过程中,在从库dump,mysqldump进程也要在从库执行,记录当时主库的binlog和pos点,并在dump文件中注释掉这一行;
--dump-slave=1表示在dump过程中,在从库dump,mysqldump进程也要在从库执行,记录当时主库的binlog和pos点,并在dump文件中不注释掉这一行;
注意:在从库上执行备份时,即--dump-slave=2,这时整个dump过程都是stop io_thread的状态
深入理解--single-transaction:
打开general_log,准备一个数据量较小的db,开启备份,添加--single-transaction和--master-data=2参数,查看general_log,信息如下,每一步添加了我的理解
整个dump过程是同一个连接id 32,这样能保证在设置session级别的变量的时候不影响到其他连接
thread_id: 32
argument: ucloudbackup@localhost on
*************************** 14. row ***************************
thread_id: 32
argument: /*!40100 SET @@SQL_MODE='' */
*************************** 15. row ***************************
thread_id: 32
argument: /*!40103 SET TIME_ZONE='+00:00' */
*************************** 16. row ***************************
thread_id: 32
argument: FLUSH /*!40101 LOCAL */ TABLES
*************************** 17. row ***************************
thread_id: 32
argument: FLUSH TABLES WITH READ LOCK
批注:因为开启了--master-data=2,这时就需要flush tables with read lock锁住全库,记录当时的master_log_file和master_log_pos点
*************************** 18. row ***************************
thread_id: 32
argument: SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
批注:--single-transaction参数的作用,设置事务的隔离级别为可重复读,即REPEATABLE READ,这样能保证在一个事务中所有相同的查询读取到同样的数据,也就大概保证了在dump期间,如果其他innodb引擎的线程修改了表的数据并提交,对该dump线程的数据并无影响,然而这个还不够,还需要看下一条
*************************** 19. row ***************************
thread_id: 32
argument: START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
这时开启一个事务,并且设置WITH CONSISTENT SNAPSHOT为快照级别(如果mysql版本高于某一个版本值,我还不大清楚40100代表什么版本)。想象一下,如果只是可重复读,那么在事务开始时还没dump数据时,这时其他线程修改并提交了数据,那么这时第一次查询得到的结果是其他线程提交后的结果,而WITH CONSISTENT SNAPSHOT能够保证在事务开启的时候,第一次查询的结果就是事务开始时的数据A,即使这时其他线程将其数据修改为B,查的结果依然是A,具体的测试看我下面的测试结果
*************************** 20. row ***************************
thread_id: 32
argument: SHOW MASTER STATUS
这时候执行这个命令来记录当时的master_log_file和master_log_pos点,注意为什么这个时候记录,而不是再18 row和19 row之间就记录,个人认为应该都是可以的,这里是测试结果,start transaction并不会产生binlog的移动,而18 row和19 row的动作也在同一个thread id中
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 1690 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
*************************** 21. row ***************************
thread_id: 32
argument: UNLOCK TABLES
等记录完成后,就立即释放了,因为现在已经在一个事务中了,其他线程再修改数据已经无所谓,在本线程中已经是可重复读,这也是这一步必须在19 rows之后的原因,如果20 rows和21 rows都在19 rows之前的话就不行了,因为这时事务还没开启,一旦释放,其他线程立即就可以更改数据,从而无法保证得到事务开启时最准确的pos点。*************************** 22. row ***************************
thread_id: 32
argument: SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IN (SELECT DISTINCT LOGFILE_GROUP_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME IN ('user'))) GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE ORDER BY LOGFILE_GROUP_NAME
*************************** 23. row ***************************
thread_id: 32
argument: SELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME, EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='mysql' AND TABLE_NAME IN ('user')) ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME
*************************** 24. row ***************************
thread_id: 32
argument: mysql
*************************** 25. row ***************************
thread_id: 32
argument: SHOW TABLES LIKE 'user'
*************************** 26. row ***************************
thread_id: 32
argument: show table status like 'user'
dump表以前都需要show一下各自信息,确保表,视图等不损坏,可用,每一步错了mysqldump都会报错并中断,给出对应的错误码,常见的myqldump错误请参考我的另外一篇blog http://blog.csdn.net/cug_jiang126com/article/details/49359699
*************************** 27. row ***************************
thread_id: 32
argument: SET OPTION SQL_QUOTE_SHOW_CREATE=1
*************************** 28. row ***************************
thread_id: 32
argument: SET SESSION character_set_results = 'binary'
*************************** 29. row ***************************
thread_id: 32
argument: show create table `user`
*************************** 30. row ***************************
thread_id: 32
argument: SET SESSION character_set_results = 'utf8'
*************************** 31. row ***************************
thread_id: 32
argument: show fields from `user`
*************************** 32. row ***************************
thread_id: 32
argument: SELECT /*!40001 SQL_NO_CACHE */ * FROM `user`
这就是我们show processlist时看到的信息,而数据是怎么通过一条select语句就dump到本地文件里的呢,并且还转成成相应的create和insert语句,这就是mysqldump这个客户端工具的工作了,这里不做讨论
*************************** 33. row ***************************
最后并没有看到commit,因为在整个事务中,其实并没有修改任何数据,只是为了保证可重复读得到备份时间点一致性的快照,dump完成后提交不提交应该无所谓了。
myisam引擎为什么无法保证在--single-transaction下得到一致性的备份?
因为它压根就不支持事务,自然就无法实现上述的过程,虽然添加了--single-transaction参数的myisam表处理过程和上面的完全一致,但是因为不支持事务,在整个dump过程中无法保证可重复读,无法得到一致性的备份。而innodb在备份过程中,虽然其他线程也在写数据,但是dump出来的数据能保证是备份开始时那个binlog pos的数据。
myisam引擎要保证得到一致性的数据的话,他是如何实现的呢?
它是通过添加--lock-all-tables,这样在flush tables with read lock后,直到整个dump过程结束,断开线程后才会unlock tables释放锁(没必要主动发unlock tables指令),整个dump过程其他线程不可写,从而保证数据的一致性
如果我一定要在mysiam引擎中也添加--single-transaction参数,再用这个备份去创建从库或恢复到指定时间点,会有什么样的影响?
我个人的理解是如果整个dump过程中只有简单的insert操作,是没有关系的,期间肯定会有很多的主键重复错误,直接跳过或忽略就好了。如果是update操作,那就要出问题了,分几种情况考虑
1) 如果是基于时间点的恢复,假设整个dump过程有update a set id=5 where id=4之类的操作,相当于重复执行两次该操作,应该问题不大
2) 如果是创建从库,遇到上面的sql从库会报错,找不到该记录,这时跳过就好
3)不管是恢复还是创建从库,如果dump过程中有update a set id=id+5 之类的操作,那就有问题,重复执行两次,数据全变了。
深入理解--lock-all-tables
打开general_log,准备一个数据量较小的db,开启备份,添加--lock-all-tables(其实也是默认设置)和--master-data=2参数,查看general_log,信息如下,理解--lock-all-tables怎么保证数据一致性
mysql> select thread_id,argument from general_log where thread_id=185\G
*************************** 1. row ***************************
thread_id: 185
argument: ucloudbackup@10.10.108.15 on
*************************** 2. row ***************************
thread_id: 185
argument: /*!40100 SET @@SQL_MODE='' */
*************************** 3. row ***************************
thread_id: 185
argument: /*!40103 SET TIME_ZONE='+00:00' */
*************************** 4. row ***************************
thread_id: 185
argument: FLUSH /*!40101 LOCAL */ TABLES
*************************** 5. row ***************************
thread_id: 185
argument: FLUSH TABLES WITH READ LOCK
这里flush tables with read lock之后就不会主动unlock tables,保证整个dump过程整个db数据不可更改,也没有事务的概念了
*************************** 6. row ***************************
thread_id: 185
argument: SHOW MASTER STATUS
同样记录主库的位置
*************************** 7. row ***************************
thread_id: 185
argument: SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE ORDER BY LOGFILE_GROUP_NAME
*************************** 8. row ***************************
thread_id: 185
argument: SELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME, EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME
*************************** 9. row ***************************
thread_id: 185
argument: SHOW DATABASES
*************************** 10. row ***************************
thread_id: 185
argument: jjj
*************************** 11. row ***************************
thread_id: 185
argument: SHOW CREATE DATABASE IF NOT EXISTS `jjj`
测试可重复读和快照读(WITH CONSISTENT SNAPSHOT )
准备工作3.1(测试可重读)
session 1:
mysql> select * from xx;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
mysql> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Query OK, 0 rows affected (0.00 sec)
设置事务隔离级别为可重复读
mysql> START TRANSACTION ;
Query OK, 0 rows affected (0.00 sec)
我们先不开快照读观察现象
session 2:
mysql> insert into xx values (5);
Query OK, 1 row affected (0.00 sec)
session 1:
mysql> select * from xx;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+------+
5 rows in set (0.00 sec)
批注:这时因为没有设置快照读,所以当session 2有数据更新时,可查到该数据,接
下来我们继续在session 2 插入数据
session 2:
mysql> insert into xx values (6);
Query OK, 1 row affected (0.00 sec)
这时再观察session 1的数据
session 1
mysql> select * from xx;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+------+
5 rows in set (0.00 sec)
查询发现还是只有5条,表示可重复实现了。
准备工作3.2(测试快照读)
session 1
mysql> select * from xx;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Query OK, 0 rows affected (0.00 sec)
mysql> START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */;
Query OK, 0 rows affected (0.00 sec)
这时我们在session 2插入数据
session 2:
mysql> insert into xx values (2);
Query OK, 1 row affected (0.00 sec)
这时我们再观察session 1的结果
session 1:
mysql> select * from xx;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
发现还是只有一条数据,证明实现了快照读
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from xx;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
事务1 提交后方可看见第二条记录
---------------------
作者:胡儿胡儿
来源:CSDN
原文:https://blog.csdn.net/cug_jiang126com/article/details/49824471
版权声明:本文为博主原创文章,转载请附上博文链接!
【转】mysqldump原理探究的更多相关文章
- [原] KVM 虚拟化原理探究(1)— overview
KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...
- [原] KVM 虚拟化原理探究 —— 目录
KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...
- [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化
KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...
- [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化
KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...
- [原] KVM 虚拟化原理探究(4)— 内存虚拟化
KVM 虚拟化原理探究(4)- 内存虚拟化 标签(空格分隔): KVM 内存虚拟化简介 前一章介绍了CPU虚拟化的内容,这一章介绍一下KVM的内存虚拟化原理.可以说内存是除了CPU外最重要的组件,Gu ...
- [原] KVM 虚拟化原理探究(3)— CPU 虚拟化
KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
- 弱类型变量原理探究(转载 http://www.csdn.net/article/2014-09-15/2821685-exploring-of-the-php)
N首页> 云计算 [问底]王帅:深入PHP内核(一)——弱类型变量原理探究 发表于2014-09-19 09:00| 13055次阅读| 来源CSDN| 36 条评论| 作者王帅 问底PHP王帅 ...
- js事件底层原理探究
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
随机推荐
- 超级大佬已提前布局AI域名,人工智能时代真的来临了?
近日,郭盛华公司巨资收购的ai域名引起了业界深度关注,ai人工智能行业想必大家都熟悉不会陌生,但是ai域名你知道吗?了解域名行业的米友,对于ai域名肯定都熟悉,为什么今天小编要突然提到ai域名?因为a ...
- ps制作雾的效果
制作雾的效果 方法一: 新建图层,将前景色设置为白色,背景色为黑色(因为雾的颜色是根据前景色决定的,也可根据这个原理制作火焰效果) 选择滤镜->渲染->云彩(也可选择其他效果的云彩) (选 ...
- java面向对象4-多态
5 多态 5.1多态:polymorphism概念 定义:某一类事物的多种存在形态表现形式:父类变量指向子类实例 例:动物中猫,狗 猫这个对象对应的类型是猫类型 猫 x = new 猫(); 同时猫也 ...
- Oracal数据库安装配置教程
官网注册账号登录 https://www.oracle.com/technetwork/database/enterprise-edition/downloads/oracle12c-windows- ...
- python接口自动化一(发送get请求)
一.环境安装 1.用pip安装requests模块 >>pip install requests 二.get请求 1.导入requests后,用get方法就能直接访问url地址,如:htt ...
- 选择vim编辑器的7个理由
当我刚刚开始用 vi 文本编辑器的时候,我讨厌它!我认为这是有史以来设计上最痛苦和反人类的编辑器.但我还是决定我必须学会它,因为如果你使用的是 Unix,vi 无处不在并且是唯一一个保证你可以使用的编 ...
- jQery Datatables回调函数中文
Datatables——回调函数 ------------------------------------------------- fnCookieCallback:还没有使用过 $(documen ...
- UVa 11235 Frequent values (RMQ && 区间出现最多次的数的次数)
题意 : 给出一个长度为 n 的不降序序列,并且给出 q 个形如(L, R)的问询,问你这个区间出现的最多次的数的次数. 分析 : 很自然的想到将区间“缩小”,例如1 1 2 3 3 3就可以变成2 ...
- UVa 572 Oil Deposits (Floodfill && DFS)
题意 :输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块.如果两个字符“@”所在的格子相邻(横竖以及对角方向),就是说它们属于同一个八连块. 分析 :可以考虑种子填充深搜的方法.两重for循 ...
- idea启动或install时报错:There are test failures,如何跳过测试?
用idea install项目时失败,报这样的错: [INFO] BUILD FAILURE [INFO] --------------------------------------------- ...