Dlaczego InnoDB przechowuje wszystkie bazy danych w jednym pliku?

51

Było wygodne, aby MyISAM przechowywał każdą tabelę w odpowiednim pliku. InnoDB poczynił postępy w wielu aspektach, ale zastanawiam się, dlaczego InnoDB przechowuje wszystkie bazy danych w jednym pliku ( ibdata1domyślnie).

Rozumiem, że InnoDB mapuje lokalizację danych w pliku według poszczególnych plików indeksu dla tabel, ale nie rozumiem, dlaczego łączy wszystkie dane w jednym pliku. A co ważniejsze, po co mieszać dane ze wszystkich baz danych na serwerze?

Ciekawą funkcją MyISAM jest to, że można skopiować / wkleić folder bazy danych na inny komputer, a następnie użyć bazy danych (bez zrzutu).

Googlebot
źródło

Odpowiedzi:

66

Architektura InnoDB wymaga użycia czterech podstawowych rodzajów stron informacyjnych

  • Strony danych tabeli
  • Tabele indeksu stron
  • Tabela Metadane
  • Dane MVCC (w celu wsparcia izolacji transakcji i zgodności z ACID )
    • Wycofywanie segmentów
    • Cofnij spację
    • Podwójny bufor zapisu (zapisywanie w tle, aby uniknąć polegania na buforowaniu systemu operacyjnego)
    • Wstaw bufor (zarządzanie zmianami w nieunikalnych indeksach wtórnych)

Zobacz obrazowe przedstawienie ibdata1

Domyślnie innodb_file_per_table jest wyłączony. Powoduje to, że wszystkie cztery typy stron informacyjnych trafiają do jednego pliku o nazwie ibdata1. Wiele osób próbuje rozpowszechniać dane, tworząc wiele plików ibdata. Może to prowadzić do fragmentacji danych i stron indeksu.

Dlatego często zalecam oczyszczenie infrastruktury InnoDB, używając domyślnego pliku ibdata1 i nic więcej .

Kopiowanie jest bardzo niebezpieczne ze względu na infrastrukturę, w której działa InnoDB. Istnieją dwie podstawowe infrastruktury

  • tablica_pliku_internatywnego wyłączona
  • włączony plik innodb_file_per_table

InnoDB ( wyłączony plik_nodb_plik_pera )

Po wyłączeniu innodb_file_per_table wszystkie te typy informacji InnoDB są dostępne w ibdata1. Jedynym przejawem dowolnej tabeli InnoDB poza ibdata1 jest plik .frm tabeli InnoDB. Kopiowanie wszystkich danych InnoDB jednocześnie wymaga skopiowania wszystkich plików / var / lib / mysql.

Kopiowanie pojedynczej tabeli InnoDB jest całkowicie niemożliwe. Musisz zrzut MySQL, aby wyodrębnić zrzut tabeli jako logiczną reprezentację danych i odpowiadających im definicji indeksu. Następnie załadujesz ten zrzut do innej bazy danych na tym samym serwerze lub innym serwerze.

InnoDB ( włączony plik innodb_file_per_table )

Przy włączonej opcji innodb_file_per_table dane tabeli i jej indeksy znajdują się w folderze bazy danych obok pliku .frm. Na przykład dla tabeli db1.mytable przejawem tej tabeli InnoDB poza ibdata1 byłoby:

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

Systemowa przestrzeń tabel ibdata1

Wszystkie metadane dla db1.mytable nadal znajdują się w ibdata1 i nie ma absolutnie żadnej możliwości uniknięcia tego . Ponów dzienniki i dane MVCC również nadal działają z ibdata1.

Jeśli chodzi o fragmentację tabeli, oto co dzieje się z ibdata1:

  • innodb_file_per_table włączony : możesz zmniejszyć plik db1.mytables za pomocąALTER TABLE db1.mytable ENGINE=InnoDB;lubOPTIMIZE TABLE db1.mytable;. Powoduje to, że /var/lib/mysql/db1/mytable.ibd jest fizycznie mniejszy bez fragmentacji.
  • innodb_file_per_table wyłączony : nie można zmniejszyć pliku db1.mytables za pomocąALTER TABLE db1.mytable ENGINE=InnoDB;lubOPTIMIZE TABLE db1.mytable;ponieważ znajduje się on w ibdata1. Właściwie uruchamiając dowolne polecenie, spraw, aby tabela była ciągła i szybsza do odczytu i zapisu. Niestety dzieje się to na końcu ibdata1. To sprawia, że ​​ibdata1 szybko rośnie. Zostało to w pełni rozwiązane w moim poście do czyszczenia InnoDB .

OSTRZEŻENIE (lub NIEBEZPIECZEŃSTWO, jak powiedziałby Robot w Lost in Space )

Jeśli zastanawiasz się nad skopiowaniem pliku .frm i .ibd, czeka Cię świat cierpienia. Kopiowanie plików .frm i .ibd tabeli InnoDB jest dobre tylko wtedy i tylko wtedy, gdy możesz zagwarantować, że identyfikator obszaru tabel pliku .ibd jest dokładnie zgodny z wpisem id obszaru tabel w metadanych pliku ibdata1 .

Napisałem dwa posty w DBA StackExchange na temat tej koncepcji identyfikatora obszaru tabel

Oto doskonały link, jak ponownie podłączyć dowolny plik .ibd do ibdata1 w przypadku niedopasowanych identyfikatorów obszaru tabel: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Po przeczytaniu tego, powinieneś natychmiast uświadomić sobie, że kopiowanie plików .ibd jest po prostu szalone.

W przypadku InnoDB wystarczy tylko coś takiego przenieść

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

