mysqldump备份7

http://www.cnblogs.com/ivictor/p/5505307.html

对于MySQL的备份,可分为以下两种:

1. 冷备

2. 热备

其中,冷备,顾名思义,就是将数据库关掉,利用操作系统命令拷贝数据库相关文件。而热备指的是在线热备,即在不关闭数据库的情况下,对数据库进行备份。实际生产中基本上都是后者。

关于热备,也可分为两种方式:

1. 逻辑备份

2. 物理备份

对于前者,常用的工具是MySQL自带的mysqldump,对于后者,常用的工具是Percona提供的XtraBackup。

对于规模比较小,业务并不繁忙的数据库,一般都是选择mysqldump。

那么,mysqldump的备份原理是什么呢?

抛开源码不谈,其实我们可以通过打开general log,查看mysqldump全库备份时执行的命令来了解mysqldump背后的原理。

打开general log

mysql> set global general_log=on;

其中,general log的存放路径可通过以下命令查看

mysql> show variables like ‘%general_log_file%‘;

执行全库备份

# mysqldump --master-data=2  -R --single-transaction -A -phello > 3306_20160518.sql

其中

--master-data指定为2指的是会在备份文件中生成CHANGE MASTER的注释。具体在本例中,指的是

-- CHANGE MASTER TO MASTER_LOG_FILE=‘mysql2-bin.000049‘, MASTER_LOG_POS=587;

如果该值设置为1,则生成的是CHANGE MASTER的命令,而不是注释。

-R 备份存储过程与函数

--single-transaction 获取InnoDB表的一致性备份。

-A 相当于--all-databases。

下面来看看general log中的内容

160518 11:00:59    14 Connect   [email protected] on
                   14 Query     /*!40100 SET @@SQL_MODE=‘‘ */
                   14 Query     /*!40103 SET TIME_ZONE=‘+00:00‘ */
                   14 Query     FLUSH /*!40101 LOCAL */ TABLES
                   14 Query     FLUSH TABLES WITH READ LOCK
                   14 Query     SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
                   14 Query     START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
                   14 Query     SHOW VARIABLES LIKE ‘gtid\_mode‘
                   14 Query     SHOW MASTER STATUS
                   14 Query     UNLOCK TABLES
                   14 Query     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
                   14 Query     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
                   14 Query     SHOW DATABASES
                   14 Query     SHOW VARIABLES LIKE ‘ndbinfo\_version‘

其中,比较重要的有以下几点:

1. FLUSH /*!40101 LOCAL */ TABLES

Closes all open tables, forces all tables in use to be closed, and flushes the query cache.

2. FLUSH TABLES WITH READ LOCK

执行flush tables操作,并加一个全局读锁,很多童鞋可能会好奇,这两个命令貌似是重复的,为什么不在第一次执行flush tables操作的时候加上锁了,其实,这样做的原因在于可以尽量减少加锁的影响。

加上全局读锁,只允许读,不允许更新操作。

3. SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

设置当前会话的事务隔离等级为RR,RR可避免不可重复读和幻读。

4. START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */

获取当前数据库的快照,这个是由mysqldump中--single-transaction决定的。

这个只适用于支持事务的表,在MySQL中,只有Innodb。

注意:START TRANSACTION和START TRANSACTION WITH CONSISTENT SNAPSHOT并不一样,

START TRANSACTION WITH CONSISTENT SNAPSHOT是开启事务的一致性快照。

RC下的START TRANSACTION WITH CONSISTENT SNAPSHOT相当于RR下的START TRANSACTION。

不明白事务的童鞋可能觉得这点会比较绕,其实所谓的不可重复读和幻读可简单理解为,在同一个事务内,两次SELECT的结果并不相同。

之所以要使用START TRANSACTION WITH CONSISTENT SNAPSHOT,因为每个表的备份时间并不相同,这就要求在对第一张表进行备份的期间,对第二个表进行的操作,并不会反映到第二张表开始备份时执行的SELECT操作中。(注:mysqldump备份的底层实现即是select * from tab)。而这用START TRANSACTION就无法实现。

5.  SHOW MASTER STATUS

