Perché usare innodb_file_per_table?


27

Ci sono molti articoli che esagerano (IMHO ovviamente) la necessità innodb_file_per_table. Capisco che con innodb_file_per_table, ci dovrebbe essere un migliore controllo sui singoli tavoli; come il backup di ogni tabella separatamente. Tuttavia, la richiesta di prestazioni migliori è discutibile.

Nel mio test, non vi è alcuna differenza nelle prestazioni di innodb_file_per_tablee ibdata1per un database di 60 GB. Certo, è stato un semplice test con query normali e la situazione può essere diversa per query complicate nella vita reale (questa è la ragione per cui ho posto questa domanda). Linux a 64 bit con ext4può gestire efficacemente file di grandi dimensioni.

Con innodb_file_per_table, sono necessarie più operazioni di I / O su disco; e questo è significativo per complicazioni JOINe FOREIGN KEYvincoli.

Il tablespace è condiviso su singolo ibdata; come tablespace dedicati per tabelle separate possono risparmiare spazio su disco? Ovviamente, è più facile liberare spazio per ogni tabella ALTER, ma è comunque un processo costoso (con blocco della tabella).

DOMANDA: non innodb_file_per_tableha un effetto su una migliore performance di MySQL? Se si, perché?


Vedi questa risposta alla mia domanda: dba.stackexchange.com/questions/7924/… potrebbe anche aiutare.
KM.

Risposte:


19

Non penso sia una questione di prestazioni ma di gestione.

Con file separati per tabella, ad esempio è possibile archiviare database diversi in diversi dispositivi di archiviazione.

È possibile gestire il caso di database molto grandi nei file system che non sono in grado di gestire file di grandi dimensioni (almeno rinviare il problema fino a quando una tabella non raggiunge il limite della dimensione del file).

Non hai una crescita incontrollata del tablespace. Se hai alcuni tavoli grandi che lasci cadere, il ibdatafile rimane piccolo.

Un aspetto che può influire sulle prestazioni è la frammentazione dei dati e degli indici delle tabelle, che sarà limitata per tabella. Ma questo ha bisogno di essere testato per essere confermato.


La crescita del tablespace è esattamente il motivo per cui vuoi innodb_file_per_table.
sjas,

13

Perché usare innodb_file_per_table?

Perché è più facile gestire i singoli poiché può essere eseguito a livello di file. Ciò significa che anche se il server è inattivo, è comunque possibile copiare i dati copiando i file della tabella mentre l'utilizzo di un tablespace condiviso significa copiare tutto che può essere inutilmente massiccio, sia trovare un modo per far funzionare il server per estrarre i dati ( non vuoi davvero estrarre manualmente i dati con un editor esadecimale).

Qualcuno ha avvertito che non è possibile semplicemente copiare e incollare i .ibdfile da un server all'altro. Questo può essere vero, ma non dovrebbe applicarsi ai backup sullo stesso server (sto usando il termine backup qui nel senso tradizionale del fare una copia; cioè, non cambiando drasticamente il tutto). Inoltre, ibdata1viene ricreato automaticamente all'avvio (come visto nella fase di eliminazioneibdata1 della maggior parte delle guide di "conversione in file per tabella"). Pertanto, non è necessario copiare ibdata1oltre ai .ibdfile (e i .frmfile corrispondenti , ecc.).

Se si tenta di ripristinare una tabella persa, dovrebbe essere sufficiente copiarne .ibde il .frmfile, nonché information_schema(che è molto più piccolo di ibdata1). In questo modo, puoi metterli in un server fittizio ed estrarre il tuo tavolo senza dover copiare l'intera cosa enorme.

Tuttavia, la richiesta di prestazioni migliori è discutibile. ... Con innodb_file_per_table, sono necessarie più operazioni di I / O su disco; e questo è significativo nei complicati JOIN e nei vincoli ESTERI CHIAVE.

