2009-12-09 18 views
15

Tôi có một tệp mysqldump của nhiều cơ sở dữ liệu (5). Một trong những cơ sở dữ liệu mất một thời gian rất dài để tải, là có một cách để phân chia các tập tin mysqldump bởi cơ sở dữ liệu, hoặc chỉ cần nói mysql để tải chỉ một trong những cơ sở dữ liệu được chỉ định?Chia nhỏ tệp mysqldump với nhiều cơ sở dữ liệu, theo cơ sở dữ liệu

Manish

+0

Kiểm tra giải pháp này cho Windows/linux: http://stackoverflow.com/questions/132902/how-do-i-split-the-output-from-mysqldump-into-smaller-files/30988416#30988416 – Alisa

Trả lời

0

01 "Tệp mysqldump" chỉ là một tệp văn bản chứa đầy câu lệnh SQL. Như vậy, bạn có thể sử dụng nhiều trình chỉnh sửa văn bản khác nhau để cắt nhỏ cách bạn thấy phù hợp.

Bạn có thể được phục vụ tốt hơn bằng cách thực hiện một kết xuất có chọn lọc hơn ngay từ đầu (chỉ một cơ sở dữ liệu cho mỗi tệp, v.v.). Nếu bạn không có quyền truy cập vào cơ sở dữ liệu gốc, bạn cũng có thể khôi phục hoàn toàn, sau đó sử dụng mysqldump một lần nữa tạo các bãi chứa cho các cơ sở dữ liệu riêng lẻ.

Nếu bạn chỉ muốn một giải pháp nhanh chóng và dơ bẩn, tìm kiếm nhanh trên google sẽ tham chiếu đến một số coupletools cũng có thể hữu ích.

20

Tập lệnh Perl này sẽ thực hiện thủ thuật.

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

Run này cho các tập tin dump chứa tất cả các cơ sở dữ liệu

./splitmysqldump < all_databases.sql 
+0

cảm ơn cho kịch bản tốt đẹp nó làm việc như quyến rũ – sakhunzai

1

Tôi đã làm việc trên một tập lệnh python chia tách một tệp kết xuất lớn thành tệp nhỏ, một tệp cho mỗi cơ sở dữ liệu. Đó là tên là dumpsplit và đây là một vết trầy xước:

#!/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]) 
13

Hoặc, nó có thể tiết kiệm mỗi cơ sở dữ liệu vào tập tin riêng biệt trực tiếp ...

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

Sử dụng 'mysql --batch --skip-column-names' thay vì' sed' cho đầu ra có thể phân tích máy. [(tham khảo)] (https://dev.mysql.com/doc/refman/5.0/en/mysql-command-options.html) –

0

Giống như Stano đề nghị điều tốt nhất là nên làm điều đó lúc bãi với một cái gì đó giống như ...

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

Tất nhiên, điều này phụ thuộc vào sự hiện diện của một ~/file .my.cnf với

[client] 
user=root 
password=rootpass 

Nếu không chỉ định nghĩa chúng với các thông số -u -p và với mysql và mysqldump gọi:

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

Hope this helps

0

tôi có thể làm bãi và tải lại ở bước sau:

  1. Lấy kết xuất của cấu trúc bảng bằng --no-data với các bãi trên mỗi cơ sở dữ liệu.
  2. Tạo cấu trúc trong máy chủ mới
  3. Hãy bãi dữ liệu của bảng với --no-tạo-info cho mỗi cấp độ cơ sở dữ liệu
  4. Bây giờ, khi có bãi mỗi cơ sở dữ liệu, tôi có thể chia nhỏ các tập tin ngay cả với tập tin cắt nếu một số tập tin cụ thể là lớn.

Lưu ý: nếu bạn đang sử dụng bảng MyISAM, bạn có thể tắt đánh giá chỉ mục trong bước 4 và bật lại sau này để chèn nhanh hơn.