理解master-data和–dump-slave
深入理解–single-transaction:
整个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下得到一致性的备份?
myisam引擎要保证得到一致性的数据的话,他是如何实现的呢?
如果我一定要在mysiam引擎中也添加–single-transaction参数,再用这个备份去创建从库或恢复到指定时间点,会有什么样的影响?
3)不管是恢复还是创建从库,如果dump过程中有update a set id=id+5 之类的操作,那就有问题,重复执行两次,数据全变了。
深入理解–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`