RE:NODE

Базы данных15 мин чтения

Импорт и экспорт в phpMyAdmin: лимиты, кодировки и ошибки

Как экспортировать и импортировать базу данных в phpMyAdmin: важные параметры, лимит загрузки, utf8mb4 и номера ошибок, которые вам встретятся.

0 прочтений

Чтобы снять копию базы данных: Export, выберите Custom, формат SQL, отметьте gzipped в разделе сжатия, нажмите Go. Чтобы вернуть её на место: Import, выберите файл, проверьте, что кодировка указана utf-8, нажмите Go. Если всё идёт как надо, на этом работа заканчивается, а в большинстве случаев так и бывает. Когда не получается, почти всегда причина одна из трёх: файл больше лимита загрузки, напечатанного на странице Import, кодировка файла не совпадает с кодировкой целевой базы, или в дампе есть объект, который вашему пользователю базы данных создавать нельзя. В этом руководстве подробно разобраны обе вкладки, а затем по очереди каждый из этих сбоев.

phpMyAdmin - это веб-интерфейс, а у веб-интерфейсов есть таймауты и потолки загрузки, которых нет у командной строки. Одна эта фраза объясняет большую часть недовольства, которое люди испытывают от работы с ним. Если знать, где находится потолок и как его три раза обойти, двухчасовая борьба превращается в работу на пять минут.

Что такое phpMyAdmin и чем он не является#

phpMyAdmin - это PHP-приложение, которое от вашего имени обращается к серверу базы данных, совместимому с MySQL. Сама база данных - не он. У него нет собственного хранилища, копии ваших данных он не держит, и если его удалить, не пропадёт ничего. Всё, что он делает, - это запрос, который вы могли бы набрать сами, поэтому и существует вкладка SQL, и поэтому кнопку «Show SQL» под большинством операций стоит нажать хотя бы раз.

Отсюда два следствия, и оба важны для импорта и экспорта:

  • Всё выполняется внутри одного PHP-запроса. У запроса есть лимит времени ($cfg['ExecTimeLimit'], по умолчанию 300 секунд) и лимит памяти, а у стоящего перед ним веб-сервера свои. Дамп, который импортируется четыре минуты, - это нормально. Тот, что импортируется сорок, через браузер не дойдёт до конца, что бы вы с ним ни делали.
  • Он умеет только то, что умеет ваш пользователь базы данных. phpMyAdmin - не привилегированный чёрный ход. Если пользователь, привязанный к вашей базе, не может создать триггер, импорт, в котором есть триггер, остановится на этой строке, какие бы параметры вы ни отметили.

Кроме того, phpMyAdmin - это инструмент именно для семейства MySQL. С PostgreSQL и MongoDB он не работает, и никакая настройка этого не изменит. Если у вас Postgres, аналогичная задача решается через pg_dump и pg_restore; если Mongo - через mongodump и mongorestore. Дальше в статье предполагается, что перед вами именно phpMyAdmin.

Слот базы данных на хостинге с панелью#

На хостинге с панелью phpMyAdmin вы не устанавливаете и не знаете, где он лежит. В тариф входит некоторое число слотов баз данных, и каждый слот создаётся на вкладке Databases в панели. При создании генерируются четыре значения, которые вам ещё понадобятся:

ПолеЧто это
HostАдрес, по которому отвечает база данных, часто не localhost
Database nameОбычно с префиксом, например s14_shop
UsernameГенерируется и привязан только к этой одной базе
PasswordГенерируется, показывается в панели, его можно сменить

Именно эти четыре значения попадают в wp-config.php, в файл .env или в строку подключения. Не держите их в коде и не отправляйте в систему контроля версий - о том, где им место, рассказано в статье переменные окружения и секреты.

В RE:NODE на той же вкладке есть кнопка Open in phpMyAdmin. Она входит с одноразовым токеном, который истекает через 60 секунд, так что ссылку нельзя переслать, сохранить в закладки или использовать повторно: если вы открыли её и ушли за кофе, вернётесь к странице входа и нажмёте кнопку ещё раз. Слоты баз данных входят в каждую линейку, где они есть, - один в игровом тарифе, два в тарифах для приложений и сайтов, - а учётные данные выдаются на каждую базу, а не на аккаунт. Линейка хостинга баз данных - это другой продукт: там серверы PostgreSQL и MongoDB со своим суперпользователем, и phpMyAdmin к ним отношения не имеет.

