Як я можу налаштувати MySQL Innodb для обробки 1000-ти вставок на годину?


10

У мене дуже високий веб-сайт із трафіком, де можливо щороку вставляти 1000 тисяч нових записів.

Ця одна помилка калічить сайт:

PDOException: SQLSTATE[40001]: Serialization failure: 1213 
Deadlock found when trying to get lock; 
try restarting transaction: INSERT INTO {location_instance} 
(nid, vid, uid, genid, lid) VALUES (:db_insert_placeholder_0, 
:db_insert_placeholder_1, :db_insert_placeholder_2, 
:db_insert_placeholder_3, :db_insert_placeholder_4); 
Array ( [:db_insert_placeholder_0] => 1059 [:db_insert_placeholder_1] => 
1059 [:db_insert_placeholder_2] => 0 [:db_insert_placeholder_3] => 
cck:field_item_location:1059 [:db_insert_placeholder_4] => 1000 )

Я був би дуже здивований, якби MySQL не впорався з таким типом навантаження. Отже, у мене виникають питання, чи це проблема з базою даних, і як я можу налаштувати MySQL, щоб він міг обробляти стільки трафіку?

У мене є копія мого веб-сайту, створеного на сервері розробки зі скриптами, що імітують завантаження вмісту, що додається на веб-сайт. У мене працює Ubuntu, стек LAMP, з 16 Гб оперативної пам’яті.

Правда, я не дуже обізнаний у базах даних. Насправді я починаю з типового my.cnf, який постачається з ним після завершення "apt-get install". Столи всі Innodb. Які початкові налаштування та підхід до налаштування ви б рекомендували розпочати вирішення цієї проблеми?

Дайте мені знати, яка додаткова інформація вам може знадобитися.

Дякую


Ви починаєте з продукту my.cnf за замовчуванням для виробництва? Людина, ти мусиш її більше оптимізувати. Детальніше розкажу про вас у моїй відповіді. :-)

Відповіді:


11

Ви маєте справу з тупиком, а не проблемою з ефективністю.

Якщо у вас є тисяча нових записів на годину, ви далеко далеко від меж MySQL. MySQL може обробляти щонайменше 50 разів ваші навантаження.

Тупики викликаються кодом програми та не є виною сервера бази даних. Тупики не можна виправити на стороні сервера MySQL, за винятком деяких конкретних ситуацій.

InnoDBможе показати вам детальну інформацію про тупик, запустивши SHOW ENGINE INNODB STATUSв запиті MySQL або з mysql -uroot -p... -e "SHOW ENGINE INNODB STATUS".

Однак це показує лише останній тупик, який стався, журналу тупикового зв'язку немає.

На щастя, є інструмент pt-deadlock-logger, який вирішує цю проблему, піклується про InnoDBстан опитування та зберігає всю детальну інформацію про тупик, перш ніж оновити її новим тупиком.


Добре знати! Я бачу в команді show status інформацію про блокування та відповідні запити та таблицю. З огляду на те, що це в моєму коді, як я можу використовувати цю інформацію з команди статусу, щоб почати налагоджувати проблему? Запит PHO PDO досить прямий вперед - підключіть, підготуйте, виконайте, повторіть. Я радий опублікувати будь-який код або повідомлення про стан, якщо це допоможе.
користувач658182

@ user658182 перевірте цю публікацію в stackoverflow про те, як поводитися з тупиками: як уникнути mysql тупику, виявленого при спробі заблокувати
доблесть

1
@ max-vernon дякую за редагування синтаксису, явно англійською мовою це не моя рідна мова :-).
доблесть

1
-е «ШОУ ДВИГАТЕЛЯ ІННОДБА»
гліф

8

Це може бути так само просто, як одна частина вашого коду, яка виконує транзакцію:

insert into t1...
insert into t2...
commit;

а інша частина вашого коду змінює ті самі таблиці в іншому порядку:

delete from t2 where...
delete from t1 where...
commit;

Якщо обидві ці транзакції виконуються одночасно, може статися умова перегонів: перша транзакція не може змінитись, t2оскільки вона заблокована другою транзакцією; тоді як друга транзакція аналогічно блокується, оскільки t1блокується першою транзакцією. MySQL вибирає одну транзакцію, щоб стати "жертвою", коли ВСТУП / ОНОВЛЕННЯ / УДАЛЕННЯ виходить з ладу. Програмі потрібно визначити цю помилку та повторити спробу - можливо, після паузи, щоб інша транзакція встигла закінчитись. Нічого не пов’язаного з обмеженням пропускної спроможності, лише невдалий термін, який може бути посилений способом впорядкування коду. Переключіть DELETE в транзакції №2 або ВСТАВКИ в транзакції №1, і тоді немає конфлікту - кожна транзакція буде чекати доступу до потрібних таблиць.

У MySQL 5.6 ви можете запустити за допомогою параметра innodb_print_all_deadlocks, увімкнутого для збору інформації про всі тупикові місця (не лише останню) в журналі помилок MySQL.

[Обов'язкова відмова: Я працівник Oracle. Сказане вище - це моя особиста думка, а не офіційна заява.]

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