Righe mancanti dopo la conversione online da MyISAM a InnoDB


16

Abbiamo un database ragionevolmente piccolo che volevamo convertire da MyISAM a InnoDB. Essendo noob del database, abbiamo appena convertito (usando l'alter table) senza nemmeno smontare il sito.

Ora che la conversione è stata eseguita, molte righe intermittenti sembrano mancare. Ciò è forse dovuto alle operazioni durante la conversione? O il problema è altrove?


Quali tabelle mancano le righe? Quelli che hai convertito o altri tavoli?
collo lungo l'

Risposte:


20

L'esecuzione di un ALTER per modificare i motori di archiviazione non farà scomparire le righe. Tuttavia, lascia che ti dia qualche consiglio dato che hai detto che sei "noob del database" nella tua domanda.

Quando modifichi lo schema esistente o fai qualcosa che potrebbe influenzare i dati, ecco alcuni consigli di base:

  1. Prima fai un backup.
  2. Avere un piano di cambiamento.
  3. Metti alla prova il tuo piano su un host offline.
  4. Avere un piano di test per confrontare i dati prima e dopo.
  5. Pianifica e prendi un tempo morto.
  6. Effettua un backup e un'istantanea immediatamente dopo l'entrata in vigore del downtime e verifica che il traffico sia stato arrestato.
  7. Se stai eseguendo MYISAM, usa 'CONTROLLA TABELLA' per valutare con cosa hai a che fare prima di ALTER.
  8. Copia la tabella localmente oltre al backup, per ogni evenienza.
  9. Procedere con cautela, abilitare "--show warning" e altri output in modo da avere il quadro completo mentre si apportano le modifiche.
  10. Se i dati sono importanti per te, assumere un DBA, anche solo per consultare durante la migrazione in modo da avere un esperto veterano al tuo fianco.

Probabilmente c'è molto di più in cui potrei entrare, ma quanto sopra ti fornirà le opzioni quando qualcosa va storto.

Per quanto riguarda i tuoi dati / righe mancanti, non c'è modo di sapere w / o "prima / dopo" per confrontare. Puoi confrontare con il tuo ultimo backup per almeno verificarlo.


Ho letto questo. Buon piano DR. La tua risposta ottiene +1 per essere più sensibile alla domanda di quanto non fossi in aggiunta a un piano futuro.
RolandoMySQLDBA,

1
@randy Contrassegnato come domanda preferita a causa della tua buona risposta
techExplorer

8

Uno dei modi migliori per convertire MyISAM in InnoDB senza molti tempi di inattività ha un solo prerequisito: utilizzare uno slave di replica.

Ecco una vista a volo d'uccello del piano

  1. Creare un'impostazione master / slave di replica
  2. Converti ogni tabella MyISAM sullo slave in InnoDB
  3. Punta la tua app sullo Slave

Sembra semplice? Ci sono molti dettagli dietro questo.

Creare un'impostazione master / slave di replica

C'è un modo semplice per creare uno Slave senza disturbare molto il Maestro. Ho scritto due post:

Piuttosto che dettagliare come usare rsync, leggi questi due post.

Converti ogni tabella MyISAM sullo slave in InnoDB

Sul DB Slave è possibile la seguente istruzione SQL:

Per MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Versione per MySQL precedente a MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Utilizzando l'output della query, si dispone di uno script di conversione per lo slave.

Devi inserire queste due righe nella parte superiore dello script:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Lo script disabiliterà prima la registrazione binaria (se lo slave è stato configurato per avere registri binari), interromperà la replica e convertirà ogni tabella MyISAM in InnoDB.

Ecco come creare quello script ed eseguirlo:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Punta la tua app sullo Slave

Eseguire query SELECT dallo Slave. Se sei soddisfatto del contenuto dei dati sullo Slave, sentiti libero di puntare la tua app allo schiavo come segue:

  1. Sullo slave, esegui SHOW SLAVE STATUS\Ge assicurati che Seconds_Behind_Master sia 0
  2. Sullo Slave, mysqldump -h (IP dello Slave) -u ... -p ... --le transazioni singole - routine - trigger - tutti i database> MySQLBackup.sql (Ehi, un backup farebbe bene circa ora)
  3. Sul Master, esegui service mysql stop(il tempo di inattività inizia)
  4. Ripeti il ​​passaggio 1
  5. Punta la tua app sullo slave (i tempi di inattività terminano alla prima connessione dell'app)

Se hai fatto questo incolume, CONGRATULAZIONI !!!

BONUS AGGIUNTO : Se si imposta la replica master / master (aka replica circolare) anziché Master / Slave, è possibile farlo invece:

  1. Sullo schiavo, corri SHOW SLAVE STATUS\Ge assicurati che Seconds_Behind_Master sia 0
  2. Sullo Slave, mysqldump -h (IP dello Slave) -u ... -p ... --le transazioni singole - routine - trigger - tutti i database> MySQLBackup.sql (Ehi, un backup farebbe bene circa ora)
  3. Punta la tua app sullo Slave (il tempo di inattività inizia e termina alla prima connessione dell'app)
  4. Sul nuovo Master, corri STOP SLAVE;
  5. Sul nuovo Master, corri CHANGE MASTER TO MASTER_HOST='';

Quello che hai ora è Master / Slave al contrario. Il nuovo master ha dati InnoDB e il vecchio master ora è uno slave con dati MyISAM. Se dividi letture e scritture, le letture possono andare dallo Slave (le letture sono più veloci da MyISAM di InnoDB) e le scritture vanno al Master (supporto transazionale per InnoDB). Come canta Hannah Montana, ottieni il meglio da entrambi i mondi (Sì, ho due figlie che adorano lo spettacolo) !!!

UN ALTRO BONUS AGGIUNTO : poiché il Master ora è InnoDB, puoi fare mysqldump dal Master senza tempi di inattività e senza interferire con le transazioni. L'unico inconveniente è aumentare la CPU e l'I / O del disco. È quindi possibile un mysqldump di strutture di tabella solo sul Master (InnoDB) e un mysqldump dei dati solo sullo slave (tale dump non avrà riferimenti a InnoDB o MyISAM. Saranno solo dati) più un mysqldump del le strutture della tabella per lo slave devono avere il layout MyISAM.

Le possibilità possono continuare grazie a questa nuova configurazione ...

AGGIORNAMENTO 2011-08-27 19:50 EDT

Mie scuse. Non ho letto completamente la domanda. Hai già eseguito la conversione .

Solo se hai già attivato la registrazione binaria e hai un backup precedente, puoi farlo

  • ripristina / var / lib / mysql in un'altra posizione, come / var / lib / mysql2
  • correre service mysql stop
  • correre service mysql start --datadir=/var/lib/mysql2
  • mysqldump il database da quel backup in /root/olddata.sql
  • eseguire mysqlbinlog su tutti i log binari in / var / lib / mysql (non / var / lib / mysql2) dal punto temporale dall'ultimo backup in /root/changes.sql
  • Carica changes.sql in mysql (poiché punta ancora a / var / lib / mysql2)

Questo dovrebbe catturare tutto ciò che è stato registrato e la conversione dovrebbe essere avviata. Ancora una volta, questo è tutto contiguo per te che hai già attivato la registrazione binaria prima dell'ultimo backup . Altrimenti, le mie condoglianze.

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.