FAKTY
Powiedziałeś, że używasz ext4
. Limit rozmiaru pliku to 16 TB. Dlatego Sample.ibd
nie powinien być pełny.
Mówiłeś swoje innodb_data_file_path
IS ibdata1:10M:autoextend
. W związku z tym sam plik ibdata1 nie ma ograniczenia rozmiaru poza systemem operacyjnym.
Dlaczego w ogóle pojawia się ta wiadomość? Zauważ, że komunikat brzmi „Tabela ... jest pełna”, a nie „Dysk ... jest pełny”. Ten warunek pełnej tabeli wynika z logicznego punktu widzenia . Pomyśl o InnoDB. Jakie interakcje mają miejsce?
Domyślam się, że InnoDB próbuje załadować 93 GB danych jako pojedynczą transakcję. Skąd Table is Full
pochodzi wiadomość? Chciałbym spojrzeć na ibdata1, nie pod względem jego fizycznego rozmiaru (który już wykluczyłeś), ale pod kątem osiąganych limitów transakcji.
Co znajduje się w ibdata1, gdy włączona jest opcja innodb_file_per_table i ładujesz nowe dane do MySQL?
Moje podejrzenia mówią mi, że winni są Cofnij Dzienniki i / lub Ponów Dzienniki.
Co to są te dzienniki? Według książki
Rozdział 10: „Silniki magazynujące” Strona 203 W paragrafach 3,4 podano:
Silnik InnoDB zachowuje dwa typy dzienników: dziennik cofania i dziennik powtarzania. Dziennik cofania służy do wycofywania transakcji, a także do wyświetlania starszych wersji danych dla zapytań działających na wymaganym poziomie izolacji transakcji. Kod obsługujący dziennik cofania można znaleźć w storage / innobase / buf / log / log0log.c .
Celem dziennika ponownych zapisów jest przechowywanie informacji, które zostaną wykorzystane podczas odzyskiwania po awarii. Pozwala procesowi odzyskiwania na ponowne wykonanie transakcji, które mogły lub nie zostały zakończone przed awarią. Po ponownym wykonaniu tych transakcji baza danych jest doprowadzana do spójnego stanu. Kod zajmujący się dziennikiem powtórzeń można znaleźć w storage / innobase / log / log0recv.c .
ANALIZA
W ibdata1 znajduje się 1023 dzienników cofania (patrz Wycofywanie segmentów i cofanie spacji) . Ponieważ dzienniki cofania przechowują kopie danych, które pojawiły się przed ponownym załadowaniem, wszystkie dzienniki cofania 1023 osiągnęły limit. Z innej perspektywy wszystkie dzienniki cofania 1023 mogą być poświęcone jednej transakcji, która ładuje Sample
tabelę.
ALE POCZEKAJ...
Prawdopodobnie mówisz „ładuję pustą Sample
tabelę”. W jaki sposób zaangażowane są dzienniki cofania? Zanim Sample
tabela została załadowana 93 GB danych, była pusta. Reprezentowanie każdego nieistniejącego wiersza musi zajmować trochę miejsca do czyszczenia domu w dziennikach cofania. Wypełnianie 1023 dzienników cofania wydaje się banalne, biorąc pod uwagę ilość napływających danych ibdata1
. Nie jestem pierwszą osobą, która to podejrzewa:
Z dokumentacji MySQL 4.1 zwróć uwagę Posted by Chris Calender on September 4 2009 4:25pm
:
Zauważ, że w 5.0 (wcześniejszych niż 5.0.85) i 5.1 (wcześniejszych niż 5.1.38) możesz otrzymać błąd „tabela jest pełna” dla tabeli InnoDB, jeśli w InnoDB zabraknie cofnięć (błąd # 18828).
Oto raport o błędzie dla MySQL 5.0: http://bugs.mysql.com/bug.php?id=18828
PROPOZYCJE
Kiedy tworzysz mysqldump Sample
tabeli, użyj --no-autocommit
mysqldump --no-autocommit ... mydb Sample > Sample.sql
Spowoduje to wyraźne COMMIT;
po każdym INSERT
. Następnie załaduj ponownie stół.
Jeśli to nie zadziała ( nie spodoba ci się to ), zrób to
mysqldump --no-autocommit --skip-extended-insert ... mydb Sample > Sample.sql
Dzięki temu każdy WSTAW ma tylko jeden wiersz. Mysqldump będzie znacznie większy (ponad 10 razy większy) i jego przeładowanie może potrwać od 10 do 100 razy dłużej.
W obu przypadkach pozwoli to uniknąć zalania dzienników cofania.
Spróbuj !!!
AKTUALIZACJA 2013-06-03 13:05 EDT
DODATKOWE SUGESTIE
Jeśli tabela systemowa InnoDB (aka ibdata1) osiągnie limit rozmiaru pliku i nie można użyć dzienników cofania, możesz po prostu dodać inny systemowy obszar tabel (ibdata2).
Właśnie zetknąłem się z tą sytuacją zaledwie dwa dni temu. Zaktualizowałem mój stary post tym, co zrobiłem: Zobacz Projektowanie bazy danych - Tworzenie wielu baz danych, aby uniknąć bólu głowy związanego z ograniczeniem rozmiaru tabeli
Zasadniczo musisz zmienić ścieżkę do pliku innodb_data_file_path, aby uwzględnić nowy systemowy plik obszaru tabel. Pozwól mi wyjaśnić, jak:
SCENARIUSZ
Na dysku (ext3) serwer mojego klienta miał:
[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql 362807296 Jun 2 00:15 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun 2 00:15 ibdata2
Ustawienie było
innodb_data_file_path=ibdata1:346M;ibdata2:500M:autoextend:max:10240000M
Zauważ, że ibdata2
wzrosła do 2196875759616, co jest 2145386484M
.
Musiałem osadzić rozmiar pliku ibdata2
w innodb_data_file_path i dodaćibdata3
innodb_data_file_path=ibdata1:346M;ibdata2:2196875759616;ibdata3:10M:autoextend
Po ponownym uruchomieniu mysqld zadziałało:
[root@l*****]# ls -l ibd*
-rw-rw---- 1 s-em7-mysql s-em7-mysql 362807296 Jun 3 17:02 ibdata1
-rw-rw---- 1 s-em7-mysql s-em7-mysql 2196875759616 Jun 3 17:02 ibdata2
-rw-rw---- 1 s-em7-mysql s-em7-mysql 32315015168 Jun 3 17:02 ibdata3
W ciągu 40 godzin ibdata3
wzrosła do 31G. MySQL po raz kolejny działał.