按数据库将mysqldump文件与多个数据库拆分
我有一个包含多个数据库的mysqldump文件(5)。其中一个数据库需要很长时间才能加载,有没有办法按数据库拆分mysqldump文件,或者只告诉mysql只加载一个指定的数据库 Manish一个“mysqldump文件”只是一个充满SQL语句的文本文件。因此,您可以使用任何种类的文本编辑器,以您认为合适的方式将其切碎 首先进行更具选择性的转储(每个文件只有一个数据库,等等)可能会更好。如果您没有访问原始数据库的权限,也可以执行完全还原,然后再次使用mysqldump为各个数据库创建转储按数据库将mysqldump文件与多个数据库拆分,mysql,database,backup,mysqldump,reload,Mysql,Database,Backup,Mysqldump,Reload,我有一个包含多个数据库的mysqldump文件(5)。其中一个数据库需要很长时间才能加载,有没有办法按数据库拆分mysqldump文件,或者只告诉mysql只加载一个指定的数据库 Manish一个“mysqldump文件”只是一个充满SQL语句的文本文件。因此,您可以使用任何种类的文本编辑器,以您认为合适的方式将其切碎 首先进行更具选择性的转储(每个文件只有一个数据库,等等)可能会更好。如果您没有访问原始数据库的权限,也可以执行完全还原,然后再次使用mysqldump为各个数据库创建转储 如果你
如果你只是想要一个快速而肮脏的解决方案,那么快速的谷歌搜索会产生一个可能也很有用的参考 这个Perl脚本应该可以做到这一点
#!/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/perl-w
#
#splitmysqldump-将mysqldump文件拆分为每个数据库转储文件。
严格使用;
使用警告;
我的$dbfile;
我的$dbname=q{};
my$header=q{};
而(){
#新数据库部分的开头:
#关闭当前打开的文件并启动一个新文件
if(m/--当前数据库\:\`([-\w]+)\`/){
if(已定义$dbfile&&tell$dbfile!=-1){
关闭$dbfile或死亡“无法关闭文件!”
}
$dbname=$1;
打开$dbfile、“>>”、“$1_dump.sql”或“无法创建文件!”;
打印$dbfile$头文件;
打印“正在写入文件$1_dump.sql…\n”;
}
if(已定义$dbfile&&tell$dbfile!=-1){
打印$dbfile$\ux;
}
#捕获开头的转储文件头
#要打印到每个单独的转储文件。
if(!$dbname){$header.=$\u;}
}
关闭$dbfile或死亡“无法关闭文件!”
对包含所有数据库的转储文件运行此命令
./splitmysqldump < all_databases.sql
/splitmysqldump这是一篇很好的博客文章,我经常提到它,用mysqldump
做这类事情
您可以轻松地扩展它以提取单个数据库。我一直在编写一个python脚本,该脚本将一个大转储文件拆分为小转储文件,每个数据库一个。它的名字是dumpsplit,这里有一个划痕:
#!/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])
或者,可以将每个数据库直接保存到单独的文件中
#!/bin/bash
dblist=`mysql -u root -e "show databases" | sed -n '2,$ p'`
for db in $dblist; do
mysqldump -u root $db | gzip --best > $db.sql.gz
done
就像Stano建议的,最好的办法是在垃圾场的时候用
mysql -Ne "show databases" | grep -v schema | while read db; do mysqldump $db | gzip > $db.sql.gz; done
当然,这取决于~/.my.cnf文件的存在
[client]
user=root
password=rootpass
否则,只需在mysql和mysqldump调用中使用-u和-p参数定义它们:
mysql -u root -prootpass -Ne "show databases" | grep -v schema | while read db; do mysqldump -u root -prootpass $db | gzip > $db.sql.gz; done
希望这有帮助我可以分步骤进行转储和重新加载:
以表结构的转储为例,其中不包含每个数据库转储的数据
在新服务器中创建结构
以表的数据转储为例,每个数据库级别没有创建信息
现在,就像每个数据库都有转储一样,如果某个特定文件很大,我甚至可以使用剪切文件分割这些文件
注意:如果您使用的是MyISAM表,则可以在步骤4中禁用索引求值,然后重新启用,以加快插入速度。对于机器可解析的输出,请使用mysql--batch--skip column names
而不是sed
。检查此Windows/linux解决方案:不鼓励只提供链接答案,请在此处发布链接要点!这是最好的,因为不需要创建任何文件。只要粘贴并运行适当的配置更改。最适合寻找快速单行解决方案的人。经过一段时间的处理后,我发现此脚本有一个错误:无法在./splitmysqldump第34行,第188681行使用未定义的值作为符号引用。