Как я могу переместить базу данных с одного сервера на другой?

136

Как я могу переместить таблицы MySQL с одного физического сервера на другой?

Например, такой точный сценарий: у меня есть сервер MySQL, который использует таблицу innodb и имеет размер около 20 ГБ.

Я хочу переместить его на новый сервер, какой самый эффективный способ сделать это?

Джон
источник
4
Я хотел бы использовать xtrabackup percona.com/docs/wiki/… Это очень похоже на его копирование, но вы можете поддерживать работу сервера и предполагая, что вы используете в основном таблицы innodb (которые, как вы сказали, у вас были), вы можете считать это «горячим» резервное копирование, а также.
Джонатан
Я не получаю выгоду от других людей, использующих этот инструмент. Он бесплатный / с открытым исходным кодом, и хотя он был сделан компанией, его достаточно просто использовать, и вам не нужно думать о покупке поддержки у этой компании.
Джонатан

Ответы:

80

Мой любимый способ - передать команду sqldump команде sql. Вы можете сделать все базы данных или конкретную. Так, например,

mysqldump -uuser -ppassword myDatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword 

Вы можете сделать все базы данных с

mysqldump --all-databases -uuser -ppassword | mysql -hremoteserver -uremoteuser -premoteserver 

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

Дэвид Холл
источник
4
Совет: если ни одна из баз данных не разрешает удаленные подключения, проложите канал netcat.
Барт ван Хейкелом
1
Чтобы это работало, мне нужно было создать пустую базу данных с тем же именем на удаленном сервере, а затем добавить имя этой базы данных в конец команды.
Zugwalt
1
Это элегантно, но без сжатия вряд ли достаточно быстро для базы данных объемом 20 ГБ.
Daddy32
Это решение подходит только для полностью контролируемой сети (если и только в защищенной частной сети, читайте: не в Интернете)! Но быстрое и простое решение!
Тдагеть
Это молниеносно! Но то, что сказал @Zugwalt, было верно и для меня. Команда не работала, пока я не создал базу данных (пустую). Add добавил имя базы данных в конец команды.
Скитс
65

Я недавно переместил базу данных на 30 ГБ со следующей ошибкой:

