Чи безпечно використовувати 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 або на самому диску прискорює змивання файлів і робить роботу безпечнішою. Ви також можете спробувати використовувати команду hdparm Unix для відключення кешування записів диска в кеш-пам'яті апаратних засобів або використовувати іншу команду, специфічну для постачальника обладнання.

Виходячи з цього, значення, відмінні від 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 насправді можна втратити?
Пейсьєр

1
Пейсьєр, так. Дані гарантовано записуються на диск лише після того, як вони будуть "перенесені на диск". До цього часу це може бути лише в оперативній пам'яті.
Еміль Вікстрьом

2
@RolandoMySQLDBA ти людина, серйозно. Якщо ви робите що-небудь, окрім консалтингових концертів mysql, ви, можливо, повинні змінити свій кар'єрний шлях.
sjas

25

The 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, якщо: це мій комп'ютер розвитку або домашня міні-база даних, де немає конфіденційних даних.

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

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

Я віддаю перевагу 2, тому що він має ~ 75x більшу швидкість запису, і він виходить ТІЛЬКИ, якщо апаратне забезпечення виходить з ладу.

У будь-якому випадку ви повинні знати, що вам потрібно набагато більше швидкості запису або до 1 секунди інформації?


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

3
75x швидше? Потрібне цитування.
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
shareef

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

попередні зміни

Неможливо змінити в деяких випадках, наприклад, якщо у вас є реплікація multi az:

ПІІ в деяких випадках неможливо змінити


1

Якщо апаратне забезпечення вийде з ладу, ви можете втратити всі свої дані, тому я використовую param = 2 без жодних турбот. У будь-якому випадку ви можете розділити ваші чутливі (замовлення, віртуальні гроші, ...) та регулярні (статистичні дані, кошики, ...) дані між двома db-серверами та зберегти їх безпечно та швидко. Для транзакцій між базами даних ви можете використовувати http://dev.mysql.com/doc/refman/5.7/uk/xa.html


"Втратити всі свої дані", чи ви маєте на увазі транзакції, які отримували запити за останні кілька секунд чи так?
NiCk Newman

1
Поломка обладнання може означати втрату цілого жорсткого диска, отже, "втратити всі ваші дані". Тому, якщо у вас не встановлено реплікацію, ваші дані не в міру того, як часто ви робите резервні копії, так що справа в цій відповіді полягає в тому, що в порівнянні з другою або двома втраченими даними нічого не турбуватися
thomasrutter
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.