Экспорт: Quick, Custom и параметры, которые важны#

Сначала выберите базу данных в дереве слева, а не таблицу - если только вам действительно не нужна одна таблица. Затем Export. Предлагаются два метода.

Quick даёт обычный файл .sql с разумными значениями по умолчанию. Это правильный выбор для небольшой базы, которую вы собираетесь тут же импортировать куда-то в похожее место.

Custom показывает всё, и для всего, что вам дорого, используйте именно его. Параметры, которые меняют результат:

ПараметрЗначениеЗачем
FormatSQLCSV и JSON теряют структуру, ключи и типы
CompressiongzippedТекстовый дамп сжимается примерно в 5-10 раз
Add DROP TABLEВключить, для восстановленияДелает импорт идемпотентным
IF NOT EXISTSВыключить, для восстановленияИначе существующие таблицы молча остаются как есть
AUTO_INCREMENTВключитьСохраняет следующий id после восстановления
Enclose names with backquotesВключитьПереживёт таблицы с именами order и group
Extended insertsВключитьГораздо меньше и гораздо крупнее запросов: намного быстрее
Maximal length of created query50000 или меньшеДолжно оставаться ниже лимита пакета сервера
Charset of the fileutf-8См. следующий раздел

В разделе «Object creation options» отдельные флажки есть для представлений (views), для процедур (procedures, functions и events) и для триггеров. Не во всех версиях они включены по умолчанию, и разница между дампом, который восстанавливает работающее приложение, и дампом, который восстанавливает мёртвое, обычно сводится к пропавшей хранимой процедуре. Отметьте их, затем откройте дамп и поищите CREATE PROCEDURE и CREATE TRIGGER, чтобы убедиться, что они на месте.

«Extended inserts» - это самый мощный рычаг производительности. Если он выключен, вы получаете по одному INSERT на строку, а для таблицы в миллион строк это миллион обращений к SQL-парсеру. Если включён - по одному запросу на пачку:

sql
INSERT INTO `orders` (`id`, `total`, `created_at`) VALUES(1, 19.99, '2026-08-01 09:12:44'),(2, 42.50, '2026-08-01 09:31:02'),(3, 7.00,  '2026-08-01 10:04:19');

Размер пачки определяется параметром «Maximal length of created query». Оставьте значение по умолчанию, если только импорт не падает с ошибкой 2006 - это лимит пакета, о нём речь ниже.

Наконец, выбирайте «Save output to a file», а не вывод SQL в браузер. Дамп в 200 МБ, отрисованный как веб-страница, утянет за собой всю вкладку.

Кодировки, или почему ваш текст превратился в вопросительные знаки#

Это самый частый способ, которым импорт «проходит успешно» и портит данные. Кодировка MySQL под названием utf8 - это не UTF-8. Это трёхбайтовое подмножество, которое правильно называется utf8mb3, и оно не может хранить ничего за пределами базовой многоязычной плоскости: ни эмодзи, ни некоторых более редких иероглифов CJK, ни математических символов. Настоящая кодировка - utf8mb4. В современном MySQL 8 по умолчанию стоит utf8mb4; на старых серверах и в старых установках MariaDB часто по умолчанию latin1, а база, созданная много лет назад, сохраняет ту кодировку, с которой создавалась.

Проверьте, что у вас есть, прежде чем что-либо экспортировать:

sql
SHOW VARIABLES LIKE 'character_set_%';SHOW CREATE DATABASE `shop`;SELECT table_name, table_collation FROM information_schema.tables  WHERE table_schema = 'shop';

Экспорт phpMyAdmin записывает собственное объявление в начало файла, и именно это делает дамп переносимым:

sql
/*!40101 SET NAMES utf8mb4 */;SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";START TRANSACTION;SET time_zone = "+00:00";

