Posso ripristinare una singola tabella da un file mysqlump mysql completo?


194

Ho un backup mysqldump del mio database mysql composto da tutte le nostre tabelle che è di circa 440 mega. Voglio ripristinare il contenuto di una sola delle tabelle dal mysqldump. È possibile? Teoricamente, potrei semplicemente ritagliare la sezione che ricostruisce la tabella che desidero, ma non so nemmeno come modificare efficacemente un documento di testo di quelle dimensioni.


2
FWIW, potresti anche usare mydumper . Questo crea un dump logico come mysqldump, ma genera file separati per tabella e può eseguire sia il dumping che il caricamento multi-thread, quindi richiede meno tempo.
Bill Karwin,

Risposte:


289

Puoi provare a usare sed per estrarre solo la tabella che desideri.

Supponiamo che il nome della tabella sia mytablee che il file mysql.dump sia il file contenente il tuo enorme dump:

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

Questo copierà nel file mytable.dumpciò che si trova tra CREATE TABLE mytablee il successivo CREATE TABLEcorrispondente alla tabella successiva.

È quindi possibile regolare il file mytable.dumpche contiene la struttura della tabella mytablee i dati (un elenco di INSERT).


5
È anche più bello della mia risposta poiché si occupa anche di CREATE TABLE, ma dovresti cercare con i backquotes per non ottenere un altro tavolo chiamato "thisismytabletoo".
JCCyC,

