¿Puedo restaurar una sola tabla desde un archivo mysql mysqldump completo?

194

Tengo una copia de seguridad mysqldump de mi base de datos mysql que consta de todas nuestras tablas, que es de aproximadamente 440 megas. Quiero restaurar el contenido de solo una de las tablas del mysqldump. es posible? Teóricamente, podría cortar la sección que reconstruye la tabla que quiero, pero ni siquiera sé cómo editar efectivamente un documento de texto de ese tamaño.

Mobius
fuente
2
FWIW, también puedes usar mydumper . Esto crea un volcado lógico como mysqldump, pero genera archivos separados por tabla, y puede realizar tanto el volcado como la carga de subprocesos múltiples, por lo que lleva menos tiempo.
Bill Karwin

Respuestas:

289

Puede intentar usar sed para extraer solo la tabla que desee.

Digamos que el nombre de su tabla es mytabley el archivo mysql.dump es el archivo que contiene su gran volcado:

$ sed -n -e '/CREATE TABLE.*`mytable`/,/CREATE TABLE/p' mysql.dump > mytable.dump

Esto copiará en el archivo mytable.dumplo que se encuentra entre CREATE TABLE mytabley el siguiente CREATE TABLEcorrespondiente a la siguiente tabla.

Luego puede ajustar el archivo mytable.dumpque contiene la estructura de la tabla mytabley los datos (una lista de INSERT).

uloBasEI
fuente
55
Eso es incluso mejor que mi respuesta, ya que también se ocupa de CREATE TABLE, pero debe buscar con las comillas inversas para no obtener otra tabla llamada "thisismytabletoo".
JCCyC
1
Cierto. No estaba seguro de si los nombres de las tablas en todos los volcados de mysql siempre están rodeados de comillas o si "CREATE TABLE mytable" también podría ser posible. Podemos adaptar fácilmente la primera expresión regular si sabemos cómo se ve el volcado. Un segundo problema podría ser si la tabla mytable no es única (una en la base de datos db1 y otra en la base de datos db2). Ambos se exportarán en el archivo mytable.dump. Si la tabla no es única, podemos usar el mismo comando sed, primero con CREATE DATABASE para extraer solo la base de datos correcta. Luego, use el comando sed con CREATE TABLE.
uloBasEI
13
¡Dulce! Recuerde agregar DROP TABLE en la parte superior y eliminar DROP TABLE [siguiente tabla] en la parte inferior del archivo.
Nathan
20
Para no agregar / eliminar DROP TABLE, es más útil hacer coincidir por Table structure for tablecomentario, en lugar de hacerlo por CREATE TABLE. Esto garantizará que la siguiente tabla no se descarte si se olvida eliminar su instrucción DROP TABLE y permite la canalización para la restauración de la tabla con un solo comando (gzip | sed | mysql). Sin embargo, esta solución depende de la sintaxis de comentarios mysqldump (no sé qué tan estándar es).
Olexa
12
Con la modificación de Olexa es perfecto: sed -n -e '/ Estructura de tabla para. * `Mytable /, / Estructura de tabla para / p' whole.sql> mytable.sql
deeenes
120

Usé una versión modificada del comando sed de uloBasEI. Incluye el comando DROP anterior y se lee hasta que mysql termina de volcar datos en su tabla (UNLOCK). Trabajó para mí (re) importar wp_users a un montón de sitios de Wordpress.

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' mydump.sql > tabledump.sql
Bryn
fuente
3
En realidad, esta es una solución mucho mejor que la elegida como respuesta anterior. No puedo creer que no haya recibido más votos a favor.
rICh
9
Sugiero agregar al menos comillas de retroceso al nombre de la tabla: `mytable`para evitar que coincidan las tablas, mytable2etc., como era mi caso.
bartekbrak
3
acabas de salvar mi trasero
Gabriel Alack
1
@ user706420 Hmm, ¿estás seguro de que tu terminal no tuvo la culpa? sedno debe interferir con la codificación ...
Bryn
66
Para aquellos con archivos SQL que no contienen el DROP TABLE(mi volcado de MySQL no tenía esto) pueden querer usar: sed -n -e '/-- Table structure for table ``<Table Name>/,/UNLOCK TABLES/p' <SQL File> > table.sql Esto hace uso de los comentarios de la tabla proporcionados antes de cada tabla en un volcado de MySQl, y garantiza que /*!40101 SET @saved_cs_client = @@character_set_client */;se incluyan líneas como .
hamx0r
50

