MySQL InnoDB - contro innodb_file_per_table?


32

Per impostazione predefinita, MySQL InnoDB archivia tutte le tabelle di tutti i DB in un file globale. È possibile modificarlo impostando innodb_file_per_table nella configurazione, che quindi crea un file di dati per ogni tabella.

Mi chiedo perché innodb_file_per_tablenon sia abilitato per impostazione predefinita. Ci sono aspetti negativi nell'usarlo?

Risposte:


32

Ho la risposta completa per questo.

Una volta che innodb_file_per_table è stato messo in atto, e le nuove tabelle InnoDB possono essere ridotte usando ALTER TABLE <innodb-table-name> ENGINE=InnoDB';Ciò ridurrà i nuovi .ibdfile GARANTITI.

Se corri ALTER TABLE <innodb-table-name> ENGINE=InnoDB';su una tabella InnoDB creata prima di usare innodb_file_per_table, strapperà i dati e gli indici per quella tabella dal file ibdata1 e li memorizzerà in un .ibdfile, questo lascerà un intero piccione permanente nell'ibdata1 che non potrà mai essere riutilizzato .

Il ibdata1file contiene normalmente quattro tipi di informazioni

  • Dati tabella
  • Indici delle tabelle
  • Dati MVCC (Multiversioning Concurrency Control)
    • Segmenti di rollback
    • Annulla spazio
  • Tabella dei metadati (dizionario dei dati)
  • Double Write Buffer (scrittura in background per impedire la dipendenza dalla cache del sistema operativo)
  • Inserisci buffer (gestione delle modifiche agli indici secondari non univoci)
  • Vedi il Pictorial Representation of ibdata1

Ecco il modo garantito per ridurre il file ibdata1 praticamente per sempre ...

PASSAGGIO 01) MySQLDump di tutti i database in un file di testo SQL (chiamalo SQLData.sql)

PASSAGGIO 02) Eliminare tutti i database (tranne gli schemi mysql, information_schema e performance_schema)

PASSAGGIO 03) Spegnimento 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
innodb_data_file_path=ibdata1:10M:autoextend

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 ( vedi l'aggiornamento sotto prima di cancellare! )

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

  • PASSAGGIO 06) Riavvia mysql

Ciò ricrea ibdata1 a 10 MB (non configurare l'opzione), ib_logfile0 e ib_logfile1 a 1G ciascuno

  • PASSAGGIO 07) Ricaricare SQLData.sql in mysql

ibdata1 crescerà ma conterrà solo metadati di tabella e dati MVCC intermittenti.

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.mytableOR ALTER TABLE mydb.mytable ENGINE=InnoDB;e il file /var/lib/mysql/mydb/mytable.ibdsi ridurrà effettivamente.

L'ho fatto numerose volte nella mia carriera come DBA MySQL senza un singolo problema da allora in poi. In effetti, la prima volta che l'ho fatto, ho compresso un file ibdata1 da 50 GB in 50 MB.

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

AGGIORNAMENTO 2013-07-02 15:08 EDT

C'è un avvertimento che ho a questo proposito che ho aggiornato in altri miei post, ma ho perso questo: sto aggiornando un po 'di più la mia risposta con innodb_fast_shutdown perché ho usato per riavviare mysql e fermare mysql per farlo. Ora, questo passaggio è fondamentale poiché ogni transazione non impegnata può avere altre parti mobili all'interno e all'esterno dei registri delle transazioni di InnoDB ( vedi InnoDB Infrastruttura ).

Si noti che l'impostazione innodb_fast_shutdown su 2 pulirà anche i logout ma esistono ancora più parti mobili e vengono raccolte su Crash Recovery durante l'avvio di mysqld. L'impostazione di 0 è la migliore.


Informazioni fantastiche - grazie! 50 GB >> 50 MB: è davvero impressionante!
UpTheCreek,

Ciao, ho provato a fare esattamente come hai scritto qui, l'unico "problema" è che il server non si avvia in seguito. se faccio il mysql di servizio di avvio si blocca lì. Se cambio il mio vecchio file cnf è tutto ok. Hai qualche idea su questo?
Nicola Peluchetti,

Questa domanda è per Nicola: hai fatto il passaggio 5 ???
RolandoMySQLDBA

Un'altra domanda per @Nicola: quanta RAM hai nel tuo sistema ???
RolandoMySQLDBA

2
Stai attento! L'opzione innodb_fast_shutdown=0deve essere impostata in MySQL, prima di chiuderla per eliminare i file di registro! ( ib_logfile0e ib_logfile1) Altrimenti, potresti perdere dati!
Totor,

12

Vedi bug .

