2009-12-09 12 views
15

Ho un file mysqldump di più database (5). Uno dei database richiede molto tempo per essere caricato, esiste un modo per dividere il file mysqldump per database o semplicemente per dire a mysql di caricare solo uno dei database specificati?Suddividere un file mysqldump con più database, per database

Manish

+0

Controlla questa soluzione per Windows/linux: http://stackoverflow.com/questions/132902/how-do-i-split-the-output-from-mysqldump-into-smaller-files/30988416#30988416 – Alisa

risposta

0

Un "file mysqldump" è solo un file di testo completo di istruzioni SQL. Come tale, puoi usare qualsiasi varietà di editor di testo per sminuzzarlo come meglio credi.

Si potrebbe essere meglio serviti facendo un dump più selettivo in primo luogo (solo un database per file, ecc.). Se non si ha accesso al database originale, è possibile anche eseguire un ripristino completo, quindi utilizzare mysqldump per creare nuovamente i dump per i singoli database.

Se si desidera una soluzione rapida e sporca, una ricerca rapida su google produce riferimenti a uno coupletools che potrebbe essere utile.

20

Questo script Perl dovrebbe fare il trucco.

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

Eseguire questo per il file dump che contiene tutti i database

./splitmysqldump < all_databases.sql 
+0

grazie per una bella sceneggiatura ha funzionato come il fascino – sakhunzai

1

Ho lavorato a uno script python che divide un file di dump in piccoli, uno per database. Il suo nome è dumpsplit ed ecco un graffio:

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

Oppure, è possibile salvare tutti i database in un file separato direttamente ...

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

Usa 'mysql --batch --skip-column-names' invece di' sed' per l'output parseable della macchina. [(Riferimento)] (https://dev.mysql.com/doc/refman/5.0/en/mysql-command-options.html) –

0

Come Stano ha suggerito la cosa migliore sarebbe quella di farlo in fase di discarica con qualcosa di simile ...

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

Naturalmente, questo si basa sulla presenza di un file ~/.my.cnf con

[client] 
user=root 
password=rootpass 

Altrimenti basta definire con i parametri -u e -p per il mysql e mysqldump chiamata:

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

Spero che questo aiuti

0

potrei fare il dump e ricaricare in passi:

  1. Prendere il dump della struttura della tabella con --no-data con dump per database.
  2. creare la struttura di nuovo server
  3. Prendere il dump dei dati della tabella con --no-create-info al livello di database
  4. Ora, come hanno discariche per database, posso dividere i file anche con il file di taglio, se qualche file particolare è grande.

Nota: se si utilizzano le tabelle MyISAM, è possibile disabilitare la valutazione degli indici durante il passaggio 4 e riattivarlo successivamente per rendere più veloce l'inserimento.