Dynamiczna zmiana na innodb_flush_log_at_trx_commit

11

Jest to związane z tym pytaniem . Pomaga uzyskać lepszą wydajność dla tabel InnoDB.

Według instrukcji MySQL , innodb_flush_log_at_trx_committo zmienna globalna dynamiczny. Dlatego mogę to zmienić za pomocą polecenia SET GLOBAL i wydaje się, że działa.

mysql> SET GLOBAL innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected

mysql> SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set

Ale nie zmieniło to faktycznego ustawienia MySQL. Kiedy zaktualizowałem my.cnf i zrestartowałem serwer MySQL, zadziałało. Więc nie mogę zmienić globalnej zmiennej w czasie wykonywania?

Wolę wartość domyślną innodb_flush_log_at_trx_commit=1, ale muszę ją zmienić na 2, zanim uruchomię proces przywracania dużej bazy danych, aby przyspieszyć. Ale gdy proces się zakończy, chcę zmienić wartość z powrotem na 1. Czy można to zrobić w czasie wykonywania?

Nie mam dostępu do pliku my.cnf na moim udostępnionym serwerze hostingowym.

Sithu
źródło

Odpowiedzi:

12

Chociaż zgadzam się z zaleceniem Rolando dotyczącym zmiany innodb_flush_method, nie byłem w 100% jasny, co miałeś na myśli przez:

nie zmieniło to faktycznego ustawienia MySQL

Chcę zwrócić uwagę na zastrzeżenie , że zmiana zmiennej GLOBAL wpływa na wszelkie nowe połączenia, ale nie modyfikuje bieżącej sesji (moje wyróżnienie):

Zmiana zmiennej globalnej nie wpływa na zmienną sesyjną dla żadnego klienta, który jest aktualnie podłączony ( nawet dla klienta, który wydaje instrukcję SET GLOBAL ).

Aby to sprawdzić:

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)


mysql> SHOW SESSION VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> SHOW SESSION VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

mysql> connect;
Connection id:    6
Current database: *** NONE ***

mysql> SHOW SESSION VARIABLES LIKE 'innodb_flush_log%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 2     |
+--------------------------------+-------+
1 row in set (0.00 sec)
Derek Downey
źródło
2
Ta odpowiedź ma sens. Dokumentacja ( dev.mysql.com/doc/refman/5.5/en/... ) nie mówi, że zmienna na poziomie sesji może być zmieniona, tylko na poziomie globalnym. Doświadczyłem, że wiele razy zmiana max_connections zi SET GLOBAL max_connections = 1000;kiedy biegnę, SHOW VARIABLES LIKE 'max_connections';aby zobaczyć starą wartość, doprowadzałaby do szału, aż wyloguję się i wrócę. +1 za ten punkt widzenia, który jest oczywisty i często zapominany.
RolandoMySQLDBA,
@Rolando mnie też! również był zadowolony, gdy stwierdziłem, że mogę „połączyć”; zamiast wylogowywania się i ponownego logowania. Oszczędza czas!
Derek Downey
Ta koncepcja uruchamiania connectjest dla mnie nowa w MySQL. Zrobiłem to milion razy w PostgreSQL i Oracle. Nigdy nie myślałem, że MySQL na to pozwala
RolandoMySQLDBA,
@DTest, dziękuję za odpowiedź. Według moich głębokich testów działało to dynamicznie. W moim lokalnym hoście zmienna sesji została zmieniona bez uruchamiania połączenia (dostałem błąd przy problemie connect). Przy wartości 2 importowanie 2 241 319 rekordów zajęło 27 minut 43 sekund, podczas gdy wartość 1 zajęła około 1 dnia. Ustawienie wydaje się działać w bieżącej sesji, ale przywróciło oryginalne ustawienie (z my.cnf) po ponownym uruchomieniu.
Sithu,
@DerekDowney, czy to tylko dla niektórych ustawień, takich jak innodb_flush_log_at_trx_commit? A może dla wszystkich ustawień ustawienie opcji globalnie wpłynie na bieżącą sesję?
Pacerier,
7

Ustawiając innodb_flush_log_at_trx_commit , ryzykujesz pomylenie z interoperacyjnością mysqld / OS. Mówię to, ponieważ system operacyjny ma zaufanie do wykonania czyszczenia.

Zwróć uwagę na ostrożność zawartą w dokumentacji MySQL

Wiele systemów operacyjnych i niektóre urządzenia dyskowe 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ęciach sprzętowych lub użyć innej komendy specyficznej dla dostawcy sprzętu.

Mówi to następująco: system operacyjny może kłamać jak oszukujący mąż. System operacyjny mówi, że opróżni się na dysk i po prostu tego nie robi. Dlatego nawet jeśli ustawisz innodb_flush_log_at_trx_commit, musisz rozdzielić opróżnianie systemu operacyjnego na dysk z opróżniania mysqld na dysk.

Spróbuj ustawić innodb_flush_method na O_DIRECT, jeśli jeszcze tego nie zrobiłeś. Możesz zobaczyć różnicę, ponieważ metoda flush różni się znacznie (zobacz mój Mar 04, 2011post Wyjaśnienie na zmiennej MySQL innodb_flush_method ).

CAVEAT

Jak wspomniałeś, nie masz dostępu do my.cnf. Skontaktuj się z SysAdmin u swojego dostawcy i zmień innodb_flush_method .

AKTUALIZACJA 2012-12-10 12:45 EDT

Obecnie używam MySQL 5.5.12 na moim komputerze. Po podłączeniu i uruchomieniu show variables like 'innodb_flush_method';dostaję

mysql> show variables like 'innodb_flush_method';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| innodb_flush_method |       |
+---------------------+-------+
1 row in set (0.05 sec)

mysql>

Ponieważ jest pusty, oznacza to tylko, że używane jest ustawienie domyślne. Proszę przeczytać mój post z 4 marca 2011 r. W sprawie wyjaśnienia zmiennej MySQL innodb_flush_method

RolandoMySQLDBA
źródło
Najpierw przetestowałem na moim localhost. Nie mogłem znaleźć innodb_flush_methodw my.ini(nie my.cnf). Informacje o serwerze - Apache 2.4.1, PHP 5.4.4, MySQL 5.5
Sithu
Zauważyłem, że niezależnie od wersji serwera lub ini / cnf, plik konfiguracyjny nie ma innodb_flush_methodustawień i SHOW VARIABLESnie pokazuje go.
Sithu,
Dziękuję za waszą AKTUALIZACJĘ, ja też ją dostałem, po prostu zastanawiałem się, dlaczego nie widzimy jej wartości. Ponieważ nie mogłem go znaleźć my.inilub my.cnfnie jest to zmienna dynamiczna, nie jestem pewien, jak ją skonfigurować.
Sithu,