Un fattore importante nelle prestazioni del database è il motore di archiviazione utilizzato dal database e, più specificamente, le sue tabelle. Diversi motori di archiviazione forniscono prestazioni migliori in una situazione rispetto a un'altra. Per l'uso generale, ci sono due contendenti da considerare. Questi sono MyISAM, che è il motore di archiviazione MySQL predefinito, o InnoDB, che è un motore alternativo integrato in MySQL destinato ai database ad alte prestazioni. Prima di poter comprendere la differenza tra i due motori di archiviazione, è necessario comprendere il termine "blocco".
Cos'è il blocco in MySQL?
Per proteggere l'integrità dei dati archiviati all'interno dei database, MySQL utilizza il blocco. Bloccare, in poche parole, significa proteggere i dati dall'accesso. Quando viene applicato un blocco, i dati non possono essere modificati se non dalla query che ha avviato il blocco. Il blocco è un componente necessario per garantire l'accuratezza delle informazioni memorizzate. Ciascun motore di archiviazione ha un metodo di blocco diverso utilizzato. A seconda dei dati e delle procedure di query, un motore può superare un altro. In questa serie, esamineremo i due tipi di blocco più comuni utilizzati dai nostri due motori di archiviazione.
Blocco del tavolo: La tecnica per bloccare un'intera tabella quando è necessario aggiornare o eliminare una o più celle all'interno della tabella. Il blocco delle tabelle è il metodo predefinito utilizzato dal motore di archiviazione predefinito, MyISAM.
Esempio:blocco della tabella MyISAM | Colonna A | Colonna B | Colonna C | |
Richiesta 1 AGGIORNAMENTO | Riga 1 | Scrittura | dati | dati |
Query 2 SELECT (Attendere) | Riga 2 | dati | dati | dati |
Query 3 AGGIORNAMENTO (Attendere) | Riga 3 | dati | dati | dati |
Query 4 SELECT (Attendere) | Riga 4 | dati | dati | dati |
Query 5 SELECT (Attendere) | Riga 5 | dati | dati | dati |
L'esempio illustra come una singola operazione di scrittura blocca l'intera tabella facendo sì che altre query attendano il completamento della query UPDATE. |
Blocco a livello di riga: L'atto di bloccare un intervallo effettivo di righe in una tabella mentre una o più celle all'interno dell'intervallo vengono modificate o eliminate. Il blocco a livello di riga è il metodo utilizzato dal motore di archiviazione InnoDB ed è destinato ai database ad alte prestazioni.
Esempio:blocco a livello di riga InnoDB | Colonna A | Colonna A | Colonna A | |
Richiesta 1 AGGIORNAMENTO | Riga 1 | Scrittura | dati | dati |
Query 2 SELEZIONA | Riga 2 | Lettura | dati | dati |
Query 3 AGGIORNAMENTO | Riga 3 | dati | Scrittura | dati |
Query 4 SELECT | Riga 4 | Lettura | Lettura | Lettura |
Query 5 SELECT | Riga 5 | Lettura | dati | Lettura |
L'esempio mostra come l'utilizzo del blocco a livello di riga consenta l'esecuzione di più query su singole righe bloccando solo le righe aggiornate anziché l'intera tabella. |
MyISAM contro InnoDB
Confrontando i due motori di archiviazione, arriviamo al nocciolo dell'argomento tra l'utilizzo di InnoDB su MyISAM. Un'applicazione o un sito Web con una tabella utilizzata di frequente funziona eccezionalmente bene utilizzando il motore di archiviazione InnoDB risolvendo i colli di bottiglia del blocco delle tabelle. Tuttavia, la questione dell'uso dell'uno sull'altro è soggettiva in quanto nessuno dei due è perfetto in tutte le situazioni. Ci sono punti di forza e limitazioni per entrambi i motori di archiviazione. La conoscenza intima della struttura del database e delle pratiche di query è fondamentale per selezionare il miglior motore di archiviazione per le tabelle.
MyISAM supererà le prestazioni di InnoDB su tabelle di grandi dimensioni che richiedono un'attività di lettura notevolmente maggiore rispetto a quella di scrittura. La leggibilità di MyISAM eclissa InnoDB perché bloccare l'intera tabella è più veloce che capire quali righe sono bloccate nella tabella. Più informazioni nella tabella, più tempo impiega InnoDB per capire quali non sono accessibili. Se la tua applicazione si basa su tabelle enormi che non cambiano i dati frequentemente, MyISAM supererà le prestazioni di InnoDB. Al contrario, InnoDB supera MyISAM quando i dati all'interno della tabella cambiano frequentemente. Le modifiche alla tabella scrivono i dati più che leggere i dati al secondo. In queste situazioni, InnoDB può tenere il passo con grandi quantità di richieste più facilmente che bloccare l'intera tabella per ognuna.
Dovrei usare InnoDB con siti WordPress, Magento o Joomla?
La risposta breve qui è sì, nella maggior parte dei casi. I team di supporto per l'hosting più utili di Liquid Web hanno riscontrato diversi colli di bottiglia nel blocco delle tabelle quando i client utilizzano alcune applicazioni Web standard di oggi. La maggior parte degli utenti di popolari applicazioni di terze parti come WordPress, Magento e Joomla hanno una conoscenza limitata dei componenti del database o del codice sottostanti coinvolti per prendere una decisione informata sui motori di archiviazione. La maggior parte dei colli di bottiglia del blocco delle tabelle di questi sistemi di gestione dei contenuti (CMS) vengono generalmente risolti modificando tutte le tabelle del sito su InnoDB anziché su MyISAM predefinito. Se stai ospitando molti di questi tipi di CMS sul tuo server, sarebbe utile modificare il motore di archiviazione predefinito in MySQL per utilizzare InnoDB per tutte le nuove tabelle in modo che qualsiasi installazione di nuove tabelle inizi con InnoDB.
Impostazione del motore di archiviazione predefinito
Imposta il tuo motore di archiviazione predefinito su InnoDB aggiungendo default_storage_engine=InnoDB a [mysqld] sezione del file di configurazione del sistema che si trova in: /etc/my.cnf. Il riavvio del servizio MySQL è necessario affinché il server rilevi le modifiche al file.
~ $ cat /etc/my.cnf
[mysqld]
log-error=/var/lib/mysql/mysql.err
innodb_file_per_table=1
default-storage-engine=innodb
innodb_buffer_pool_size=128M
Conversione di tutte le tabelle tra MyISAM e InnoDB
Sfortunatamente, MySQL non ha intrinsecamente un'opzione per convertire le tabelle, lasciando che ogni tabella venga modificata individualmente. Il team di supporto di Liquid Web ha messo insieme un piano di manutenzione facile da seguire per questo processo. Lo script, che puoi eseguire sul server necessario tramite accesso shell (SSH), convertirà tutte le tabelle tra i motori di archiviazione.
NotaPianificare di conseguenza quando si eseguono operazioni batch di questa natura nel caso in cui si verifichino tempi di inattività. La migliore pratica è eseguire il backup di tutti i database MySQL prima di implementare una modifica di questa portata, in questo modo si fornisce un punto di ripristino semplice per prevenire qualsiasi perdita di dati.Passaggio 1: Preparazione
Pianifica di iniziare in un momento della giornata in cui i tempi di inattività avrebbero conseguenze minime. Questo processo di per sé non richiede tempi di inattività, tuttavia, potrebbero essere necessari tempi di inattività per riprendersi da circostanze impreviste.
Passaggio 2: Backup di tutti i database in un file
Il comando seguente crea un unico file di backup di tutti i database denominato all-databases-backup.sqld e può essere eliminato una volta che la conversione è riuscita e non ci sono problemi evidenti. mysqldump --all-databases > all-databases-backup.sql
Passaggio 3: Registra i motori di tabella esistenti in un file
Esegui lo script seguente per registrare i motori di tabella esistenti in un file denominato table-engine-backup.sql . Puoi quindi "importare" o "eseguire" questo file in un secondo momento per riconvertirlo ai motori originali, se necessario.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=",Engine,";") FROM information_schema.tables WHERE table_schema NOT IN("mysql","information_schema","performance_schema");' | tee table-engine-backup.sql
Se è necessario ripristinare i motori delle tabelle per qualsiasi motivo, eseguire:mysql < table-engine-backup.sql
Passaggio 4a: Converti le tabelle MyISAM in InnoDB
Il comando seguente procederà anche se una tabella non riesce e ti consente di sapere quali tabelle non sono state convertite. L'output viene salvato nel file denominato convert-to-innodb.log per una revisione successivaw.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=InnoDB;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "MyISAM";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-innodb.log
Fase 4b:converti tutte le tabelle InnoDB in MyISAM
Questo comando procederà anche se una tabella non riesce e ti consente di sapere quali tabelle non sono state convertite. L'output viene anche salvato nel file denominato convert-to-myisam.log per una revisione successiva.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=MyISAM;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "InnoDB";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-myisam.log
Conversione di una singola tabella tra MyISAM e InnoDB
I seguenti comandi illustrano come viene eseguita la conversione di una singola tabella.
NotaSostituire database_name con il nome database corretto e table_name con il nome tabella corretto. Assicurati di avere un backup valido della tabella in questione prima di procedere.
Backup di una singola tabella in un file mysqldump database_name table_name > backup-table_name.sql
Convertire una singola tabella in InnoDB
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=InnoDB;’
Converti una singola tabella in MyISAM:
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=MyISAM;’
Dai un'occhiata ai nostri altri articoli di questa serie, Prestazioni MySQL:identificazione di query lunghe, per individuare query lente all'interno del tuo database. Resta sintonizzato per il nostro prossimo articolo in cui tratteremo la memorizzazione nella cache e l'ottimizzazione.