Error establishing a database connection: чиним WordPress по шагам
Что означает ошибка соединения с базой, как проверить доступы в wp-config, восстановить упавшую базу и не потерять данные при починке.
Содержание
- Что вообще означает эта строчка
- Первые пять минут: чья это проблема
- Проверка доступов в wp-config.php
- Когда виноват хостинг
- Повреждённые таблицы
- Кончилось место на диске
- Восстановление из дампа без потери заявок
- Таблица быстрой диагностики
- Чек-лист: порядок действий за 15 минут
- Что настроить после, чтобы узнать раньше клиента
- Сколько это стоит починить
- Частые вопросы
Строчка про невозможность соединения с базой значит одно из четырёх: неверные доступы в конфиге, лежащий сервер базы у хостинга, повреждённые таблицы или кончившееся место на диске. Проверять надо в этом порядке, весь разбор укладывается в 15 минут.
Открываете сайт, а вместо главной белый экран с одной строчкой: Error establishing a database connection. Ни меню, ни логотипа, админка тоже не пускает. Ошибка соединения с базой данных WordPress выглядит одинаково страшно и в случае, когда у хостера просто перегружен MySQL, и в случае, когда таблицы физически побиты. Разница в том, что первое лечится ожиданием, а второе руками и дампом. Ниже пошаговый разбор: как за пять минут понять, чья это проблема, что смотреть в wp-config.php, как чинить таблицы и как восстановиться из бэкапа, не потеряв заявки за последние сутки.

