我可以从完整的mysql mysqldump文件中恢复单个表吗?

时间:2009-06-18 16:50:33

标签: mysql backup mysqldump restore

我有一个mysqldump备份我的mysql数据库,包括我们所有的表,大约440兆。我想从mysqldump中恢复其中一个表的内容。这可能吗?从理论上讲,我可以删除重建我想要的表的部分,但我甚至不知道如何有效地编辑那个大小的文本文档。

21 个答案:

答案 0 :(得分:248)

您可以尝试使用sed以仅提取所需的表格。

假设您的表名是mytable,文件mysql.dump是包含您的巨大转储的文件:

$ sed -n -e '/CREATE TABLE.*`mytable`/,/CREATE TABLE/p' mysql.dump > mytable.dump

这将在文件mytable.dump中复制CREATE TABLE mytable与下一个表格对应的下一个CREATE TABLE之间的内容。

然后,您可以调整包含表mytable.dump结构的文件mytable和数据(INSERT列表)。

答案 1 :(得分:98)

我使用了uloBasEI的sed命令的修改版本。它包括前面的DROP命令,并读取直到mysql完成将数据转储到您的表(UNLOCK)。为我工作(重新)将 wp_users 导入到一堆Wordpress网站。

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' mydump.sql > tabledump.sql

答案 2 :(得分:45)

这可以更轻松地完成吗?我就这样做了:

创建临时数据库(例如还原):

  

mysqladmin -u root -p create restore

恢复临时数据库中的完整转储:

  

mysql -u root -p restore< fulldump.sql

转储要恢复的表:

  

mysqldump restore mytable> mytable.sql

将表导入另一个数据库:

  

mysql -u root -p database< mytable.sql

答案 3 :(得分:12)

一个简单的解决方案是简单地创建一个只想要单独恢复的表的转储。您可以使用mysqldump命令使用以下语法执行此操作:

mysqldump -u [user] -p[password] [database] [table] > [output_file_name].sql

然后正常导入它,它只会导入转储的表。

答案 4 :(得分:9)

无论如何,执行该操作的任何进程都必须遍历转储的整个文本并以某种方式解析它。我只是在寻找

INSERT INTO `the_table_i_want`

并将输出传递给mysql。看一下转储中的第一个表,确保你以正确的方式获得INSERT。

编辑:好的,这次格式正确。

答案 5 :(得分:7)

