Безопасно ли использовать innodb_flush_log_at_trx_commit = 2


54

Я повернулся innodb_flush_log_at_trx_commit = 2и получил очень высокую скорость записи. Но безопасно ли его использовать на производственном веб-сайте?

Ответы:


57

Вы можете потерять до одной секунды транзакций. Значение по умолчанию равно 1, что помогает поддерживать InnoDB ACID .

Согласно документации MySQL на innodb_flush_log_at_trx_commit

Если значение innodb_flush_log_at_trx_commit равно 0, буфер журнала записывается в файл журнала один раз в секунду, и операция записи на диск выполняется с файлом журнала, но при фиксации транзакции ничего не делается. Когда значение равно 1 (по умолчанию), буфер журнала записывается в файл журнала при каждой фиксации транзакции, и операция записи на диск выполняется с файлом журнала. Когда значение равно 2, буфер журнала записывается в файл при каждой фиксации, но операция очистки на диск не выполняется с ним. Однако очистка файла журнала происходит один раз в секунду, когда значение равно 2. Обратите внимание, что очистка один раз в секунду не гарантируется на 100% каждую секунду из-за проблем с планированием процесса.

Значение по умолчанию 1 требуется для полного соответствия ACID. Вы можете добиться лучшей производительности, установив значение, отличное от 1, но тогда вы можете потерять до одной секунды транзакций в случае сбоя. При значении 0 любой сбой процесса mysqld может стереть последнюю секунду транзакций. При значении 2 только сбой операционной системы или отключение питания могут стереть последнюю секунду транзакций. Восстановление после сбоя InnoDB работает независимо от значения.

Для максимально возможной долговечности и согласованности в настройке репликации, использующей InnoDB с транзакциями, используйте innodb_flush_log_at_trx_commit = 1 и sync_binlog = 1 в файле my.cnf главного сервера.

предосторожность

Многие операционные системы и некоторые дисковые устройства обманывают операцию записи на диск. Они могут сказать mysqld, что сброс произошел, хотя это не так. Тогда долговечность транзакций не гарантируется даже при значении 1, а в худшем случае отключение питания может даже повредить базу данных InnoDB. Использование дискового кеша с резервным питанием от батареи в контроллере диска SCSI или на самом диске ускоряет очистку файлов и делает работу более безопасной. Вы также можете попробовать использовать команду Unix hdparm, чтобы отключить кэширование записи на диск в аппаратных кэшах, или использовать другую команду, специфичную для поставщика оборудования.

Исходя из этого, значения, отличные от 1, подвергают InnoDB риску потери транзакций на 1 секунду или данных фиксации транзакции.

В документации также написано использование sync_binlog=1.

Согласно документации MySQL на sync_binlog

Значение 1 - самый безопасный выбор, потому что в случае сбоя вы теряете не более одного оператора или транзакции из двоичного журнала. Однако это также самый медленный выбор (если только на диске нет кеша с резервным питанием от батареи, что делает синхронизацию очень быстрой).

Ваш самый безопасный выбор

[mysqld]
innodb_flush_log_at_trx_commit=1
sync_binlog=1

Если вы не возражаете против возможной потери данных (до 1 секунды), то вы можете использовать 0 или 2 на свой страх и риск, если награды (более высокая скорость записи) того стоят.


3
Роландо: +1 за последние несколько строк sync_binlog = 1 ...
Абдул Манаф

@AbdulManaf, всегда стремитесь к целостности данных, а не к скорости. Если вы хотите пожертвовать скоростью ради целостности данных, вы потеряете гораздо больше времени на решение проблем с данными.
Pacerier

1
@RolandoMySQLDBA, «Потеря стоимости транзакции за секунду» означает ли вы, что успешный commit может быть на самом деле потерян?
Pacerier

1
Пейсер, да. Данные гарантированно будут записаны на диск только после их «сброса на диск». До этого он может быть только в оперативной памяти.
Эмиль Викстрем

2
@RolandoMySQLDBA, ты человек, серьезно. Если вы занимаетесь чем-то другим, кроме выступлений в MySQL, вы, возможно, должны изменить свой карьерный путь.
Sjas

25

innodb_flush_log_at_trx_commitИспользуется с целью как ..

Если значение innodb_flush_log_at_trx_commit равно 0, буфер журнала записывается в файл журнала один раз в секунду, и операция записи на диск выполняется с файлом журнала, но при фиксации транзакции ничего не делается.

Когда значение равно 1 (по умолчанию), буфер журнала записывается в файл журнала при каждой фиксации транзакции, и операция записи на диск выполняется над файлом журнала.

Когда значение равно 2, буфер журнала записывается в файл при каждой фиксации, но операция очистки на диск не выполняется с ним. Однако очистка файла журнала происходит один раз в секунду, когда значение равно 2. Обратите внимание, что очистка один раз в секунду не гарантируется на 100% каждую секунду из-за проблем с планированием процесса.

Значение по умолчанию 1 требуется для полного соответствия ACID. Вы можете добиться лучшей производительности, установив значение, отличное от 1, но тогда вы можете потерять до одной секунды транзакций в случае сбоя. При значении 0 любой сбой процесса mysqld может стереть последнюю секунду транзакций. При значении 2 только сбой операционной системы или отключение питания могут стереть последнюю секунду транзакций. Восстановление после сбоя InnoDB работает независимо от значения.

По моему мнению, использование innodb_flush_log_at_trx_commitдо 2 не должно быть проблемой. Но использовать 1 является самым безопасным.


3
Я только что заметил, что вы ответили только через 18 секунд после меня с практически тем же ответом. +1 !!!
RolandoMySQLDBA