Non sorprende, le prestazioni dipenderanno interamente dai database specifici in uso. Una persona avrà (anche molto) risultati diversi da un'altra.

È vero che ci saranno più operazioni di I / O su disco con file per tabella, ma solo leggermente di più. Pensa a come funziona il sistema.

  • Per un database monolitico:

    1. Il server è avviato
    2. ibdata1 è aperto
    3. Intestazione e metadati vengono letti
    4. Strutture e metadati vengono memorizzati nella cache
    5. Le domande accadono
      1. Il server accede al disco e legge i dati dal già aperto ibdata1
      2. Il server può memorizzare nella cache i dati
  • Per un database per tabella:

    1. Il server è avviato
    2. ibdata1 è aperto
    3. Intestazione e metadati vengono letti
    4. Ogni singolo .ibdfile viene aperto
    5. Intestazione e metadati vengono letti da ciascun .ibdfile
    6. Strutture e metadati vengono memorizzati nella cache
    7. Le domande accadono
      1. Il server accede al disco e legge i dati dal .ibdfile già aperto
      2. Il server può memorizzare nella cache i dati

Noterai che quando il server è in esecuzione, non puoi spostare i file di dati perché il server ha degli handle aperti su di essi. Questo perché quando si avvia, li apre e li lascia aperti. Non li apre e li chiude per ogni singola query.

Come tale, ci sono solo alcune altre operazioni di I / O all'inizio, all'avvio del server; non mentre è in esecuzione. Inoltre, sebbene ogni singolo .ibdfile abbia un proprio overhead separato (firme, strutture dei file, ecc.), Essi vengono memorizzati nella cache e non vengono riletti per ogni query. Inoltre, le stesse strutture vengono lette anche con un tablespace condiviso, quindi non c'è quasi più (se non del tutto) più memoria richiesta.

Innodb_file_per_table ha un effetto su una migliore prestazione di mysql?

In realtà, se non altro, le prestazioni potrebbero in effetti essere peggiori .

Quando si utilizza un tablespace condiviso, le operazioni di lettura e scrittura possono talvolta / spesso essere combinate in modo che il server legga un campione di dati da più tabelle in una volta sola ibdata.

Tuttavia, se i dati sono distribuiti su più file, è necessario eseguire un'operazione I / O separata per ognuno di essi.

Ovviamente questo è di nuovo interamente dipendente dal database in questione; l'impatto sulle prestazioni del mondo reale dipenderà dalle dimensioni, dalla frequenza delle query e dalla frammentazione interna del tablespace condiviso. Alcune persone possono notare una grande differenza, mentre altri potrebbero non vedere alcun impatto.

Il tablespace è condiviso su un singolo ibdata; come tablespace dedicati per tabelle separate possono risparmiare spazio su disco?

Non è così. Semmai, aumenta l' utilizzo del disco in parte.

Non ho un database da 60 GB con cui testare, ma il mio database personale "scarso" che contiene la mia installazione di WordPress e alcune piccole tabelle per uso personale e test di sviluppo pesava a ~ 30 MB mentre utilizzava un tablespace condiviso. Dopo averlo convertito in file per tabella, si è gonfiato a ~ 85 MB. Anche facendo cadere tutto e reimportando, era ancora> 60 MB.

Questo aumento è dovuto a due fattori:

  • La dimensione minima assoluta per ibdata1è - per qualche motivo - 10 MB, anche se non hai altro che information_schemaarchiviato al suo interno.

  • Con un tablespace condiviso, ibdata1ha solo un sovraccarico come firme di file, metadati, ecc., Ma per tabella, ogni singolo .ibdfile ha tutto questo. Ciò significa che il totale (anche con un ipotetico <10 MB ibdata1) sarebbe un po 'più grande di almeno:

    GetTotalSizeofOverhead() * GetNumTables()

