从RDS(兼容MySQL) 导出数据案例分析

作者:丁奇 

背景

MySQL全量逻辑备份恢复最基础的方法,就是mysqldump生成文本,再通过source 命令直接导入。一般用于实例迁移或者版本升级。

这里说明最近碰到的一个失败例子。

描述

这个例子可以简要复现如下,在源库上执行如下操作:

use mydb;

create table t1 (id int);

create view v1 as select * from t1;

drop table t1;

之后执行 mysqldump mydb,发现mysqldump中途退出。简化后出错原因很明显,就是视图v1对应的表t1已经不存在,这个视图本身非法。

这个错误很危险,因为如果没有捕获这个错误,直接认为mysqldump执行完成,并将生成的结果应用于目标库,则会导致数据丢失!

其实这个问题并不像看起来那么简单。

一个问题

mysqldump只需要生成show create view v1的结果即可—-这会导致在目标库source的时候报错—-为什么会在dump的时候就报错?

MySQL Tips: mysqldump导出整库,默认情况下,会在导出前对整库里面的每个表加读锁,即Lock tables tb1 read, tb2 read,…, tbn read.

​本例中由于视图v1需要的实体表t1已经不存在,lock table v1 read 返回失败。因此整个库所有表都没有正常导出。如果以此输出结果导入到目标库,则整库数据丢失。

MySQL Tips: mysqldump若正常结束,生成的文件结果最后一行是“– Dump completed on + 时间”。

​使用dump的结果文件必须先检查结果文件的完整性,判断末行的文本是一个推荐操作。

导整库的时候为什么需要对所有表都加读锁呢?目的是为了得到一致性读视图。也就是说,在导出整库期间,不会有更新,这样才保证导出数据的一致性。

而实际上这个是历史遗留问题,InnoDB本身支持一致性读,也就是说只要启动一个事务(begin/start transaction),则在此事务存续期间,对于本实例内InnoDB表的更新,此导出事务均不可见。也就是说InnoDB事务可以保证事务期间看到的视图与事务启动瞬间看到的一致。

而锁表会堵住更新,导库又往往是长时间的操作,因此备份期间能允许读写对OLTP应用来说至关重要。

MySQL Tips: 若确保mysqldump导出的数据中只有InnoDB表,可以用 –single-transaction 避免锁表。

问题继续

加了–single-transaction后不需要锁表,是否还会导致mysqldump失败?答案依然是会。这次我们发现输出的错误是 “SHOW FIELDS FROM v1″ 失败。由于show fields v1需要解析视图并列出执行结果的列信息,而表t1已经不存在因此报错。

问题是,为什么需要执行一个 SHOW FIELDS?

这就说到restore的依赖问题。

MySQL Tips: mysqldump生成导出文件时。同一个库内实体表先生成,之后是视图。多个实体表是按照字母升序生成,多个视图也是按字母升序生成。

这样就可能存在这样的情况,某个视图v1依赖视图v2,而v1的字母排序前于v2。比如视图名为x,而依赖的另一个视图名为y。这样在按顺序输出的时候,如果不做任何处理,在输出文件中就会先出现create view x …而由于x依赖于y但y还没有生成,就会导致restore阶段执行失败。

MySQL Tips: mysqldump解决视图依赖问题的方法,就是在生成实体表阶段,如果碰到视图,则创建一个同名的临时实体表,该表的结果与视图完全相同。

配合的策略是在生成真正的视图前,先将临时实体表删除。这样在restore阶段,创建任何视图V1前,它所依赖的视图V2有两种情况:

1) 字母排序V2 > V1,则当前库中有一个名为V2的临时实体表,这样视图V1能够正常创建;

2) 字母排序V2 < V1,则此时视图V2已经存在,这样视图V1能够正常创建;

以上策略解决了视图循环依赖的问题,这个机制需要早生成实体表阶段得到视图执行结果的列名,因此需要执行一个 SHOW FIELDS。

实践建议

上面的分析说明了”为什么”,以下操作型的读者希望的实践建议:

1) 为避免无效视图影响导出,可以在调用mysqldump时增加–force参数,强行忽略此错误。这个忽略不会对数据造成影响;