zrobić kopię tabeli InnoDB.

Jeśli migrujesz go na inny serwer DB, użyj mysqldump.

Jeśli chodzi o mieszanie wszystkich tabel InnoDB ze wszystkich baz danych, widzę mądrość. W firmie DB / Web hostingowej mojego pracodawcy mam jednego klienta MySQL, który ma tabelę w jednej bazie danych, której ograniczenia są mapowane na inną tabelę w innej bazie danych w tej samej instancji MySQL. Dzięki jednemu wspólnemu repozytorium metadanych umożliwia obsługę transakcji i obsługę MVCC w wielu bazach danych.

RolandoMySQLDBA
źródło
Czy to oznacza, że ​​kiedy używam pliku innodb na włączoną tabelę i jeśli muszę zaimportować dane z jednego serwera na inny, będę musiał użyć tylko mysqldump, a nie innych narzędzi, takich jak Percona xtrabackup?
tesla747,
14

Możesz przełączyć InnoDB do przechowywania tabel na plik, dodając innodb-file-per-table do swojego cnf.

Innodb naprawdę dba o strony danych na poziomie podstawowym. W rzeczywistości możesz skonfigurować InnoDB tak, aby używało tylko surowego urządzenia blokowego bez systemu plików, co jeszcze! http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

Istnieją udogodnienia do przechowywania tabel dla plików, takie jak możliwość łatwiejszego odzyskania zajętego miejsca poprzez optymalizację.

Nawet w przypadku plików na tabelę nie można tak łatwo skopiować plików ibd, ponieważ InnoDB jest transakcyjny i przechowuje informacje o jego stanie w globalnie udostępnianych plikach ibdata / log.

Nie oznacza to, że nie można tego zrobić. Jeśli tabela jest offline, możesz odrzucić / zaimportować obszary tabel i skopiować pliki .idbs wokół http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

atxdba
źródło
Bez wątpienia InnoDB jest elastycznym silnikiem, ale nie rozumiem, w jaki sposób przechowywanie wszystkich danych w jednym pliku jest korzystne (ponieważ ta nowa struktura została zaimplementowana w InnoDB w porównaniu z MyISAM).
Googlebot,
Myślę, że to bardziej jedna z tych perspektyw jest 20/20 rzeczy. Opcja „plik na tabelę” została dodana po pierwszym stoczeniu się programu Innodb z półek. Poza tym, że jest to własne urządzenie blokujące, aby uniknąć narzutu systemu plików, nie mogę podać powodu, dla którego zrzucanie ich wszystkich jest lepsze (a cała sprawa z urządzeniem blokowym to jego własna debata). Wszystkie moje ustawienia innodb mają włączony plik na tabelę.
atxdba
O to chodzi, nie poleganie na systemie plików może być nieocenione, ale domyślnie nie jest aktywne. Dlatego kilku użytkowników będzie z niego korzystać.
Googlebot
1
Jeden plik na jedną tabelę może zaszkodzić, jeśli masz wiele tabel i mało pamięci RAM (na przykład sklep Magento może mieć około 1000 tabel). Należy również zoptymalizować ustawienie otwartych plików (biorąc pod uwagę ograniczenia systemu operacyjnego). Dlatego używaj ostrożnie.
ypercubeᵀᴹ
Z pewnością może to utrudnić działania naprawcze. Tak, powinieneś mieć kopię zapasową, ale jeśli nie, InnoDB utrudnia to z powodu tej struktury.
mikato,
10

Jest to zachowanie domyślne, ale nie obowiązkowe. Z dokumentów MySQL, Korzystanie z przestrzeni tabel dla tabeli :

Domyślnie wszystkie tabele i indeksy InnoDB są przechowywane w systemowym obszarze tabel. Alternatywnie możesz przechowywać każdą tabelę InnoDB i jej indeksy we własnym pliku . Ta funkcja nosi nazwę „wielu obszarów tabel”, ponieważ każda tabela tworzona podczas obowiązywania tego ustawienia ma własny obszar tabel.

Przyczyną tego są prawdopodobnie różne architektury dwóch silników (MyISAM i InnoDB). Na przykład w InnoDB nie można po prostu skopiować pliku .ibd do innej bazy danych lub instalacji. Objaśnienie (z tej samej strony):

Zagadnienia dotyczące przenośności plików .ibd

Nie można swobodnie przenosić plików .ibd między katalogami baz danych, jak w przypadku plików tabel MyISAM. Definicja tabeli przechowywana we współdzielonym obszarze tabel InnoDB obejmuje nazwę bazy danych. Identyfikatory transakcji i numery sekwencji dziennika przechowywane w plikach obszaru tabel również różnią się między bazami danych.

ypercubeᵀᴹ
źródło
Bardzo pouczająca odpowiedź i wyjaśnienie problemu, ale wciąż jestem ciekawy, jak duży plik zawierający wszystkie bazy danych może poprawić wydajność (jeśli tak jest).
Googlebot,
Wydajność nie jest lepsza z powodu posiadania jednego pliku dla wszystkich. Różne parametry, takie jak blokowanie na poziomie wierszy zamiast na poziomie tabeli, zwiększają wydajność. I oczywiście główną zaletą są transakcje i ograniczenia FK (a tym samym integralność bazy danych).
ypercubeᵀᴹ
1
Masz całkowitą rację co do uczciwości! Rozumiem, dlaczego lepiej umieścić wszystkie tabele bazy danych w jednym pliku pojedynczym; ale nie rozumiem, dlaczego umieszczanie wszystkich baz danych (które są całkowicie niezależne) w tym samym pliku. InnoDB domyślnie używa tylko jednego pliku do przechowywania danych.
Googlebot