На вкладке Import есть выпадающий список «Character set of the file». Он должен соответствовать байтам, которые на самом деле лежат в файле, а не тем, какими вы хотели бы их видеть. Если экспорт был в utf8mb4, а вы импортируете как latin1, каждый символ с диакритикой превращается в два символа-кракозябры, а импорт рапортует об успехе. Предупреждения нет. Ущерб виден, только когда кто-то открывает страницу и находит é там, где раньше было é.

Три правила, которые убирают эту проблему целиком:

  1. Экспортируйте и импортируйте в одной кодировке и предпочитайте utf-8 на обоих концах.
  2. Если исходная база в latin1, а на целевой нужна utf8mb4, преобразуйте после импорта командой ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4, а не обманывая импортёр.
  3. Никогда не открывайте дамп в текстовом редакторе, который пересохраняет файл в другой кодировке. «Блокнот» в Windows таким образом стоил людям целых баз данных.

Импорт дампа#

Import, выберите файл, убедитесь, что формат SQL и кодировка правильная, нажмите Go. Что на этой странице стоит понимать:

  • Максимальный размер напечатан прямо на странице - что-то вроде «Max: 2,048KiB». Он берётся из upload_max_filesize и post_max_size в PHP, из меньшего из двух, и изнутри phpMyAdmin изменить его обычно нельзя.
  • Сжатые файлы принимаются напрямую. Файл shop.sql.gz или shop.sql.zip распаковывается по пути внутрь, а поскольку лимит относится к загружаемым байтам, дамп в gzip поднимает ваш эффективный потолок примерно в десять раз. Это самая лёгкая победа из доступных, и большинство её упускает.
  • Частичный импорт управляется двумя параметрами: «Allow the interruption of an import in case the script detects it is close to the PHP timeout limit» и «Skip this number of queries starting from the first one». Вместе они позволяют продолжить. Если импорт остановился после 4000 запросов, отметьте флажок, поставьте пропуск 4000 и запустите тот же файл снова.
  • Режим совместимости SQL должен оставаться NONE, если только вы не импортируете дамп с намного более старого сервера и не знаете, какой именно режим ему нужен.

Импортируйте в пустую базу везде, где можно. Импорт поверх существующих таблиц - это способ получить наполовину слитые данные, которые выглядят нормально, пока внешний ключ не укажет на строку, которой нет. Создайте новую базу, импортируйте, проверьте и только потом переключайте приложение.

Если в дампе таблицы ссылаются друг на друга, а порядок неверный, решение - отключить проверки на время импорта, а не переставлять файл вручную:

sql
SET FOREIGN_KEY_CHECKS = 0;-- вставьте или выполните дамп здесьSET FOREIGN_KEY_CHECKS = 1;

Включите их обратно в той же сессии, а потом выполните запрос, доказывающий, что никаких осиротевших строк не проскочило. Оставить проверки внешних ключей выключенными навсегда - это не решение, а решение узнать о проблеме позже.

Как загрузить большой файл, если лимит загрузки меньше#

Вы с этим столкнётесь. Способы, в порядке убывания того, насколько они должны вам нравиться:

  1. Сожмите дамп в gzip. Экспортируйте со сжатием или выполните gzip shop.sql локально. Дамп в 300 МБ превращается в 30-60 МБ, а этого обычно хватает, чтобы пройти лимит без всего остального.
  2. Разрежьте файл. Дампы SQL построчные, так что split работает - при условии, что резать нужно по границам запросов, а заголовок оставлять в первой части. Специальный инструмент для нарезки дампов надёжнее, чем нарезка на глаз.
  3. Используйте выпадающий список «web server upload directory». Если хостер настроил $cfg['UploadDir'], файл можно положить на сервер через SFTP или файловый менеджер и выбрать его в phpMyAdmin, а не загружать через браузер. Так лимит загрузки обходится полностью, но лимит времени остаётся. О том, как загрузить туда файл, рассказано в статье SFTP и файловый менеджер.
  4. Пропуск и продолжение. Частичный импорт, как выше. Утомительно, но надёжно.
  5. Используйте командную строку, если она у вас есть. На VDS с доступом к shell потолок исчезает:
bash
$ gunzip -c shop.sql.gz | mysql -h db.example.net -u shopuser -p shop

