роботи/speed/sports-books-store
// кейс 03 · швидкість · opencart 3 · 24 579 товарів

Категорії з 2 205 мс до 292 мс — і помилки HTTP 500 припинились.

Магазин спортивної літератури на 24 579 товарів віддавав HTTP 500 приблизно на кожен сьомий запит. Сервер не був перевантажений, і ніхто його не атакував. База тримала 22,8 мільйона сесій, які ніколи не видалялись.

клієнт
магазин спортивної літератури, UA
платформа
OpenCart 3.0.3, MariaDB
каталог
24 579 товарів
послуга
03 · прискорити
тривалість
один вечір
рік
2026
категорія «шахи», час сторінки
292 мс2 205 мс
помилки бази, на добу
0915
розмір бази
301 МБ2 562 МБ

симптом

Приблизно кожен сьомий запит повертав HTTP 500 — 825 таких за півтори години. У журналі помилок щоразу одне й те саме: магазин не може відкрити з’єднання з базою. Кількість росла тижнями — від 17 на добу на початку серпня до 915 у день діагностики.

діагностика

Сервер був завантажений на 40%, трафік рівний — жодної атаки. Тариф хостингу дозволяє 30 з’єднань з базою на користувача, і магазин їх вичерпував. Кожен запит, разом із ботами, переписував рядок у таблиці сесій; на 2,3 ГБ кожен такий запис тримав з’єднання достатньо довго, щоб черга переповнювалась.

Таблиця розрослась, бо очищення сесій в OpenCart 3.0.3 порівнює число з датою, і це порівняння жодного разу не спрацювало. Сесії з 2023 року лежали на місці.

diagnosis.logфрагмент
01$ count responses --last 90m
02http 200 ........... 4,479
03http 500 ........... 825
04$ tail error_log
05mysql .............. max_user_connections (30) exceeded
06$ inspect db --largest
07oc_session ......... 22.8M rows · 89% of database
08# clean-up compares int with datetime: nothing deleted since 2023

що зроблено

  1. Бекап бази без сесій і окремо — живих сесій.
  2. 22,8 мільйона застарілих рядків видалено порціями по 5 000 — за 17 хвилин, магазин увесь час працював.
  3. Очищення сесій виправлено так, що термін дії рахує сама база. PHP і MySQL на цьому сервері живуть із різницею в три години, і перша версія виправлення розлогінювала кожного відвідувача на кожному запиті. Це спіймано порівнянням даних сесії між двома запитами — тест із кошиком при цьому проходив.
  4. Додано індекс на дерево категорій і модифікацію, яка не рахує рейтинг, знижку й акційну ціну для кожного товару категорії, коли сторінка за ними не сортується.
  5. Статику закешовано на місяць–рік; сканер SQL-ін’єкцій, що гатив по магазину, заблоковано.

що не знадобилось

Ні нового сервера, ні тарифу — нинішній був завантажений на 40%. Ні переписування теми, ні плагіна кешу.

що досі повільне

Категорія, у якій майже весь каталог — 24 209 товарів, — досі відкривається близько 2,2 секунди. Щоб показати 24 книжки за абеткою, база мусить відсортувати їх усі; той самий запит без сортування — 12 мс. Цій сторінці потрібен сторінковий кеш, а не ще один індекс. PHP досі 7.2: оновлення блокує зашифрований сторонній модуль, доки хостинг не дасть завантажувач для новішої версії.