您应该尝试使用@bryn命令,但使用`分隔符,否则您也将提取具有前缀或后缀的表,这是我通常所做的:

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' dump.sql > mytable.sql

另外,出于测试目的,您可能希望在导入之前更改表名:

sed -n -e 's/`mytable`/`mytable_restored`/g' mytable.sql > mytable_restored.sql

要导入,您可以使用mysql命令:

mysql -u root -p'password' mydatabase < mytable_restore.sql

答案 6 :(得分:6)

  1. 备份

    $ mysqldump -A | gzip > mysqldump-A.gz
    
  2. 恢复单个表

    $ mysql -e "truncate TABLE_NAME" DB_NAME
    $ zgrep ^"INSERT INTO \`TABLE_NAME" mysqldump-A.gz | mysql DB_NAME
    

答案 7 :(得分:4)

处理此问题的一种可能方法是还原到临时数据库,并从临时数据库中转储该表。然后使用新脚本。

答案 8 :(得分:3)

这个工具可能就是你想要的:tbdba-restore-mysqldump.pl

https://github.com/orczhou/dba-tool/blob/master/tbdba-restore-mysqldump.pl

e.g。从数据库转储文件恢复表:

  

tbdba-restore-mysqldump.pl -t yourtable -s yourdb -f backup.sql

答案 9 :(得分:2)

这也可能有所帮助。

# mysqldump -u root -p database0 > /tmp/database0.sql
# mysql -u root -p -e 'create database database0_bkp'
# mysql -u root -p database0_bkp < /tmp/database0.sql
# mysql -u root -p database0 -e 'insert into database0.table_you_want select * from database0_bkp.table_you_want'

答案 10 :(得分:1)

您可以使用vi编辑器。类型:

vi -o mysql.dump mytable.dump

打开整个转储mysql.dump和新文件mytable.dump。 按/找到适当的插入行,然后键入短语,例如:“插入`mytable`”,然后使用yy复制该行。按ctrl+w然后down arrow key切换到下一个文件,将复制的行粘贴到pp。最后,通过:wq键入:q和相当vi编辑器来保存新文件。

请注意,如果您使用多个插入转储数据,则可以使用Nyy一次复制(猛拉)所有数据,其中N是要复制的行数。

我用920 MB大小的文件完成了它。

答案 11 :(得分:1)

大多数现代文本编辑器应该能够处理大小的文本文件,如果您的系统符合它的话。

无论如何,我必须非常快地做到这一点,我没有时间找到任何工具。我设置了一个新的MySQL实例,导入了整个备份,然后只吐出我想要的表。

然后我将该表导入主数据库。

这很乏味但很容易。祝你好运。

答案 12 :(得分:1)

sed -n -e '/-- Table structure for table `my_table_name`/,/UNLOCK TABLES/p' database_file.sql > table_file.sql

这是一个比上面的其他一些更好的解决方案,因为并非所有SQL转储都包含DROP TABLE语句。这个将适用于所有类型的转储。

答案 13 :(得分:1)

表在转储和数据库中应具有相同的结构。

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql.tar.gz | mysql -u<user> -p<password> database_name`

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql | mysql -u<user> -p<password> database_name`

答案 14 :(得分:0)

回到'08,我也需要这样做。我写了一个Perl脚本,它会做到这一点,它现在是我选择的方法。还总结了如何在awk中执行此操作或如何在其他地方恢复并提取。最近我也将这个sed方法添加到列表中。您可以在此处找到脚本和其他方法:http://blog.tsheets.com/2008/tips-tricks/extract-a-single-table-from-a-mysqldump-file.html

答案 15 :(得分:0)

使用“表my_table的表结构”和“转储表my_table的数据”来阻止SQL的块。

您可以按如下方式使用Windows命令行来获取各个部分的行号。根据需要调整搜索到的字符串。

find / n“for table`”sql.txt

将返回以下内容:

---------- SQL.TXT

[4384] - 表my_table

的表结构

[4500] - 转储表my_table

的数据

[4514] - 表some_other_table

的表结构

......等等。

这可以获得你需要的行号...现在,如果我只知道如何使用它们......调查。

答案 16 :(得分:0)

获得一个体面的文本编辑器,如Notepad ++或Vim(如果你已经精通它)。搜索表名,您应该只能突出显示该表的CREATE,ALTER和INSERT命令。用键盘而不是鼠标导航可能更容易。我会确保你在一台有足够或RAM的机器上,以便一次加载整个文件不会有问题。一旦您突出显示并复制了所需的行,最好将复制的部分备份到自己的备份文件中,然后将其导入MySQL。

答案 17 :(得分:0)

前面提到的'sed'解决方案很不错,但提到的不是100%安全

  • 您可能拥有包含以下数据的INSERT命令: ...创建表...(无论如何)... mytable ...

  • 甚至是确切的字符串“CREATE TABLE`mytable`;” 如果你正在存储DML命令!

(如果表格很大,你不想手动检查)

我会验证所使用的转储版本的确切语法,并进行更严格的模式搜索:

避免使用“。*”并使用“^”以确保我们从行的开头开始。 我宁愿抓住最初的'DROP'

总而言之,这对我来说效果更好:

sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump

答案 18 :(得分:0)

我尝试了几个选项,速度非常慢。这会在几分钟内将360GB转储拆分到其表中:

How do I split the output from mysqldump into smaller files?

答案 19 :(得分:0)

您可以使用如下所示的终端行导入单个表。 此处将单用户表导入特定数据库。

mysql -u root -p -D my_database_name < var/www/html/myproject/tbl_user.sql

答案 20 :(得分:0)

我很欣赏这里的一些独创性,但实际上根本没有理由使用 sed 来解决 OP 的问题。

注释“use --one-database”是正确答案,内置于 MySQL/MariaDB。无需第三方黑客。

mysql -u root -p databasename --one-database < localhost.sql 将只导入所需的数据库。

我还发现在某些情况下,当使用它导入一系列数据库时,它会为我创建列表中的下一个数据库(但不放入任何内容)。不知道为什么这样做,但它使恢复更容易。

使用此命令,交互式输入密码,它将导入请求的数据库。