Общий тариф для сайта или игры shell не даёт, так что там настоящий список - это варианты с 1 по 4. Если вы делаете это ежемесячно, это довод в пользу того, чтобы держать базу там, куда можно добраться из терминала, - честное сравнение есть в статье VDS или игровая панель.

У очень больших баз данных ответ другой: по возможности вообще не переносите их логическим дампом. Начиная примерно с 5 ГБ время импорта начинает измеряться часами, и правильный подход - обычно репликация или копирование на уровне файлов, а для обоих нужен административный доступ к обоим серверам.

Чего в экспорте нет#

Экспорт базы данных - это описание одной базы. Восстановление из него не возвращает то, что живёт рядом с ней:

  • Пользователи и их права. Они хранятся в системных таблицах самого сервера, которые вы не экспортируете. После импорта на новом хостинге вы создаёте нового пользователя и выдаёте ему права на новую базу. Если в строке подключения приложения всё ещё старое имя пользователя, подключиться не удастся, и вы обвините импорт.
  • Всё, что лежит в других базах. Представления и запросы между базами тихо ломаются, пока их кто-нибудь не вызовет.
  • Конфигурация сервера. Размеры пакетов, таймауты, режим SQL, таблицы часовых поясов. Запрос, который работал на одном сервере, может упасть на другом, потому что отличается sql_mode, чаще всего когда STRICT_TRANS_TABLES отвергает нулевую дату, принимавшуюся на старом сервере.
  • Файлы. Загруженные картинки, папка WordPress wp-content, аватары пользователей. В базе лежат их пути, а не байты. Перенос сайта - это всегда две задачи, и в статье перенос WordPress на новый хостинг разобраны обе.
  • Учётные записи `DEFINER` у представлений, триггеров и процедур в пригодном для использования виде. Имена переезжают, но указывают на пользователей, которых на целевом сервере может не быть, - отсюда ошибка 1227.

Экспорт - это ещё и не стратегия резервного копирования, потому что backup, который вы делаете вручную, - это backup, который вы перестанете делать. Поставьте его на расписание, храните больше одного поколения и время от времени восстанавливайте один, чтобы убедиться, что он работает. Более подробно об этом в статье резервные копии баз данных и восстановление, а проверка восстановления до того, как оно понадобится - это та часть, которую люди пропускают.

Ошибки и что означает каждая#

ОшибкаСообщениеПричина и решение
1044Access denied for user to databaseВ дампе есть CREATE DATABASE или USE. Удалите эти строки и импортируйте в уже существующую базу
1045Access denied for userНеверный пароль, или пользователь ограничен другим хостом
1046No database selectedВы находитесь в корне сервера. Сначала щёлкните по базе, потом Import
1062Duplicate entry for key PRIMARYИмпорт поверх существующих строк. Импортируйте в пустую базу
1064Syntax error nearОбрезанный файл, неудачная нарезка или дамп с более новой версии сервера
1071Specified key was too longСтарый сервер с лимитом индекса 767 байт и столбцы utf8mb4. Сократите индекс или обновитесь
1227Access denied, you need SUPER privilegesУсловие DEFINER называет пользователя, которым вы не являетесь. Отредактируйте дамп и уберите эти условия
2006Server has gone awayОдин запрос превысил max_allowed_packet, либо импорт превысил время

Две из них заслуживают большего, чем строка таблицы.

Ошибка 1227 и `DEFINER`. Представления, триггеры, процедуры и события экспортируются с зашитой в запрос учётной записью, которая их создала, в виде DEFINER=old_user@localhost. На новом хосте такой учётной записи нет, а создать её вам нельзя, поэтому запрос отклоняется. Решение - поиск и замена в дампе перед импортом: удалите каждый фрагмент DEFINER= вместе с именем пользователя, которое за ним идёт, оставив сам запрос CREATE VIEW или CREATE TRIGGER нетронутым. Тогда объекты создаются от вашего имени, а это как раз то, что нужно.