这个是由--master-data决定的,记录了开始备份时,binlog的状态信息,包括MASTER_LOG_FILE和MASTER_LOG_POS

6.  UNLOCK TABLES

释放锁。

因为我的数据库中只有以下四个库

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.03 sec)

备份的时候可以发现只备份了mysql和test,并没有备份information_schema和performance_schema。

下面来看看备份mysql和test的日志输出信息,

因日志输出信息太多,在这里,只选择test库的日志信息。test库中一共有两张表test和test1。

                   14 Init DB   test
                   14 Query     SHOW CREATE DATABASE IF NOT EXISTS `test`
                   14 Query     SAVEPOINT sp
                   14 Query     show tables

                   14 Query     show table status like ‘test‘
                   14 Query     SET SQL_QUOTE_SHOW_CREATE=1
                   14 Query     SET SESSION character_set_results = ‘binary‘
                   14 Query     show create table `test`
                   14 Query     SET SESSION character_set_results = ‘utf8‘
                   14 Query     show fields from `test`
                   14 Query     SELECT /*!40001 SQL_NO_CACHE */ * FROM `test`
                   14 Query     SET SESSION character_set_results = ‘binary‘

                   14 Query     use `test`
                   14 Query     select @@collation_database
                   14 Query     SHOW TRIGGERS LIKE ‘test‘
                   14 Query     SET SESSION character_set_results = ‘utf8‘
                   14 Query     ROLLBACK TO SAVEPOINT sp

                   14 Query     show table status like ‘test1‘
                   14 Query     SET SQL_QUOTE_SHOW_CREATE=1
                   14 Query     SET SESSION character_set_results = ‘binary‘
                   14 Query     show create table `test1`
                   14 Query     SET SESSION character_set_results = ‘utf8‘
                   14 Query     show fields from `test1`
                   14 Query     SELECT /*!40001 SQL_NO_CACHE */ * FROM `test1`
                   14 Query     SET SESSION character_set_results = ‘binary‘

                   14 Query     use `test`
                   14 Query     select @@collation_database
                   14 Query     SHOW TRIGGERS LIKE ‘test1‘
                   14 Query     SET SESSION character_set_results = ‘utf8‘
                   14 Query     ROLLBACK TO SAVEPOINT sp

                   14 Query     RELEASE SAVEPOINT sp

                   14 Query     use `test`
                   14 Query     select @@collation_database
                   14 Query     SET SESSION character_set_results = ‘binary‘
                   14 Query     SHOW FUNCTION STATUS WHERE Db = ‘test‘
                   14 Query     SHOW CREATE FUNCTION `mycat_seq_currval`
                   14 Query     SHOW PROCEDURE STATUS WHERE Db = ‘test‘
                   14 Query     SET SESSION character_set_results = ‘utf8‘
                   14 Quit

从上述输出可以看出:

1. 备份的核心是SELECT /*!40001 SQL_NO_CACHE */ * FROM `test1`语句。

该语句会查询到表test1的所有数据,在备份文件中会生成相应的insert语句。

其中SQL_NO_CACHE的作用是查询的结果并不会缓存到查询缓存中。

2. SHOW CREATE DATABASE IF NOT EXISTS `test`,show create table `test1`

生成创库语句和创表语句。

3. SHOW TRIGGERS LIKE ‘test1‘

可以看出,如果不加-R参数,默认是会备份触发器的。

4. SHOW FUNCTION STATUS WHERE Db = ‘test‘

SHOW CREATE FUNCTION `mycat_seq_currval`

SHOW PROCEDURE STATUS WHERE Db = ‘test‘

用于备份存储过程和函数。

5. 设置SAVEPOINT,然后备份完每个表后再回滚到该SAVEPOINT。

不知道为什么要这么设置,感觉这样完全没必要,

因为前面通过START TRANSACTION WITH CONSISTENT SNAPSHOT开启的事务只能通过commit或者rollback来结束,而不是ROLLBACK TO SAVEPOINT sp。

PS:这样做不会阻塞在备份期间对已经备份表的ddl操作,具体可见下面的“后续补充”第三点。

总结:

