Eliminazione della tabella MySQL con transazioni in sospeso


10

C'è un modo per eliminare una tabella o un database InnoDB con transazioni in sospeso in MySQL (preferibilmente a livello di file system)?

Quello che è successo:

Uso MySQL 5.5.28 e ho corso LOAD DATA INFILE…per importare un enorme set di dati (300 milioni di righe) in una tabella InnoDB. Non ho usato set autocommit = 0;prima. Sfortunatamente, è mysqldstato fermato proprio nel mezzo dell'importazione.

Al riavvio mysql, tenta di ripristinare la transazione riempiendo il registro di sistema con messaggi come questo:

mysqld_safe [4433]: 121212 16:58:52 InnoDB: in attesa del completamento di 1 transazioni attive

Il problema è che il rollback è in esecuzione da più di 25 ore durante le quali mysqldnon accetta connessioni socket.

Non posso semplicemente cancellare /var/lib/mysql/*e ricominciare da zero perché ci sono anche altri database / tabelle InnoDB su questa macchina. Tuttavia, la tabella problematica è l'unica tabella in un database separato. L'eliminazione dell'intera tabella o dell'intero database non è un problema poiché posso reimportare tutti i dati in seguito.

Risposte:


8

Non c'è nulla che tu possa veramente fare perché un rollback viene eseguito tramite il tablespace UNDO all'interno di ibdata1 , che dovrebbe essere cresciuto immensamente.

Se si interrompe il processo mysqld e si riavvia mysql, riprenderà da dove era stato interrotto come parte del ciclo di recupero da crash.

DISCLAIMER: non responsabile per la perdita di dati

Quello che potresti fare potrebbe comportare la perdita di dati per altre tabelle, ma c'è qualcosa che puoi fare per aggirare il normale ciclo di recupero da crash di InnoDB.

Esiste un'opzione di avvio denominata innodb_force_recovery , che consente di ignorare varie fasi del ripristino da crash di InnoDB.

Secondo la documentazione MySQL su Forcing InnoDB Recovery , ecco le impostazioni e i suoi effetti:

1 (SRV_FORCE_IGNORE_CORRUPT)

Lascia che il server funzioni anche se rileva una pagina danneggiata. Prova a fare in modo che SELECT * FROM tbl_name salti i record e le pagine di indice danneggiati, il che aiuta a scaricare le tabelle.

2 (SRV_FORCE_NO_BACKGROUND)

Impedisci l'esecuzione del thread principale. Se si verifica un arresto anomalo durante l'operazione di eliminazione, questo valore di ripristino lo impedisce.

3 (SRV_FORCE_NO_TRX_UNDO)

Non eseguire i rollback delle transazioni dopo il ripristino di emergenza.

4 (SRV_FORCE_NO_IBUF_MERGE)

Impedisci operazioni di unione del buffer di inserimento. Se provocherebbero un arresto, non eseguirli. Non calcolare le statistiche della tabella.

5 (SRV_FORCE_NO_UNDO_LOG_SCAN)

Non guardare i registri di annullamento all'avvio del database: InnoDB considera impegnate anche le transazioni incomplete.

6 (SRV_FORCE_NO_LOG_REDO)

Non eseguire il roll-forward del registro di ripetizione in connessione con il ripristino.

Con le modifiche transazionali nascoste nei registri UNDO e REDO, si corre il rischio di

  • perdere dati significava essere scritti
  • conservare i dati destinati ad essere eliminati

Nel caso in cui si prevedano effetti collaterali negativi, eseguire il backup dell'intero / var / lib / mysql e metterlo da qualche parte nel caso in cui si desideri copiare ibdata1, ib_logfile0 e ib_logfile1 e riprovare il normale ripristino.

Se mysql è completamente attivo in una delle modalità

  • mysqldump tutti i dati tranne la tabella offensiva
  • spegnimento mysql
  • rimuovi tutto in / var / lib / mysql tranne / var / lib / mysql / mysql
  • avvia mysql
  • ricaricare il mysqldump

CAVEAT: assicurati di eseguire il backup di tutto !!!

Spero che possa aiutare !!!


1

Ho avuto una situazione simile questa settimana.

E dopo quattro iterazioni di ripristino di un backup completo su un server di prova e tentando di eliminare, eliminare o eliminare i tavoli con le gigantesche transazioni in sospeso, alla fine siamo arrivati ​​a venerdì pomeriggio e abbiamo deciso di lasciarlo funzionare. Per tre giorni, la transazione è terminata con un carico trascurabile del server e il database è andato bene. Che era molto meglio di qualsiasi delle operazioni manuali su file .frm e tabelle mysql che avevano tentato e fallito.

La mia soluzione: non eliminarlo . Consentire il completamento delle transazioni in sospeso, anche se è necessario rimandare altre operazioni per alcuni giorni o trovare spazio su disco da qualche parte o lasciare che il server slave si occupi del carico.

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.