Ошибка 2006 и лимит пакета. max_allowed_packet ограничивает размер одного запроса. Extended insert, собранный из таблицы с большими текстовыми или blob-столбцами, может его превысить. Экспортируйте заново с меньшим значением «Maximal length of created query» - безопасно 16000 - и те же данные придут в виде большего числа запросов поменьше. Та же ошибка появляется и тогда, когда соединение просто истекло посреди импорта, - это другая проблема с тем же сообщением.

Пример из практики: переезд сайта на новый хостинг#

Порядок важен, потому что цель - чтобы после снятия копии в старую базу ничего не записывалось.

  1. Переведите сайт в режим обслуживания или смиритесь с тем, что всё записанное с этого момента будет потеряно.
  2. В phpMyAdmin на старом хостинге: Export, Custom, SQL, gzipped, DROP TABLE включён, представления и процедуры отмечены, сохраните в файл. Проверьте, что размер файла правдоподобен: дамп живого магазина размером 4 КБ значит, что вы выгрузили не то.
  3. На новом хостинге создайте слот базы данных и запишите host, имя, пользователя и пароль.
  4. Откройте phpMyAdmin из панели, выберите новую базу, Import, выберите файл .sql.gz, кодировка utf-8, Go.
  5. Сравните число строк в трёх самых больших таблицах с обеих сторон через SELECT COUNT(*). Это занимает минуту и сразу ловит обрезанный импорт.
  6. Обновите учётные данные приложения: новые host, имя, пользователь и пароль. Для WordPress это четыре строки в wp-config.php.
  7. Скопируйте файлы, затем направьте DNS на новый адрес. В статье DNS-записи простыми словами сказано, какую именно запись менять; пока изменение не разошлось, не выключайте старый сервер.
  8. Храните файл дампа две недели. Это ничего не стоит, и это единственный путь назад.

Если сайт хранит в базе абсолютные URL, как это делает WordPress, обычный импорт оставит его указывающим на старый домен. Не запускайте простой UPDATE ... REPLACE по содержимому: сериализованные массивы PHP хранят собственные длины строк, и наивная замена их портит. Используйте инструмент поиска и замены, который понимает сериализацию, или search-replace из WP-CLI, который её понимает.

FAQ#

Почему импорт останавливается посередине без ошибки?

Почти всегда виноват лимит времени PHP. Запрос был прерван, пока импорт ещё шёл, поэтому браузер показывает обрезанную или пустую страницу. Отметьте «Allow the interruption of an import», запомните, сколько запросов выполнилось, и запустите файл снова, вписав это число в поле пропуска.

Можно ли экспортировать только одну таблицу?

Да. Выберите таблицу в дереве слева перед нажатием Export или выберите базу и укажите в Custom, какие таблицы включить. Помните, что отдельная таблица, вынутая из набора с внешними ключами, сама по себе в пустую базу не импортируется.

Безопасно ли хранить экспорт в gzip как backup?

Это корректная логическая копия базы на момент снятия, и она восстановится на любой совместимый сервер. Но она не автоматическая, не проверенная и хранится только там, куда вы её положили. Считайте её одной копией из трёх и время от времени проверяйте, что она всё ещё открывается.

На странице Import написано Max 2,048KiB, а мой файл весит 40 МБ. Можно ли поднять лимит?

Изнутри phpMyAdmin нельзя - это настройка PHP на веб-сервере. Сначала сожмите файл, воспользуйтесь каталогом загрузки на сервере, если хостер его предлагает, или разрежьте дамп. На машине, где PHP под вашим контролем, помогает одновременное повышение upload_max_filesize и post_max_size.

Почему после вполне успешного импорта некоторые символы выглядят неправильно?

Кодировка файла не совпала с тем, что в нём лежало. Восстановите исходный дамп в новую пустую базу с правильной настройкой, а не пытайтесь чинить текст на месте, а как проверить, что у вас есть, смотрите в разделе о кодировках выше.

Нужен ли мне phpMyAdmin вообще, если хостер даёт базу данных?

Нет. Это удобство. Подойдёт любой клиент, который говорит на этом протоколе, включая настольные программы и командную строку, а для больших или повторяющихся задач они лучше. phpMyAdmin оправдывает себя для быстрых правок, беглого взгляда на то, что на самом деле лежит в таблице, и разового экспорта с машины, где больше ничего не установлено.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000