1. mysqldump的本质是通过select * from tab来获取表的数据的。

2. START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */必须放到FLUSH TABLES WITH READ LOCK和UNLOCK TABLES之间,放到之前会造成START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */和FLUSH TABLES WITH READ LOCK之间执行的DML语句丢失,放到之后,会造成从库重复插入数据。

3. mysqldump只适合放到业务低峰期做,如果备份的过程中数据操作很频繁,会造成Undo表空间越来越大,undo表空间默认是放到共享表空间中的,而ibdata的特性是一旦增大,就不会收缩。

4. mysqldump的效率还是比较低下,START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */只能等到所有表备份完后才结束,其实效率比较高的做法是备份完一张表就提交一次,这样可尽快释放Undo表空间快照占用的空间。但这样做,就无法实现对所有表的一致性备份。

参考:

http://tencentdba.com/blog/mysqldump-backup-principle/

后续补充:

最近翻了下源码,msyqldump对应的是client/mysqldump.c。里面的注释还是有一定的参考意义,一并附上。

1. 关于FLUSH TABLE和FLUSH TABLES WITH READ LOCK的

  /*
    We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
    will wait but will not stall the whole mysqld, and when the long update is
    done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
    FLUSH TABLES is to lower the probability of a stage where both mysqldump
    and most client connections are stalled. Of course, if a second long
    update starts between the two FLUSHes, we have that bad stall.
  */

2. 为什么备份结束时没有执行commit操作

  /*
    No reason to explicitely COMMIT the transaction, neither to explicitely
    UNLOCK TABLES: these will be automatically be done by the server when we
    disconnect now. Saves some code here, some network trips, adds nothing to
    server.
  */

3. 关于ROLLBACK TO SAVEPOINT的

/**
      ROLLBACK TO SAVEPOINT in --single-transaction mode to release metadata
      lock on table which was already dumped. This allows to avoid blocking
      concurrent DDL on this table without sacrificing correctness, as we
      won‘t access table second time and dumps created by --single-transaction
      mode have validity point at the start of transaction anyway.
      Note that this doesn‘t make --single-transaction mode with concurrent
      DDL safe in general case. It just improves situation for people for whom
      it might be working.
    */

上面的意思是不阻塞并发的DDL操作。

下面具体来测试一下:

第一种情况:

会话1发起事务,并查询test表的值,然后会话2进行添加列操作,该操作被hang住。

第二种情况:

会话1发起事务,然后会话2进行添加列操作,发现该操作成功。

第三种情况:

模仿mysqldump的备份原理,设置断点。

注意,DDL操作发起的时间是在执行了select * from test之后,如果是在之前,根据上面第二种情况的测试,是可以进行DDL操作的。

此时,如果不执行ROLLBACK TO SAVEPOINT sp,DDL操作会一直hang下去,执行了该操作后,DDL操作可以继续执行了。

由此可见,ROLLBACK TO SAVEPOINT确实可以提高DDL的并发性。

但还有一点需要注意,如果DDL操作是发生在select * from test之前,正如第二种情况所演示的,DDL操作会成功,此时,查看test表的数据会报以下错误:

[email protected] 04:32:49 > select * from test;
ERROR 1412 (HY000): Table definition has changed, please retry transaction

对应mysqldump,会报如下错误:

mysqldump: Error 1412: Table definition has changed, please retry transaction when dumping table `test` at row: 0

时间: 2024-12-18 20:03:50

mysqldump备份7的相关文章

解决mysqldump备份报错: Couldn't execute 'SHOW FIELDS FROM Unknown error 1356

服务器环境: [[email protected] mysql]# cat /etc/redhat-releaseCentOS Linux release 7.3.1611 (Core) [[email protected] mysql]# uname -aLinux localhost.localdomain 3.10.0-514.21.1.el7.x86_64 #1 SMP Thu May 25 17:04:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

mysqldump备份结合binlog日志恢复

