We / Wy Czekaj, powodując tak duże spowolnienie (EXT4 JDB2 przy 99% We / Wy) podczas zatwierdzania MySQL


14

Piszę indeksatora, używając Pythona, który indeksuje dokumenty i wstawia je do bazy danych, zanim był to pojedynczy proces, ale teraz przeszedłem do wieloprocesowości z uruchomionymi 4 równoległymi procesami. Po każdym wyodrębnieniu tekstu wstawia się on do bazy danych i zatwierdza.

Teraz pojawia się problem z IO, głównym problemem IO nie jest mój proces, ale system jdb2 EXT4. Wynosi 99,99% i powoduje, że procesor czeka na IO przy każdym zatwierdzeniu MySQL.

Widziałem wielu mających ten problem w Internecie, a ich rozwiązaniem jest montowanie za pomocą bariery = 0. Czy to całkowicie zablokowałoby kronikowanie? Moje serwery mają UPS i kuszą mnie, prawda?


Czy wszystkie twoje dane InnoDB ???
RolandoMySQLDBA

Odpowiedzi:


4

Umieść bazę danych w systemie plików bez kronikowania. Co najmniej większe serwery (serwer Oracle, SQL) mają własną funkcję dziennika (dziennik transakcji) i odpowiednio optymalizują swoje operacje wejścia / wyjścia. Masz dziennik i bazę danych na oddzielnych systemach plików i dyskach i polegasz na wewnętrznej funkcjonalności bazy danych w celu obsługi złego IO. Zwykle nie ma zmian w systemie plików (większa konfiguracja) oprócz daty zapisu, ponieważ pliki nie rozwijają się - byłyby generowane z ich „ostatecznym” rozmiarem (ok, administratorzy mogą to zmienić), a zmiany są, jak powiedziałem, śledzone przez bazę danych dziennik transakcji poziomu.

Możesz także powiedzieć nam, jaka jest twoja warstwa sprzętowa. Większość ludzi nie docenia, że IOPS jest czynnikiem ograniczającym bazę danych, i uważa, że ​​mały zestaw płyt jest odpowiednim środowiskiem dla dużej bazy danych. Podczas gdy niektórzy z nas pracują nad bazami danych przy użyciu większej liczby dysków, potencjalnie obsługując większą liczbę IOPS.


Zmodyfikowałbym to, używając systemu plików, który nie korzysta z dziennika dla danych, a jedynie z metadanych. Ext4 można również skonfigurować w ten sposób.
the-wabbit

Tak. Na koniec dziennik podwaja IO - a dziennik bazy danych zrobi to samo, więc masz dużo więcej IOPS, niż musisz. I redundancja, która w zasadzie nie jest potrzebna. Systemowe połączenie jest NICE, aby chronić plik .... ale jest bezużyteczne, gdy aplikacja już to robi, co robią bazy danych.
TomTom

Która oferuje najlepszą wydajność w przypadku braku dziennika? Dzięki!
Phyo Arkar Lwin

4

Zawsze będzie kompromis między odpornością a wydajnością.

W przypadku MySQL na ext4 domyślnie bariery = 1 rzeczywiście powodują spowolnienie, jednak pierwszym działaniem nie powinno być wyłączenie kronikowania lub włączenie danych = cofanie.

Po pierwsze, jeśli odporność ma duże znaczenie, z pewnością warto skorzystać z macierzy RAID z podtrzymaniem bateryjnym.

Wybrane opcje montażu, szczególnie w macierzy RAID bez akumulatora:

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

To celowo nie korzysta z danych = zapisywania, ponieważ nie chcę ryzykować uszkodzenia systemu plików, co spowoduje, że „stare dane pojawią się w plikach po awarii i przywróceniu dziennika” (cytat pochodzi z man mount).

Idealna konfiguracja w my.cnf dla pełnej odporności na ustawienia związane z I / O to:

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

Wybrałem następującą sekwencję kompromisów w celu zwiększenia wydajności:

  1. sync_binlog = 0: jest to pierwsza konfiguracja MySQL, którą zmieniam od pełnej odporności. Powodem tego jest to, że daje znaczną poprawę wydajności, szczególnie tam, gdzie binlog_format=row(niestety wymagane dla Jiry). Korzystam z wystarczającej liczby replik MySQL w klastrze, że jeśli binlog miałby zostać uszkodzony przez scenariusz utraty zasilania, zrobiłbym kopię binarną z innej repliki.
  2. innodb_flush_log_at_trx_commit = 2: Podczas gdy wymagana jest wartość 1 dla pełnej zgodności ACID, z wartością 2 "bufor dziennika jest zapisywany do pliku przy każdym zatwierdzeniu, ale operacja czyszczenia na dysk nie jest na nim wykonywana. Jednak opróżnianie na plik dziennika ma miejsce raz na sekundę, również gdy wartość wynosi 2. Pamiętaj, że opróżnianie raz na sekundę nie jest gwarantowane w 100% co sekundę z powodu problemów z planowaniem procesu. ” (cytat z dokumentów MySQL)
  3. Zaktualizuj używane opcje montowania data=writeback. Zauważ, że jeśli jest to twój główny system plików, musisz także przekazać opcję wiersza poleceń jądra. Złożyłem w tym kilka kroków na ścianie kodowej .
  4. Przetestuj różne wartości innodb_flush_method. Wykazano, że O_DIRECT poprawia wydajność w niektórych obciążeniach, ale nie jest pewne, że będzie to działać w twoim środowisku.
  5. Upgrade do SSD, w którym to przypadku można także chcą zwiększyć innodb_io_capacity, i dostroić ustawienia, takie jak innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threads, i innych możliwych do ustawienia.

