Qual è il modo migliore per ridurre la dimensione di ibdata in mysql?


63

Ho alcuni server di produzione i cui ibdatafile aumentano di giorno in giorno.

Ha già consumato 290 GB di spazio.

Le tabelle nei server sono principalmente InnoDB e ci sono richieste di lettura e scrittura elevate.

Anche la dimensione del file di registro aumenta. C'è un'enorme quantità di dati nelle tabelle.

Come posso controllare la dimensione crescente di entrambi?

Non sto usando innodb_file_per_table.

Risposte:


104

Tieni presente che il file più occupato nell'infrastruttura InnoDB è / var / lib / mysql / ibdata1

Questo file contiene normalmente molte classi di informazioni (quando innodb_file_per_table è 0)

  • Dati tabella
  • Indici delle tabelle
  • Dati MVCC (Multiversioning Concurrency Control)
    • Segmenti di rollback
    • Annulla tablespace
  • Tabella dei metadati
  • Vedi rappresentazione pittorica

Molte persone creano più file ibdata sperando in una migliore gestione e prestazioni dello spazio su disco. Non aiuta

Sfortunatamente, OPTIMIZE TABLE su una tabella InnoDB memorizzata in ibdata1 fa due cose:

  • Rende i dati e gli indici della tabella contigui all'interno di ibdata1
  • Fa crescere ibdata1 perché i dati contigui vengono aggiunti a ibdata1

È possibile separare i dati delle tabelle e gli indici delle tabelle da ibdata1 e gestirli in modo indipendente utilizzando innodb_file_per_table . Per ridurre ibdata1 una volta per tutte, devi fare quanto segue

Step 01) MySQLDump di tutti i database in un file di testo SQL (chiamalo SQLData.sql) ( Maggiori dettagli qui )

Step 02) Eliminare tutti i database (ad eccezione mysql, performance_schemae information_schema)

Passaggio 03) Spegni mysql

Passaggio 04) Aggiungi le seguenti righe a /etc/my.cnf

[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 per innodb_buffer_pool_size, assicurati che innodb_log_file_size sia il 25% di innodb_buffer_pool_size.

Passaggio 05) Elimina ibdata1, ib_logfile0 e ib_logfile1

A questo punto, dovrebbe esserci solo lo schema mysql in / var / lib / mysql

Passaggio 06) Riavvia mysql

Ciò ricrea ibdata1 a 10 MB, ib_logfile0 e ib_logfile1 a 1G ciascuno

Passaggio 07) Ricaricare SQLData.sql in mysql

ibdata1 crescerà ma conterrà solo metadati di tabella

Ogni tabella InnoDB esiste al di fuori di ibdata1

Supponiamo di avere una tabella InnoDB denominata mydb.mytable. Se vai in / var / lib / mysql / mydb, vedrai due file che rappresentano la tabella

  • mytable.frm (intestazione del motore di archiviazione)
  • mytable.ibd (Home dei dati delle tabelle e degli indici delle tabelle per mydb.mytable)

ibdata1 non conterrà più dati e indici InnoDB.

Con l'opzione innodb_file_per_table in /etc/my.cnf, puoi eseguire OPTIMIZE TABLE mydb.mytablee il file /var/lib/mysql/mydb/mytable.ibdsi ridurrà effettivamente.

L'ho fatto molte volte nella mia carriera come DBA MySQL

In effetti, la prima volta che l'ho fatto, ho compresso un file ibdata1 da 50 GB in 500 MB.

Provaci. Se hai ulteriori domande al riguardo, inviami un'e-mail. Fidati di me. Questo funzionerà a breve termine e nel lungo periodo. !!!

Se desideri vedere quanti dati effettivi sono memorizzati in MyISAM e InnoDB, esegui questa query:

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size"
FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

Anche con le impostazioni suggerite per my.cnf (che già ho), eliminando ib_logfile0 e 1 e quindi avviando mysql, i nuovi file vengono creati e in pochi secondi crescono per uguagliare le dimensioni del database come visualizzato dalla query precedente. Non sono sicuro che mysql stia copiando tutte le tabelle e gli indici in questi file mantenendo ogni tabella in un file separato.
Allen King,
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.