问题描述:
mysql数据库里面fund_netvalue表遇到问题,以前的很多数据确实,不明白是什么时候导致的,只能从近期备份的数据库(mysqldump -uroot -p123 dbname >dbname_20131107.sql) 里面找到那张表并
恢复
但是怎么做呢?
我先mysql登录数据库然后(create database forback)然后use forback再然后source dbname_20131107.sql!
接着退出登录(mysqldump -uroot -p123 forback fund_netvalue >fund_netvalue_20131107.sql)
现在找到了以前的表,准备恢复吧,但是我们知道mysqldump导出的表的格式是先drop掉原来的表在创建新的表再插入,我们只是需要补充之前的一些数据,11/07到今天12/31的数据还是要的!好吧。我就先
vi fund_netvalue_20131107.sql!把drop语句和前面的建表语句都删了,然后再恢复,但是你们知道,这张备份表和现在的表肯定有很多数据是相同的,执行语句(mysql -uroot -p123 -f dbname<fund_netvalue_20131107.sql)的时候我加了-f选项,就算会报错(ERROR 1062 (23000) at line 4676: Duplicate entry '750003-2013-11-07' for key 1)也跳过!我以为这样就可以补充起数据了,但是我太天真了,错是报了一些,但是该插入的还是没有插入呀,如何,卡住了,这么办,我之前一直以为是语句执行错了,但是几遍之后依旧如此呀!难道是导出的表格式错误,head -50 fund_netvalue_20131107.sql|more,看到里面的插入语句是这样的格式
INSERT INTO `fund_netvalue` VALUES ('770001','2013-03-11','1.14420000','1.14420000'....),('770001','2013-03-08','1.14500000','1.14500000'....),(...),(...)
难道是这种insert语句不行,不管这么多,找出两条数据用这样的格式试下,insert into fund_netvalue (key1,key2,.....)vaules(value1,value2,......)
其中前一条是表里面存在的记录,后一条不存在!执行,还是报错,但是后面那条数据插入了数据库!(我也试过前面那一种格式,不行)!好吧,这样能行,我就把数据导成那种格式的吧,但是怎么导成那种格式的呢!我是用了一种笨办法,在mysql-front客户端先把所有的数据查询出来(select * from fund_netvalue(forback数据库))然后导出sql语句!再把他复制到服务器上然后执行,哈哈,可以了!
问题解决了,但是有很多疑问没有解决
insert的两种格式有什么区别?
mysqldump导出的语句可以不包含前面的drop和建表语句么,还有他导出的insert格式有选项可以控制么?或者有那别的命令可以用?
还有一定要新建数据库才能恢复备份数据库里面的一张表么?
解决疑问3:
1):将整个文件导入测试server中,再mysqldump导出需要的表,再导入线上server。
如果库的量很少,这样倒是也不慢,可当库的量有一定的级别了,就会很慢。很可能备份时使用了压缩,再需要解压缩的步骤。
2):通过mysql>show tables;查看到mysqldump备份时的表的备份顺序,其和show tables的看的顺序一样的。锁定了表的位置,通过awk或sed取出其需要的表数据。
针对方法2:
假如你show tables的结果为:
table_1
table_2
table_3
.......
zcat mysqldump.date.sql.gz |sed -n -e '/-- Table structure for table `table_10`/,/-- Table structure for table `table_11`/p' >/tmp/table_10.sql
table_n
此时想恢复table_10的数据时,使用awk做如下操作:
1
zcat mysqldump.date.sql.gz|awk '/^-- Table structure for table `table_10`/,/^-- Table structure for table `table_11`/{print}' >/tmp/table_10.sql
注意:awk的''和""的区别,假如""中使用``就会报错;其中``可以替换为..。如下
1
zcat mysqldump.date.sql.gz|awk "/^-- Table structure for table .table_10./,/^-- Table structure for table .table_11./{print}">/tmp/table_10.sql
使用sed作如下操作:
1
其实方法2就是要知道,show tables的表顺序和mysqldump时的顺序相同;其次是dump出的文件特殊标志-- Table structure for table `table_n` 。
可以通过下面的一条语句直接把某张表的提取出来:
awk -vRS="" '/workflows/' test.sql ――workflows是表名
摘自博客http://lgdvsehome.blog.51cto.com/3360656/1243307
解决疑问1
问了同事,说前一种是属于一条sql语句,恰中一个报错,都执行不了。但是后一种是n多条语句,一句报错,其他接着执行!
具体是不是这样的,以后看到更权威的再补充!
解决疑问2:
mysqldump选项控制!
我现在就不mysqldump --help 或者是 man mysqldump输出一大长串控制选项了,只写几个今天涉及到的!
--no-create-info,-t
只导出数据,而不添加 CREATE TABLE 语句。
不见了drop语句和建表语句
--compatible=name
它告诉 mysqldump,导出的数据将和哪种数据库或哪个旧版本的 MySQL 服务器相兼容。值可以为 ansi、mysql323、mysql40、postgresql、oracle、mssql、db2、maxdb、no_key_options、 no_tables_options、no_field_options 等,要使用几个值,用逗号将它们隔开。当然了,它并不保证能完全兼容,而是尽量兼容。
--extended-insert = true|false
默认情况下,mysqldump 开启 --complete-insert 模式,因此不想用它的的话,就使用本选项,设定它的值为 false 即可
--complete-insert,-c
导出的数据采用包含字段名的完整 INSERT 方式,也就是把所有的值都写在一行。这么做能提高插入效率,但是可能会受到 max_allowed_packet 参数的影响而导致插入失败。因此,需要谨慎使用该参数,至少我不推荐。
这样,还是一个insert,只是把列名写出来了
--extended-insert, -e
使用具有多个VALUES列的INSERT语法。这样使导出文件更小,并加速导入时的速度。默认为打开状态,使用--skip-extended-insert取消选项。
这个选项,哈哈,终于出现了多个insert语句!