2) 使用–result-file参数保存mysqldump结果,同时将所有控制台收到的返回都作为报警返回给调用端;

3) 检查 result-file的最后一行,若无“Dump completed on”字样,则返回严重错误,终止备份恢复流程。

 

时间: 2025-01-21 09:37:25

从RDS(兼容MySQL) 导出数据案例分析的相关文章

sqoop2:从mysql导出数据到hdfs

sqoop2:从mysql导出数据到hdfs中 sqoop-shell 启动sqoopp-shell jjzhu:bin didi$ sqoop2-shell Setting conf dir: /opt/sqoop-1.99.7/bin/../conf Sqoop home directory: /opt/sqoop-1.99.7 Sqoop Shell: Type 'help' or '\h' for help. sqoop:000> set server --host localhost

Mysql导出数据的正确方法_Mysql

之前折磨了很久,想在Mysql命令行下导出数据库,但就是每天提示不那个错误,后来才知道其实mysqldump不是mysql命令,因此不能在Mysql命令行下导出. 下面是错误的做法: . 下面才是正确的做法: 即:mysql导出数据库命令只能在系统命令行下使用,而不能在mysql命令行下使用.

MySQL运维案例分析:Binlog中的时间戳

背景 众所周知,在Binlog文件中,经常会看到关于事件的时间属性,出现的方式都是如下这样的. #161213 10:11:35 server id 11766 end_log_pos 263690453 CRC32 0xbee3aaf5 Xid = 83631678 我们清楚地知道,161213 10:11:35表示的就是时间值,但除此之外呢?还能知道它的什么信息呢? 案例分析 先从一个典型的案例入手来讲述其中的细节,比如曾经在Galera Cluster碰到的一个问题,可以先看一段Binlo

java从mysql导出数据的具体实例_java

复制代码 代码如下: import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement; import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.FileReader;import java.io.IOExce

mysql导出数据错误-求大拿帮忙啊,MySql select导出的问题

问题描述 求大拿帮忙啊,MySql select导出的问题 小弟刚学编程,碰见的问题,求大神解答一下啊. 在Mysql用select查询导出的时候用下面的语句 mysql -hlocalhost -uroot -pzonvan select * from broadcast_members into outfile "ljf-1.txt"; 正确内容是这样的: [root@localhost ~]# cat ljf-3.txt id broadcast_id called_retrie

MySQL 导出数据为csv格式的方法_Mysql

方案有很多种,我这里简单说一下: 1.  into outfile 复制代码 代码如下: SELECT * FROM mytable   INTO OUTFILE '/tmp/mytable.csv'   FIELDS TERMINATED BY ','   OPTIONALLY ENCLOSED BY '"'   LINES TERMINATED BY '\n';   在我使用过程中发现一个特别严重问题,这里面不能插入查询条件,比如where这些,也就是说只能整表导出,不知道是不是我的写法有问

MySQL锁实际案例分析(一)

案例来源: ITPUB论坛,原帖地址 http://www.itpub.net/thread-2055372-1-1.html --------------------------------------------------------------------------正文-------------------------------------------------------------------------- 数据库隔离级别RR 表结构及数据如下图: 作者的疑问1:总是提示有黑客

云计算安全的奥秘:云数据案例分析 原文出自

您企业的数据存储是在哪里的?让我们来关注一下这方面的细节问题吧. 关于云计算的困惑 对于一般的大众而言,云计算仍然是一个谜一般神秘的东西.据Citrix在2012年八月进行的一项调研显示:"有51%的受访者,甚至包括大多数的千禧一代,居然相信风暴天气会影响云计算." 该项调研还发现,"大多数美国人(54%)声称自己从来没有使用云计算.然而,实际上这些受访者中有95%的人其实已经使用过云计算服务."这项调研还采访了受访者们如何使用网上银行.购物.社交网络.在线游戏和照

Mysql导出数据表结构

$sql = "show create table category";$res = mysql_query($sql) or die(mysql_error());while($obj=mysql_fetch_object($res))...{ print_r($obj); echo "<hr>";} 输出 stdClass Object( [Table] => category [Create Table] => CREATE TABLE