it-swarm.it

Come recuperare una tabella InnoDB i cui file sono stati spostati

Quindi ho un server db di prova che è stato installato su un flusso di replica. Sopra il nome è emersa un'ottimizzazione che ha riempito rapidamente lo spazio sul datadir degli slave. Mysql stava aspettando diligentemente un po 'più di spazio.

Questo datadir è un file system usato SOLO come datadir di mysql, quindi non c'era nient'altro da liberare.

Avevo una tabella di test innodb da 4 concerti che non faceva parte del flusso di replica, quindi ho pensato di provare qualcosa per vedere se funzionava, ed essendo un ambiente di test non ero troppo preoccupato se le cose andassero orribilmente male.

Ecco i passi che ho preso

  1. Svuotato il tavolo che stavo per spostare
  2. Posizionato un blocco di lettura su di esso (anche se non c'era nulla di scritto e non era nel flusso di replica)
  3. Copiato .frm e .ibd su un filesystem con spazio libero
  4. Sbloccato il tavolo
  5. Ha troncato quella tabella: questo ha liberato abbastanza spazio perché l'ottimizzazione finisse, facendo ricominciare a replicare la replica.
  6. Smettere di schiavizzare/spegnere mysql
  7. Copia il file da tmp alla directory dei dati
  8. Riavvia mysql

Nulla viene visualizzato nel registro .err, le cose sembrano buone. Mi collego e utilizzo mydb; e vedere la tabella con cui stavo scherzando nelle tabelle degli spettacoli. Ma se ci provo

select * from testtable limit 10;

Ottengo l'errore

ERROR 1146 (42S02): Table 'mydb.testtable' doesn't exist

Da quello che posso dire finora posso leggere bene da tutte le altre tabelle e la replica è stata avviata senza alcun reclamo.

C'è qualcosa che posso fare per recuperare da questo punto? Posso ricostruirlo da zero, se necessario, ma ero curioso di ciò che gli altri pensavano di questa impresa in generale. C'era qualcosa nella serie di passi che avrei fatto con risultati più impeccabili?

E se questo non fosse un server di prova non potrei semplicemente 'farlo dal vivo' e vedere cosa succede? Quale sarebbe il modo migliore per liberare temporaneamente spazio su uno slave di produzione se dovessi farlo?

14
atxdba

La cosa più grande che la maggior parte delle persone dimentica di TRUNCATE TABLE è che TRUNCATE TABLE è DDL e non DML . In InnoDB, i metadati all'interno di ibdata1 contengono un elenco numerato di tabelle InnoDB. L'uso di TRUNCATE TABLE provoca lo spostamento dell'ID dei metadati interno della tabella InnoDB. Ciò accade perché TRUNCATE TABLE esegue effettivamente quanto segue:

Esempio: troncare una tabella InnoDB chiamata mydb.mytb

USE mydb
CREATE TABLE newtb LIKE mytb;
ALTER TABLE mytb RENAME oldtb;
ALTER TABLE newtb RENAME mytb;
DROP TABLE oldtb;

Il nuovo mytb avrebbe quindi un diverso ID metadata interno.

Quando hai copiato il file .ibd in un'altra posizione, l'ibd contiene al suo interno l'id originale dei metadati. Il semplice ripristino del file .ibd non causa una riconciliazione dell'ID metadata interno con quello di ibdata1.

Quello che avresti dovuto fare è questo:

Copia il file .ibd della tabella InnoDB. Quindi, esegui questo

ALTER TABLE tablename DISCARD TABLESPACE;

Per riportarlo in un secondo momento, copiare il file .ibd in Datadir ed eseguirlo

ALTER TABLE tablename IMPORT TABLESPACE;

Ciò avrebbe preservato l'id dei metadati interno.

Assicurarsi che .frm sia sempre presente.

Una volta ho aiutato un cliente a ripristinare 30 tabelle di InnoDB che aveva nascosto allo stesso modo. Ho dovuto usare un altro server DB e giocare ad alcuni giochi aggiungendo e rilasciando tabelle InnoDB per cercare l'id corretto dei metadati interni.

Il cliente ha trovato questo articolo: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . L'abbiamo usato e ci ha aiutato moltissimo. Spero che ti aiuti.

15
RolandoMySQLDBA