it-swarm.it

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

Ho alcuni server di produzione i cui file ibdata 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.

66
Abdul Manaf

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

Puoi 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

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

Passaggio 02) Elimina tutti i database (tranne mysql, performance_schema, e 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) Ricarica 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.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 compresso un file ibdata1 da 50 GB in 500 MB.

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

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;
110
RolandoMySQLDBA