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
- Creare un'impostazione master / slave di replica
- Converti ogni tabella MyISAM sullo slave in InnoDB
- 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:
- Sullo slave, esegui
SHOW SLAVE STATUS\G
e assicurati che Seconds_Behind_Master sia 0
- 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)
- Sul Master, esegui
service mysql stop
(il tempo di inattività inizia)
- Ripeti il passaggio 1
- 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:
- Sullo schiavo, corri
SHOW SLAVE STATUS\G
e assicurati che Seconds_Behind_Master sia 0
- 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)
- Punta la tua app sullo Slave (il tempo di inattività inizia e termina alla prima connessione dell'app)
- Sul nuovo Master, corri
STOP SLAVE;
- 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.