При переносе сайта на другой хостинг или восстановлении из резервной копии чаще всего проблемы возникают с импортом большой базы MySQL. База на несколько мегабайт загружается через phpMyAdmin за секунды, но когда её размер доходит до сотен мегабайт или нескольких гигабайт, процесс обрывается на середине. Браузер показывает пустую страницу, phpMyAdmin сообщает об истечении времени, либо сам MySQL разрывает соединение. Разберём, почему так происходит и как надёжно импортировать большую базу без ошибок.
Почему большой дамп не загружается через phpMyAdmin
phpMyAdmin — обычное PHP-приложение, поэтому на него действуют ограничения PHP. Чтобы файл вообще дошёл до сервера, значения upload_max_filesize и post_max_size должны быть больше размера дампа. Даже если файл загрузился, скрипт не может работать дольше, чем разрешает max_execution_time, а многогигабайтную базу за несколько минут импортировать невозможно. Кроме того, у веб-сервера и прокси есть свои таймауты, поэтому браузер может показать ошибку 504 Gateway Timeout, а импорт в это время останется недоделанным.
Частично импортированная база — опасное состояние. Одни таблицы заполнены полностью, другие пусты или обрезаны, а сайт может работать неправильно, не показывая явных ошибок. Поэтому если импорт прервался, лучше очистить базу и начать заново, а не пытаться «догрузить» остаток.
Что означает ошибка max_allowed_packet
Вторая распространённая проблема возникает на стороне самого MySQL. Параметр max_allowed_packet задаёт максимальный размер пакета или запроса, который сервер принимает за один раз. mysqldump обычно объединяет много строк в один длинный INSERT, а если в таблице есть столбцы BLOB или LONGTEXT с картинками или большими текстами, даже одна строка может весить несколько мегабайт. Если запрос превышает лимит, появляется одна из ошибок:
ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes
ERROR 2006 (HY000): MySQL server has gone away
Второе сообщение бывает и по другим причинам, например когда соединение долго простаивало и было закрыто. Но если оно появляется во время импорта, особенно на большой таблице, в первую очередь стоит проверить лимит пакета. Со стороны клиента его можно увеличить параметром командной строки, а глобальное значение на сервере на виртуальном хостинге пользователь сам изменить не может — для этого нужно обратиться в техподдержку.
Самый надёжный способ: SSH и команда mysql
Если на вашем хостинге включён доступ по SSH, импорт через командную строку — самый стабильный вариант. Лимиты PHP и таймауты браузера здесь вообще не участвуют, процесс выполняется прямо на сервере. Сначала загрузите файл дампа в папку хостинга по FTP или SFTP, затем выполните команду:
mysql -u baza_user -p --default-character-set=utf8mb4 \
--max_allowed_packet=512M baza_nomi < dump.sql
Если дамп сжат, распаковывать его заранее не нужно — можно передать поток напрямую. Это экономит место на диске, ведь текстовый SQL-дамп после сжатия обычно становится в несколько раз меньше:
gunzip < dump.sql.gz | mysql -u baza_user -p baza_nomi
Долгий импорт полезно запускать так, чтобы он не остановился при обрыве SSH-сессии. Для этого используют nohup или, если он есть на сервере, screen. Чтобы команда не запрашивала пароль, его можно записать в файл настроек, доступный для чтения только вам:
# ~/.my.cnf (права: chmod 600 ~/.my.cnf)
[client]
user=baza_user
password=PAROL
nohup sh -c 'gunzip < dump.sql.gz | mysql baza_nomi' > import.log 2>&1 &
После завершения посмотрите файл import.log: если он пуст, ошибок не было. Когда работа закончена, пароль из .my.cnf разумно удалить, ведь он хранится на сервере открытым текстом.
Как правильно подготовить дамп
Успех импорта во многом зависит от того, как был сделан дамп. При экспорте со старого сервера несколько параметров mysqldump заметно облегчают следующий шаг. --single-transaction сохраняет таблицы InnoDB в согласованном состоянии без остановки сайта, а --quick читает большие таблицы построчно, не загружая их целиком в память:
mysqldump -u baza_user -p --single-transaction --quick \
--default-character-set=utf8mb4 baza_nomi | gzip > dump.sql.gz
Очень большую базу можно выгрузить по таблицам в отдельные файлы. Тогда при ошибке в одной таблице вы перезагружаете только её, а не всё целиком. Резать файл утилитой split по количеству строк не рекомендуется: она может разрезать один INSERT посередине, и получится битый SQL. Следите и за кодировкой: если в старой базе utf8, а в новой utf8mb4, после импорта проверьте кириллицу и эмодзи.
Что делать, если SSH нет
На некоторых тарифах командной строки нет. Тогда есть три пути. Первый — разбить дамп по таблицам на несколько небольших файлов и импортировать их через phpMyAdmin по очереди, каждый меньше лимита загрузки. Второй — использовать скрипты поэтапного импорта, которые читают большой дамп частями и за каждый запрос выполняют ограниченное число команд, поэтому не упираются в лимит времени PHP. Третий и самый простой — загрузить файл на хостинг и поручить импорт техподдержке.
Представьте, что сайт магазина электроники из Ташкента misol.uz переезжает от другого провайдера. Вместе с товарами, историей заказов и логами база весит 2,5 ГБ, и каждая попытка загрузить её через phpMyAdmin обрывается через десять минут. Сжав дамп через gzip и импортировав его по SSH командой выше, всю работу можно закончить примерно за полчаса без единого таймаута. На хостинге sayt.uz в такой ситуации можно загрузить файл и открыть тикет в кабинете с просьбой о помощи.
Что проверить после импорта
То, что импорт завершился без ошибок, ещё не значит, что всё на месте. Сравните количество таблиц в старой и новой базе, проверьте число строк в ключевых таблицах запросом SELECT COUNT(*). Убедитесь, что в конфигурационном файле сайта указаны новое имя базы, пользователь и пароль, затем проверьте страницы, поиск и оформление заказа. Если в текстах появились вопросительные знаки или «кракозябры», это проблема кодировки, и импорт нужно повторить с правильным --default-character-set.