我有我的 mysql 数据库的 mysqldump 备份,其中包含我们所有的表,大约 440 兆。我想从 mysqldump 中恢复其中一张表的内容。这可能吗?从理论上讲,我可以剪掉重建我想要的表格的部分,但我什至不知道如何有效地编辑那个大小的文本文档。
20 回答
您可以尝试使用 sed 来仅提取您想要的表。
假设您的表的名称是mytable
并且文件mysql.dump
是包含您的大转储的文件:
$ sed -n -e '/CREATE TABLE.*`mytable`/,/Table structure for table/p' mysql.dump > mytable.dump
这将在文件中复制mytable.dump
位于CREATE TABLE mytable
与下CREATE TABLE
一个表对应的下一个之间的内容。
然后,您可以调整mytable.dump
包含表结构mytable
和数据(列表INSERT
)的文件。
我使用了 uloBaseEI 的 sed 命令的修改版本。它包括前面的 DROP 命令,并读取直到 mysql 完成将数据转储到您的表 (UNLOCK)。为我工作(重新)将wp_users导入到一堆 Wordpress 网站。
sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' mydump.sql > tabledump.sql
这可以更轻松地完成吗?我是这样做的:
创建一个临时数据库(例如恢复):
mysqladmin -u root -p 创建恢复
恢复临时数据库中的完整转储:
mysql -u root -p 恢复 < fulldump.sql
转储您要恢复的表:
mysqldump 恢复 mytable > mytable.sql
将表导入另一个数据库:
mysql -u root -p 数据库 < mytable.sql
一个简单的解决方案是简单地创建一个您希望单独恢复的表的转储。您可以使用 mysqldump 命令执行此操作,语法如下:
mysqldump -u [user] -p[password] [database] [table] > [output_file_name].sql
然后正常导入,只会导入转储的表。
无论哪种方式,任何执行此操作的进程都必须遍历转储的整个文本并以某种方式对其进行解析。我只是为了
INSERT INTO `the_table_i_want`
并将输出通过管道传输到 mysql。看一下转储中的第一个表,以确保您以正确的方式获得 INSERT。
编辑:好的,这次格式正确。
备份
$ mysqldump -A | gzip > mysqldump-A.gz
恢复单表
$ mysql -e "truncate TABLE_NAME" DB_NAME $ zgrep ^"INSERT INTO \`TABLE_NAME" mysqldump-A.gz | mysql DB_NAME
您应该尝试 @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
解决此问题的一种可能方法是恢复到临时数据库,并仅从临时数据库中转储该表。然后使用新脚本。
sed -n -e '/-- Table structure for table `my_table_name`/,/UNLOCK TABLES/p' database_file.sql > table_file.sql
这是比上述其他一些解决方案更好的解决方案,因为并非所有 SQL 转储都包含DROP TABLE
语句。这将适用于各种转储。
这个工具可能就是你想要的:tbdba-restore-mysqldump.pl
https://github.com/orczhou/dba-tool/blob/master/tbdba-restore-mysqldump.pl
例如从数据库转储文件中恢复一个表:
tbdba-restore-mysqldump.pl -t yourtable -s yourdb -f backup.sql
表在转储和数据库中应具有相同的结构。
`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`
这也可能有帮助。
# 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'
如果您的系统能够满足要求,大多数现代文本编辑器应该能够处理该大小的文本文件。
无论如何,我必须非常快地完成一次,我没有时间找到任何工具。我设置了一个新的 MySQL 实例,导入了整个备份,然后只输出了我想要的表。
然后我将该表导入主数据库。
这很乏味但相当容易。祝你好运。
前面提到的“sed”解决方案很好,但如上所述不是 100% 安全的
您可能有包含数据的 INSERT 命令:... CREATE TABLE...(whatever)...mytable...
甚至是确切的字符串“CREATE TABLE `mytable`;” 例如,如果您要存储 DML 命令!
(如果表格很大,您不想手动检查)
我将验证所使用的转储版本的确切语法,并进行更严格的模式搜索:
避免使用“.*”并使用“^”来确保我们从行首开始。而且我更愿意抓住最初的“DROP”
总而言之,这对我来说效果更好:
sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump
您可以使用 vi 编辑器。类型:
vi -o mysql.dump mytable.dump
打开整个转储mysql.dump
和一个新文件mytable.dump
。通过按找到适当的插入行/
,然后键入一个短语,例如:“插入到`mytable`”,然后使用复制该行yy
。切换到下一个文件ctrl+w
,down arrow key
粘贴复制的行pp
。:wq
最后通过键入和相当 vi 编辑器保存新文件:q
。
Nyy
请注意,如果您已使用多个插入转储数据,则可以使用其中N
要复制的行数一次复制(拉出)所有数据。
我用一个 920 MB 大小的文件完成了它。
我尝试了一些选项,但速度非常慢。这会在几分钟内将 360GB 的转储拆分到其表中:
获得像 Notepad++ 或 Vim 这样的体面的文本编辑器(如果您已经精通它)。搜索表名,您应该能够仅突出显示该表的 CREATE、ALTER 和 INSERT 命令。使用键盘而不是鼠标进行导航可能更容易。而且我会确保你在一台有大量内存的机器上,这样一次加载整个文件就不会出现问题。一旦您突出显示并复制了您需要的行,最好将复制的部分备份到它自己的备份文件中,然后将其导入 MySQL。
SQL 的块被“表的表结构my_table
”和“表的转储数据”阻止my_table
。
您可以按如下方式使用 Windows 命令行来获取各个部分的行号。根据需要调整搜索的字符串。
查找 /n "for table `" sql.txt
将返回以下内容:
---------- SQL.TXT
[4384]-- 表的表结构my_table
[4500]-- 转储表的数据my_table
[4514]-- 表的表结构some_other_table
... ETC。
这会给你你需要的行号......现在,如果我只知道如何使用它们......调查。
您可以使用终端线导入单个表,如下所示。 这里将单个用户表导入特定的数据库。
mysql -u root -p -D my_database_name < var/www/html/myproject/tbl_user.sql
我很佩服这里的一些独创性,但实际上根本没有理由使用它sed
来解决 OP 的问题。
注释“use --one-database”是正确的答案,内置于 MySQL/MariaDB。无需第三方黑客。
mysql -u root -p databasename --one-database < localhost.sql
只会导入所需的数据库。
我还发现在某些情况下,当使用它导入一系列数据库时,它会为我在列表中创建下一个数据库(但不会在其中放入任何内容)。不知道为什么这样做,但它使恢复更容易。
使用此命令,以交互方式输入密码,它将导入请求的数据库。