Mam bazę danych MySQL umiarkowanej wielkości z około 30 tabelami, z których niektóre to 10 milionów rekordów, a około 100 milionów. mysqldump
Wszystkich tabel (w osobnych plikach) jest dość szybka, trwa może 20 minut. Generuje około 15 GB danych. Największe zrzuty plików znajdują się w zakresie 2 GB.
Kiedy ładuję dane do MySQL na innym urządzeniu, sześciordzeniowym komputerze o pojemności 8 GB, trwa to wiecznie. Z łatwością 12 godzin zegarowych lub więcej.
Właśnie uruchamiam klienta mysql, aby załadować plik, tj
mysql database < footable.sql
bezpośrednio z pliku bezpośrednio z mysqldump
mysqldump database foo > footable.sql
Najwyraźniej robię coś złego. Od czego zacząć, aby można było zakończyć w rozsądnym czasie?
Nie używam żadnych przełączników ani do zrzutu ani obciążenia.
Odpowiedzi:
Weź pod uwagę kilka punktów, które mogą ci pomóc w przypadku wygenerowania zrzutu i przywrócenia go.
Extended inserts
na zrzutach.--tab
formatem, abyś mógł użyćmysqlimport
, który jest szybszy niżmysql < dumpfile
.innodb_flush_log_at_trx_commit = 2
plik my.cnf, tymczasowo podczas importowania. możesz ustawić go z powrotem na 1, jeśli potrzebujesz ACIDSpróbuj..
źródło
innodb_flush_log_at_trx_commit = 2
uratowała mi dzień. Importowanie zrzutu 600 MB (jako pojedynczej dużej transakcji) wymagałoby 6 godzin, ale przy tym tymczasowym ustawieniu wykonano to w 30 minut!Oprócz odpowiedzi Abdula chciałbym podkreślić znaczenie
--disable-keys
opcji, która wyłącza klawisze, dopóki wszystkie dane nie zostaną załadowane do tabeli. Ta opcja jest włączona jako część--opt
przełącznika, który jest domyślnie włączony, ale uznał, że należy to zaznaczyć.Jeśli nie pominiesz klawiszy podczas wstawiania, to każdy wstawiony wiersz odbuduje indeks. Niezwykle wolny proces.
źródło
--opt
jest domyślnieThis option is effective only for nonunique indexes of MyISAM tables. It has no effect for other tables
Ostatnio dużo z tym miałem do czynienia. Możesz zdecydowanie poprawić wydajność importu, wykonując import równolegle. Większość spowolnień opiera się na operacjach wejścia / wyjścia, ale nadal możesz uzyskać 40% poprawę, zrzucając do tabel, a następnie importując je, powiedzmy 4 na raz.
Możesz to zrobić za pomocą xargs:
spakowanie plików przed wypchnięciem ich do mysql niczego nie spowalnia, głównie z powodu obniżonego wejścia / wyjścia. Moje tabele zostały skompresowane do około 10: 1, więc oszczędza dużo miejsca na dysku.
Przekonałem się, że na 4 podstawowych komputerach użycie 4 procesów jest optymalne, choć tylko nieznacznie lepsze niż użycie 3. Jeśli masz dyski SSD lub szybką macierz RAID, prawdopodobnie skalujesz się lepiej.
Kilka innych rzeczy do odnotowania. Jeśli masz dyski sektorowe 4k, upewnij się, że masz
key_cache_block_size=4096
imyisam_block_size=4K
.Jeśli używasz tabel MyISAM, ustaw wartość
myisam_repair_threads = 2
lub wyższą. Pozwoli to twoim dodatkowym rdzeniom pomóc w odbudowie indeksów.Upewnij się, że w ogóle nie zamieniasz. Jeśli tak, zmniejsz rozmiar
innodb_buffer_pool_size
.Wydaje mi się, że dzięki innnodb otrzymałem też trochę przyspieszenia:
(ostatnich trzech nie testowałem zbytnio - wydaje mi się, że znalazłem je jako sugestie w internecie). Zauważ, że
innodb_flush_log_at_commit=0
może to spowodować uszkodzenie z powodu awarii mysql lub braku zasilania.źródło
*_block_size
imyisam_repair_threads
? Ponadto nie jestem pewien, czy powinniśmy oferować porady dotyczące dostrajania zmiennych w oparciu o „sugestie z sieci” :)Jeśli masz głównie tabele MyISAM, powinieneś zwiększyć bufor wstawiania zbiorczego . Oto, co mówi Dokumentacja MySQL na temat ustawiania rozmiaru_wystąpienia_wstaw :
Musisz zrobić dwie rzeczy
1) Dodaj go do /etc/my.cnf
2) Ustaw dla niego globalną wartość
Jeśli nie masz uprawnień do globalnego ustawiania wielkości luzem_wstaw_buforu, zrób to
Oczywiście nie dotyczy to InnoDB.
Z innego punktu widzenia, niezależnie od tego, czy tabele to InnoDB czy MyISAM, jeśli indeksy są większe niż tabela, możesz mieć zbyt wiele indeksów. Zwykle witam gości, że ponowne załadowanie Myysam mysqldump powinno zająć 3 razy więcej czasu niż samo wykonanie mysqldump. Witam również, że ponowne załadowanie mysqldump InnoDB powinno zająć 4 razy więcej czasu niż wykonanie mysqldump.
Jeśli przekraczasz współczynnik 4: 1 w celu przeładowania mysqldump, na pewno masz jeden z dwóch problemów:
Możesz zmierzyć rozmiar swoich danych za pomocą silnika pamięci za pomocą tego:
Sprawdź, czy indeksy są prawie tak duże jak dane, czy nawet większe
Możesz również rozważyć wyłączenie rejestrowania binarnego w następujący sposób:
przed ponownym załadowaniem skryptu
źródło
Jeśli całkowicie obejdziesz system plików i po prostu potokujesz wyjście mysqldump bezpośrednio do procesu MySQL, powinieneś zauważyć zauważalną poprawę wydajności. Ile ostatecznie zależy od typu używanego dysku, ale rzadko używam plików zrzutu bez względu na rozmiar bazy danych tylko z tego powodu.
źródło
Według moich doświadczeń dysk twardy jest wąskim gardłem. Zapomnij o wirujących dyskach. SSD jest lepszy, ale zdecydowanie najlepiej jest to zrobić w pamięci RAM - jeśli masz wystarczająco dużo miejsca na przechowywanie całej bazy danych przez krótki czas. W przybliżeniu:
Dla mnie zrzut ~ 10G (/ var / lib / mysql zużywający ~ 20G) można zaimportować w około 35 minut (mydumper / myloader), 45 minut (mysqldump --tab / mysqlimport), 50 minut (mysqldump / mysql) , na Xeonie 2x6 z rdzeniem 3,2 GHz
Jeśli nie masz wystarczającej ilości pamięci RAM na jednym komputerze, ale masz kilka komputerów obok siebie z szybką siecią, ciekawie byłoby sprawdzić, czy ich pamięci RAM można połączyć z nbd (urządzenie blokujące sieć). Lub za pomocą innodb_file_per_table możesz prawdopodobnie powtórzyć powyższy proces dla każdej tabeli.
źródło