1、single-transaction
官方解释如下:
--single-transaction:
Creates a consistent snapshot by dumping all tables in a single transaction. Works ONLY for tables stored in storage engines which support multiversioning (currently only InnoDB does); the dump is NOT guaranteed to be consistent for other storage engines. While a --single-transaction dump is in process, to ensure avalid dump file (correct table contents and binary log position), no other connection should use the following statements:ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not isolated from them. Option automatically turns off --lock-tables.
由上面加粗的黑体字可以看到几个关键信息:
(1)可以在一个事务里对全部表获取一个一致性快照这里保证了可以在此时获得此一时刻的一致性数据;
(2)只对有版本控制的存储引擎,目前为止是只有innodb有这个功能同样大众的myisam引擎使用不了;
(3)在这个过程中,alter、drop、rename和truncate是无法隔离的,即不能使用额表操作
(4)自动关闭 --lock-tables 选项
我们打开mysql的general-log,来查看 mysqldump --single-transaction -B test >t.log到底发生了什么,查看general-log,如下:
(1) SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
(2)START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
(3)UNLOCK TABLES
第一行是使当前session的事务级别为可重复读;
第二行是开始一个事务并且获得一个一致性快照,其实这个时候就是对当前所有表的数据进行了一个保存,其实这里应该使用了MVCC多版本控制,这就是为什么只有innodb才有的功能;
第三行是释放锁,这也解释了为什么说使用mysqldump不会锁表(因为第二行已经取得了快照,不需要锁表了)。
2、master-data
master-data主要是为了记录binlog的log和pos,用于之后基于时间点的恢复,所以非常重要。
同样执行mysqldump --master-data=2 -B test >t.log
(1)FLUSH TABLES
(2)FLUSH TABLES WITH READ LOCK
(3)SHOW MASTER STATUS
第一行flush tables To execute FLUSH, you must have the RELOAD privilege.
执行flush,需要reload权限
Closes all open tables, forces all tables in use to be closed, and flushes the query cache. FLUSH TABLES also removes all query results from the query cache, like the RESET QUERY CACHE statement
关闭打开的表,清除query-cache里的缓存!一句话:使所有表回写到db;
第二行FLUSH TABLES WITH READ LOCKCloses all open tables and locks all tables for all databases with a global read lock until you explicitly release the lock by executing UNLOCK TABLES. This is a very convenient way to get backups if you have a file system such as Veritas or ZFS that can take snapshots in time.
对所有表获得一个全局的读锁,并且直到你显式地“UNLOCK TABLES”才会释放锁;
第三行无非是是记录下当前的binlog的log和pos。3、从上面第二个例子可以看到没有出现出现unlock tables,因为没有 single-transaction,所以,是会锁表的!所以一般以上两个参数是会一起使用的:
mysqldump --single-transaction --master-data=2
(1)FLUSH TABLES
(2)FLUSH TABLES WITH READ LOCK
(3)SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
(4)START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
(5)SHOW MASTER STATUS
(6)UNLOCK TABLES
又上面六行可知,既保证不会锁表的情况下获得一致性快照、又可以精确地记下binlog位置!
可以总结上面的问题是:
当在执行“mysqldump –single-transaction –master-data”之前,如果有一个很长时间的查询(select)没有结束,那么“mysqldump –single-transaction –master-data”里的FLUSH TABLES WITH READ LOCK将会一直等待前一个查询结束才会执行,而更加严重的是,在没有执行完FLUSH TABLES WITH READ LOCK之前,其他的所有update、delete等更改操作都将会被阻塞!
以上的结论很恐怖,比如一不小心写了个很烂的每名中索引的全表扫描,执行了一晚上都没跑完,而凌晨的备份也将阻塞,同样也导致了数据无法写入和更改,这其实也就等同于整个系统已经瘫痪了!
参考:
http://www.mysqlperformanceblog.com/2010/04/24/how-fast-is-flush-tables-with-read-lock/
http://dev.mysql.com/doc/refman/5.0/en/flush.html
http://linuxcommand.org/man_pages/mysqldump1.html
实例:如下是导出的文件中记录的日志文件的起始位置,在复制后改为主备复制需要用到此日志文件的信息及其位置
-- MySQL dump 10.13 Distrib 5.1.61, for redhat-linux-gnu (x86_64)
--
-- Host: localhost Database: fnbl_core
-- ------------------------------------------------------
-- Server version 5.5.24-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.002799', MASTER_LOG_POS=91553713;