Perché InnoDB archivia tutti i database in un unico file?


51

Era conveniente che MyISAM usasse memorizzare ogni tabella in un file corrispondente. InnoDB ha fatto progressi in molti aspetti, ma mi chiedo perché InnoDB memorizzi tutti i database in un file ( ibdata1per impostazione predefinita).

Comprendo che InnoDB mapperà la posizione dei dati nel file per singoli file di indice per le tabelle, ma non capisco perché mescoli tutti i dati in un unico file. E, soprattutto, perché mescolare i dati di tutti i database sul server?

Una caratteristica interessante di MyISAM è che è possibile copiare / incollare una cartella del database su un altro computer e quindi utilizzare il database (senza dump).

Risposte:


67

L'architettura di InnoDB richiede l'uso di quattro tipi base di pagine informative

  • Pagine dei dati della tabella
  • Pagine indice delle tabelle
  • Tabella MetaData
  • Dati MVCC (per supportare l'isolamento delle transazioni e la conformità ACID )
    • Segmenti di rollback
    • Annulla spazio
    • 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 la rappresentazione pittorica di ibdata1

Per impostazione predefinita, innodb_file_per_table è disabilitato. Questo fa sì che tutti e quattro i tipi di pagina di informazioni eseguano l'archiviazione di un singolo file chiamato ibdata1. Molte persone cercano di diffondere i dati creando più file ibdata. Ciò potrebbe portare alla frammentazione dei dati e delle pagine dell'indice.

Questo è il motivo per cui consiglio spesso di ripulire l'infrastruttura InnoDB, usando il file ibdata1 predefinito e niente di più .

La copia è molto pericolosa a causa dell'infrastruttura in cui funziona InnoDB. Esistono due infrastrutture di base

  • innodb_file_per_table disabilitato
  • innodb_file_per_table abilitato

InnoDB ( innodb_file_per_table disabilitato)

Con innodb_file_per_table disabilitato, tutti questi tipi di informazioni di InnoDB vivono all'interno di ibdata1. L'unica manifestazione di qualsiasi tabella InnoDB al di fuori di ibdata1 è il file .frm della tabella InnoDB. La copia di tutti i dati di InnoDB in una sola volta richiede la copia di tutti / var / lib / mysql.

Copiare una singola tabella InnoDB è totalmente impossibile. È necessario eseguire il dump MySQL per estrarre un dump della tabella come rappresentazione logica dei dati e delle definizioni dell'indice corrispondenti. Quindi caricare quel dump su un altro database sullo stesso server o su un altro server.

InnoDB ( innodb_file_per_table abilitato)

Con innodb_file_per_table abilitato, i dati della tabella e i relativi indici vivono nella cartella del database accanto al file .frm. Ad esempio, per la tabella db1.mytable, la manifestazione di quella tabella InnoDB al di fuori di ibdata1 sarebbe:

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

Spazio tabelle di sistema ibdata1

Tutti i metadati per db1.mytable risiedono ancora in ibdata1 e non c'è assolutamente alcun modo per aggirare questo . Anche i registri di ripetizione e i dati MVCC vivono ancora con ibdata1.

Quando si tratta di frammentazione della tabella, ecco cosa succede a ibdata1:

  • innodb_file_per_table abilitato : puoi ridurre db1.mytables conALTER TABLE db1.mytable ENGINE=InnoDB;oOPTIMIZE TABLE db1.mytable;. Ciò comporta /var/lib/mysql/db1/mytable.ibd fisicamente più piccolo senza frammentazione.
  • innodb_file_per_table disabilitato : non è possibile ridurre db1.mytables conALTER TABLE db1.mytable ENGINE=InnoDB;oOPTIMIZE TABLE db1.mytable;perché risiede con ibdata1. Eseguendo effettivamente entrambi i comandi, rendere la tabella contigua e più veloce da leggere e scrivere. Sfortunatamente, ciò si verifica alla fine di ibdata1. Questo fa sì che ibdata1 cresca rapidamente. Questo è completamente affrontato nel mio post di pulizia di InnoDB .

ATTENZIONE (o PERICOLO come direbbe il Robot in Lost in Space )

Se stai pensando di copiare semplicemente il file .frm e .ibd, sei in linea con il mondo del male. La copia del file .frm e .ibd di una tabella InnoDB è utile solo se e solo se è possibile garantire che l'id del tablespace del file .ibd corrisponda esattamente alla voce dell'ID del tablespace nei metadati del file ibdata1 .

Ho scritto due post in DBA StackExchange su questo concetto di id del tablespace

Ecco un link eccellente su come ricollegare qualsiasi file .ibd a ibdata1 in caso di ID spazio tabella non corrispondenti: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Dopo aver letto questo, dovresti capire immediatamente che copiare i file .ibd è semplicemente folle.

Per InnoDB, devi solo fare qualcosa per spostarti

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

per fare una copia di una tabella InnoDB.

Se lo stai migrando su un altro server DB, usa mysqldump.

Per quanto riguarda il missaggio di tutte le tabelle InnoDB da tutti i database, posso effettivamente vedere la saggezza nel farlo. Nella società di hosting DB / Web del mio datore di lavoro, ho un client MySQL che ha una tabella in un database i cui vincoli sono associati a un'altra tabella in un altro database all'interno della stessa istanza MySQL. Con un repository di metadati comune, rende possibile il supporto transazionale e l'operatività MVCC su più database.


Significa quando uso il file innodb per tabella abilitata e se devo importare i miei dati da un server all'altro, dovrò usare solo mysqldump e non altri strumenti come Percona xtrabackup?
tesla747,

14

Puoi attivare / disattivare InnoDB per archiviare le tabelle per file aggiungendo innodb-file-per-tabella al tuo cnf.

Innodb si preoccupa davvero solo delle pagine di dati a un livello base. In effetti, è possibile configurare InnoDB per utilizzare solo un dispositivo a blocchi grezzi senza file system. http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

Esistono dei vantaggi per l'archiviazione delle tabelle per i file, ad esempio la possibilità di recuperare più facilmente lo spazio utilizzato tramite l'ottimizzazione.

Anche con i file per tabella, non puoi semplicemente copiare i file ibd così facilmente poiché InnoDB è transazionale e memorizza le informazioni sul suo stato nei file ibdata / log condivisi a livello globale.

Questo non vuol dire che non si può fare. Se la tabella non è in linea, puoi scartare / importare i tablespace e copiare i .idbs in http://dev.mysql.com/doc/refman/5.5/it/innodb-multiple-tablespaces.html


Non c'è dubbio che InnoDB sia un motore flessibile, ma non capisco come sia utile memorizzare tutti i dati in un file (poiché questa nuova struttura è stata implementata in InnoDB rispetto a MyISAM).
Googlebot,

Penso che più di uno di quei senni di poi sia 20/20 cose. L'opzione file per tabella è stata aggiunta dopo che innodb è stato rimosso per la prima volta dagli scaffali. A parte dare il proprio dispositivo a blocchi per evitare il sovraccarico del file system, non posso fornire un motivo per cui scaricarli tutti insieme sia meglio (e l'intera cosa del dispositivo a blocchi è il proprio dibattito). Tutte le mie configurazioni innodb hanno file abilitato per tabella.
Atxdba,

