Ecco una risposta più completa per quanto riguarda InnoDB. È un processo un po' lungo, ma può valere la pena.
Tieni presente che /var/lib/mysql/ibdata1
è il file più occupato nell'infrastruttura InnoDB. Normalmente ospita sei tipi di informazioni:
- Dati tabella
- Indici delle tabelle
- MVCC (Multiversioning Concurrency Control)
Dati
- Segmenti di rollback
- Annulla spazio
- Metadati tabella (dizionario dati)
- Doppio buffer di scrittura (scrittura in background per evitare che si affidi alla memorizzazione nella cache del sistema operativo)
- Inserisci buffer (gestione delle modifiche agli indici secondari non univoci)
- Vedi
Pictorial Representation of ibdata1
Architettura InnoDB
Molte persone creano più ibdata
file che sperano in una migliore gestione e prestazioni dello spazio su disco, tuttavia questa convinzione è sbagliata.
Posso eseguire OPTIMIZE TABLE
?
Sfortunatamente, eseguendo OPTIMIZE TABLE
contro una tabella InnoDB archiviata nel file tablespace condiviso ibdata1
fa due cose:
- Rende contigui i dati e gli indici della tabella all'interno di
ibdata1
- Rende
ibdata1
crescere perché i dati contigui e le pagine di indice vengono aggiunti aibdata1
Tuttavia, puoi separare i dati delle tabelle e gli indici delle tabelle da ibdata1
e gestirli in autonomia.
Posso eseguire OPTIMIZE TABLE
con innodb_file_per_table
?
Supponiamo di dover aggiungere innodb_file_per_table
a /etc/my.cnf (my.ini)
. Puoi quindi eseguire semplicemente OPTIMIZE TABLE
su tutte le tabelle InnoDB?
Buone notizie :Quando esegui OPTIMIZE TABLE
con innodb_file_per_table
abilitato, questo produrrà un .ibd
file per quella tabella. Ad esempio, se hai la tabella mydb.mytable
con una datadir di /var/lib/mysql
, produrrà quanto segue:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
Il .ibd
conterrà le pagine dati e le pagine indice per quella tabella. Ottimo.
Cattive notizie :Tutto quello che hai fatto è estrarre le pagine dati e le pagine indice di mydb.mytable
dal vivere in ibdata
. La voce del dizionario dei dati per ogni tabella, incluso mydb.mytable
, rimane ancora nel dizionario dei dati (consultare la Rappresentazione pittorica di ibdata1
). NON PUOI SEMPLICEMENTE ELIMINARE ibdata1
A QUESTO PUNTO!!! Tieni presente che ibdata1
non si è affatto ridotto.
Pulizia dell'infrastruttura InnoDB
Per ridurre ibdata1
una volta per tutte devi fare quanto segue:
-
Dump (ad esempio, con
mysqldump
) tutti i database in un.sql
file di testo (SQLData.sql
viene utilizzato di seguito) -
Elimina tutti i database (tranne
mysql
einformation_schema
) AVVISO :Per precauzione, esegui questo script per assicurarti di avere tutte le autorizzazioni utente in atto:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants
-
Accedi a mysql ed esegui
SET GLOBAL innodb_fast_shutdown = 0;
(Questo cancellerà completamente tutte le rimanenti modifiche transazionali daib_logfile0
eib_logfile1
) -
Spegni MySQL
-
Aggiungi le seguenti righe a
/etc/my.cnf
(omy.ini
su Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G
(Nota a margine:qualunque sia il tuo set per
innodb_buffer_pool_size
, assicuratiinnodb_log_file_size
è il 25% diinnodb_buffer_pool_size
.Inoltre:
innodb_flush_method=O_DIRECT
non è disponibile su Windows) -
Elimina
ibdata*
eib_logfile*
, Facoltativamente, puoi rimuovere tutte le cartelle in/var/lib/mysql
, eccetto/var/lib/mysql/mysql
. -
Avvia MySQL (questo ricreerà
ibdata1
[10 MB per impostazione predefinita] eib_logfile0
eib_logfile1
a 1G ciascuno). -
Importa
SQLData.sql
Ora, ibdata1
continuerà a crescere ma conterrà solo i metadati della tabella perché ogni tabella InnoDB esisterà al di fuori di ibdata1
. ibdata1
non conterrà più dati e indici InnoDB per altre tabelle.
Ad esempio, supponiamo di avere una tabella InnoDB denominata mydb.mytable
. Se guardi in /var/lib/mysql/mydb
, vedrai due file che rappresentano la tabella:
mytable.frm
(intestazione del motore di archiviazione)mytable.ibd
(Dati tabella e indici)
Con il innodb_file_per_table
opzione in /etc/my.cnf
, puoi eseguire OPTIMIZE TABLE mydb.mytable
e il file /var/lib/mysql/mydb/mytable.ibd
si ridurrà effettivamente.
L'ho fatto molte volte nella mia carriera come DBA MySQL. In effetti, la prima volta che l'ho fatto, ho ridotto di 50 GB ibdata1
file fino a soli 500 MB!
Provaci. Se hai altre domande su questo, chiedi. Fidati di me; questo funzionerà sia a breve che a lungo termine.
AVVISO
Al passaggio 6, se mysql non può riavviarsi a causa di mysql
schema begin droppato, guarda indietro al passaggio 2. Hai fatto la copia fisica di mysql
schema. Puoi ripristinarlo come segue:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Torna al passaggio 6 e continua
AGGIORNAMENTO 04-06-2013 11:13 EDT
Per quanto riguarda l'impostazione di innodb_log_file_size al 25% di innodb_buffer_pool_size nel passaggio 5, questa regola generale è piuttosto vecchia scuola.
Torna su July 03, 2006
, Percona ha pubblicato un bell'articolo perché scegliere un corretto innodb_log_file_size . Più tardi, il Nov 21, 2008
, Percona ha proseguito con un altro articolo su come calcolare la dimensione corretta in base al carico di lavoro di picco mantenendo un'ora di modifiche
.
Da allora ho scritto post in DBA StackExchange sul calcolo della dimensione del registro e su dove ho fatto riferimento a quei due articoli di Percona.
Aug 27, 2012
:Ottimizzazione corretta per una tabella InnoDB da 30 GB su server con 48 GB di RAMJan 17, 2013
:MySQL 5.5 - Innodb - innodb_log_file_size superiore a 4 GB combinati?
Personalmente, continuerei a seguire la regola del 25% per una configurazione iniziale. Quindi, poiché il carico di lavoro può essere determinato in modo più accurato nel tempo in produzione, è possibile ridimensionare i registri durante un ciclo di manutenzione in pochi minuti.