Ovviamente questi non aumenteranno enormemente (a meno che tu non stia utilizzando un host che limiti le dimensioni del tuo database o li memorizzi su un'unità flash, ecc.), Ma sono comunque aumenti e passando da ( ogni ) tabella a file -per-tavolo è possibile ridurre ibdata1a 10 MB, il totale complessivo sarà invariabilmente maggiore di quello che era.


11

Questo è il motivo per cui uso SEMPRE innodb_file_per_table:

Senza file per tabella, il file ibdata non viene mai compresso o ridotto o mai ridotto nello spazio. Non quando si elimina una riga, si elimina una tabella o un database. 2 GB di dati possono diventare file da 20 GB in pochissimo tempo se si dispone di un sistema di accodamento attivo.

Diciamo che vuoi fare un backup del tuo attuale tavolo da 1 GB prima di una modifica, quindi rilasciarlo in seguito. Sei bloccato con un GB di spazio ora inutilizzato nel tuo ibdata. Bummer.

Probabilmente ci sono infiniti esempi di casi in cui misure temporanee gonfiano il singolo file di dati, ma è sufficiente dire che, secondo me, non c'è mai un motivo per NON usare innodb_file_per_table

Inoltre, ecco un buon post da leggere: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table


1
Mi sono reso conto che va bene anche SEMPRE farlo. Gli array di archiviazione magnetici supportati dagli SSD possono gestire le cache di lettura / scrittura in modo più efficace rispetto ai file più piccoli per le tabelle. Per un gruppo di tabelle che% 99,99 delle volte vengono semplicemente "lette" ma non scritte, si trovano sempre nella cache del controller di archiviazione, il che rappresenta una notevole riduzione dei tempi di risposta.
sdkks,

5

La mia ragione per non usare innodb_file_per_table è la prestazione.

Ho fatto alcuni test per il nostro database con 450 tabelle su mysql 5.5.45 Linux CentOS versione 6.7

Per i test unitari che inseriscono dispositivi nel database prima di ogni test (non usando tutte le tabelle ogni volta) e anche i test stessi funzionano molto con il database (inserisce, aggiorna, elimina, seleziona) le prestazioni erano 3-5 volte migliori quando le tabelle del database non lo erano separato in più file.

Ti consiglio di testare il tuo database con le query che desideri utilizzare e confrontarlo prima di decidere di utilizzare innodb_file_per_table

Forse puoi scoprire che per il server di produzione puoi usare innodb_file_per_table ma per l'ambiente CI (continua l'integrazione) che avvia test di unità (usa molto DB) e anche gli sviluppatori che iniziano molto test di unità è meglio non usarlo a causa delle prestazioni.


2
Immagino che ciò sia dovuto al tempo necessario per allocare i file iniziali per tutte le 450 tabelle rispetto all'allocazione di un singolo file. In produzione questo accadrà solo una volta, quindi non dovrebbe essere un problema, ma è opportuno sottolineare che per creare rapidamente un database e poi ridurlo completamente e ripetere più volte su un singolo file ibdata è meglio.
ColinM

2

Rende i dati più gestibili perché puoi recuperare spazio inutilizzato, il che è bello.

Penso che se il tuo database viene utilizzato principalmente per query selezionate non influirà molto sulle prestazioni. Deve ancora leggere la stessa quantità di dati. Non penso che importi molto da quali file sta leggendo i dati.

Tuttavia, potrebbe peggiorare le prestazioni su un database che esegue molti inserimenti e aggiornamenti. Questo perché mysql chiama fsync () sul file di archiviazione dopo aver eseguito il commit di una transazione. Se esiste un singolo file, effettua una chiamata e attende il completamento della chiamata. Se sono presenti molti file, è necessario effettuare più volte la chiamata e attendere la restituzione di tutte quelle chiamate prima che il comando commit possa tornare.

Ecco un post di qualcuno che ha riscontrato questo problema: http://umangg.blogspot.com/2010/02/innodbfilepertable.html



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.