AKTUALIZACJA: tl; dr: Problem polegał na tym, że MySQL używa TMPDIR
podczas tworzenia indeksów. A moje TMPDIR
zabrakło miejsca na dysku.
Oryginalny Q:
Próbuję dodać indeks do tabeli InnoDB i uzyskać table is full error
. Mam wystarczającą ilość miejsca na dysku, a konfiguracja MySQL ma plik na tabelę = 1. Dane w tabeli wynoszą 85 GB i zakładam, że indeks wyniesie około 20 GB - 30 GB i mam znacznie więcej miejsca na dysku niż to. Używam również ext3, więc nie sądzę, aby był problem z limitem rozmiaru pliku z punktu widzenia systemu operacyjnego.
Zalogowany błąd wygląda następująco:
140616 13:04:33 InnoDB: Error: Write to file (merge) failed at offset 3 1940914176.
InnoDB: 1048576 bytes should have been written, only 970752 were written.
InnoDB: Operating system error number 0.
InnoDB: Check that your OS and file system support files of this size.
InnoDB: Check also that the disk is not full or a disk quota exceeded.
InnoDB: Error number 0 means 'Success'.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/operating-system-error-codes.html
140616 13:04:33 [ERROR] /usr/libexec/mysqld: The table 'my_table' is full
Co to powoduje i jak mogę to rozwiązać?
Utwórz tabelę:
`CREATE TABLE `my_table` (
`uid_from` bigint(11) NOT NULL,
`uid_to` bigint(11) NOT NULL,
`counter` int(11) NOT NULL,
`updated` date NOT NULL,
PRIMARY KEY (`uid_to`,`uid_from`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8`
Ponieważ dane mają pojemność 87,4 GB i szacuję, że jest około 1,5B wierszy.
SHOW GLOBAL VARIABLES LIKE 'tmpdir';
Variable_name Value
tmpdir /tmp
[root@web ~]# df -h /tmp
Filesystem Size Used Avail Use% Mounted on
/dev/xvda1 40G 24G 14G 64% /
Odpowiedzi:
Nie daj się zwieść komunikatowi o błędzie
The table 'my_table' is full
. Ten rzadki scenariusz nie ma absolutnie nic wspólnego z przestrzenią dyskową. Ten pełny stan tabeli ma związek z wewnętrzną instalacją hydrauliczną InnoDB.Najpierw spójrz na ten schemat architektury InnoDB
Należy pamiętać, że systemowy obszar tabel (plik ibdata) ma tylko 128 segmentów wycofania i 1023 miejsc wycofania na segment wycofania. Ogranicza to wielkość zdolności wycofywania transakcji. Innymi słowy, jeśli pojedynczy segment wycofania potrzebuje więcej niż 1023 miejsc do obsługi transakcji, transakcja spełni ten
table is full
warunek.Pomyśl o restauracji Red Lobster w New Jersey . Może mieć pojemność 200 osób. Jeśli restauracja jest pełna, kolejka ludzi może wyjść na zewnątrz i czekać. Jeśli ludzie na linii zniecierpliwią się, mogą wyjść, ponieważ restauracja jest pełna. Oczywiście rozwiązaniem nie byłoby powiększenie New Jersey (lub zwiększenie przestrzeni dyskowej). Rozwiązaniem byłoby powiększenie restauracji Red Lobster. W ten sposób możesz zwiększyć pojemność siedzeń, powiedzmy, do 240. Mimo to linia może utworzyć się na zewnątrz, jeśli ponad 240 osób zdecyduje się przyjechać do Red Lobster.
Aby dać przykład, miałem klienta z 2 TB systemowego obszaru tabel i wyłączono plik innodb_file_per_table . (346G dla ibdata1, reset dla ibdata2). Uruchomiłem to zapytanie
Następnie odejmowałem InnoDBDataIndexSpace od sumy rozmiarów plików dla ibdata1 i ibdata2. Mam dwie rzeczy, które mnie zszokowały
Table is Full
warunekOznacza to, że 106 GB używało wewnętrznej instalacji hydraulicznej InnoDB. Klient korzystał wówczas z ext3.
Rozwiązaniem było dla mnie dodanie ibdata3. Omówiłem to w moim starym poście Jak rozwiązać „Tabela ... jest pełna” za pomocą „innodb_file_per_table”?
Omówiłem to również w innych postach
Mar 31, 2014
: katalog mysql powiększa się do 246G po jednym zapytaniu, które nie powiodło się z powodu zapełnienia tabeliNov 25, 2011
: BŁĄD 1114 (HY000) w wierszu 6308 w pliku i tabela analiza_użytkownika jest pełnaPamiętaj, że ten warunek może się zdarzyć, nawet jeśli włączono opcję innodb_file_per_table . W jaki sposób? Cofnięcia i dzienniki cofania są źródłem niekontrolowanych skoków wzrostu dla ibdata1 .
TWOJA RZECZYWISTA PYTANIE
Ponieważ dodajesz indeks do tabeli i dostajesz
Table is Full
, tabela musi być ogromna i nie może zmieścić się w jednym segmencie wycofywania. Musisz wykonać następujące czynności:KROK 01
Pobierz dane do pliku zrzutu
KROK 02
Zaloguj się do MySQL i uruchom to
KROK 03
Załaduj tabelę z dodatkowym indeksem z danymi
To wszystko.
Widzisz, problem polega na tym, że ALTER TABLE spróbuje wstrzyknąć wszystkie wiersze w twojej ogromnej tabeli jako pojedynczą transakcję. Użycie mysqldump spowoduje wstawienie danych do tabeli (teraz z nowym indeksem) tysiące wierszy na raz, nie wszystkie wiersze w pojedynczej transakcji.
Nie martw się o
what if this doesn't work?
Oryginalna tabela zostanie nazwanamytable_old
w przypadku czegokolwiek. może służyć jako kopia zapasowa. Możesz usunąć kopię zapasową, gdy wiesz, że nowy stół działa dla Ciebie.Spróbuj !!!
AKTUALIZACJA 16.06.2014, 11:13 EDT
Jeśli martwisz się o większy zrzut danych, po prostu zgzipuj.
Możesz wykonać te same kroki, ale w następujący sposób
KROK 01
Pobierz dane do pliku zrzutu
KROK 02
Zaloguj się do MySQL i uruchom to
KROK 03
Załaduj tabelę z dodatkowym indeksem z danymi
lub
AKTUALIZACJA 16.06.2014, 12:55 EDT
Właśnie pomyślałem o innym aspekcie dotyczącym tej kwestii.
Ponieważ wykonujesz DDL, a nie DML, możliwe, że nie jest to wewnętrzna instalacja hydrauliczna InnoDB. Ponieważ DDL nie może przywrócić programu InnoDB , problemem musi być zewnętrzna instalacja hydrauliczna. Gdzie zatkana jest ta zewnętrzna hydraulika? Podejrzewam, że folder temp dla systemu operacyjnego. Dlaczego?
Widzisz
disk quota exceeded
? Gdzie jest narzucany ten przydział dysku?Uruchom to zapytanie
Powiedziałeś, że to
/var/lib/mysqltmp
Teraz uruchom to w systemie operacyjnym
Coś mi mówi, że
/var/lib/mysqltmp
zabrakło miejsca W końcu masz tylko 14G za darmo. W oczach DDL (w celu utworzenia indeksu) wycofanie nastąpiło nie w pliku ibdata1, ale wtmpdir
lokalizacji. Jeśli/var/lib/mysqltmp
nigdzie nie jest zamontowany, dane tymczasowe są zapisywane na partycji głównej. Jeśli/var/lib/mysqltmp
gdzieś jest zamontowany, to to mocowanie jest wypełniane danymi wiersza. W obu przypadkach nie ma wystarczającej ilości miejsca na uzupełnienie DDL.Masz tutaj dwie opcje
OPCJA 1
Możesz także utworzyć duży dysk (być może ze 100 + GB) i zamontować
/var/lib/mysqltmp
na tym dużym dysku.OPCJA 2
Moje trzyetapowe sugestie powinny nadal działać, nawet przy ograniczonej przestrzeni dyskowej
KOMENTARZ
Szkoda, że komunikat o błędzie mówi
Oznacza to, że system operacyjny jest w porządku. Nie istnieje również żaden powiązany numer błędu dla tej sytuacji.
Jest jeszcze jedna rzecz, którą powinieneś wiedzieć. Dokumentacja MySQL mówi, że szybkie tworzenie indeksu dla InnoDB wciąż trafia na dysk :
AKTUALIZACJA 16.06.2014, 13:58 EDT
Upewnij się, że
/mnt/cbsvolume1/var/lib/mysql
masz 100G lub więcej za darmoźródło