按数据库拆分包含多个数据库的mysqldump文件

时间:2009-12-09 20:43:20

标签: mysql database backup mysqldump reload

我有一个包含多个数据库的mysqldump文件(5)。其中一个数据库需要很长时间才能加载,有没有办法按数据库拆分mysqldump文件,或者只是告诉mysql只加载一个指定的数据库?

和Manish

7 个答案:

答案 0 :(得分:23)

这个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!"

对包含所有数据库的转储文件运行此命令

./splitmysqldump < all_databases.sql

答案 1 :(得分:15)

或者,可以直接将每个数据库保存到单独的文件中......

#!/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

答案 2 :(得分:1)

这是一篇很棒的博客文章,我总是通过mysqldump重新引用它来做这种事情。

http://gtowey.blogspot.com/2009/11/restore-single-table-from-mysqldump.html

您可以轻松扩展它以提取单个数据库。

答案 3 :(得分:1)

我一直在研究一个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])

答案 4 :(得分:1)

就像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

否则只需使用-u和-p参数将它们定义为mysql和mysqldump调用:

mysql -u root -prootpass -Ne "show databases" | grep -v schema | while read db; do mysqldump -u root -prootpass $db | gzip > $db.sql.gz; done

希望这有帮助

答案 5 :(得分:0)

“mysqldump文件”只是一个充满SQL语句的文本文件。因此,您可以使用各种文本编辑器来查看您认为合适的方式。

首先进行更具选择性的转储(每个文件只有一个数据库等)可能会更好。如果您无权访问原始数据库,则还可以执行完全还原,然后再次使用mysqldump为各个数据库创建转储。

如果您只想要一个快速而肮脏的解决方案,快速谷歌搜索会产生对couple tools的引用,这可能也很有用。

答案 6 :(得分:0)

我可以按步骤进行转储和重新加载:

  1. 使用--no-data转储表结构,每个数据库使用转储。
  2. 在新服务器中创建结构
  3. 使用--no-create-info per database level
  4. 获取表的数据转储
  5. 现在,正如每个数据库的转储一样,如果某个特定文件很大,我甚至可以使用剪切文件拆分文件。
  6. 注意:如果您使用的是MyISAM表,则可以在步骤4中禁用索引评估,稍后重新启用它以使插入更快。