Ci sono aspetti negativi nell'usarlo?

  • più file aperti
  • aprire / riaprire dall'alto
  • Il file .ibd non si restringe (vedere 1 , 2 )

Uso sempre innodb_file_per_table su database di grandi dimensioni.


Anche se non lo usi, i file ibdata non si ridurranno, neanche :(
minaev

1
Grazie. Mi chiedo anche perché non esiste un'opzione per avere un file per db?
UpTheCreek

1
@UpTheCreek, le tabelle sono entità. I database sono gruppi logici di entità, piuttosto che entità a sé stanti. È più ovvio con MyISAM, dove i database sono directory e le tabelle sono file.
John Gardeniers,

Volevo solo sottolineare che mentre i file .ibd non si restringono automaticamente , né lo fanno ibdata1l'alternativa al file per tabella. Almeno è possibile ridurre un .ibd usando optimize table, il che è banale rispetto alla riduzione di ibdata1.
Roman,

8

innodb_file_per_table è abilitato di default in MariaDB.


1
Non nel mio (la versione predefinita in CentOS 7). È necessario l'equivalente di MySQL 5.6.6 o versioni successive. In caso contrario, l'impostazione predefinita è disattivata .
Lightness Races con Monica

2

Il motivo per cui ho deciso di non utilizzare innodb_file_per_table, è perché ogni tabella viene inserita nel proprio file, il che significa che ogni tabella ottiene il proprio overhead separato (firme dei file, ecc.) Che causa la dimensione totale e totale della MySQLdirectory più grande di se si utilizza un tablespace condiviso. Inoltre, c'è più spazio sprecato a causa del cluster-slack quando si hanno più file piccoli invece di uno singolo, grande.

Certo, l'overhead aggiuntivo non è una grande quantità nel grande schema delle cose, specialmente se stai utilizzando un disco di grandi dimensioni o hai un database gigante, ma per me stesso (e probabilmente molti "utenti domestici"), tutto sommato e era ancora troppo per il piccolo disco con cluster di grandi dimensioni in cui tenevo il mio negozio MySQL.

Ad esempio, il mio archivio di database con i miei database WordPress e pochi altri piccoli database (phpBB, dev, alcuni test AMP, ecc), la conversione in per-tavolo cambiato da 32MB a 50MB, e che non è nemmeno compreso il ibdata1che ancora richiede un minimo di 10 MB , per un totale di almeno 60 MB.

Come ho detto, questo potrebbe non essere un grosso problema per alcune persone, in particolare le imprese, ma se sei un utente domestico che ospita solo il tuo sito, blog, ecc., Può davvero essere un fattore in cose come la scelta un fornitore di host perché molti host limitano le dimensioni del database oltre all'utilizzo totale del disco.


1
Pensavo fossi pazzo (a chi importa di circa dieci megabyte ???) fino a quando non hai capito le quote strette dei provider di hosting. Non ci avrei mai pensato.
Dan Pritts il

@DanPritts, in particolare gli host gratuiti. Inoltre, potresti avere un disco gigante, ma non tutti. Nell'ultimo anno ho ampliato la mia partizione dati principale da 1 GB a 2 GB perché era troppo stretta, ma anche 10 MB qui e 10 MB lì (specialmente con i file di registro) possono consumarlo velocemente. Inoltre, non dimenticare di aggiungere anche i rifiuti dei cluster. Infine, non è nemmeno necessariamente un disco rigido . Ad esempio, sto attualmente "trasferendo" il mio sito Web in modo da poterlo ospitare da qualsiasi sistema, quindi un'unità flash da 2 GB è già limitata. Pertanto, mantenere dimensioni ridotte ed evitare le scritture è fondamentale. E poi ci sono sistemi integrati!
Synetech,

Inoltre, non è 10 MB (questa è la dimensione minima assoluta per IBDATA1). È passato da 30 MB a ~ 85 MB. Eliminando il tutto e importando un dump da zero, ho finito con un 69MB invece dei precedenti 30MB (una supposizione quale database ne occupasse più della metà ☺). Per qualche ragione, nonostante l'utilizzo per tabella, il mio ibdata1è ancora 18 MB. ☹
Synetech,

Sembra piuttosto qualcosa che ho avuto con un'installazione CMS con vs. one senza selinux abilitato, a giudicare dalle dimensioni dei file di 32M contro 50M. Non riesco davvero a credere ai numeri, quanti database hai anche che i metadati di alcuni file possono aggiungere dimensioni MEGABYTES su sistemi altrimenti identici?
sjas,

2

Solo per aggiungere qualche informazione in più

Da mysql 5.6.6 è abilitato di default


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.