por - mysqldump mariadb
Copiar/duplicar la base de datos sin usar mysqldump (8)
Sin acceso local al servidor, ¿hay alguna forma de duplicar / clonar una base de datos MySQL (con contenido y sin contenido) en otra sin usar mysqldump
?
Actualmente estoy usando MySQL 4.0.
En 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
La mejor manera de clonar tablas de base de datos sin mysqldump:
- Crear una nueva base de datos.
Crear consultas clónicas con consulta:
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'';
Ejecutar esa salida!
Pero tenga en cuenta que los scripts anteriores solo clonan rápidamente las tablas , no las vistas, los activadores y las funciones del usuario: puede obtener rápidamente la estructura mediante mysqldump --no-data --triggers -uroot -ppassword
, y luego usar para clonar solo la instrucción de inserción.
¿Por qué es una pregunta real? Debido a que la carga de mysqldumps es muy lenta si DB es superior a 2Gb. Y no puede clonar tablas InnoDB simplemente copiando archivos de base de datos (como copias de seguridad de instantáneas).
Puede duplicar una tabla sin datos ejecutando:
CREATE TABLE x LIKE y;
(Ver los documentos de MySQL CREATE TABLE )
Podría escribir un script que tome el resultado de SHOW TABLES
de una base de datos y copie el esquema en otra. Debería poder hacer referencia a esquemas + nombres de tablas como:
CREATE TABLE x LIKE other_db.y;
En cuanto a los datos, también puede hacerlo en MySQL, pero no es necesariamente rápido. Una vez que haya creado las referencias, puede ejecutar lo siguiente para copiar los datos:
INSERT INTO x SELECT * FROM other_db.y;
Si está utilizando MyISAM, es mejor que copie los archivos de la tabla; será mucho más rápido Debería poder hacer lo mismo si está utilizando INNODB con espacios de tablas por tabla .
Si terminas haciendo un INSERT INTO SELECT
, ¡asegúrate de desactivar temporalmente los índices con ALTER TABLE x DISABLE KEYS
!
EDITAR Maatkit también tiene algunos scripts que pueden ser útiles para sincronizar datos. Puede que no sea más rápido, pero probablemente podría ejecutar sus scripts de sincronización en datos en vivo sin mucho bloqueo.
Puedo ver que usted dijo que no quería usar mysqldump
, pero llegué a esta página mientras buscaba una solución similar y otros también podrían encontrarla. Con eso en mente, aquí hay una forma sencilla de duplicar una base de datos desde la línea de comandos de un servidor de Windows:
- Cree la base de datos de destino utilizando MySQLAdmin o su método preferido. En este ejemplo,
db2
es la base de datos de destino, donde sedb1
base de datos de origendb1
. - Ejecute la siguiente instrucción en una línea de comando:
mysqldump -h [server] -u [user] -p[password] db1 | mysql -h [server] -u [user] -p[password] db2
Nota: NO hay espacio entre -p
y [password]
Realmente no sé lo que quieres decir con "acceso local". Pero para esa solución, debe poder acceder a través del servidor ssh para copiar los archivos donde se almacena la base de datos .
No puedo usar mysqldump, porque mi base de datos es grande (7Go, mysqldump fail) Si la versión de la base de datos de 2 mysql es muy diferente, es posible que no funcione, puede verificar su versión de mysql usando mysql -V.
1) Copie los datos de su servidor remoto a su computadora local (vps es el alias de su servidor remoto, se puede reemplazar por [email protected])
ssh vps:/etc/init.d/mysql stop
scp -rC vps:/var/lib/mysql/ /tmp/var_lib_mysql
ssh vps:/etc/init.d/apache2 start
2) Importe los datos copiados en su computadora local
/etc/init.d/mysql stop
sudo chown -R mysql:mysql /tmp/var_lib_mysql
sudo nano /etc/mysql/my.cnf
-> [mysqld]
-> datadir=/tmp/var_lib_mysql
/etc/init.d/mysql start
Si tiene una versión diferente, es posible que deba ejecutar
/etc/init.d/mysql stop
mysql_upgrade -u root -pPASSWORD --force #that step took almost 1hrs
/etc/init.d/mysql start
Si está utilizando Linux, puede usar este script de bash: (quizás necesite una limpieza de código adicional pero funciona ... y es mucho más rápido que 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}
for TABLE in `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
Tenga en cuenta que hay un comando mysqldbcopy como parte de las utilidades mysql add .... https://dev.mysql.com/doc/mysql-utilities/1.5/en/utils-task-clone-db.html
Todas las soluciones anteriores llegan al punto un poco, sin embargo, simplemente no copian todo. Creé una función PHP (aunque un poco larga) que copia todo, incluyendo tablas, claves externas, datos, vistas, procedimientos, funciones, activadores y eventos. Aquí está el código:
/* 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 schema if 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 if any 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 table to add foreign key and insert 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 all foreign keys for a particular table in 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 if any foreign keys were returned and recreates them in the new schema
// Note: ON UPDATE and ON DELETE 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 if any views were returned and recreates them in the new schema
if (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 if any triggers were returned and recreates them in the new schema
if (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 if any procedures were returned and recreates them in the new schema
if (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 if any functions were returned and recreates them in the new schema
if (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 if any events were returned and recreates them in the new schema
if (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]));
}
}
}