#!/usr/bin/perl -w
#
# splitmysqldump - split mysqldump file into per-database dump files.
use strict;
use warnings;
my $dbfile;
my $dbname = q{};
my $header = q{};
while (<>) {
# Beginning of a new database section:
# close currently open file and start a new one
if (m/-- Current Database\: \`([-\w]+)\`/) {
if (defined $dbfile && tell $dbfile != -1) {
close $dbfile or die "Could not close file!"
}
$dbname = $1;
open $dbfile, ">>", "$1_dump.sql" or die "Could not create file!";
print $dbfile $header;
print "Writing file $1_dump.sql ...\n";
}
if (defined $dbfile && tell $dbfile != -1) {
print $dbfile $_;
}
# Catch dump file header in the beginning
# to be printed to each separate dump file.
if (! $dbname) { $header .= $_; }
}
close $dbfile or die "Could not close file!"
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import re
import os
HEADER_END_MARK = '-- CHANGE MASTER TO MASTER_LOG_FILE'
FOOTER_BEGIN_MARK = '\/\*\!40103 SET TIME_ZONE=@OLD_TIME_ZONE \*\/;'
DB_BEGIN_MARK = '-- Current Database:'
class Main():
"""Whole program as a class"""
def __init__(self,file,output_path):
"""Tries to open mysql dump file to call processment method"""
self.output_path = output_path
try:
self.file_rsrc = open(file,'r')
except IOError:
sys.stderr.write('Can\'t open %s '+file)
else:
self.__extract_footer()
self.__extract_header()
self.__process()
def __extract_footer(self):
matched = False
self.footer = ''
self.file_rsrc.seek(0)
line = self.file_rsrc.next()
try:
while line:
if not matched:
if re.match(FOOTER_BEGIN_MARK,line):
matched = True
self.footer = self.footer + line
else:
self.footer = self.footer + line
line = self.file_rsrc.next()
except StopIteration:
pass
self.file_rsrc.seek(0)
def __extract_header(self):
matched = False
self.header = ''
self.file_rsrc.seek(0)
line = self.file_rsrc.next()
try:
while not matched:
self.header = self.header + line
if re.match(HEADER_END_MARK,line):
matched = True
else:
line = self.file_rsrc.next()
except StopIteration:
pass
self.header_end_pos = self.file_rsrc.tell()
self.file_rsrc.seek(0)
def __process(self):
first = False
self.file_rsrc.seek(self.header_end_pos)
prev_line = '--\n'
line = self.file_rsrc.next()
end = False
try:
while line and not end:
if re.match(DB_BEGIN_MARK,line) or re.match(FOOTER_BEGIN_MARK,line):
if not first:
first = True
else:
out_file.writelines(self.footer)
out_file.close()
if not re.match(FOOTER_BEGIN_MARK,line):
name = line.replace('`','').split()[-1]+'.sql'
print name
out_file = open(os.path.join(self.output_path,name),'w')
out_file.writelines(self.header + prev_line + line)
prev_line = line
line = self.file_rsrc.next()
else:
end = True
else:
if first:
out_file.write(line)
prev_line = line
line = self.file_rsrc.next()
except StopIteration:
pass
if __name__ == '__main__':
Main(sys.argv[1],sys.argv[2])
8条答案
按热度按时间xytpbqjk1#
这个Perl脚本应该可以完成这个任务。
对包含所有数据库的转储文件运行以下命令
wyyhbhjk2#
或者,可以直接将每个数据库保存到单独的文件中...
s2j5cfk03#
这是一篇很棒的博客文章,我总是重新引用它来用
mysqldump
做这类事情。http://gtowey.blogspot.com/2009/11/restore-single-table-from-mysqldump.html
您可以轻松地扩展它以提取单个数据库。
nsc4cvqm4#
我一直在编写一个python脚本,它将一个大的转储文件拆分为小文件,每个数据库一个。它的名字是dumpsplit,这里有一个划痕:
7jmck4yq5#
就像斯塔诺建议的最好的办法是在转储时间用像...
当然,这依赖于~/.my.cnf文件的存在
否则,只需在mysql和mysqldump调用中使用-u和-p参数定义它们:
希望这对你有帮助
qnzebej06#
我知道这篇文章很古老,但我认为,仍然是现实的。Riedsio(上面)的链接指的是挑选单个表,这不是我要找的,也不是这篇文章的内容-但它可以很容易地应用于从一个大型数据库的mysqldump中轻松挑选单个数据库:
假设您从一个mysqldump.sql.gz文件开始,*zgrep -n 'CurrentDatabase' mysqldump.sql.gz * 为每个数据库提供一个包含起始行号的列表。
找到要还原的数据库的行号以及下一个数据库的行号。假设你想恢复数据库axp,行号是10934和12034。输入 *zcat mysqldump.sql.gz| sed -n '10934,12034 p'| mysql-urootaxp *,您将只将该数据库加载到mysql中(当然,假设您有一个空的axp数据库来加载它)
或者,你当然可以将输出重定向到一个数据库文件并加载它,但这需要更多的步骤:
5q4ezhmt7#
“mysqldump文件”只是一个充满SQL语句的文本文件。因此,您可以使用任何种类的文本编辑器来分割您认为合适的内容。
首先进行更有选择性的转储(每个文件只转储一个数据库,等等)可能会更好。如果您没有访问原始数据库的权限,也可以执行完全恢复,然后再次使用mysqldump为各个数据库创建转储。
如果你只是想要一个快速和肮脏的解决方案,一个快速的谷歌搜索会产生一个coupletools的引用,这也可能是有用的。
ctzwtxfj8#
我可以按以下步骤进行转储和重新加载:
1.使用--no-data转储每个数据库的表结构。
1.在新服务器中创建结构
1.在每个数据库级别使用--no-create-info进行表的数据转储
1.现在,由于每个数据库都有转储,如果某个特定的文件很大,我甚至可以使用cut file拆分文件。
注意:如果你使用的是MyISAM表,你可以在第4步中禁用索引评估,然后重新启用它,以使你的插入更快。