24

Мое мнение отличается от других. innodb_flush_log_at_trx_commit = 0 if: это мой компьютер для разработки или домашняя мини-база данных, где нет конфиденциальных данных.

innodb_flush_log_at_trx_commit = 2, если: это блог / статистика / электронная коммерция (с ~ 100-кратным магазином в день) и т. д.

innodb_flush_log_at_trx_commit = 1, если: у вас много клиентов или вам нужно работать с денежными транзакциями, такими как банк. так что на этот раз вы должны разделить ваш поток данных между несколькими серверами, чтобы иметь скорость и безопасность.

Я предпочитаю 2, потому что у него скорость записи примерно в 75 раз выше и он дает сбой ТОЛЬКО в случае отказа оборудования

В любом случае, вы должны знать, что вам нужно, гораздо больше скорости записи или до 1 секунды информации?


1
+1 за75x faster write speed and it fails ONLY if hardware fails.
Наман Гала

3
В 75 раз быстрее? Нужна цитата.
Pacerier

5
Мой собственный тест: 5000 UPDATEс innodb_flush_log_at_trx_commit = 1: 179 секунд. С innodb_flush_log_at_trx_commit = 2: 1.12секунды. В моем случае скорость записи в 160 раз выше.
Кевин

Хороший ответ. Стоит подумать о том, что - если ваша машина дает сбой после успешной транзакции, есть вероятность, что транзакция не была записана на диск с innodb_flush_log_at_trx_commit = 2, и, тем не менее, вашему приложению был указан успешный результат (т.е. mysqld удается отправить сетевой пакет, указывающий, что транзакция успешно завершена). водителю в вашем приложении), этот шанс очень и очень мал
Владислав Вантроуб

Можете ли вы улучшить свой ответ, указав, что под документами подразумеваетсяcrash
Шариф

2

Я пытаюсь ответить, какова цель innodb_flush_log_at_trx_commit?

InnoDB выполняет большинство своих операций в памяти ( InnoDB Buffer Pool). Все измененные данные записываются InnoDB transaction log fileи затем записываются (записываются) в долговременное хранилище (жесткий диск).

В целях безопасности данных ( Durability from ACID) InnoDB должен хранить измененные данные каждой транзакции в постоянном хранилище. В то же время запись на диск для каждой транзакции является дорогостоящим процессом.

Дисковый ввод-вывод является блокирующим процессом, и он очень медленный, это медленный диск, в дальнейшем это уменьшит количество InnoDB transaction per seconds(пропускная способность диска).

InnoDB предоставляет innodb_flush_log_at_trx_commitпеременную для управления частотой этой операции очистки. В зависимости от значения, операция очистки InnoDB ведет себя по-разному.

(Уже объяснил в других ответах)

0 - запись в файл журнала и сброс на диск каждую секунду (данные в пуле буферов не записываются в файл журнала - для повышения производительности). 1 - Сбросить на диск при фиксации транзакции - по умолчанию (Для безопасности данных - соответствие ACID) 2 - запись в файл журнала для каждой транзакции и сброс на диск каждую секунду. (Для увеличения производительности)

В зависимости от требования приложения ( Performance Vs data safety), вы можете установить эту переменную. Разница между 0 и 2 - оба увеличат производительность, значение 2 хранит данные в файле транзакции и может быть восстановлено в случае сбоя или сбоя, но не в 0.

Во многих случаях сброс на диск означает, что данные записываются с InnoDB buffer pool (memory) to Operating systems cacheфактически не записанного на диск хранения (постоянное хранилище). В случае сбоя, в худшем случае вы можете потерять данные до одной секунды)

Прирост производительности зависит от среды, и вы можете сравнить и определить. В среде репликации для обеспечения безопасности и согласованности данных установите innodb_flush_log_trx_commit = 1и sync_binlog=1.

Если основной целью приложения является производительность, InnoDB предоставляет переменную для управления частотой очистки журнала, innodb_flush_log_at_timeoutкоторая позволяет вам установить диапазон частоты очистки журнала 1 to 2700 seconds, по умолчанию он равен 1.

Имейте в виду, что при увеличении интервала очистки до N секунд выигрыш в производительности приводит к снижению безопасности данных до N секунд. Например, если вы устанавливаете сброс каждые 5 секунд, выигрыш в пропускной способности очень высок, но в случае сбоя питания или сбоя системы вы потеряете данные на 5 секунд.

В этой статье обсуждаются операции очистки и фиксации транзакций InnoDB .

Вы можете изменить режим 2 на aws rds:

можно изменить после того, как вы сделаете режим 2 на AWS

previewchanges

Не изменяется в некоторых случаях, например, если у вас есть репликация multi az:

К вашему сведению, не изменяемые в некоторых случаях


1

Если ваше оборудование выходит из строя, вы можете потерять все свои данные, поэтому я использую param = 2 без каких-либо забот. В любом случае вы можете разделить свои конфиденциальные (заказ, виртуальные деньги, ...) и обычные (статистика, корзина, ...) данные между серверами 2 дБ и обеспечить их безопасность и скорость. Для транзакций между базами данных вы можете использовать http://dev.mysql.com/doc/refman/5.7/en/xa.html


«Потерять все свои данные», или вы имеете в виду транзакции, которые запрашивались в последние несколько секунд или около того?
NiCk Newman

1
Отказ оборудования может означать потерю всего жесткого диска, следовательно, «потерять все ваши данные». Таким образом, если у вас нет настроек репликации, ваши данные в любом случае
зависят
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.