Старый сервер

  • Остановить MySQL сервер
  • Скопируйте содержимое datadir в другое место на диске ( ~/mysqldata/*)
  • Запустите сервер mysql снова (время простоя составило 10-15 минут)
  • сжать данные ( tar -czvf mysqldata.tar.gz ~/mysqldata)
  • скопируйте сжатый файл на новый сервер

Новый сервер

  • установить MySQL (не запускать)
  • распаковать сжатый файл ( tar -xzvf mysqldata.tar.gz)
  • переместить содержимое mysqldata в datadir
  • Убедитесь, что ваш innodb_log_file_size такой же на новом сервере, или, если это не так, не копируйте старые файлы журнала ( mysql сгенерирует их )
  • Запустите MySQL
Дерек Дауни
источник
1
Пропустить копию после сжатия / распаковки. Передайте tar по сети, используя ssh, или (если и только если в защищенной частной сети прочитано: не через Интернет) используйте netcat, чтобы избежать издержек шифрования. Кроме того, если в локальной сети пропустить gzipping, если у вас есть быстрый сетевой канал, вы обнаружите, что передача ограничена на вращающемся ядре, выполняющем сжатие
atxdba
Это работает как для innodb, так и для myisam? Кроме того, пользователи MySQL находятся в датадир, а?
giorgio79
2
@ giorgio79, конечно, до тех пор, пока вы перемещаете файлы ibdata. По умолчанию они находятся в датадир. Пользователи MySQL хранятся в папке mysql в табличном пространстве пользователя.
Дерек Дауни
2
Будет ли эта процедура работать при переходе с Windows на Linux?
ypercubeᵀᴹ
2
@ TypoCubeᵀᴹ извините, что на ответ ушло более двух лет, но это помогло бы мне, если бы кто-то сказал однозначно: «Да, он работает с Windows на Linux». В моем случае я перешел с Windows Server 2012 R2 на Cent OS (Red Hat 4.8.5-11) . Конкретная версия mysql была Maria DB 10.1 . Как было предписано, я остановил обе службы mysql, произвел Rsynced каталог данных, и после запуска службы mysql на новом сервере все базы данных, таблицы базы данных и пользователи базы данных были полностью исправны.
WEBjuju
30

В соответствии с Руководством по изучению сертификации MySQL 5.0 , глава 32, раздел 32.3.4, стр. 456 457 описаны условия двоичной переносимости, в которых описывается следующее:

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

Для MyISAM двоичная переносимость означает, что вы можете напрямую скопировать файлы для таблицы MyISAM с одного сервера MySQL на другой на другом компьютере, и второй сервер сможет получить доступ к таблице.

Для InnoDB двоичная переносимость означает, что вы можете напрямую копировать файлы табличного пространства с сервера MySQL на одном компьютере на другой сервер на другом компьютере, и второй сервер сможет получить доступ к табличному пространству. По умолчанию все таблицы InnoDB, управляемые сервером, хранятся вместе в табличном пространстве, поэтому переносимость табличного пространства зависит от того, являются ли все отдельные таблицы InnoDB переносимыми. Если хотя бы одна таблица не является переносимой, ни одно из них не является табличным пространством.

Таблицы MyISAM и табличные пространства InnoDB являются двоично переносимыми с одного хоста на другой, если выполняются два условия:

  • Обе машины должны использовать целочисленную арифметику с двумя дополнениями
  • Обе машины должны использовать формат IEEE с плавающей запятой, иначе таблицы не должны содержать столбцы с плавающей запятой (FLOAT или DOUBLE)

На практике эти два условия представляют собой небольшое ограничение. Целочисленная арифметика с двумя дополнениями и формат IEEE с плавающей точкой являются нормой для современного оборудования. Третье условие переносимости двоичных файлов InnoDB - использование строчных имен для таблиц и баз данных. Это связано с тем, что InnoDB хранит эти имена внутри (в своем словаре данных) в нижнем регистре в Windows. Использование строчных имен позволяет переносить двоичные файлы между Windows и Unix, чтобы принудительно использовать строчные имена, вы можете поместить следующие строки в файл опций:

[mysqld]
lower_case_table_names=1

Если вы сконфигурируете InnoDB для использования табличных пространств для таблиц, условия переносимости двоичных файлов будут расширены, чтобы включить также файлы .ibd для таблиц InnoDB. (Условия для общих табличных пространств все еще применяются, потому что он содержит словарь данных, в котором хранится информация обо всех таблицах InnoDB.)

Если условия двоичной переносимости не выполняются, вы можете скопировать таблицы MyISAM или InnoDB с одного сервера на другой, выгрузив их в некотором текстовом формате (например, с помощью mysqldump) и перезагрузив их на целевой сервер.

Существует два основных способа перемещения отдельных таблиц на основе механизма хранения.

Для данного примера предположим следующее:

  1. datadir - это / var / lib / mysql
  2. база данных называется mydb
  3. таблица в базе данных mydb называется mytable .

MyISAM таблицы

Если mydb.mytable использует механизм хранения MyISAM, таблица будет физически отображаться как три отдельных файла.

  1. /var/lib/mysql/mydb/mytable.frm (файл .frm)
  2. /var/lib/mysql/mydb/mytable.MYD (файл .MYD)
  3. /var/lib/mysql/mydb/mytable.MYI (файл .MYI)

.Frm содержит структуру таблицы
.MYD содержит данные таблицы
.MYI содержит страницу индекса таблицы

Эти файлы используются взаимозависимо для представления таблицы с логической точки зрения в MySQL. Так как эти файлы не имеют дальнейшей логической привязки к нему, перенос таблицы с одного сервера БД на другой. Вы даже можете сделать это с сервера Windows на сервер Linux или MacOS. Конечно, вы можете отключить MySQL и скопировать 3 файла таблицы. Вы можете запустить следующее:

LOCK TABLES mydb.mytable READ;
SELECT SLEEP(86400);
UNLOCK TABLES;

в одном сеансе SSH держать таблицу только для чтения и удерживать блокировку в течение 24 часов. Через секунду выполните копирование в другой сессии ssh. Затем завершите сеанс mysql с 24-часовой блокировкой. Вам не нужно ждать 24 часа.

Таблицы InnoDB

Исходя из вышеупомянутой цитаты из книги сертификации, существует множество факторов, которые определяют, как сделать резервную копию конкретной таблицы InnoDB. Для простоты, ясности и краткости просто выполните mysqldump желаемой таблицы, используя параметры --single-транзакции, чтобы получить идеальный дамп таблицы на момент времени. Не нужно разбираться с семантикой InnoDB, если вам нужна только одна таблица. Вы можете перезагрузить этот дамп-файл на любой сервер MySQL по вашему выбору.

Поскольку два вопроса были объединены здесь (Jcolebrand): РЕДАКТИРОВАТЬ

Если вы более чем готовы жить с некоторой медленной производительностью БД, вы можете выполнить серию rsyncs со старого сервера (ServerA) на новый сервер (ServerB), даже если mysql все еще работает на ServerA.

Шаг 01) Установите ту же версию MySQL на сервере B, что и у ServerA

Шаг 02) На сервере A, запустите SET GLOBAL innodb_max_dirty_pages_pct = 0;из mysql и около 10 минут (Это удаляет грязные страницы из пула буферов InnoDB. Это также помогает быстрее выполнять завершение работы mysql) Если ваша база данных - это MyISAM, вы можете пропустить этот шаг.

Шаг 03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql

Шаг 04) Повторяйте шаг 03, пока rsync не займет менее 1 минуты

Шаг 05) service mysql stopна сервере А

Шаг 06) Выполните еще одну rsync

Шаг 07) scp ServerA:/etc/my.cnf ServerB:/etc/

Шаг 08) service mysql startна сервере B

Шаг 08) service mysql startна сервере А (необязательно)

Попробуйте!

ПРЕДОСТЕРЕЖЕНИЕ

Вы можете создать подчиненное устройство репликации следующим образом. Просто помните, что в главном /etc/my.cnf явно указывается идентификатор сервера, а в ведомом /etc/my.cnf - другой номер для идентификатора сервера.

RolandoMySQLDBA
источник
29

Вам даже не нужен mysqldump, если вы перемещаете всю схему базы данных, и вы готовы остановить первую базу данных (поэтому она согласована при передаче)

  1. Остановить базу данных (или заблокировать ее)
  2. Перейдите в каталог, где находятся файлы данных mysql.
  3. Передача через папку (и ее содержимое) в каталог данных нового сервера mysql
  4. Начать резервное копирование базы данных
  5. На новом сервере введите команду «create database».
  6. Повторно создайте пользователей и предоставьте разрешения.

Я не могу вспомнить, обрабатывает ли mysqldump пользователей и разрешения, или только данные ... но даже если это так, это намного быстрее, чем делать дамп и запускать его. Я бы использовал это, только если мне нужно было выгрузить базу данных mysql, чтобы затем вставить ее в какую-то другую СУБД, если мне нужно было изменить параметры хранения (innodb против myisam), или, возможно, если бы я менял основные версии mysql (но Я думаю, что я сделал это между 4 и 5, хотя)

Джо
источник
Это более эффективно, особенно если вы являетесь системным администратором / администратором базы данных. Кстати, mysqldump использует --all-databasesдампы схемы mysql. Запуск mysql на следующей машине вызывает разрешения, если вы перенесли папку данных на другую машину с тем же основным выпуском MySQL. (MySQL 5.5.x в MySQL 5.5.x, MySQL 5.1.x в MySQL 5.1.x, MySQL 5.0.x в MySQL 5.0.x)
RolandoMySQLDBA
4
@ Джо, да, mysqldumpобрабатывает пользователей и разрешения, так как они хранятся в mysqlсхеме.
Шломи Ноах
Этот подход особенно полезен для облачного хостинга, такого как AWS. Вы можете остановить mysql, размонтировать и отключиться от текущего сервера; подключить и смонтировать на новый сервер и запустить mysql. Никаких затрат на копирование, если том остался в той же ферме серверов.
LateralFractal
12

Если вы просто хотите переместить конкретную таблицу, попробуйте:

mysqldump -u username -ppassword databasename tablename > databasename.tablename.sql

Вы можете указать больше имен таблиц выше, в той же команде. После завершения команды переместите файл databasename.tablename.sql на другой сервер, а затем восстановите, используя:

mysql -u username -ppassword databasename < databasename.tablename.sql

Обратите внимание, что обратный файл .sql создается с помощью программы mysqldump , а восстановление выполняется непосредственно в mysql .

StanleyJohns
источник
7
  1. Если у вас есть доступ по ssh, вы можете использовать mysqldump из командной строки
  2. Если у вас нет доступа по ssh, но у вас есть доступ к phpMyAdmin, вы можете использовать его для экспорта / импорта
  3. Если у вас нет доступа к phpMyAdmin, есть несколько удобных сценариев php, которые будут выгружать и импортировать (однако, исходя из собственного опыта, я никогда не находил такой надежный, как phpMyAdmin).

Может быть такая возможность, когда вы перемещаете реальные файлы базы данных (для моей установки они расположены в / var / lib / mysql), но я не совсем уверен, как это будет действовать / работать.

poelinca
источник
5

Тебе нужно взять время простоя. Это займет некоторое время в зависимости от скорости вашей сети. Я собираюсь предположить, что вы работаете с MySQL в Linux / Unix. Вот процесс, который я использую:

  1. Остановите демон mysql на исходном хосте.
  2. Создайте папку tmp на целевом хосте для получения файлов.
  3. Используйте screen, чтобы создать сеанс оболочки, который выживет, если ваш ssh отключится.
  4. Используйте rsync для передачи файлов между хостами. Примерно так: rsync -avhP исходный пользователь @ targethost: / путь / к / папке /
  5. Запустите тестовые случаи, чтобы убедиться, что вы ничего не потеряли при передаче.

Затем продолжайте как обычно, настраивая локальный MySQL.

* Примечание: вы также можете использовать параметр -c с rsync, чтобы добавить контрольную сумму к передаче, однако это будет медленным, в зависимости от скорости процессора.

randomx
источник
4

Я могу подтвердить, что метод DTest также работает для копирования между Ubuntu и OSX.

Чтобы скопировать все базы данных без каких-либо дампов или чего-либо подобного:

Убедитесь, что у вас есть чистый mysql из mysql (установил dmg, скачанный с mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg ), что (ОЧЕНЬ ВАЖНО) никогда не запускался.

Скопируйте содержимое папки / var / lib / mysql / с компьютера с Ubuntu поверх / usr / local / mysql / data / contents на компьютере Mac. Чтобы получить доступ к папке получения на машине с Ubuntu, мне пришлось использовать sudo, то есть:

sudo cp /var/lib/mysql /home/foouser/mysql_data_folder
sudo chown -R foouser /home/foouser/mysql_data_folder

Я скопировал папку с помощью scp.

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

После копирования папки выполните следующие действия на компьютере Mac:

sudo chown -R _mysql /usr/local/mysql/data/
sudo chgrp -R wheel /usr/local/mysql/data/
sudo chmod -R g+rx /usr/local/mysql/data/

Запустите сервер mysql в первый раз (из панели настроек в System Preferences-> mysql). Все пользователи и базы данных теперь должны быть настроены правильно.

Это работало с MySQL 5.1.61 на Ubuntu 64 бит 11.10 и MySQL 5.1.63 на OSX LION (MacBook Pro).

paalvibe
источник
4

Я думаю, что все предыдущие ответы, вероятно, работают нормально, но на самом деле не решают проблему установки имени базы данных во время передачи.

Вот как я это сделал с помощью bash:

Вы могли бы быть лучше использовать , rsyncчем scpи не сжимать файл , если вы делаете это часто.

На моем исходном сервере:

me@web:~$ d=members
me@web:~$ mysqldump $d | gzip > $d.sql.gz
me@web:~$ scp -i .ssh/yourkeynamehere $d.sql.gz $sbox:$d.sql.gz

На моем сервере назначения:

me@sandbox:~$ d1=members
me@sandbox:~$ d2=members_sb
me@sandbox:~$ mysqladmin create $d2
me@sandbox:~$ cat $d1.sql.gz | gunzip |  mysql $d2

На любой машине, чтобы увидеть прогресс:

me@sandbox:~$ ls *.gz 
me@sandbox:~$ cat $d.sql.gz | gunzip |  less

Все это предполагает, что у вас есть файл конфигурации MySQL в вашем домашнем каталоге на обеих машинах и установлены разрешения:

$ echo "
[client]
user=drupal6
password=metoknow
host=ord-mysql-001-sn.bananas.com
[mysql]
database=nz_drupal" > .my.cnf
$ chmod 0600 ~/.my.cnf
ErichBSchulz
источник
3

вы перемещаете его на другой сервер базы данных MySQL? если это так, используйте экспорт

# mysqldump -u username -ppassword database_name > FILE.sql

источник
MySQLDump? Вот когда вы имеете дело с небольшим количеством данных?
О, Чин Бун,
2
Я думаю, что маленький / большой в наши дни довольно субъективен. Когда я увидел название вопроса, я ожидал, что база данных размером более 20 ГБ будет считаться «большой» ...
Аарон Бертран
3

Общий метод Linux:

/etc/init.d/mysqld stop
rsync -avz source_files destination
vi /etc/my.cnf

отредактируйте datadir (и сокет) для mysqld и mysqld_safe (если применимо), чтобы указать новое местоположение, затем

/etc/init.d/mysql start

Я опубликовал это, потому что никто, кажется, просто не перечислил наименьшее количество шагов, чтобы сделать это, и я чувствую, что это самый простой способ лично.

seeafish
источник
2

Возможно, это лучший способ сделать это:

Версия 1 : копирование файлов данных (только MYISAM)

ssh server1
service mysql stop
cd $mysql-data-dir
rsync -avz dirs-or-files server2:$mysql-data-dir
service mysql start

Служба SSH Server2 перезапустить MySQL

  • Если ваши файлы базы данных доступны только для чтения, вы можете пропустить остановку сервера.

Версия 2 : mysqldump

Установите pigz - на современные процессоры Xeon или Opteron, особенно если у вас 2 или более процессора, это НАМНОГО быстрее, чем gzip.

ssh server1 
mysqldump ... | pigz > backup-YYMDD.sql.gz
rsync backup-YYMDD.sql.gz server:location

ssh server2
pigz -dc location/backup-YYMDD.sql.gz | mysql ..

Версия 3 : master / slave + mysqldump / file-copy

In HA environment you should use the following trick:
setup slave server & do all backups from it
before backups - do "slave stop"; 
then do version 1 or version 2

сценарий:

touch full.start
mysqladmin -h slave-db stop-slave
echo "show slave status \G" | mysql -h slave-db > FULL/comfi-$NOW.master-position
/usr/bin/mysqldump -h slave-db --default-character-set=utf8 -A --opt --skip-lock-tables | pigz > "FULL/XXXX-$NOW.sql.gz"
mysqladmin -h slave-db start-slave
touch full.end

ln -fs "FULL/XXXX-$NOW.sql.gz" FULL.sql.gz

PS:

для копирования небольших таблиц используйте:

таблица схем mysqldump ssh server1 | ssh server2 mysql схема

parf
источник
2

Я бы предложил два простых шага для переноса всей базы данных с одного сервера на другой.

Шаг 1 : Сделайте полное резервное копирование баз данных на исходном сервере, используя mysqldump .

Шаг 2 : Вы можете использовать команду rsync для передачи всей базы данных на конечный сервер.

Рудра
источник