Czy bezpiecznie jest używać innodb_flush_log_at_trx_commit = 2

54

Odwróciłem się innodb_flush_log_at_trx_commit = 2i uzyskałem bardzo dużą prędkość zapisu. Ale czy można bezpiecznie korzystać z witryny produkcyjnej?

Bruce Dou
źródło

Odpowiedzi:

57

Możesz stracić transakcje o wartości do jednej sekundy. Wartość domyślna to 1, co pomaga zachować zgodność z InnoDB ACID .

Zgodnie z dokumentacją MySQL na temat innodb_flush_log_at_trx_commit

Jeśli wartość innodb_flush_log_at_trx_commit wynosi 0, bufor dziennika jest zapisywany do pliku dziennika raz na sekundę, a operacja opróżniania dysku jest wykonywana na pliku dziennika, ale nic nie jest wykonywane przy zatwierdzeniu transakcji. Gdy wartość wynosi 1 (wartość domyślna), bufor dziennika jest zapisywany do pliku dziennika przy każdym zatwierdzeniu transakcji, a operacja opróżniania dysku jest wykonywana na pliku dziennika. Gdy wartość wynosi 2, bufor dziennika jest zapisywany do pliku przy każdym zatwierdzeniu, ale operacja czyszczenia na dysku nie jest na nim wykonywana. Jednak opróżnianie pliku dziennika odbywa się raz na sekundę również wtedy, 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.

Domyślna wartość 1 jest wymagana do pełnej zgodności z ACID. Możesz osiągnąć lepszą wydajność, ustawiając wartość inną niż 1, ale wtedy możesz stracić do jednej sekundy transakcji w wyniku awarii. Przy wartości 0 każda awaria procesu mysqld może usunąć ostatnią sekundę transakcji. Przy wartości 2 tylko awaria systemu operacyjnego lub przerwa w dostawie prądu mogą usunąć ostatnią sekundę transakcji. Odzyskiwanie po awarii InnoDB działa niezależnie od wartości.

Aby uzyskać największą możliwą trwałość i spójność w konfiguracji replikacji przy użyciu InnoDB z transakcjami, użyj innodb_flush_log_at_trx_commit = 1 i sync_binlog = 1 w pliku my.cnf serwera głównego.

Uwaga

Wiele systemów operacyjnych i sprzęt dyskowy oszukują operację flush-to-disk. Mogą powiedzieć mysqld, że kolor miał miejsce, nawet jeśli nie. Wtedy trwałość transakcji nie jest gwarantowana nawet przy ustawieniu 1, aw najgorszym przypadku przerwa w zasilaniu może nawet uszkodzić bazę danych InnoDB. Korzystanie z pamięci podręcznej dysku z podtrzymaniem bateryjnym w kontrolerze SCSI lub w samym dysku przyspiesza opróżnianie plików i zwiększa bezpieczeństwo operacji. Możesz także spróbować użyć komendy Unix hdparm, aby wyłączyć buforowanie zapisów na dyskach w pamięci podręcznej sprzętu, lub użyć innej komendy specyficznej dla dostawcy sprzętu.

Na tej podstawie wartości inne niż 1 narażają InnoDB na ryzyko utraty wartości transakcji trwającej 1 sekundę lub wartości danych zatwierdzenia transakcji.

Dokumentacja mówi również o użyciu sync_binlog=1.

Według dokumentacji MySQL na sync_binlog

Wartość 1 jest najbezpieczniejszym wyborem, ponieważ w przypadku awarii tracisz najwyżej jedną instrukcję lub transakcję z dziennika binarnego. Jest to jednak najwolniejszy wybór (chyba że dysk ma pamięć podręczną podtrzymywaną bateryjnie, co sprawia, że ​​synchronizacja jest bardzo szybka).

Twój najbezpieczniejszy wybór to

[mysqld]
innodb_flush_log_at_trx_commit=1
sync_binlog=1

Jeśli nie przeszkadza ci możliwa utrata danych (do 1 sekundy), możesz użyć 0 lub 2 na własne ryzyko, jeśli nagrody (szybsza prędkość zapisu) są tego warte.

