Копировать / дублировать базу данных без использования mysqldump
427
Без локального доступа к серверу, есть ли способ дублировать / клонировать базу данных MySQL (с контентом и без контента) в другой без использования mysqldump?
Удостоверьтесь, что вы этого не сделаете: CREATE TABLE t2 SELECT * FROM t1;поскольку вы потеряете информацию об индексе, любые специальные вещи, такие как auto_increment и т. Д. Многие Google для этой таблицы копий, приведут вас к этому, и у вас будут нежелательные результаты. ,
Джон Хант
59
Не по теме вопрос получает 92 голосов и 37 избранных. Недурно за такой не по теме вопрос. Устаревшие рекомендации.
pal4life
25
100% согласны с тем, что «закрыто как не по теме» неправильно, и что гильдейны должны быть обновлены - требуется больше снисходительности - ТАК движется в неправильном направлении. Очевидно, что @will полностью не в курсе, и его права модератора должны быть удалены - этот единственный вопрос является достаточным доказательством.
stolsvik
10
Закрыто как не по теме - это на 100% неправильно. Это точный вопрос, который у меня есть, и у него есть четко определенный технический ответ, который не связан с простым мнением. Я думаю, что модератор, должно быть, делал такие поиски слов, как «лучший», чтобы найти вопросы, которые нужно закрыть.
Сэм Голдберг
Ответы:
686
Я вижу, вы сказали, что не хотите использовать mysqldump, но я зашел на эту страницу, когда искал похожее решение, и другие тоже могут его найти. Имея это в виду, вот простой способ дублировать базу данных из командной строки Windows-сервера:
Создайте целевую базу данных, используя MySQLAdmin или предпочитаемый вами метод. В этом примере db2это целевая база данных, куда db1будет скопирована исходная база данных .
Выполните следующую инструкцию в командной строке:
Случай с mysqldump заключается в том, что должен быть более быстрый способ, чем сериализация данных в запросы, передача запросов вне процесса и через tty обратно в тот же процесс , повторный анализ запросов и их выполнение в виде операторов. Это звучит ужасно неэффективно и ненужно . Мы не говорим о скрещивании между мастерами MySQL или смене механизмов хранения. Это шокирует, что нет эффективной внутрипроцессной двоичной передачи.
Тоддиус Жо
42
Если вы не хотите сохранить пароль открытым текстом в истории терминалов, вам нужно разделить команду: mysqldump -h [server] -u [user] -p db1 > db1, в mysql -h [server] -u [user] -p db2 < db1 противном случае будет предложено ввести пароль столовых его, по крайней мере для меня , когда с помощью шпаклевки.
Kapex
5
использование mysqldump и mysql из bash становится намного проще, если вы настроите свой файл .my.cnf для хранения файлов user / host / password
ErichBSchulz
4
mysqldump -u root -p -v db1 | mysql -u root -p db2и два раза введите pass
hlcs
6
Боже, не могли бы вы, пожалуйста, объяснить, почему мой вопрос о том, что "без mysqldump" имеет первый ответ, использует mysqldump? с, как, в 6 раз больше голосов, чем правильный ? давай, ТАК ...
igorsantos07
135
Вы можете дублировать таблицу без данных, выполнив:
Вы можете написать сценарий, который берет выходные данные SHOW TABLESиз одной базы данных и копирует схему в другую. Вы должны иметь возможность ссылаться на имена схем и таблиц, например:
CREATETABLE x LIKE other_db.y;
Что касается данных, вы также можете сделать это в MySQL, но это не обязательно быстро. После того, как вы создали ссылки, вы можете выполнить следующее, чтобы скопировать данные:
INSERTINTO x SELECT*FROM other_db.y;
Если вы используете MyISAM, вам лучше скопировать файлы таблиц; это будет намного быстрее Вы должны быть в состоянии сделать то же самое, если вы используете INNODB с для табличных табличных пространств .
Если вы в конечном итоге делаете INSERT INTO SELECT, не забудьте временно отключить индексы с помощью ALTER TABLE x DISABLE KEYS!
РЕДАКТИРОВАТЬ Maatkit также имеет несколько сценариев, которые могут быть полезны для синхронизации данных. Возможно, это не будет быстрее, но вы, вероятно, могли бы запустить их сценарии синхронизации на реальных данных без особой блокировки.
Я попытался скопировать файлы таблиц базы данных MyISAM один раз, но это просто повредило новую базу данных. Возможно, я плохой, но это определенно не такая тривиальная операция, как некоторые говорят.
Йохан Фредрик Варен
2
Это хороший трюк, и я фанат, но важное замечание: он не переносит никаких ограничений внешнего ключа (даже тех, которые являются внешними по отношению к копируемой схеме) в соответствии с документами MySQL
abigperson
59
Если вы используете Linux, вы можете использовать этот bash-скрипт: (возможно, ему нужна дополнительная очистка кода, но он работает ... и это намного быстрее, чем mysqldump | mysql)
#!/bin/bash
DBUSER=user
DBPASSWORD=pwd
DBSNAME=sourceDb
DBNAME=destinationDb
DBSERVER=db.example.com
fCreateTable=""
fInsertData=""
echo "Copying database ... (may take a while ...)"
DBCONN="-h ${DBSERVER} -u ${DBUSER} --password=${DBPASSWORD}"
echo "DROP DATABASE IF EXISTS ${DBNAME}"| mysql ${DBCONN}
echo "CREATE DATABASE ${DBNAME}"| mysql ${DBCONN}forTABLEin`echo "SHOW TABLES"| mysql $DBCONN $DBSNAME | tail -n +2`; do
createTable=`echo "SHOW CREATE TABLE ${TABLE}"|mysql -B -r $DBCONN $DBSNAME|tail -n +2|cut -f 2-`
fCreateTable="${fCreateTable} ; ${createTable}"
insertData="INSERT INTO ${DBNAME}.${TABLE} SELECT * FROM ${DBSNAME}.${TABLE}"
fInsertData="${fInsertData} ; ${insertData}"
done;
echo "$fCreateTable ; $fInsertData"| mysql $DBCONN $DBNAME
Если вы используете приведенный выше скрипт с таблицами InnoDB и имеете внешние ключи, измените последнюю строку на следующую:echo "set foreign_key_checks = 0; $fCreateTable ; $fInsertData ; set foreign_key_checks = 1;" | mysql $DBCONN $DBNAME
pegli
Копирует ли это также данные об ограничениях и другие свойства таблиц?
Лукас Моескопс
1
Это выглядит так, потому что он использует инструкцию «SHOW CREATE TABLE», которая генерирует CREATE TABLE со всеми свойствами оригинала.
Данита
1
Если вы столкнулись с проблемой, описанной @zirael, возможно, это связано с тем, что сценарию не удается скопировать представления. Вы можете игнорировать представления из копии, изменив SHOW TABLESстроку на SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'и добавив | cut -f 1. Полная строка должна выглядеть примерно так, но замените двойные обратные кавычки на одинарные обратные кавычки: for TABLE in ``echo "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'" | mysql $DBCONN $DBSNAME | tail -n +2 | cut -f 1``; do
Code Commander
1
Я очистил этот скрипт от @jozjan и применил некоторые комментарии, касающиеся внешних и других ключей, для создания этой версии в GIST gist.github.com/christopher-hopper/8431737
Кристофер
11
В PHP:
function cloneDatabase($dbName,$newDbName){
global $admin;$db_check =@mysql_select_db ($dbName );$getTables =$admin->query("SHOW TABLES");$tables = array();while($row= mysql_fetch_row($getTables)){$tables[]=$row[0];}$createTable = mysql_query("CREATE DATABASE `$newDbName` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;")or die(mysql_error());
foreach($tables as$cTable){$db_check =@mysql_select_db ($newDbName );$create=$admin->query("CREATE TABLE $cTable LIKE ".$dbName.".".$cTable);if(!$create){$error = true;}$insert=$admin->query("INSERT INTO $cTable SELECT * FROM ".$dbName.".".$cTable);}return!isset($error);}// usage
$clone = cloneDatabase('dbname','newdbname');// first: toCopy, second: new database
Но для этого требуется установка дополнительного пакета:apt install mysql-utilities
Джоэл Г Мэтью
2
Но не было никаких ограничений, говоря, что это невозможно ... и это обычно устанавливаемая вещь (но, как вы говорите, необязательная). Если он не установлен, многие найдут установку этого пакета проще, чем настройку и запуск 60-строчного скрипта Bash. и т.д ....
фурикула
Ваш пост, вероятно, был отклонен, потому что вы не включили другую информацию, кроме ссылки. Ответы должны быть более полными.
Джоэл Г Мэтью
1
Я действительно не знаю, что вы подразумеваете под "локальным доступом". Но для этого решения вам необходимо иметь доступ через ssh к серверу для копирования файлов, в которых хранится база данных .
Я не могу использовать mysqldump, потому что моя база данных большая (7Go, ошибка mysqldump). Если версия базы данных 2 mysql слишком отличается, она может не работать, вы можете проверить версию mysql, используя mysql -V.
1) Скопируйте данные с удаленного сервера на локальный компьютер (vps - это псевдоним удаленного сервера, его можно заменить на root@1.2.3.4)
Это наиболее эффективный способ сделать это, но я думаю, что «без локального доступа к серверу» означает, что мы не можем получить доступ к системе. Возможно, общий хостинг? Так что это не ответ.
Валерио Бозз
1
Все предыдущие решения достигают некоторой точки, однако они просто не копируют все. Я создал функцию PHP (хотя и несколько длинную), которая копирует все, включая таблицы, внешние ключи, данные, представления, процедуры, функции, триггеры и события. Вот код:
/* This function takes the database connection, an existing database, and the new database and duplicates everything in the new database. */function copyDatabase($c,$oldDB,$newDB){// creates the schemaif it does not exist
$schema="CREATE SCHEMA IF NOT EXISTS {$newDB};";
mysqli_query($c,$schema);// selects the new schema
mysqli_select_db($c,$newDB);// gets all tables in the old schema$tables ="SELECT table_name
FROM information_schema.tables
WHERE table_schema = '{$oldDB}'
AND table_type = 'BASE TABLE'";$results = mysqli_query($c,$tables);// checks ifany tables were returned and recreates them in the new schema, adds the foreign keys,and inserts the associated data
if(mysqli_num_rows($results)>0){// recreates all tables first
while($row= mysqli_fetch_array($results)){$table="CREATE TABLE {$newDB}.{$row[0]} LIKE {$oldDB}.{$row[0]}";
mysqli_query($c,$table);}// resets the results to loop through again
mysqli_data_seek($results,0);// loops through each tabletoaddforeignkeyandinsert data
while($row= mysqli_fetch_array($results)){// inserts the data into each table$data ="INSERT IGNORE INTO {$newDB}.{$row[0]} SELECT * FROM {$oldDB}.{$row[0]}";
mysqli_query($c,$data);// gets allforeign keys for a particular tablein the old schema$fks ="SELECT constraint_name, column_name, table_name, referenced_table_name, referenced_column_name
FROM information_schema.key_column_usage
WHERE referenced_table_name IS NOT NULL
AND table_schema = '{$oldDB}'
AND table_name = '{$row[0]}'";$fkResults = mysqli_query($c,$fks);// checks ifanyforeign keys were returned and recreates them in the new schema// Note:ONUPDATEandONDELETE are not pulled from the original so you would have to change this to your liking
if(mysqli_num_rows($fkResults)>0){while($fkRow = mysqli_fetch_array($fkResults)){$fkQuery ="ALTER TABLE {$newDB}.{$row[0]}
ADD CONSTRAINT {$fkRow[0]}
FOREIGN KEY ({$fkRow[1]}) REFERENCES {$newDB}.{$fkRow[3]}({$fkRow[1]})
ON UPDATE CASCADE
ON DELETE CASCADE;";
mysqli_query($c,$fkQuery);}}}}// gets all views in the old schema$views ="SHOW FULL TABLES IN {$oldDB} WHERE table_type LIKE 'VIEW'";$results = mysqli_query($c,$views);// checks ifany views were returned and recreates them in the new schemaif(mysqli_num_rows($results)>0){while($row= mysqli_fetch_array($results)){$view="SHOW CREATE VIEW {$oldDB}.{$row[0]}";$viewResults = mysqli_query($c,$view);$viewRow = mysqli_fetch_array($viewResults);
mysqli_query($c, preg_replace("/CREATE(.*?)VIEW/","CREATE VIEW", str_replace($oldDB,$newDB,$viewRow[1])));}}// gets all triggers in the old schema$triggers ="SELECT trigger_name, action_timing, event_manipulation, event_object_table, created
FROM information_schema.triggers
WHERE trigger_schema = '{$oldDB}'";$results = mysqli_query($c,$triggers);// checks ifany triggers were returned and recreates them in the new schemaif(mysqli_num_rows($results)>0){while($row= mysqli_fetch_array($results)){$trigger="SHOW CREATE TRIGGER {$oldDB}.{$row[0]}";$triggerResults = mysqli_query($c,$trigger);$triggerRow = mysqli_fetch_array($triggerResults);
mysqli_query($c, str_replace($oldDB,$newDB,$triggerRow[2]));}}// gets all procedures in the old schema$procedures ="SHOW PROCEDURE STATUS WHERE db = '{$oldDB}'";$results = mysqli_query($c,$procedures);// checks ifany procedures were returned and recreates them in the new schemaif(mysqli_num_rows($results)>0){while($row= mysqli_fetch_array($results)){$procedure="SHOW CREATE PROCEDURE {$oldDB}.{$row[1]}";$procedureResults = mysqli_query($c,$procedure);$procedureRow = mysqli_fetch_array($procedureResults);
mysqli_query($c, str_replace($oldDB,$newDB,$procedureRow[2]));}}// gets all functions in the old schema$functions ="SHOW FUNCTION STATUS WHERE db = '{$oldDB}'";$results = mysqli_query($c,$functions);// checks ifany functions were returned and recreates them in the new schemaif(mysqli_num_rows($results)>0){while($row= mysqli_fetch_array($results)){$function="SHOW CREATE FUNCTION {$oldDB}.{$row[1]}";$functionResults = mysqli_query($c,$function);$functionRow = mysqli_fetch_array($functionResults);
mysqli_query($c, str_replace($oldDB,$newDB,$functionRow[2]));}}// selects the old schema(a must for copying events)
mysqli_select_db($c,$oldDB);// gets all events in the old schema$query ="SHOW EVENTS
WHERE db = '{$oldDB}';";$results = mysqli_query($c,$query);// selects the new schema again
mysqli_select_db($c,$newDB);// checks ifany events were returned and recreates them in the new schemaif(mysqli_num_rows($results)>0){while($row= mysqli_fetch_array($results)){$event ="SHOW CREATE EVENT {$oldDB}.{$row[1]}";$eventResults = mysqli_query($c,$event);$eventRow = mysqli_fetch_array($eventResults);
mysqli_query($c, str_replace($oldDB,$newDB,$eventRow[3]));}}}
Понижено, потому что вопрос не в том, чтобы «не использовать mysqldump», а в том, чтобы «использовать лучший подход, чем mysqldump». Это еще хуже с mysqldumpточки зрения эффективности.
Валерио Бозз
1
На самом деле я хотел добиться именно этого в PHP, но ни один из ответов здесь не был очень полезным, поэтому вот мое - довольно простое - решение с использованием MySQLi:
//Database variables
$DB_HOST ='localhost';$DB_USER ='root';$DB_PASS ='1234';$DB_SRC ='existing_db';$DB_DST ='newly_created_db';// MYSQL Connect$mysqli = new mysqli($DB_HOST,$DB_USER,$DB_PASS )or die($mysqli->error );//Create destination database$mysqli->query("CREATE DATABASE $DB_DST")or die($mysqli->error );// Iterate through tables of source database$tables =$mysqli->query("SHOW TABLES FROM $DB_SRC")or die($mysqli->error );while($table=$tables->fetch_array()):$TABLE=$table[0];// Copy tableand contents in destination database$mysqli->query("CREATE TABLE $DB_DST.$TABLE LIKE $DB_SRC.$TABLE")or die($mysqli->error );$mysqli->query("INSERT INTO $DB_DST.$TABLE SELECT * FROM $DB_SRC.$TABLE")or die($mysqli->error );
endwhile;
Я не уверен, что tihis делает клон 1: 1, но похоже, что простых баз данных может быть достаточно.
beppe9000
Я использую это для создания быстрых установок WordPress на моем сервере разработки. Эта часть в паре с некоторыми другими подпрограммами дублирует и настраивает исходную установку в новый проект. Для этого он работает просто отлично ... но пустая база данных WordPress не очень сложна, поэтому я не могу сделать заявление для более расширенных вариантов использования
GDY
0
Лучший способ клонировать таблицы базы данных без mysqldump:
Создать новую базу данных.
Создайте клон-запросы с запросом:
SET@NewSchema ='your_new_db';SET@OldSchema ='your_exists_db';SELECT CONCAT('CREATE TABLE ',@NewSchema,'.',table_name,' LIKE ', TABLE_SCHEMA ,'.',table_name,';INSERT INTO ',@NewSchema,'.',table_name,' SELECT * FROM ', TABLE_SCHEMA ,'.',table_name,';')FROM information_schema.TABLES where TABLE_SCHEMA =@OldSchema AND TABLE_TYPE !='VIEW';
Запустите этот вывод!
Но обратите внимание, скрипт выше просто быстрых таблиц клонирования, а не представлений, триггеров и пользовательских функций: вы можете быстро получить структуру mysqldump --no-data --triggers -uroot -ppassword, а затем использовать для клонирования только оператор вставки.
Почему это актуальный вопрос? Потому что загрузка mysqldumps ужасно медленная, если размер базы данных превышает 2 ГБ. И вы не можете клонировать таблицы InnoDB, просто копируя файлы БД (например, резервное копирование снимка).
SQL, который показывает команды SQL, должен запускаться для дублирования базы данных из одной базы данных в другую. для каждой таблицы создается оператор таблицы и оператор вставки. предполагается, что обе базы данных находятся на одном сервере:
select@fromdb:="crm";select@todb:="crmen";SET group_concat_max_len=100000000;SELECT GROUP_CONCAT( concat("CREATE TABLE `",@todb,"`.`",table_name,"` LIKE `",@fromdb,"`.`",table_name,"`;\n","INSERT INTO `",@todb,"`.`",table_name,"` SELECT * FROM `",@fromdb,"`.`",table_name,"`;")
SEPARATOR '\n\n')as sqlstatement
FROM information_schema.tables where table_schema=@fromdb and TABLE_TYPE='BASE TABLE';
mysqldump
?CREATE TABLE t2 SELECT * FROM t1;
поскольку вы потеряете информацию об индексе, любые специальные вещи, такие как auto_increment и т. Д. Многие Google для этой таблицы копий, приведут вас к этому, и у вас будут нежелательные результаты. ,Ответы:
Я вижу, вы сказали, что не хотите использовать
mysqldump
, но я зашел на эту страницу, когда искал похожее решение, и другие тоже могут его найти. Имея это в виду, вот простой способ дублировать базу данных из командной строки Windows-сервера:db2
это целевая база данных, кудаdb1
будет скопирована исходная база данных .mysqldump -h [server] -u [user] -p[password] db1 | mysql -h [server] -u [user] -p[password] db2
Примечание: между
-p
и[password]
источник
mysqldump -h [server] -u [user] -p db1 > db1
, вmysql -h [server] -u [user] -p db2 < db1
противном случае будет предложено ввести пароль столовых его, по крайней мере для меня , когда с помощью шпаклевки.mysqldump -u root -p -v db1 | mysql -u root -p db2
и два раза введите passВы можете дублировать таблицу без данных, выполнив:
(См. Документацию MySQL CREATE TABLE )
Вы можете написать сценарий, который берет выходные данные
SHOW TABLES
из одной базы данных и копирует схему в другую. Вы должны иметь возможность ссылаться на имена схем и таблиц, например:Что касается данных, вы также можете сделать это в MySQL, но это не обязательно быстро. После того, как вы создали ссылки, вы можете выполнить следующее, чтобы скопировать данные:
Если вы используете MyISAM, вам лучше скопировать файлы таблиц; это будет намного быстрее Вы должны быть в состоянии сделать то же самое, если вы используете INNODB с для табличных табличных пространств .
Если вы в конечном итоге делаете
INSERT INTO SELECT
, не забудьте временно отключить индексы с помощьюALTER TABLE x DISABLE KEYS
!РЕДАКТИРОВАТЬ Maatkit также имеет несколько сценариев, которые могут быть полезны для синхронизации данных. Возможно, это не будет быстрее, но вы, вероятно, могли бы запустить их сценарии синхронизации на реальных данных без особой блокировки.
источник
CREATE TABLE ... SELECT
.Если вы используете Linux, вы можете использовать этот bash-скрипт: (возможно, ему нужна дополнительная очистка кода, но он работает ... и это намного быстрее, чем mysqldump | mysql)
источник
echo "set foreign_key_checks = 0; $fCreateTable ; $fInsertData ; set foreign_key_checks = 1;" | mysql $DBCONN $DBNAME
SHOW TABLES
строку наSHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'
и добавив| cut -f 1
. Полная строка должна выглядеть примерно так, но замените двойные обратные кавычки на одинарные обратные кавычки:for TABLE in ``echo "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE'" | mysql $DBCONN $DBSNAME | tail -n +2 | cut -f 1``; do
В PHP:
источник
Обратите внимание, что есть команда mysqldbcopy как часть утилит add on mysql .... https://dev.mysql.com/doc/mysql-utilities/1.5/en/utils-task-clone-db.html
источник
apt install mysql-utilities
Я действительно не знаю, что вы подразумеваете под "локальным доступом". Но для этого решения вам необходимо иметь доступ через ssh к серверу для копирования файлов, в которых хранится база данных .
Я не могу использовать mysqldump, потому что моя база данных большая (7Go, ошибка mysqldump). Если версия базы данных 2 mysql слишком отличается, она может не работать, вы можете проверить версию mysql, используя mysql -V.
1) Скопируйте данные с удаленного сервера на локальный компьютер (vps - это псевдоним удаленного сервера, его можно заменить на root@1.2.3.4)
2) Импортируйте данные, скопированные на ваш локальный компьютер
Если у вас другая версия, вам может потребоваться запустить
источник
Все предыдущие решения достигают некоторой точки, однако они просто не копируют все. Я создал функцию PHP (хотя и несколько длинную), которая копирует все, включая таблицы, внешние ключи, данные, представления, процедуры, функции, триггеры и события. Вот код:
источник
mysqldump
точки зрения эффективности.На самом деле я хотел добиться именно этого в PHP, но ни один из ответов здесь не был очень полезным, поэтому вот мое - довольно простое - решение с использованием MySQLi:
источник
Лучший способ клонировать таблицы базы данных без mysqldump:
Создайте клон-запросы с запросом:
Запустите этот вывод!
Но обратите внимание, скрипт выше просто быстрых таблиц клонирования, а не представлений, триггеров и пользовательских функций: вы можете быстро получить структуру
mysqldump --no-data --triggers -uroot -ppassword
, а затем использовать для клонирования только оператор вставки.Почему это актуальный вопрос? Потому что загрузка mysqldumps ужасно медленная, если размер базы данных превышает 2 ГБ. И вы не можете клонировать таблицы InnoDB, просто копируя файлы БД (например, резервное копирование снимка).
источник
SQL, который показывает команды SQL, должен запускаться для дублирования базы данных из одной базы данных в другую. для каждой таблицы создается оператор таблицы и оператор вставки. предполагается, что обе базы данных находятся на одном сервере:
источник
Mysqldump не плохое решение. Самый простой способ дублировать базу данных:
mysqldump -uusername -ppass dbname1 | mysql -uusername -ppass dbname2
Кроме того, вы можете изменить механизм хранения следующим образом:
mysqldump -uusername -ppass dbname1 | sed 's/InnoDB/RocksDB/' | mysql -uusername -ppass dbname2
источник