È possibile pulire un motore di archiviazione mysql innodb in modo che non memorizzi i dati dalle tabelle eliminate?
O devo ricostruire un nuovo database ogni volta?
È possibile pulire un motore di archiviazione mysql innodb in modo che non memorizzi i dati dalle tabelle eliminate?
O devo ricostruire un nuovo database ogni volta?
Risposte:
Ecco una risposta più completa riguardo a 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. Ospita normalmente sei tipi di informazioni:
Pictorial Representation of ibdata1
Molte persone creano più ibdata
file sperando in una migliore gestione e prestazioni dello spazio su disco, tuttavia questa convinzione è errata.
OPTIMIZE TABLE
?Sfortunatamente, l'esecuzione OPTIMIZE TABLE
su una tabella InnoDB memorizzata nel file tablespace condiviso ibdata1
fa due cose:
ibdata1
ibdata1
crescere perché le pagine di dati e indice contigui vengono aggiunti aibdata1
Tuttavia, è possibile separare i dati delle tabelle e gli indici delle tabelle da ibdata1
e gestirli in modo indipendente.
OPTIMIZE TABLE
con innodb_file_per_table
?Supponiamo che si dovesse aggiungere innodb_file_per_table
a /etc/my.cnf (my.ini)
. Puoi quindi eseguire solo OPTIMIZE TABLE
su tutte le tabelle InnoDB?
Buone notizie : quando si esegue OPTIMIZE TABLE
con innodb_file_per_table
abilitato, questo produrrà un .ibd
file per quella tabella. Ad esempio, se si dispone di una tabella mydb.mytable
con 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 di dati e le pagine indice per quel tavolo. Grande.
Cattive notizie : tutto ciò che hai fatto è estrarre le pagine di dati e le pagine di indice mydb.mytable
dal vivere ibdata
. La voce del dizionario dei dati per ogni tabella, incluso mydb.mytable
, rimane ancora nel dizionario dei dati (vedere la rappresentazione grafica di ibdata1 ). NON PUOI ESSERE SOLO ELIMINATO ibdata1
A QUESTO PUNTO !!! Si noti che ibdata1
non si è affatto ridotto.
Per ridurre ibdata1
una volta per tutte è necessario effettuare le seguenti operazioni:
Dump (ad es. Con mysqldump
) tutti i database in un .sql
file di testo ( SQLData.sql
utilizzato di seguito)
Elimina tutti i database (eccetto mysql
e information_schema
) CAVEAT : per precauzione, esegui questo script per assicurarti di disporre di tutte le autorizzazioni utente:
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 eliminerà completamente tutte le rimanenti modifiche transazionali da ib_logfile0
e ib_logfile1
)
Chiudi MySQL
Aggiungi le seguenti righe a /etc/my.cnf
(o my.ini
su Windows)
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
(Sidenote: qualunque sia il tuo set innodb_buffer_pool_size
, assicurati che innodb_log_file_size
sia il 25% di innodb_buffer_pool_size
.
Inoltre: innodb_flush_method=O_DIRECT
non è disponibile su Windows)
Elimina ibdata*
e ib_logfile*
, facoltativamente, puoi rimuovere tutte le cartelle in /var/lib/mysql
, tranne /var/lib/mysql/mysql
.
Avviare MySQL (questo ricrea ibdata1
[10 MB per impostazione predefinita] ib_logfile0
e ib_logfile1
a 1G ciascuno).
Importare SQLData.sql
Ora, ibdata1
continuerà a crescere ma conterrà solo metadati di 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 dentro /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 l' innodb_file_per_table
opzione in /etc/my.cnf
, è possibile eseguire OPTIMIZE TABLE mydb.mytable
e il file /var/lib/mysql/mydb/mytable.ibd
verrà effettivamente ridotto.
L'ho fatto molte volte nella mia carriera come DBA MySQL. In effetti, la prima volta che l'ho fatto, ho ridotto un file da 50 GB ibdata1
a soli 500 MB!
Provaci. Se hai ulteriori domande su questo, basta chiedere. Fidati di me; questo funzionerà a breve termine e nel lungo periodo.
Al passaggio 6, se mysql non è in grado di riavviarsi a causa mysql
dell'inizio dello schema rilasciato, tornare al passaggio 2. È stata effettuata la copia fisica dello 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
Per quanto riguarda l'impostazione di innodb_log_file_size al 25% di innodb_buffer_pool_size al passaggio 5, questa regola generale è piuttosto vecchia scuola.
Di nuovo July 03, 2006
, Percona aveva un bell'articolo sul perché scegliere un innodb_log_file_size corretto . Successivamente, Nov 21, 2008
Percona ha seguito un altro articolo su come calcolare la dimensione corretta in base al picco del carico di lavoro mantenendo un'ora di modifiche .
Da allora ho scritto messaggi nello StackExchange di DBA sul calcolo delle dimensioni del registro e su cui ho fatto riferimento a quei due articoli di Percona.
Aug 27, 2012
: Ottimizzazione corretta per 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 con la regola del 25% per una configurazione iniziale. Quindi, poiché il carico di lavoro può essere determinato in modo più preciso nel tempo in produzione, è possibile ridimensionare i registri durante un ciclo di manutenzione in pochi minuti.
innodb_open_tables
se necessario. Il valore predefinito è 300.
Il motore InnoDB non memorizza i dati eliminati. Durante l'inserimento e l'eliminazione delle righe, lo spazio inutilizzato viene allocato nei file di archiviazione di InnoDB. Nel tempo, lo spazio complessivo non diminuirà, ma nel tempo lo spazio "cancellato e liberato" verrà automaticamente riutilizzato dal server DB.
È possibile ottimizzare ulteriormente e gestire lo spazio utilizzato dal motore attraverso una riorganizzazione manuale delle tabelle. Per fare ciò, scaricare i dati nelle tabelle interessate utilizzando mysqldump, eliminare le tabelle, riavviare il servizio mysql e quindi ricreare le tabelle dai file di dump.