симптом
Приблизно кожен сьомий запит повертав HTTP 500 — 825 таких за півтори години. У журналі помилок щоразу одне й те саме: магазин не може відкрити з’єднання з базою. Кількість росла тижнями — від 17 на добу на початку серпня до 915 у день діагностики.
діагностика
Сервер був завантажений на 40%, трафік рівний — жодної атаки. Тариф хостингу дозволяє 30 з’єднань з базою на користувача, і магазин їх вичерпував. Кожен запит, разом із ботами, переписував рядок у таблиці сесій; на 2,3 ГБ кожен такий запис тримав з’єднання достатньо довго, щоб черга переповнювалась.
Таблиця розрослась, бо очищення сесій в OpenCart 3.0.3 порівнює число з датою, і це порівняння жодного разу не спрацювало. Сесії з 2023 року лежали на місці.
що зроблено
- Бекап бази без сесій і окремо — живих сесій.
- 22,8 мільйона застарілих рядків видалено порціями по 5 000 — за 17 хвилин, магазин увесь час працював.
- Очищення сесій виправлено так, що термін дії рахує сама база. PHP і MySQL на цьому сервері живуть із різницею в три години, і перша версія виправлення розлогінювала кожного відвідувача на кожному запиті. Це спіймано порівнянням даних сесії між двома запитами — тест із кошиком при цьому проходив.
- Додано індекс на дерево категорій і модифікацію, яка не рахує рейтинг, знижку й акційну ціну для кожного товару категорії, коли сторінка за ними не сортується.
- Статику закешовано на місяць–рік; сканер SQL-ін’єкцій, що гатив по магазину, заблоковано.
що не знадобилось
Ні нового сервера, ні тарифу — нинішній був завантажений на 40%. Ні переписування теми, ні плагіна кешу.
що досі повільне
Категорія, у якій майже весь каталог — 24 209 товарів, — досі відкривається близько 2,2 секунди. Щоб показати 24 книжки за абеткою, база мусить відсортувати їх усі; той самий запит без сортування — 12 мс. Цій сторінці потрібен сторінковий кеш, а не ще один індекс. PHP досі 7.2: оновлення блокує зашифрований сторонній модуль, доки хостинг не дасть завантажувач для новішої версії.