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
ibdata1crescere 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.sqlfile di testo (SQLData.sqlviene utilizzato di seguito) -
Elimina tutti i database (tranne
mysqleinformation_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_logfile0eib_logfile1) -
Spegni MySQL
-
Aggiungi le seguenti righe a
/etc/my.cnf(omy.inisu 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_DIRECTnon è 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_logfile0eib_logfile1a 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.