RolandoMySQLDBA
źródło
3
Rolando: +1 za kilka ostatnich linii sync_binlog = 1 ...
Abdul Manaf
@AbdulManaf, Zawsze idź do integralności danych niż prędkości. Jeśli chcesz poświęcić szybkość na rzecz integralności danych, stracisz znacznie więcej czasu na rozwiązywanie problemów z danymi.
Pacerier,
1
@RolandoMySQLDBA, „tracąc sekundę transakcji”, czy masz na myśli to, że sukces commit rzeczywiście może zostać utracony?
Pacerier,
1
Pacerier, tak. Dane są gwarantowane, że zostaną zapisane na dysk dopiero po „opróżnieniu na dysk”. Do tego czasu może znajdować się tylko w pamięci RAM.
Emil Vikström,
2
@RolandoMySQLDBA jesteś człowiekiem, poważnie. Jeśli robisz coś innego niż etatowe konsultacje MySQL, prawdopodobnie powinieneś zmienić ścieżkę kariery.
sjas,
25

innodb_flush_log_at_trx_commitJest stosowany w celu jak ..

Jeśli wartość innodb_flush_log_at_trx_commit wynosi 0, bufor dziennika jest zapisywany do pliku dziennika raz na sekundę i operacja opróżniania dysku jest wykonywana na pliku dziennika, ale nic nie jest wykonywane przy zatwierdzeniu transakcji.

Gdy wartość wynosi 1 (domyślnie), bufor dziennika jest zapisywany do pliku dziennika przy każdym zatwierdzeniu transakcji, a operacja opróżniania dysku jest wykonywana na pliku dziennika.

Gdy wartość wynosi 2, bufor dziennika jest zapisywany do pliku przy każdym zatwierdzeniu, ale operacja czyszczenia na dysk nie jest na nim wykonywana. Jednak opróżnianie pliku dziennika odbywa się raz na sekundę również wtedy, gdy wartość wynosi 2. Należy pamiętać, że opróżnianie raz na sekundę nie jest gwarantowane w 100% co sekundę z powodu problemów z planowaniem procesu.

Domyślna wartość 1 jest wymagana do pełnej zgodności z ACID. Możesz osiągnąć lepszą wydajność, ustawiając wartość inną niż 1, ale wtedy możesz stracić do jednej sekundy transakcji w wyniku awarii. Przy wartości 0 każda awaria procesu mysqld może usunąć ostatnią sekundę transakcji. Przy wartości 2 tylko awaria systemu operacyjnego lub przerwa w dostawie prądu mogą usunąć ostatnią sekundę transakcji. Odzyskiwanie po awarii InnoDB działa niezależnie od wartości.

Moim zdaniem używanie innodb_flush_log_at_trx_commitdo 2 nie powinno stanowić problemu, ale używanie 1 jest najbezpieczniejsze.

Abdul Manaf
źródło
3
Właśnie zauważyłem, że odpowiedziałeś zaledwie 18 sekund po mnie zasadniczo taką samą odpowiedzią. +1 !!!
RolandoMySQLDBA
24

Moja opinia różni się od innych. innodb_flush_log_at_trx_commit = 0 jeśli: to mój komputer programistyczny lub domowa mini baza danych, w której nie ma wrażliwych danych.

innodb_flush_log_at_trx_commit = 2 jeśli: jest to blog / stats / e-commerce (z ~ 100x sklepem w ciągu dnia) itp.

innodb_flush_log_at_trx_commit = 1, jeśli: masz wielu klientów lub musisz pracować z transakcjami pieniężnymi, takimi jak bank. dlatego tym razem powinieneś podzielić przepływ danych na kilka serwerów, aby uzyskać szybkość i bezpieczeństwo.

Wolę 2, ponieważ ma około 75-krotnie większą prędkość zapisu i kończy się niepowodzeniem TYLKO w przypadku awarii sprzętu.

W każdym razie powinieneś wiedzieć, czego potrzebujesz o wiele więcej prędkości pisania lub do 1 sekundy informacji?

Sertekmedia
źródło
1
+1 za75x faster write speed and it fails ONLY if hardware fails.
Naman Gala
3
75x szybciej? Wymagany cytat.
Pacerier,
5
Mój własny test: 5000 UPDATEz innodb_flush_log_at_trx_commit = 1: 179 sekund. Z innodb_flush_log_at_trx_commit = 2: 1,12 sekundy. W moim przypadku jest to 160 razy szybsza prędkość zapisu.
Kevin,
Dobra odpowiedź. Jedną z rzeczy, o których należy pomyśleć, jest to, że - jeśli komputer zawiesza się po udanej transakcji, istnieje prawdopodobieństwo, że transakcja nie została zapisana na dysk z innodb_flush_log_at_trx_commit = 2, a mimo to aplikacja została wskazana jako sukces (tj. Mysqld zdoła wysłać pakiet sieciowy wskazujący, że transakcja została pomyślnie zakończona do kierowcy w Twojej aplikacji), ta szansa jest bardzo mała
Vladislav Vaintroub
czy możesz poprawić swoją odpowiedź, określając, co oznaczają dokumentycrash
shareef
2

