Jest to jeden z najbardziej kontrowersyjnych tematów, z którymi miałem do czynienia przez lata jako MySQL DBA oraz w DBA StackExchange.
Mówiąc łagodnie, po prostu nie ma innego sposobu na zmniejszenie ibdata1 . Przy wyłączonej innodb_file_per_table , za każdym razem, gdy uruchomisz OPTIMIZE TABLE
tabelę InnoDB, ibdata1 szybko rośnie. Dane, które są upuszczane przy użyciu DROP TABLE
i DROP DATABASE
nie można ich przywrócić, ponieważ są to DDL, a nie DML. Wierzę, że Oracle i MSSQL mogą wycofać DDL. MySQL nie może tego zrobić.
Istnieje kilka klas informacji, które znajdują się w ibdata1
- Dane tabeli
- Indeksy tabel
- Tabela Metadane
- Dane kontrolne MVCC
- Podwójny bufor zapisu (zapis w tle, aby uniknąć polegania na buforowaniu systemu operacyjnego)
- Wstaw bufor (zarządzanie zmianami w nieunikalnych indeksach wtórnych)
Użycie innodb_file_per_table=1
pozwoli ci stworzyć nowe tabele z danymi tabeli i indeksami tabel tworzonymi poza ibdata1. Możesz wyodrębnić dowolne tabele nadal wewnątrz ibdata1 przy użyciu ALTER TABLE ... ENGINE=InnoDB;
lub, OPTIMIZE TABLE
ale pozostawi to duże puste miejsce w ibdata1.
Niezależnie od tego musisz wyczyścić infrastrukturę InnoDB. Napisałem już posty StackExchange o tym, jak i dlaczego to zrobić:
Dobre wieści
Wystarczy zrzucić dane, załadować jeszcze raz i nigdy więcej nie powracać do tego problemu . Uruchamianie OPTIMIZE TABLE
potem rzeczywiście będzie kurczyć .ibd
pliku tabel dla każdej tabeli InnoDB.
InnoDB przechowuje wszystkie tabele InnoDB w ibdata1 tylko wtedy, gdy nie używasz następującego ustawienia w pliku domyślnym my.cnf:
TABELI DROP (i DROP DATABASE) nie można przywrócić.
To nie jest powód, dla którego nie można zmniejszyć ibdata1.
Jest to skrócone wyjaśnienie, ale ibdata1 zawiera dane wewnętrzne InnoDB oprócz danych tabeli. Z mojego zrozumienia, jego zmniejszenie wymagałoby defragmentacji, co nie jest obsługiwaną operacją.
źródło