Esto se puede hacer más fácilmente? Así es como lo hice:

Cree una base de datos temporal (por ejemplo, restaurar):

mysqladmin -u root -p crear restaurar

Restaurar el volcado completo en la base de datos temporal:

mysql -u root -p restore <fulldump.sql

Volcar la tabla que desea recuperar:

mysqldump restore mytable> mytable.sql

Importe la tabla en otra base de datos:

mysql -u raíz -p base de datos <mytable.sql

Martijn Kools
fuente
2
Esto es lo que la mayoría de la gente necesita.
sjas
2
De acuerdo con esta sugerencia de edición , debe agregar el parámetro "--one-database", para asegurarse de restaurar solo una base de datos y no destruir todo lo demás.
SL Barth - Restablece a Monica el
77
Para una base de datos realmente enorme, puede ser muy extraño: restaurar 150 GB de datos para una tabla de 100 MB.
Enyby
Acabo de ejecutar esto sin "--one-database" y aun así combinó tablas muy bien. No eliminó mis tablas existentes.
Qasim
1
Muy mala práctica! Tenía pocas bases de datos en el volcado, y al intentar restaurar solo una, eliminé todas las demás.
AndreyP
11

Una solución simple sería simplemente crear un volcado de solo la tabla que desea restaurar por separado. Puede usar el comando mysqldump para hacerlo con la siguiente sintaxis:

mysqldump -u [user] -p[password] [database] [table] > [output_file_name].sql

Luego, impórtelo de manera normal, y solo importará la tabla volcada.

Brom558
fuente
9

De una forma u otra, cualquier proceso que haga eso tendrá que pasar por todo el texto del volcado y analizarlo de alguna manera. Me encantaría

INSERT INTO `the_table_i_want`

y canalizar la salida en mysql. Eche un vistazo a la primera tabla en el basurero antes, para asegurarse de obtener los INSERTOS de la manera correcta.

Editar: OK, obtuve el formato correcto esta vez.

JCCyC
fuente
Soy tonto por no pensar de inmediato en agarrarlo. Grep salva mi tocino todos los días, al parecer. Las otras dos sugerencias fueron también explosivas y totalmente lo que hubiera hecho sin las maravillas de grep disponibles. ¡Gracias a todos!
Mobius
66
Si crees que amas a grep, cuando aprendas awk te convertirás en su esclava sexual feliz: en.wikipedia.org/wiki/Awk
JCCyC
7

Deberías probar el comando @bryn pero con el delimitador `de lo contrario también extraerás las tablas que tienen un prefijo o sufijo, esto es lo que suelo hacer:

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' dump.sql > mytable.sql

También para fines de prueba, es posible que desee cambiar el nombre de la tabla antes de importar:

sed -n -e 's/`mytable`/`mytable_restored`/g' mytable.sql > mytable_restored.sql

Para importar, puede usar el comando mysql:

mysql -u root -p'password' mydatabase < mytable_restore.sql
Maxime Biette
fuente
6
  1. Apoyo

    $ mysqldump -A | gzip > mysqldump-A.gz
  2. Restaurar tabla individual

    $ mysql -e "truncate TABLE_NAME" DB_NAME
    $ zgrep ^"INSERT INTO \`TABLE_NAME" mysqldump-A.gz | mysql DB_NAME
y.tk
fuente
4

Una posible forma de lidiar con esto es restaurar una base de datos temporal y volcar solo esa tabla de la base de datos temporal. Luego usa el nuevo script.

Tim Hoolihan
fuente
3
sed -n -e '/-- Table structure for table `my_table_name`/,/UNLOCK TABLES/p' database_file.sql > table_file.sql

Esta es una mejor solución que algunas de las anteriores porque no todos los volcados de SQL contienen una DROP TABLEdeclaración. Este funcionará con todo tipo de vertederos.

Weston Ganger
fuente
2

Esto también puede ayudar.

# mysqldump -u root -p database0 > /tmp/database0.sql
# mysql -u root -p -e 'create database database0_bkp'
# mysql -u root -p database0_bkp < /tmp/database0.sql
# mysql -u root -p database0 -e 'insert into database0.table_you_want select * from database0_bkp.table_you_want'
Pjl
fuente
2

La tabla debe presentarse con la misma estructura tanto en el volcado como en la base de datos.

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql.tar.gz | mysql -u<user> -p<password> database_name`