3

Jest całkiem prawdopodobne, że twój backend I / O nie radzi sobie tak dobrze z obciążeniem. Należy upewnić się, że system plików nie rejestruje danych. Sugerowałbym użycie data=writeback,relatime,nobarrierparametrów do zamontowania partycji danych bazy danych jako pierwszej szybkiej i brudnej optymalizacji.

Poza tym, na podstawie twoich symptomów, najwyraźniej nie używasz buforowania zapisu ze swoim kontrolerem. Należy upewnić się, że używasz pamięci podręcznej zapisu na kontrolerze z zasilaniem bateryjnym lub flash i włączyć ją - powinno to zapewnić znaczny wzrost wydajności bez znacznego wzrostu ryzyka utraty lub uszkodzenia danych. Pamiętaj, że używanie pamięci podręcznej zapisu bez baterii lub kopii zapasowej flash znacznie zwiększa ryzyko utraty lub uszkodzenia danych - więc rób to tylko w celach testowych i / lub jeśli możesz ponieść straty.


więc co powiesz na: data = writeback, relatime, nobarrier, a następnie całkowicie wyłącz Logowanie mysql? Myślę, że to znacznie przyspieszyłoby?
Phyo Arkar Lwin

hdpram -i pokazuje, że używam buforowania zapisu. więc hmm?
Phyo Arkar Lwin

@ V3ss0n nie można wyłączyć rejestrowania silnika transakcyjnego - jest to jego sedno. Możesz zdecydować o przeniesieniu dziennika transakcji na inny zestaw dysków, ponieważ ma on zupełnie inny wzorzec dostępu (głównie zapis liniowy) niż dane głównej bazy danych (losowe odczytywanie / zapisywanie) - jest to często zalecana konfiguracja. Jeśli chodzi o konfigurację pamięci: nie używasz kontrolera RAID, ale po prostu pojedyncze dyski z pamięcią podręczną zapisu? Nie pomogłoby to żadnemu z zapisów synchronicznych, ponieważ pochodzą one z jawnymi żądaniami opróżnienia pamięci podręcznej.
the-wabbit

Czy to nobarrierto samo co barrier=0?
Nic Cottrell,

@NicCottrell tak, są takie same.
kouton

3

To stare pytanie, ale w ubiegłym tygodniu mieliśmy do czynienia z tymi samymi problemami (wysokie oczekiwania we / wy i straszne prędkości wstawiania / aktualizacji) na nowym serwerze dedykowanym, a to rozwiązanie bezpośrednio rozwiązuje ten problem.

Wyłączenie kronikowania za pomocą tune2fs -O "^has_journal" /dev/<drive>było najszybszym rozwiązaniem, ponieważ eliminuje czekanie we / wy z powodu procesu JDB2. Ale nie jest to zalecane, chyba że masz dysk z podtrzymaniem bateryjnym, ponieważ stracisz dane w razie awarii. Tabele InnoDB są bezpieczne, jeśli masz doublewritewłączoną obsługę MySQL. Ale pliki takie jak .frm, logi itp. Nie są bezpieczne. Próbowaliśmy przenieść te pliki na inny dysk (szczególnie dzienniki bin), ale oczekiwanie we / wy jdb2 nadal trwało. Więc nie sprawiło nam to zbyt dużego komfortu.

data=writeback,relatime,nobarriernie pomogło to przyspieszyć zapisu / odczytu tak bardzo, jak wyłączenie kronikowania na całej partycji. Więcej opcji dla ext4 znajduje się w dokumencie EXT4 .

Prawdziwym winowajcą w naszym przypadku był sync_binlog. Mieliśmy ustawiony jest 1na /etc/mysql/my.cnfi to zabija wydajność.

Percona potwierdza to tutaj . Ustawiliśmy go na domyślny, 0a wydajność wzrosła o ponad 500%.


0

Jakiego silnika bazy danych używasz do wstawiania tych danych?

Jeśli jest to MyISAM: musi zablokować całą tabelę podczas zapisu, więc uruchamianie współbieżnych wątków wstawiania zabije KAŻDY system, bez względu na to, jak potężny.

Upewnij się, że używasz InnoDB dla tych tabel.


Ponieważ popełnia transakcje, mechanizmem nie będzie MyISAM, ponieważ MyISAM nie obsługuje transakcji.
the-wabbit

Arr, fartuch mózgu.
adapttr

Używam innodb, domyślnie mysql5.5 to innodb.
Phyo Arkar Lwin

0

Również nie jest bezpośrednio związany z mysql, ale niektóre HD mają problemy z ext4 z powodu agresywnego zarządzania energią ... kiedy to się dzieje, obciążenie maszyny wzrasta bez widocznej aktywności.

Spróbuj to wyłączyć. najpierw sprawdź dowolną wartość (jeśli chcesz ją przywrócić bez ponownego uruchamiania), a następnie wyłącz ją.

Sprawdź aktualną wartość:

    hdparm -B /dev/sda

Wyłącz to

   hdparm -B 255 /dev/sda

(lub jakikolwiek jest twój HD) i przetestuj. Prawdopodobnie nie pomoże w większości problemów, ale może pomóc niektórym użytkownikom. Ponowne uruchomienie spowoduje zresetowanie wartości lub ręczne zastąpienie 255 poprzedniej wartości.

Jeśli to pomoże, sprawdź /etc/default/hdparmlub, /etc/hdparm.confaby uzyskać bardziej trwałą konfigurację, ustawiając ją podczas uruchamiania.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.