Questo è il punto, non fare affidamento sul filesystem può essere un valore inestimabile ma non è attivo per impostazione predefinita. Pertanto, alcuni utenti lo useranno.
Googlebot,

1
Un'opzione di file per tabella può causare danni se si hanno molte tabelle e non molta RAM (ad esempio un archivio Magento può contenere circa 1000 tabelle). E anche l'impostazione dei file aperti deve essere ottimizzata (considerando i limiti del sistema operativo). Quindi, usare con cautela.
ypercubeᵀᴹ

Può certamente mettere un freno agli sforzi di recupero. Sì, dovresti avere un backup, ma se non lo fai, InnoDB rende le cose più difficili a causa di questa struttura.
mikato,

10

Questo è il comportamento predefinito ma non obbligatorio. Dai documenti MySQL, utilizzando i tablespace per tabella :

Per impostazione predefinita, tutte le tabelle e gli indici InnoDB sono memorizzati nel tablespace di sistema. In alternativa, è possibile memorizzare ogni tabella InnoDB e i relativi indici in un proprio file . Questa funzione è denominata "più tablespace" poiché ogni tabella creata quando questa impostazione è attiva ha il proprio tablespace.

Per quanto riguarda il motivo, la ragione è probabilmente le diverse architetture dei due motori (MyISAM e InnoDB). Ad esempio, in InnoDB, non puoi semplicemente copiare il file .ibd su un altro database o installazione. Spiegazione (dalla stessa pagina):

Considerazioni sulla portabilità per i file .ibd

Non è possibile spostare liberamente i file .ibd tra le directory del database come con i file della tabella MyISAM. La definizione della tabella memorizzata nel tablespace condiviso di InnoDB include il nome del database. Anche gli ID transazione e i numeri di sequenza del registro memorizzati nei file del tablespace differiscono tra i database.


Risposta molto istruttiva e chiarito il problema, ma sono ancora curioso di sapere come un file di grandi dimensioni contenente tutti i database può migliorare le prestazioni (se lo fa).
Googlebot,

Le prestazioni non sono migliori a causa della presenza di un file per tutti. Varie caratteristiche, come il blocco a livello di riga, anziché a livello di tabella, aiutano le prestazioni. E ovviamente il vantaggio principale sono le transazioni e i vincoli FK (e quindi l'integrità del database).
ypercubeᵀᴹ

1
Hai ragione sull'integrità! Capisco perché è meglio mettere tutte le tabelle di un database in un unico file; ma non capisco perché mettere tutti i database (che sono completamente indipendenti) sullo stesso file. InnoDB per impostazione predefinita usa solo un file per la memorizzazione dei dati.
Googlebot,
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.