o

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql | mysql -u<user> -p<password> database_name`
Neminath
fuente
1

La mayoría de los editores de texto modernos deberían poder manejar un archivo de texto de ese tamaño, si su sistema está a la altura.

De todos modos, tuve que hacerlo una vez muy rápido y no tuve tiempo de encontrar ninguna herramienta. Configuré una nueva instancia de MySQL, importé toda la copia de seguridad y luego escupí solo la tabla que quería.

Luego importé esa tabla a la base de datos principal.

Fue tedioso pero bastante fácil. Buena suerte.

Bryan Migliorisi
fuente
1

Puedes usar el editor vi. Tipo:

vi -o mysql.dump mytable.dump

para abrir tanto el volcado completo mysql.dumpcomo un nuevo archivo mytable.dump. Busque la inserción apropiada en la línea presionando /y luego escriba una frase, por ejemplo: "insertar en` mytable` ", luego copie esa línea usando yy. Cambie al siguiente archivo para ctrl+wentonces down arrow key, pegue la línea copiada con pp. Finalmente guarde el nuevo archivo escribiendo :wqy bastante editor vi por :q.

Tenga en cuenta que si ha volcado los datos usando múltiples inserciones, puede copiarlos (tirarlos) todos a la vez usando Nyycuál Nes el número de líneas que se copiarán.

Lo hice con un archivo de 920 MB de tamaño.

mtoloo
fuente
0

Obtenga un editor de texto decente como Notepad ++ o Vim (si ya es competente con él). Busque el nombre de la tabla y debería poder resaltar solo los comandos CREATE, ALTER e INSERT para esa tabla. Puede ser más fácil navegar con el teclado que con el mouse. Y me aseguraría de que esté en una máquina con mucha RAM o RAM para que no tenga problemas para cargar todo el archivo de una vez. Una vez que haya resaltado y copiado las filas que necesita, sería una buena idea hacer una copia de seguridad de la parte copiada en su propio archivo de copia de seguridad y luego importarla a MySQL.

Cameron
fuente
1
Esto es realmente fácil de hacer y comprensible incluso para principiantes. No sé por qué esto es rechazado.
Karl Johan Vallner
0

Los fragmentos de SQL se bloquean con "Estructura de tabla para tabla my_table" y "Volcado de datos para tabla my_table".

Puede usar una línea de comandos de Windows de la siguiente manera para obtener los números de línea para las diferentes secciones. Ajuste la cadena buscada según sea necesario.

find / n "para la tabla` "sql.txt

Se devolverá lo siguiente:

---------- SQL.TXT

[4384] - Estructura de mesa para mesa my_table

[4500] - Volcado de datos para tabla my_table

[4514] - Estructura de mesa para mesa some_other_table

... etc.

Eso te da los números de línea que necesitas ... ahora, si supiera cómo usarlos ... investigando.

Kuyenda
fuente
0

Las soluciones 'sed' mencionadas anteriormente son agradables pero, como se mencionó, no son 100% seguras

  • Puede tener comandos INSERT con datos que contengan: ... CREATE TABLE ... (lo que sea) ... mytable ...

  • o incluso la cadena exacta "CREATE TABLE` mytable`; " si está almacenando comandos DML por ejemplo!

(y si la tabla es enorme, no querrá verificarlo manualmente)

Verificaría la sintaxis exacta de la versión de volcado utilizada y tendría una búsqueda de patrones más restrictiva:

Evite ". *" Y use "^" para asegurarse de que comencemos al comienzo de la línea. Y preferiría tomar el 'DROP' inicial

En general, esto funciona mejor para mí:

sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump
phil_w
fuente