Я вожусь с этой ошибкой на клиентских сайтах примерно раз в две недели. За шесть лет накопилась статистика: в 6 случаях из 10 виноват хостинг, в 2 из 10 кто-то трогал wp-config.php или менял пароль в панели, в 1 из 10 кончилось место на диске, и ещё в 1 из 10 база действительно побилась. Порядок проверки ниже построен именно по этой частотности, чтобы вы не начинали с самого редкого.
Что вообще означает эта строчка
WordPress целиком живёт в базе. Тексты страниц, настройки темы, список плагинов, пользователи, заказы WooCommerce, даже адрес самого сайта лежат в MySQL. Файлы на диске это только код. Когда PHP не может подключиться к базе, отдавать нечего вообще: движок не знает ни какой шаблон грузить, ни какой у сайта домен.
Поэтому сайт лежит целиком, включая /wp-admin/. Это отличает ошибку базы от белого экрана из-за фатальной ошибки PHP, где админка часто ещё открывается. Если вы попали именно на второй сценарий, разбор есть в отдельной статье про белый экран смерти WordPress.
Сама ошибка приходит из функции wp_die() внутри wp-includes/class-wpdb.php и означает ровно одно: вызов mysqli_connect() вернул ошибку. Причин у этого немного, и они конечны:
- неверные логин, пароль, имя базы или хост в конфиге,
- MySQL-сервер не отвечает (упал, перегружен, на паузе, лимит соединений),
- база или пользователь удалены либо переименованы,
- на диске нет места, и MySQL не может писать во временные файлы,
- таблицы повреждены настолько, что база не открывается.
Все пять сценариев разбираем по очереди.
Первые пять минут: чья это проблема
Прежде чем лезть в файлы, отделите свою поломку от хостинговой. Три быстрые проверки.
Первое. Откройте панель хостинга и найдите phpMyAdmin. Если он не пускает или пишет «не удалось подключиться к серверу MySQL», база лежит у хостера и ваш wp-config.php не при чём. Пишите в поддержку и ждите.
Второе. Проверьте другие сайты на том же аккаунте. Если лежат все, снова хостинг.
Третье. Загляните в /wp-admin/. WordPress иногда отдаёт там более подробное сообщение вида «One or more database tables are unavailable. The database may need to be repaired». Это уже прямая подсказка про битые таблицы, к ним вернёмся ниже.
Если phpMyAdmin работает и база в нём открывается, значит MySQL жив, а проблема между ним и вашим сайтом. Дальше по шагам.
Проверка доступов в wp-config.php
Файл лежит в корне сайта. Нужны четыре константы:
define( 'DB_NAME', 'cr43080_wp1' );
define( 'DB_USER', 'cr43080_wp1' );
define( 'DB_PASSWORD', 'Xk8s2!vQpr' );
define( 'DB_HOST', 'localhost' );
Что здесь ломается чаще всего.
Пароль с кавычками и слешами. Панель хостинга генерирует пароли вида a$bc'd. Если он вставлен в одинарные кавычки без экранирования, PHP обрежет строку и пароль уедет неверный. Проверить просто: смените пароль пользователя базы на что-то из букв и цифр без спецсимволов, обновите конфиг, перезагрузите сайт.
Хост не localhost. У Timeweb, Beget, reg.ru и большинства российских shared-хостингов база живёт на отдельном сервере, и DB_HOST выглядит как cr43080.mysql.tools или localhost:3306. Значение всегда есть в панели, в разделе с базами данных. Подставили localhost наугад после переезда — получили ровно эту ошибку. Кстати, перенос сайта на новый хостинг валится на этом пункте примерно всегда, когда его делают без чек-листа.
Префикс таблиц. Константа $table_prefix не влияет на подключение, но влияет на то, найдёт ли WordPress свои таблицы. Если после восстановления дампа сайт пишет уже не про соединение, а про необходимость установки, сверьте префикс в конфиге с реальными именами таблиц в phpMyAdmin.
Проверить доступы отдельно от WordPress можно коротким скриптом. Положите его в корень как dbtest.php, откройте в браузере, потом обязательно удалите:
<?php
$link = @mysqli_connect('localhost', 'cr43080_wp1', 'ПАРОЛЬ', 'cr43080_wp1');
if (!$link) {
echo 'FAIL: ' . mysqli_connect_error();
} else {
echo 'OK, server: ' . mysqli_get_server_info($link);
}
Ответ Access denied for user означает неверный логин или пароль. Unknown database означает, что имя базы не то. Can't connect to MySQL server означает, что не тот хост или сервер лежит. Три разных диагноза за десять секунд, а не гадание.
Если есть SSH и WP-CLI, то же самое делается одной командой:
wp db check
wp config get DB_HOST
Когда виноват хостинг
Самая частая причина, и самая обидная: ваш сайт исправен, чинить нечего.
Превышен лимит соединений
На shared-тарифах лимит одновременных подключений к MySQL обычно 20-60. Пришёл поисковый бот, параллельно кто-то полез парсить каталог, WooCommerce начал пересчитывать корзины, и лимит выбран. Ошибка при этом плавающая: сайт то открывается, то нет, обновление страницы иногда помогает.
Признак: в логах или в ответе теста висит Too many connections либо User has exceeded the max_user_connections resource. Лечится либо кэшированием, чтобы каждый заход не дёргал базу, либо переездом на тариф пожирнее. Механика ровно та же, что при упоре в лимиты CPU и памяти на shared-тарифе.
База на паузе или удалена
У некоторых хостеров базы автоматически останавливаются при неоплате или при простое на тестовых тарифах. В панели база при этом видна, но помечена как остановленная. Один клик в панели возвращает сайт.
MySQL упал или перезапускается
Бывает при плановых работах и при аварии на ноде. Ждать. Полезно иметь мониторинг доступности сайта, чтобы узнать об этом от бота за минуту, а не от клиента через шесть часов.
Повреждённые таблицы
Если phpMyAdmin открывается, база на месте, доступы верные, а сайт всё равно ругается — смотрим таблицы. Симптом обычно такой: часть страниц открывается, а на других ошибка, либо в админке висит сообщение про недоступные таблицы.
Штатный ремонт включается константой в wp-config.php:
define( 'WP_ALLOW_REPAIR', true );
После этого открываете https://ваш-сайт.ru/wp-admin/maint/repair.php. Страница доступна без авторизации, поэтому константу нужно убрать сразу после ремонта, иначе любой желающий сможет запускать оптимизацию вашей базы.
Через SSH быстрее и информативнее:
mysqlcheck -u cr43080_wp1 -p --auto-repair --check cr43080_wp1
mysqlcheck -u cr43080_wp1 -p --optimize cr43080_wp1
Или через WP-CLI:
wp db repair
wp db optimize
Важная оговорка. REPAIR TABLE работает только для движка MyISAM. Если таблицы на InnoDB (а с WordPress 5.х это почти всегда так), команда вернёт «The storage engine for the table doesn’t support repair». InnoDB чинится иначе: через innodb_force_recovery в конфиге MySQL, к которому на shared-хостинге доступа нет. Практический вывод: если InnoDB побился, ваш путь лежит через дамп, а не через ремонт. Не тратьте два часа на попытки.
Проверить движок:
SELECT table_name, engine FROM information_schema.tables
WHERE table_schema = 'cr43080_wp1';
Кончилось место на диске
Отдельный сценарий, который выглядит как поломка базы, а на деле банален. MySQL не может писать во временные файлы и отдаёт ошибку соединения. Сайт лежит, при этом в панели всё зелёное.
Проверка одной командой:
df -h
du -sh ~/public_html/* | sort -h | tail -20
Типичные пожиратели места на сайтах, которые я обслуживаю:
- папка с бэкапами плагина UpdraftPlus или Duplicator, которую никто не чистил два года,
wp-content/uploads/с оригиналами фото по 8 МБ и пятью сгенерированными размерами на каждое,- логи ошибок
error_logв корне, разросшиеся до нескольких гигабайт, - кэш плагина ускорения, у которого сломалась ротация,
- сама база, раздутая ревизиями, transient-записями и таблицами удалённых плагинов.
Последний пункт заслуживает внимания: база на визитке весом 900 МБ это не норма, а симптом. Что там обычно накапливается и как чистить безопасно, разобрано в статье про раздутую базу WordPress и autoload.
Быстро посмотреть размеры таблиц:
SELECT table_name,
ROUND((data_length + index_length)/1024/1024, 1) AS mb
FROM information_schema.tables
WHERE table_schema = 'cr43080_wp1'
ORDER BY mb DESC LIMIT 15;
Восстановление из дампа без потери заявок
Допустим, база всё-таки не спасается и нужен бэкап. Здесь легко потерять данные повторно, уже своими руками.
Главное правило: перед восстановлением сделайте копию текущего состояния, каким бы битым оно ни казалось. Даже частично читаемая база лучше, чем ничего, а после DROP DATABASE вариантов не останется.
mysqldump -u cr43080_wp1 -p --single-transaction --force cr43080_wp1 > broken-$(date +%F).sql
Флаг --force заставит дамп продолжаться, спотыкаясь о битые таблицы. То, что читается, вы сохраните.
Дальше порядок такой.
- Разверните дамп в отдельную базу, не поверх боевой. Хостинг обычно даёт создать вторую бесплатно.
- Сверьте, что в ней есть: количество записей в
wp_posts, дата последнего заказа вwp_wc_ordersилиwp_postsс типомshop_order, последние строки в таблице форм. - Определите дырку. Бэкап от 3:00 ночи, база упала в 15:00, значит потеряны 12 часов заявок.
- Достаньте потерянное из других источников. Именно поэтому у всех моих клиентов заявки дублируются в Telegram и на почту: база может умереть, а переписка в боте останется. Если у вас так же, руками добьёте десяток лидов и никто ничего не заметит.
- Только теперь переключайте
DB_NAMEв wp-config.php на восстановленную базу.
Такой порядок даёт откат на каждом шаге. Если восстановленный дамп окажется неполным, боевая база всё ещё на месте.
И проверьте заодно, что бэкапы вообще есть и лежат не в той же папке, что сайт. Способы без платных плагинов я разбирал отдельно: резервные копии WordPress без платных плагинов.
Таблица быстрой диагностики
| Что видите | Вероятная причина | Первое действие |
|---|---|---|
| Ошибка на всех сайтах аккаунта | Лежит MySQL хостера | Тикет в поддержку, ждать |
| Access denied for user | Неверный логин или пароль | Сменить пароль в панели, обновить wp-config.php |
| Unknown database | Имя базы не то, база удалена | Сверить имя в панели хостинга |
| Can’t connect to MySQL server | Неверный DB_HOST | Взять хост из панели, не писать localhost наугад |
| Too many connections | Выбран лимит соединений | Включить кэш, проверить ботов, поднять тариф |
| Ошибка плавающая, через раз | Перегрузка или лимиты | Смотреть нагрузку, кэшировать, ограничить парсеров |
| Админка пишет про недоступные таблицы | Побитые таблицы | mysqlcheck, при InnoDB сразу дамп |
| Ошибка появилась после правки файлов | Сломан wp-config.php | Проверить синтаксис, кавычки, лишние пробелы |
| Ошибка после переезда | Не тот хост или префикс | Сверить DB_HOST и $table_prefix |
| Всё зелёное, но база молчит | Кончилось место | df -h, чистить логи и бэкапы |
Чек-лист: порядок действий за 15 минут
- Открыть phpMyAdmin. Не пускает — это хостинг, дальше не копаем.
- Проверить остальные сайты аккаунта.
- Скачать копию wp-config.php себе на диск до любых правок.
- Прогнать
dbtest.phpи прочитать точный текст ошибки MySQL. - Сверить DB_NAME, DB_USER, DB_PASSWORD, DB_HOST с панелью хостинга посимвольно.
- Сменить пароль базы на буквенно-цифровой, если в старом были спецсимволы.
- Посмотреть свободное место:
df -h. - Если открывается phpMyAdmin, проверить состояние таблиц и движок.
- Сделать дамп текущей базы с
--forceдо любого ремонта. - Развернуть бэкап в отдельную базу, сверить свежесть, потом переключать конфиг.
- Убрать
WP_ALLOW_REPAIRиз конфига и удалитьdbtest.php.
Последний пункт забывают чаще всего. Файл с паролем базы, оставленный в корне, живёт там годами и однажды находится сканером.
Что настроить после, чтобы узнать раньше клиента
Починили — хорошо. Теперь сделайте так, чтобы в следующий раз вы узнали об этом первым.
Мониторинг с проверкой контента, а не только кода 200. При ошибке базы сервер отдаёт вполне бодрый ответ, и примитивный пингер считает сайт живым. Настраивайте проверку на наличие строки в теле страницы. У UptimeRobot это keyword-мониторинг, доступен на бесплатном тарифе, интервал 5 минут.
Алерт в Telegram, а не на почту. Письмо в общем ящике читается утром. Уведомление в боте видно сразу.
Кастомная страница вместо стандартной ошибки. WordPress умеет показывать свой шаблон: положите файл wp-content/db-error.php, и посетитель увидит вежливое «сайт на техобслуживании, позвоните по телефону» вместо английской строчки. Заодно отдайте правильный код ответа, чтобы поисковики не выкинули страницы из индекса:
<?php
http_response_code( 503 );
header( 'Retry-After: 600' );
?>
<!doctype html>
<html lang="ru"><head><meta charset="utf-8">
<title>Технические работы</title></head>
<body style="font-family:sans-serif;text-align:center;padding:60px">
<h1>Сайт временно недоступен</h1>
<p>Идут технические работы. Заказ можно оформить по телефону +7 (000) 000-00-00.</p>
</body></html>
Пятнадцать минут работы, а магазин в момент аварии продолжает принимать звонки вместо того, чтобы пугать людей английским текстом.
Ежедневный бэкап базы вне хостинга. Дамп WordPress-базы весит от 20 до 300 МБ, хранение в объектном хранилище стоит копейки, порядка 30-60 рублей в месяц за десяток гигабайт. Против стоимости восстановления вручную это ничто.
Мониторинг свободного места. Простой скрипт в крон, который раз в сутки пишет в Telegram, если занято больше 85 процентов диска.
Сколько это стоит починить
Если приходят с уже лежащим сайтом, картина обычно такая. Проверка доступов и правка конфига: 20-30 минут, разовой работой в районе 1 500-2 500 рублей. Ремонт таблиц и чистка базы: 1-2 часа. Восстановление из дампа со сверкой заявок: 2-4 часа, потому что львиная доля времени уходит не на разворачивание бэкапа, а на аккуратное сведение потерянных данных.
Худший вариант это когда бэкапов нет вообще. Тогда речь идёт о восстановлении контента из кэша Яндекса и веб-архива, и это уже десятки часов с неполным результатом. Разработка сайта заново обошлась бы порядка 150 000 рублей, поэтому даже дорогое восстановление обычно дешевле, но радости в такой работе мало ни мне, ни клиенту.
На абонентском обслуживании эта ошибка чаще всего вообще не доходит до владельца: алерт приходит мне, база поднимается из ночного дампа, клиент узнаёт из отчёта. Что входит в такое сопровождение и сколько стоит, смотрите в тарифах.
Если сайт лежит прямо сейчас и разбираться некогда, напишите через форму на главной с указанием хостинга и CMS. Первым делом соберу дамп текущего состояния, потом буду чинить: терять данные ради скорости в этой задаче нельзя.
Частые вопросы
Что делать при ошибке соединения с базой данных
Проверить доступы в конфигурационном файле, потом доступность сервера базы, потом целостность таблиц, потом свободное место. Первые два пункта закрывают большинство случаев.
Как понять, что виноват хостинг
Если доступы в конфиге верные и не менялись, а база не отвечает, вопрос к хостингу. Косвенный признак это одновременное падение нескольких сайтов на одном аккаунте.
Что делать с повреждёнными таблицами
Запустить штатную проверку и починку таблиц. Если не помогает, разворачивать дамп. Разворачивать надо в отдельную базу и сверять, что в ней есть, а не поверх рабочей.
Как не потерять заявки при восстановлении
Посмотреть, за какой период дамп, и вручную добрать заявки из почты и мессенджера за это время. Копия трёхчасовой давности означает потерю заявок за эти часы, и их надо восстанавливать отдельно.