2009-08-18 9 views
51

Estoy usando mysqldump en un trabajo cron para hacer una copia de seguridad de una base de datos con más de 2 millones de filas.Cómo lidiar con enormes longitudes de línea creadas por mysqldump

Crea un archivo de texto que se puede usar para restaurar el registro de datos desde la línea de comandos.

pensé que sería útil para editar el vertedero antes de una restauración rápida como forma de cambiar los valores y nombres de tabla o columna - al menos hasta que aprenda más y cobrando ánimo de hacerlo con modificaciones y actualizaciones.

grandes archivos de texto Edición no me molesta, pero se sorprendió al descubrir que en un 250 megabytes volcado de mi base de datos, sólo había alrededor de 300 líneas. Cada línea tenía algo así como 800k caracteres de largo.

¿Hay alguna otra manera de generar volcados con más control sobre la longitud de línea?

¿O debería post-procesar el volcado con herramientas como sed o Perl?

+0

Considere el; entre consultas como su línea endian. – Havenard

+0

En realidad, solía Perl y dijo $ line = ~ s {\\) \\ (.} {), \ N (} g;. así que tiene un montón de líneas adicionales – pavium

+0

Es decir, el ; ya era mi eol al final de cada INSERT en table_name VALUES (..), (..), (..) .. (..); 282 líneas en todo el archivo, 252 terminando en; Elegí insertar líneas nuevas después de las comas – pavium

Respuesta

71

Por defecto, mysqldump genera un único comando INSERT por mesa, lo que resulta en una línea (muy largo) de los datos insertados para cada tabla que Conseguí descargado. Esto se debe esencialmente a que las inserciones de "lote" son mucho más rápidas que si generara una consulta INSERT por separado para cada registro en cada tabla.

Por lo tanto, no es que mysqldump haya creado líneas arbitrariamente largas, y usted puede simplemente imponer otra longitud de corte. Las líneas son largas por una razón.

Si es realmente importante para obtener los INSERT s desglosados ​​en varias líneas, se puede indicar que con:

mysqldump --extended-insert=FALSE --complete-insert=TRUE ... 

Nótese, sin embargo, que las tablas de restauración se tardará más en este formato.

+0

Miré en la página del manual de mysqldump e intenté --extended-insert = FALSE pero --complete -insert = TRUE es nuevo para mí. Lo intentaré, gracias. – pavium

+0

Esto realmente me ayudó, gracias. Las líneas extra largas producidas por MySQLDump en realidad se estaban rompiendo y no funcionaban correctamente durante la restauración ...el cambio de insertos extendidos solucionó el problema. Y desde que comprime el archivo resultante, el archivo de copia de seguridad no es tan grande. –

+0

Hacemos mucha migración heredada del Sistema de gestión de contenidos y las recomendaciones de inserción extendida e inserción completa son bastante valiosas. Gracias. –

-3

Proceso posterior del archivo de volcado con python. Puede ser más feliz que Perl o Sed.

Si está ejecutando en Linux, ya lo tiene instalado. Si está ejecutando en Windows, el instalador es sencillo.

Antes de eso, sin embargo, aprenda a utilizar SQL ACTUALIZAR y SQL ALTERAR. Serás más feliz haciendo las cosas bien.

+0

Prefiero Perl o sed, simplemente porque eso es a lo que estoy acostumbrado. Y aunque hay una cierta satisfacción al editar un archivo grande, aprenderé los comandos SQL, lo prometo. – pavium

+7

El postprocesamiento es una mala idea a menos que sea re Aliado seguro de que comprende exactamente cómo se escapan los datos, y cómo escribir el código para manejarlo. De lo contrario, vas a corromper tus datos. –

+2

Si está seguro de que no va a dañar los datos, aquí hay un comando de ejemplo para dividir las inserciones 'mysqldump -udbuser dbname | sed 's /), (/), \ n (/ g'> dump.sql' – Tamlyn

26

Estaba navegando el código fuente de MySQL en busca de una solución a este problema hoy. La longitud de línea máxima es impuesta por la variable opt_net_buffer_length que se supone que coincide con el tamaño del búfer del servidor MySQL. Es cómicamente grande.

Pero de todos modos, es una opción, por lo que sólo hacen esto:

mysqldump --net_buffer_length=5000 ... 

El valor mínimo es 4096.

+5

¿Esto causará problemas con las filas individuales que contienen más de 4K de datos? –

+0

@CyberShadow buena pregunta. Apuesto a que sí, pero no tengo idea. La próxima vez que haga esto, intentaré hacer coincidir el mysqldump net_buffer_length con el max_allowed_packet y ver si eso funciona. Acabo de realizar una importación donde 16M max_allowed_packet fue excedido por el tamaño de la consulta. Incluso 64M era demasiado pequeño, pasó a 256M y lo consiguió. Así que probablemente probaré una net_buffer_length de alrededor de 10M la próxima vez, y veré qué hace eso. –

+0

de lejos la mejor respuesta, no será demasiado lento y no romperá otros DBMS como sqlite que tiene un límite predeterminado de 500 inserciones por instrucción de inserción. ¡gracias! –

13

me encontré con una respuesta en los foros de MySQL, que de manera concluyente demostraciones agregando '\ n' después de cada grupo INSERT no es posible usando mysqldump solo, sin modificar la fuente:

El formato extendido no puede ser 100 % correctamente analizado en función de la coma o paréntesis, debe contar los campos. La mejor solución es reparar mysqldump en linebreak en la salida.

cambio muy pequeño: En la línea 3506, se puede ver donde se emite la fila interminable coma:
fputc(',',md_result_file); /* Always row break */

Simplemente inserte esta línea de inmediato después de la línea 3506:
fputc('\n',md_result_file); /* Lon Binder says wrap that line! */

re- compilar y hacer.

@see http://forums.mysql.com/read.php?28,420002,426110#msg-426110

Gracias Lon B!

(He incluido el contenido del foro de MySQL sólo en caso de que desaparezca el foro.)

+12

Ugh, ¿por qué no es esta una opción en mysqldump? Esto es lo mejor de ambos mundos. –

+0

Proporcione un enlace a la fuente de mysqldump. – Speakus

+0

@Speakus - MySQL es propiedad de Oracle y no ofrece ningún enlace directo para descargar o ver archivos fuente individuales. Puede descargar el paquete fuente desde aquí: http://dev.mysql.com/downloads/utilities/ - solo seleccione 'Fuente 'como la plataforma. – StampyCode

2

Esta bandera también se trabajó:

mysqldump --skip-extended-insert 

Así mismo que --extended-insert=FALSE.

+1

Sí, me gusta más por alguna razón :) Solo necesité esto para una diferencia, donde las líneas largas normales hacen que las diffs sean realmente dolorosas . –

Cuestiones relacionadas