http://hongge.blog.51cto.com/ MySQL备份一般采取全库备份加日志备份的方式,例如每天执行一次全备份,每小时执行一次二进制日志备份.这样在MySQL故障后可以使用全备份和日志备份将数据恢复到最后一个二进制日志备份前的任意位置或时间. 1.binlog介绍 mysql的二进制日志记录着该数据库的所有增删改的操作日志(前提是要在自己的服务器上开启binlog),还包括了这些操作的执行时间.为了显示这些二进制内容,我们可以使用mysqlbinlog命令来查看. Binlo

mysql之 mysqldump 备份恢复详解

mysqldump 程序的实现原理是通过我们给的参数信息加上数据库中的系统表信息来一个表一个表获取数据然后生成 INSERT 语句再写入备份文件中的.这样就出现了一个问题,在系统正常运行过程中,很可能会不断有数据变更的请求正在执行,这样就可能造成在 mysqldump 备份出来的数据不一致.也就是说备份数据很可能不是同一个时间点的数据,而且甚至可能都没办法满足完整性约束.这样的备份集对于有些系统来说可能并没有太大问题,但是对于有些对数据的一致性和完整性要求比较严格系统来说问题就大了,就是一个完全

mysql之mysqldump备份恢复

mysql数据备份,其重要性不言而喻.大体上我们比较常用到的有mysqldump.Xtrabackup和用lvm快照来备份,或者是有专门的mysql复制备份服务器. 特性: 逻辑备份工具,比物理备份速度慢,但更灵活,可以修改一些信息,而且跨平台也简单. 如果数据量大于1G最好还是用物理备份. 单线程的备份工具,网上有一个多线程逻辑备份工具,叫做mysqldumper,有兴趣的朋友可以看看. 可以实现Innodb存储引擎的热备或MyISAM.Aria的温备. 自身不能实现增量或是差异备份,如果备份

mysqldump备份大数据出错

mysqldump备份大数据出错技术 maybe yes 发表于2015-01-26 22:58 原文链接 : http://blog.lmlphp.com/archives/72  来自 : LMLPHP后院 网 站的数据会定期备份,现在数据大了,mysqldump 方法估计是不行了,并且失败了以后并不能接着上次的位置开始备份.报错内容:mysqldump: Error 2013: Lost connection to MySQL server during query when dumpin

mysqldump备份和恢复Mysql数据库

简单介绍: 通过mysqldump命令可以将指定的库和表全部导出为sql脚本,可以在不同版块的Mysql上面使用.例如需要升级Mysql数据库可以使用mysqldump先备份所有数据库,然后直接在升级后的Mysql数据库导入即可. 基本操作:备份单个数据库,或者库中的特定表(库名后面加表名)mysqldump备份jiaowu库[[email protected] ~]# mysqldump -uroot -p jiaowu > /root/jiaowu.sql删除jiaowu的数据库mysql>

使用mysqldump备份数据库时报Got error: 2013错误

mysqldump备份数据库是一种比较简单及方便的方法,但它也消耗一定量的内存.可话又说回来了,数据库的哪个工作不消耗内存,若不消耗内存就能完成管理的DBA那不是DBA那是神--大神.说了一些找抬扛的话,若你找跟我扛那就不必了,你赢了.呵呵!咱们言归正传啊. 今天用mysqldump工具做数据库备份时,报出这样一个错误:"Got error: 2013: Lost connection to MySQL server during query when using lock tables&quo

mysqldump备份中恢复单张表

⒈mysqldump备份中导出单张表很多时候我们需要从mysqldump备份文件中恢复出一张表,通常的做法可能是先把sql 文件恢复到一个测试数据库,然后再使用mysqldump导出一张表,再恢复到生产环境,这样,如果数据量不大这方法是可行的,但是你依然需要有一个测试机器或者临时创建一个库,不是很方便,可以利用awk/sed解决相关问题:①在原数据库中使用show tables;②利用sed或者awk,将数据导入文件中(注意表之间的排序)# awk '/^-- Table structure f

mysql使用mysqldump备份、恢复

  mysqldump是mysql用于转存储数据库的实用程序.它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等 mysqldump 语法 :      默认配置读取路径:  /etc/mysql/my.cnf     /etc/my.cnf    ~/.my.cnf            Usage: mysqldump [OPTIONS] database [tables]           OR     mysqldump [OPTI