Перенос базы MySQL на лету через SSH pipe без создания дампа на диске
Когда нужен перенос базы данных «на лету»
Обычный перенос базы данных состоит из трех долгих шагов: сделать дамп в файл .sql, скачать или передать его по сети через SCP/SFTP, а затем импортировать на целевом сервере. Однако такой подход вызывает проблемы в следующих ситуациях:
| Ситуация | Проблема стандартного метода | Преимущество передачи через SSH Pipe |
|---|---|---|
| Мало свободного места на диске | Дамп весит 50 ГБ, а на сервере свободно только 20 ГБ (запись завершится с ошибкой No space left on device). | Файл дампа вообще не создается на накопителе; данные передаются потоком через оперативную память. |
| Медленный диск (HDD) | Двойная нагрузка: сначала тяжелая запись на диск, затем повторное чтение для отправки. | Нагрузка на локальный накопитель сведена к нулю, используется только пропускная способность сети. |
| Экономия времени | Нужно ждать завершения создания архива, затем передачи, затем распаковки. | Импорт на втором сервере начинается мгновенно — с первого переданного байта. |
Пошаговая инструкция по прямой передаче базы данных
Вся магия передачи строится на стандартном конвейере Linux (символ вертикальной черты | — pipe). Утилита mysqldump отдает поток текста, который по защищенному каналу SSH сразу перенаправляется в консольный клиент mysql на принимающем сервере.
utf8mb4), в которую будет производиться заливка данных.- Шаг 1. Создаем пустую базу на новом сервере (если еще не создана):
Подключитесь к новому серверу и выполните команду создания БД:
mysql -u root -p -e "CREATE DATABASE new_database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" - Шаг 2. Запускаем прямой перенос с исходного сервера:
Находясь на старом сервере, выполните одну общую команду конвейера:
mysqldump -u local_user -p'local_password' --single-transaction --quick old_database_name | ssh remote_user@REMOTE_SERVER_IP "mysql -u remote_user -p'remote_password' new_database_name" - Шаг 3. Ускорение передачи с помощью сжатия (для баз от 10 ГБ):
Если серверы находятся в разных дата-центрах с ограниченным интернет-каналом, сожмите поток утилитой
gzipпрямо в процессе передачи:mysqldump -u local_user -p'local_password' --single-transaction --quick old_database_name | gzip -c | ssh remote_user@REMOTE_SERVER_IP "gunzip -c | mysql -u remote_user -p'remote_password' new_database_name" - Шаг 4. Проверяем целостность и количество таблиц:
После завершения команды авторизуйтесь на новом сервере и проверьте список залитых таблиц:
mysql -u remote_user -p'remote_password' new_database_name -e "SHOW TABLES;"
Частые вопросы (FAQ)
Что делают флаги --single-transaction и --quick?
Параметр --single-transaction позволяет сделать консистентный снимок таблиц InnoDB без полной блокировки сайта и чтения данных пользователями. Параметр --quick заставляет mysqldump читать строки таблицы по одной, не выгружая всю тяжелую базу целиком в оперативную память.
Что делать, если SSH работает на нестандартном порту (например, 2222)?
В секцию команды SSH добавьте ключ -p с указанием порта: mysqldump ... | ssh -p 2222 remote_user@IP "mysql ...".
Оборвется ли перенос, если закроется окно консоли на компьютере?
Да, при закрытии терминала процесс оборвется. Чтобы этого избежать, запускайте команду внутри утилиты screen или tmux, либо используйте nohup.
Работает ли этот способ для СУБД PostgreSQL?
Да, аналогичный конвейер работает и для Postgres: pg_dump -U local_user dbname | ssh remote_user@REMOTE_IP "psql -U remote_user -d dbname".