Accelerare la conversione di MyISAM in InnoDB


15

Ho un server mysql 5.1 con un database di circa 450 tabelle, che occupa 4 GB. La stragrande maggioranza di queste tabelle (tutte tranne 2) sono MyIsam. Questo è andato bene per la maggior parte (non sono necessarie transazioni), ma l'applicazione sta guadagnando traffico e alcune tabelle sono state influenzate a causa del blocco delle tabelle sugli aggiornamenti. Questo è il motivo per cui 2 delle tabelle sono InnoDB ora.

La conversione sulle tabelle più piccole (100.000 righe) non richiede molto tempo, causando tempi di inattività minimi. Tuttavia, alcune delle mie tabelle di tracciamento si stanno avvicinando a 50 milioni di righe. C'è un modo per accelerare un ALTER TABLE...ENGINE InnoDBsu tavoli di grandi dimensioni? E se no, ci sono altri metodi per convertire i tempi di inattività minimi su queste tabelle pesanti?


1
Qualcosa da tenere a mente: più domande in un singolo post tendono a scoraggiare le persone che possono rispondere a una delle domande dalla pubblicazione di una risposta.
BenV,

I VtC in quanto è piuttosto complicato rispondere. Dovresti aprire più domande singolarmente.
jcolebrand

Accetterò volentieri il consiglio di trasformarlo in una singola domanda, ma si consiglia di eliminare questa domanda e di aprirne una nuova? la riscrittura sarebbe principalmente rimuovendo i secondi 2 proiettili e modificando il primo (ho aggiornato anche il titolo per riflettere quali motori di archiviazione)
Derek Downey,

O andrebbe bene. Di solito è più facile scrivere altre due domande ed eliminare quella. Tuttavia, potresti lasciare facilmente questo come "riferimento" e fare in modo che gli altri due si riferiscano ad esso, come una domanda "questo è il mio obiettivo generale".
jcolebrand

modificalo in un solo punto, quindi pubblica le domande di follow-up.
Brian Ballsun-Stanton,

Risposte:


10

Vorrei iniziare dicendo che odio ALTER. È malvagio, IMHO.

Supponiamo che questo sia lo schema della tabella corrente:

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

Ecco il percorso che raccomando -

Crea un nuovo oggetto tabella che sostituirà quello vecchio:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

Inserisci tutte le righe della vecchia tabella per nome nella nuova tabella:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

Fumo prova la tua migrazione:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

Scambia i nomi delle tabelle in modo da poter mantenere un backup nel caso in cui sia necessario il rollback.

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

Procedere al test di regressione.

Questo approccio diventa sempre più preferibile con le tabelle con più indici e milioni di righe.

Pensieri?


1
D'accordo ... anche se se è fortemente transazionale, potrebbe essere necessario abbattere il database mentre lo si fa. (ma una tabella alternativa ti darà un periodo di inattività più lungo, molto probabilmente)
Joe

Sì, ho pensato che avrebbe richiesto tempi di inattività per le tabelle più attive. Dovrò eseguire alcuni test, ma perché ALTER TABLEimpiegare più tempo di INSERT INTO...SELECT50 milioni di righe?
Derek Downey,

Non lo farà. Fondamentalmente MySQL fa internamente esattamente come suggerito da questo poster. Crea una copia della definizione e carica di gocciolamento nella copia.
Morgan Tocker,

Mi piace questo metodo perché salta la parte "copia in tmp", che può richiedere del tempo per tabelle di grandi dimensioni.
Haluk,

Consentitemi di aggiungere ora che in MySQL 5.7 gli ALTER sono molto più veloci e più facili da gestire.
randomx,

7

1) La protezione dalle perdite è una funzione della paranoia. Effettua sempre un backup. Se sei davvero paranoico, esegui un backup e ripristina dal backup.

2) Questa pagina del manuale di MySQL contiene istruzioni per convertire i tipi di tabella.

Il modo più rapido per modificare una tabella in InnoDB è eseguire gli inserimenti direttamente in una tabella InnoDB. Cioè, utilizzare ALTER TABLE ... ENGINE = INNODB o creare una tabella InnoDB vuota con definizioni identiche e inserire le righe con INSERT INTO ... SELECT * FROM ....

3) PostgreSQL esegue ricerche full-text , The Sphinx Engine sembra farlo per MySQL


esaminerò sicuramente la sfinge, di cui ne ho sentito parlare solo di recente.
Derek Downey,

3

È X volte più facile ottimizzare l'intero server (configurazione della memoria, cache, indici) quando si utilizza un solo motore. Mescolare myisam con innodb su database di grandi dimensioni si bloccherà sempre a un certo punto forzato da un po 'di compromissione per far funzionare bene entrambi i motori (ma non eccellente :)

Vi consiglio di interesse per alcuni dedicati motori di ricerca a testo integrale come sfinge , Lucene ( solr ) e sbarazzarsi di esso dal livello di database.

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.