Разбить файл mysqldump с несколькими базами данных, по базе данных

У меня есть файл mysqldump из нескольких баз данных (5). Одна из баз данных занимает очень много времени для загрузки, есть ли способ разбить файл mysqldump по базе данных или просто сказать mysql для загрузки только одной из указанных баз данных?

Маниш

Ответы

Ответ 1

Этот Perl script должен сделать трюк.

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

Ответ 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

Ответ 3

Вот отличный пост в блоге, который я всегда пересматриваю, чтобы делать такие вещи с помощью mysqldump.

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

Вы можете легко расширить его, чтобы извлечь отдельные db.

Ответ 4

Я работал над python script, который разбивает один большой файл дампа на маленькие, по одному на базу данных. Это имя - 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 [email protected]_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])

Ответ 5

"Файл mysqldump" - это всего лишь текстовый файл, полный операторов SQL. Таким образом, вы можете использовать любое разнообразие текстовых редакторов, чтобы вырезать его, как вы сочтете нужным.

Вам может быть лучше, если вы сделаете более выборочный дамп (только одна база данных на файл и т.д.). Если у вас нет доступа к исходной базе данных, вы также можете выполнить полное восстановление, а затем использовать mysqldump для создания дампов для отдельных баз данных.

Если вам просто нужно быстрое и грязное решение, быстрый поиск в google дает ссылки на пара инструменты, которые также могут быть полезны.

Ответ 6

Как сказал Стано, лучше всего было бы сделать это во время дампа с чем-то вроде...

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

Надеюсь, что это поможет

Ответ 7

Я могу сделать дамп и перезагрузить пошагово:

  • Возьмите дамп структуры таблицы с -no-данными с дампами на базу данных.
  • Создание структуры на новом сервере
  • Возьмите дамп данных таблицы с -no-create-info на уровень базы данных
  • Теперь, когда есть базы данных для базы данных, я могу разделить файлы даже с вырезанным файлом, если какой-то конкретный файл большой.

Примечание. Если вы используете таблицы MyISAM, вы можете отключить оценку индексов во время шага 4 и снова включить ее позже, чтобы сделать вашу вставку быстрее.