Próbuję odpowiedzieć, jaki jest cel innodb_flush_log_at_trx_commit?

InnoDB wykonuje większość swoich operacji w pamięci ( InnoDB Buffer Pool). Wszystkie zmodyfikowane dane są zapisywane, InnoDB transaction log filea następnie opróżniane (zapisywane) do trwałej pamięci (dysku twardego).

Dla bezpieczeństwa danych ( Durability from ACID) InnoDB musi przechowywać zmodyfikowane dane każdej transakcji w trwałym magazynie. Jednocześnie zobowiązanie do dysku dla każdej transakcji jest kosztownym procesem.

Dysk I / O jest procesem blokującym i jest bardzo wolny, jest to wolny dysk, co dodatkowo zmniejszy liczbę InnoDB transaction per seconds(przepustowość dysku).

InnoDB zapewnia innodb_flush_log_at_trx_commitzmienną kontrolę częstotliwości tej operacji spłukiwania. W zależności od wartości operacja spłukiwania InnoDB zachowuje się inaczej.

(Już wyjaśniono w innych odpowiedziach)

0 - Zapis do pliku dziennika i opróżnianie dysku co sekundę (dane w puli buforów nie są zapisywane w pliku dziennika - w celu zwiększenia wydajności). 1 - Opróżnij dysk, gdy transakcja zostanie zatwierdzona - domyślnie (dla bezpieczeństwa danych - zgodność z ACID) 2 - zapisz do pliku dziennika dla każdej transakcji i opróżnij dysk co sekundę. (W celu zwiększenia wydajności)

Zależy od wymagania aplikacji ( Performance Vs data safety), możesz ustawić tę zmienną. Różnica między 0 a 2 - oba zwiększą wydajność, wartość 2 przechowuje dane w pliku transakcji i można je odzyskać w przypadku awarii lub awarii, ale nie w 0.

W wielu przypadkach opróżnianie na dysku oznacza, że ​​dane są zapisywane z InnoDB buffer pool (memory) to Operating systems cachefaktycznie nie zapisanego na dysku (trwałym). W przypadku awarii, w najgorszym przypadku możesz stracić dane do jednej sekundy)

Wzrost wydajności zależy od środowiska i można go porównywać i identyfikować. W środowisku replikacji, dla bezpieczeństwa i spójności danych, ustaw innodb_flush_log_trx_commit = 1i sync_binlog=1.

Jeśli głównym celem aplikacji jest wydajność, InnoDB zapewnia zmienną kontrolującą częstotliwość płukania logów - innodb_flush_log_at_timeout- która pozwala ustawić zakres częstotliwości płukania logów 1 to 2700 seconds, domyślnie jest to 1.

Należy pamiętać, że jeśli wydłużysz interwał płukania do N sekund, wzrost wydajności wiąże się z kompromisem w zakresie bezpieczeństwa danych do N sekund. Na przykład - jeśli ustawisz spłukiwanie co 5 sekund - przyrost przepustowości jest bardzo wysoki, ale w przypadku awarii zasilania lub awarii systemu utracisz dane o wartości 5 sekund.

W tym artykule omówiono operacje opróżniania i zatwierdzania transakcji InnoDB .

Możesz zmienić po wykonaniu trybu 2 na aws rds:

można zmienić po wykonaniu trybu 2 na aws

zmiany podglądu

Niemodyfikowalne w niektórych przypadkach, np. Jeśli masz replikację wielu az:

W niektórych przypadkach informacje niemodyfikowalne

rathishDBA
źródło
1

Jeśli twój sprzęt zawiedzie, możesz stracić wszystkie swoje dane, więc bez żadnych obaw używam param = 2 W każdym razie możesz podzielić swoje wrażliwe (zamówienia, wirtualne pieniądze, ...) i regularne (statystyki, koszyk, ...) dane na 2 serwery db i zapewnić im bezpieczeństwo i szybkość. Do transakcji między bazami danych można użyć http://dev.mysql.com/doc/refman/5.7/en/xa.html

Karolis Mačiulskis
źródło
„Utrata wszystkich danych”, czy masz na myśli transakcje, które były zadawane w ciągu ostatnich kilku sekund?
NiCk Newman
1
Awaria sprzętowa może oznaczać utratę całego dysku twardego, a zatem „utratę wszystkich danych”. Więc jeśli nie masz konfigurację replikacji dane są na łasce jak często robisz kopie tak, więc punkt ta odpowiedź robił to, że drugi lub dwa utraconych danych jest się czym martwić, w porównaniu
thomasrutter