1
Vero. Non ero sicuro se i nomi delle tabelle in tutti i dump mysql fossero sempre circondati da backquote o se fosse possibile anche "CREATE TABLE mytable". Possiamo facilmente adattare il primo regexp se sappiamo come appare il dump. Un secondo problema potrebbe essere se la tabella mytable non è univoca (una nel database db1 e un'altra nel database db2). Entrambi verranno esportati nel file mytable.dump. Se la tabella non è univoca, possiamo usare lo stesso comando sed, prima con CREATE DATABASE per estrarre solo il database giusto. Quindi, utilizzare il comando sed con CREATE TABLE.
uloBasEI,

13
Dolce! Ricordarsi di aggiungere DROP TABLE nella parte superiore e rimuovere DROP TABLE [tabella successiva] nella parte inferiore del file.
Nathan,

20
Per non aggiungere / rimuovere DROP TABLE, è più utile abbinare per Table structure for tablecommento, anziché abbinare per CREATE TABLE. Ciò assicurerà che la tabella successiva non venga eliminata se si dimentica di rimuovere la sua istruzione DROP TABLE e consente il piping per il ripristino della tabella a comando singolo (gzip | sed | mysql). Tuttavia, questa soluzione dipende dalla sintassi dei commenti di mysqldump (non so quanto sia standard).
Olexa,

12
Con la modifica di Olexa è perfetto: sed -n -e '/ Struttura della tabella per. * `Mytable /, / Struttura della tabella per / p' whole.sql> mytable.sql
deeenes

120

Ho usato una versione modificata del comando sed di uloBasEI. Include il comando DROP precedente e legge fino a quando mysql non esegue il dumping dei dati sulla tabella (UNLOCK). Ha funzionato per me (ri) importando wp_users in un sacco di siti Wordpress.

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

3
questa è in realtà una soluzione molto migliore di quella scelta come risposta, sopra. Non riesco a credere che non abbia ottenuto più voti.
rICh

9
Suggerisco di aggiungere almeno le virgolette al nome della tabella: `mytable`per evitare la corrispondenza delle tabelle mytable2e così via come nel mio caso.
Bartekbrak,

3
mi hai appena salvato il culo
Gabriel Alack il

1
@ user706420 Hmm, sei sicuro che il tuo terminale non sia da biasimare? sednon dovrebbe interferire con la codifica ...
bryn,

6
Per quelli con file SQL che non contengono DROP TABLE(il mio dump MySQL non aveva questo) potrebbe voler usare: sed -n -e '/-- Table structure for table ``<Table Name>/,/UNLOCK TABLES/p' <SQL File> > table.sql Questo fa uso dei commenti della tabella forniti prima di ogni tabella in un dump MySQl e garantisce che linee come /*!40101 SET @saved_cs_client = @@character_set_client */;vengano incluse.
hamx0r

50

Questo può essere fatto più facilmente? Ecco come l'ho fatto:

Creare un database temporaneo (ad es. Ripristino):

mysqladmin -u root -p crea restore

Ripristina il dump completo nel database temporaneo:

mysql -u root -p restore <fulldump.sql

Dump della tabella che si desidera ripristinare:

mysqldump restore mytable> mytable.sql

Importa la tabella in un altro database:

mysql -u root -p database <mytable.sql


2
Questo è ciò di cui la maggior parte delle persone ha bisogno.
sjas,

2
Secondo questo suggerimento di modifica , è necessario aggiungere il parametro "--one-database", per assicurarsi di ripristinare solo un database e non distruggere tutto il resto.
SL Barth - Ripristina Monica il

7
Per un db davvero enorme può essere molto strano: ripristinare 150 GB di dati per una tabella di 100 MB.
Enyby,

Ho appena eseguito questo senza "--one-database" e ha ancora unito le tabelle bene. Non ha rimosso le mie tabelle esistenti.
Qasim,

1
Pratica pessima! Avevo pochi DB in dump e, provando a ripristinarne solo uno, ho eliminato tutti gli altri.
AndreyP

11

Una soluzione semplice sarebbe quella di creare semplicemente un dump della sola tabella che si desidera ripristinare separatamente. È possibile utilizzare il comando mysqldump per farlo con la sintassi seguente:

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

Quindi importalo normalmente e importerà solo la tabella di cui è stato eseguito il dump.


9

In un modo o nell'altro, qualsiasi processo che lo farà dovrà passare attraverso l'intero testo della discarica e analizzarlo in qualche modo. Vorrei solo fare una richiesta

INSERT INTO `the_table_i_want`

e reindirizza l'output in mysql. Dai un'occhiata al primo tavolo nella discarica prima, per assicurarti di ottenere INSERT nel modo giusto.

Modifica: OK, questa volta la formattazione è corretta.


Sono stupido per non aver immediatamente pensato di prenderlo in giro. Grep mi salva la pancetta ogni giorno, a quanto pare. Gli altri due suggerimenti erano anche quelli bang-up e totalmente quello che avrei fatto senza le meraviglie di grep disponibili. Grazie a tutti!
Mobius,

6
Se pensi di amare grep, quando impari awk diventerai il suo felice schiavo del sesso: en.wikipedia.org/wiki/Awk
JCCyC,

7

Dovresti provare il comando @bryn ma con il delimitatore `altrimenti estrarrai anche le tabelle che hanno un prefisso o un suffisso, questo è quello che faccio di solito:

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

Anche a scopo di test, potresti voler cambiare il nome della tabella prima di importare:

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

Per importare è quindi possibile utilizzare il comando mysql:

mysql -u root -p'password' mydatabase < mytable_restore.sql

6
  1. di riserva

    $ mysqldump -A | gzip > mysqldump-A.gz
  2. Ripristina tabella singola

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

4

Un modo possibile per gestirlo è ripristinare su un database temporaneo e scaricare solo quella tabella dal database temporaneo. Quindi utilizzare il nuovo script.



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

Questa è una soluzione migliore di alcune delle altre precedenti perché non tutti i dump SQL contengono DROP TABLEun'istruzione. Questo funzionerà con tutti i tipi di discariche.


2

Anche questo può aiutare.

# 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'

2

La tabella deve presentare con la stessa struttura sia nel dump che nel database.

`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`

1

La maggior parte dei moderni editor di testo dovrebbe essere in grado di gestire un file di testo di quelle dimensioni, se il tuo sistema è all'altezza.

Ad ogni modo, ho dovuto farlo una volta molto rapidamente e non ho avuto il tempo di trovare alcuno strumento. Ho impostato una nuova istanza di MySQL, ho importato l'intero backup e poi ho sputato solo la tabella che volevo.

Quindi ho importato quella tabella nel database principale.

È stato noioso ma piuttosto facile. In bocca al lupo.


1

Puoi usare l'editor vi. Genere:

vi -o mysql.dump mytable.dump

per aprire sia l'intero dump mysql.dumpche un nuovo file mytable.dump. Trova l'inserto appropriato nella riga premendo /e quindi digita una frase, ad esempio: "inserisci in` mytable` ", quindi copia quella riga usando yy. Passa al file successivo da ctrl+wallora down arrow key, incolla la linea copiata con pp. Infine, salva il nuovo file digitando :wqe abbastanza editor vi di :q.

Si noti che se avete scaricato i dati utilizzando più inserti è possibile copiare (yank) tutti in una volta usando Nyy, in cui Nè il numero di linee da copiare.

L'ho fatto con un file di dimensioni 920 MB.


0

Ottieni un editor di testo decente come Notepad ++ o Vim (se sei già esperto con esso). Cerca il nome della tabella e dovresti essere in grado di evidenziare solo i comandi CREATE, ALTER e INSERT per quella tabella. Potrebbe essere più semplice navigare con la tastiera anziché con il mouse. E mi assicurerei che tu sia su una macchina con abbondanza o RAM in modo che non abbia problemi a caricare l'intero file in una volta. Una volta evidenziate e copiate le righe necessarie, sarebbe una buona idea eseguire il backup solo della parte copiata nel proprio file di backup e quindi importarlo in MySQL.


1
Questo è davvero facile da fare e comprensibile anche dai principianti. Non lo so, perché questo è sottovalutato.
Karl Johan Vallner,

0

I blocchi di SQL vengono bloccati con "Struttura tabella per tabella my_table" e "Dati di dumping per tabella my_table".

È possibile utilizzare una riga di comando di Windows come segue per ottenere i numeri di riga per le varie sezioni. Regola la stringa cercata secondo necessità.

trova / n "per tabella" "sql.txt

Verrà restituito quanto segue:

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

[4384] - Struttura della tabella per la tabella my_table

[4500] - Dati di dumping per la tabella my_table

[4514] - Struttura della tabella per la tabella some_other_table

... eccetera.

Questo ti dà i numeri di riga che ti servono ... ora, se solo sapessi come usarli ... indagando.




0

Le soluzioni "sed" menzionate in precedenza sono belle ma, come detto, non sicure al 100%

  • Potresti avere comandi INSERT con dati contenenti: ... CREATE TABLE ... (qualunque cosa) ... mytable ...

  • o anche la stringa esatta "CREATE TABLE` mytable`; " se stai memorizzando i comandi DML per esempio!

(e se la tabella è enorme non vuoi verificarla manualmente)

Verificherei l'esatta sintassi della versione di dump utilizzata e avrei una ricerca di pattern più restrittiva:

Evita ". *" E usa "^" per assicurarti di iniziare all'inizio della riga. E preferirei afferrare il 'DROP' iniziale

Tutto sommato, questo funziona meglio per me:

sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.