2009-12-09 11 views
15

Tengo un archivo mysqldump de varias bases de datos (5). Una de las bases de datos tarda mucho tiempo en cargarse, ¿hay alguna manera de dividir el archivo mysqldump por base de datos o simplemente decirle a mysql que cargue solo una de las bases de datos especificadas?Dividir un archivo mysqldump con varias bases de datos, por base de datos

Manish

+0

Compruebe esta solución para Windows/Linux: http://stackoverflow.com/questions/132902/how-do-i-split-the-output-from-mysqldump-into-smaller-files/30988416#30988416 – Alisa

Respuesta

0

un "archivo mysqldump" es simplemente un archivo de texto completo de las sentencias SQL. Como tal, puede usar cualquier variedad de editores de texto para cortarlo como mejor le parezca.

En primer lugar, sería mejor realizar un volcado más selectivo (solo una base de datos por archivo, etc.). Si no tiene acceso a la base de datos original, también puede hacer una restauración completa, luego usar mysqldump de nuevo crear volcados para las bases de datos individuales.

Si solo quiere una solución rápida y sucia, una búsqueda rápida en Google produce referencias a coupletools que también pueden serle útiles.

20

Esta secuencia de comandos Perl debería hacer el truco.

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

Ejecutar esto para el archivo de volcado que contiene todas las bases de datos

./splitmysqldump < all_databases.sql 
+0

gracias para una buena secuencia de comandos funcionó como el encanto – sakhunzai

1

He estado trabajando en una secuencia de comandos python que divide un gran archivo de volcado en archivos pequeños, uno por base de datos. Su nombre es dumpsplit y aquí está un rasguño:

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

O bien, es posible ahorrar cada base de datos en archivo separado directamente ...

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

Utilice 'mysql --batch --skip-column-names' en lugar de' sed' para la salida de máquina parseable. [(referencia)] (https://dev.mysql.com/doc/refman/5.0/en/mysql-command-options.html) –

0

Como Stano sugirió que lo mejor sería hacerlo en el momento de volcado con algo como ...

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

por supuesto, esto depende de la presencia de un archivo ~/.my.cnf con

[client] 
user=root 
password=rootpass 

De lo contrario sólo definirlos con los parámetros -u y -p para el mysql y mysqldump llamada:

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

Esperanza esto ayuda

0

que podría hacer el volcado y volver a cargar en pasos:

  1. Tome el volcado de la estructura de la tabla con --no-data con volcados por base de datos.
  2. crear la estructura en nuevo servidor
  3. Tome el volcado de datos de mesa con --no-create-info por nivel de base de datos
  4. Ahora, al igual que los vertederos por base de datos, que puede dividir los archivos, incluso con el archivo de corte si algún archivo particular es grande.

Nota: si está utilizando tablas MyISAM, puede desactivar la evaluación de índices durante el paso 4 y volver a habilitarla más adelante para hacer que su inserción sea más rápida.

Cuestiones relacionadas