¿Cómo puedo mover una base de datos de un servidor a otro?

136

¿Cómo puedo mover tablas MySQL de un servidor físico a otro?

Tal como este escenario exacto: tengo un servidor MySQL que usa una tabla innodb y tiene un tamaño de aproximadamente 20 GB.

Quiero moverlo a un nuevo servidor, ¿cuál es la forma más eficiente de hacer esto?

John
fuente
44
Usaría xtrabackup percona.com/docs/wiki/ ... Es muy parecido a copiarlo, pero puedes mantener el servidor en funcionamiento y, suponiendo que uses principalmente tablas innodb (que dijiste que tenías), puedes considerarlo un "hot" copia de seguridad también.
Jonathan
No me beneficio que otras personas usen esta herramienta. Es gratuito / de código abierto y, aunque fue creado por una empresa, es lo suficientemente fácil de usar como para no tener que considerar comprar soporte de esa empresa.
Jonathan

Respuestas:

80

Mi forma favorita es canalizar un comando sqldump a un comando sql. Puedes hacer todas las bases de datos o una específica. Entonces, por ejemplo,

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

Puedes hacer todas las bases de datos con

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

El único problema es cuando la base de datos es demasiado grande y la tubería colapsa. En ese caso, puede hacer tabla por tabla o cualquiera de los otros métodos mencionados a continuación.

David Hall
fuente
44
Consejo: Si ninguna de las bases de datos permite conexiones remotas, canalice netcat.
Bart van Heukelom
1
Para que esto funcione para mí, tuve que crear una base de datos vacía con el mismo nombre en el servidor remoto y luego agregar el nombre de esa base de datos al final del comando.
Zugwalt
1
Esto es elegante, pero sin compresión apenas lo suficientemente rápido para una base de datos de 20 GB.
Daddy32
¡Esta solución es buena solo para una red totalmente controlada (si y solo si está en una red privada segura, lea: no Internet)! ¡Pero solución rápida y fácil!
Tdaget
¡Esto es muy rápido! Pero lo que dijo @ Zugwalt también fue cierto para mí. El comando no funcionó hasta que creé la base de datos (vacía). Agregar agregó el nombre de la base de datos al final del comando.
Skeets
65

Recientemente moví una base de datos de 30GB con la siguiente estrategia:

Servidor antiguo

  • Detener el servidor mysql
  • Copie el contenido de datadir a otra ubicación en el disco ( ~/mysqldata/*)
  • Inicie el servidor mysql nuevamente (el tiempo de inactividad fue de 10-15 minutos)
  • comprimir los datos ( tar -czvf mysqldata.tar.gz ~/mysqldata)
  • copie el archivo comprimido al nuevo servidor

Nuevo servidor

  • instalar mysql (no comenzar)
  • descomprimir archivo comprimido ( tar -xzvf mysqldata.tar.gz)
  • mover contenidos de mysqldata al datadir
  • Asegúrese de que su innodb_log_file_size sea el mismo en el nuevo servidor, o si no lo es, no copie los archivos de registro antiguos ( mysql los generará )
  • Comience mysql
Derek Downey
fuente
1
Omita la copia después de comprimir / descomprimir. Transmita el alquitrán a través de la red usando ssh, o (si y solo si está en una red privada segura, lea: no Internet) use netcat para evitar la sobrecarga de cifrado. Además, si en una red local omite el gzipping, si tiene una tubería de red rápida, encontrará el cuello de botella de transferencia en un núcleo vinculado girando haciendo la compresión
atxdba
¿Esto funciona tanto para innodb como para myisam? Además, ¿los usuarios de mysql también están en datadir?
giorgio79
2
@ giorgio79 seguro siempre que mueva los archivos ibdata también. Por defecto, esos están en el datadir. Los usuarios de MySQL se almacenan en la carpeta mysql en un espacio de tabla de usuario.
Derek Downey
2
¿Funcionará este procedimiento para pasar de Windows a Linux?
ypercubeᵀᴹ
2
@ TypoCubeᵀᴹ lamento tomar más de dos años para responder, pero me hubiera ayudado que alguien dijera definitivamente: "Sí, funciona de Windows a Linux". En mi caso, pasé de Windows Server 2012 R2 a Cent OS (Red Hat 4.8.5-11) . La versión específica de mysql fue Maria DB 10.1 . Según lo prescrito, detuve ambos servicios mysql, sincronicé el directorio de datos y, al iniciar el servicio mysql en el nuevo servidor, todas las bases de datos, tablas de bases de datos y usuarios de bases de datos estaban completamente intactos.
WEBjuju
30

De acuerdo con la Guía de estudio de certificación MySQL 5.0 , el Capítulo 32, Sección 32.3.4, Páginas 456,457, describe las Condiciones para la portabilidad binaria que resaltan lo siguiente:

La portabilidad binaria es importante si desea tomar una copia de seguridad binaria realizada en una máquina y utilizarla en otra máquina que tenga una arquitectura diferente. Por ejemplo, usar una copia de seguridad binaria es una forma de copiar bases de datos de un servidor MySQL a otro.

Para MyISAM, la portabilidad binaria significa que puede copiar directamente los archivos para una tabla MyISAM de un servidor MySQL a otro en una máquina diferente y el segundo servidor podrá acceder a la tabla.

Para InnoDB, la portabilidad binaria significa que puede copiar directamente los archivos de espacio de tabla de un servidor MySQL en una máquina a otro servidor en una máquina diferente y el segundo servidor podrá acceder al espacio de tabla. De forma predeterminada, todas las tablas de InnoDB administradas por un servidor se almacenan juntas en el espacio de tablas, por lo que la portabilidad del espacio de tablas depende de si todas las tablas individuales de InnoDB son portátiles. Si incluso una tabla no es portátil, tampoco lo es el espacio de tabla.

Las tablas MyISAM y los espacios de tablas InnoDB son portátiles binarios de un host a otro si se cumplen dos condiciones:

  • Ambas máquinas deben usar aritmética de enteros con dos complementos
  • Ambas máquinas deben usar el formato de punto flotante IEEE o las tablas no deben contener columnas de punto flotante (FLOTANTE o DOBLE)

En la práctica, esas dos condiciones plantean poca restricción. La aritmética de enteros con dos complementos y el formato de coma flotante IEEE son la norma en el hardware moderno. Una tercera condición para la portabilidad binaria de InnoDB es que debe usar nombres en minúsculas para tablas y bases de datos. Esto se debe a que InnoDB almacena estos nombres internamente (en su diccionario de datos) en minúsculas en Windows. El uso de nombres en minúsculas permite la portabilidad binaria entre Windows y Unix, para forzar el uso de nombres en minúsculas, puede poner las siguientes líneas en un archivo de opciones:

[mysqld]
lower_case_table_names=1

Si configura InnoDB para usar espacios de tabla por tabla, las condiciones para la portabilidad binaria se extienden para incluir también los archivos .ibd para las tablas de InnoDB. (Las condiciones para los espacios de tabla compartidos todavía se aplican porque contiene el diccionario de datos que almacena información sobre todas las tablas de InnoDB).

Si no se cumplen las condiciones para la portabilidad binaria, puede copiar las tablas MyISAM o InnoDB de un servidor a otro descargándolas utilizando algún formato de texto (por ejemplo, con mysqldump) y volviéndolas a cargar en el servidor de destino.

Hay dos formas principales basadas en el motor de almacenamiento para mover tablas individuales.

Para el ejemplo dado, supondremos lo siguiente:

  1. datadir es / var / lib / mysql
  2. base de datos llamada mydb
  3. tabla en la base de datos mydb llamada mytable .

Mesas MyISAM

Si mydb.mytable usa el motor de almacenamiento MyISAM, la tabla se manifestará físicamente como tres archivos separados

  1. /var/lib/mysql/mydb/mytable.frm (archivo .frm)
  2. /var/lib/mysql/mydb/mytable.MYD (archivo .MYD)
  3. /var/lib/mysql/mydb/mytable.MYI (archivo .MYI)

.Frm contiene la estructura de la tabla
.MYD contiene los datos de la tabla
.MYI contiene la página de índice de la tabla

Estos archivos se usan de forma interdependiente para representar la tabla desde un punto de vista lógico en mysql. Dado que estos archivos no tienen ninguna asociación lógica adicional adjunta, migrar una tabla de un servidor DB a otro. Incluso puede hacerlo desde un servidor Windows a un servidor Linux o MacOS. Por supuesto, puede cerrar mysql y copiar los 3 archivos de la tabla. Podrías ejecutar lo siguiente:

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

en una sesión ssh para mantener la tabla como solo lectura y mantener el bloqueo durante 24 horas. Un segundo después, realice la copia en otra sesión ssh. Luego, elimine la sesión de mysql con el bloqueo de 24 horas. No necesitas esperar 24 horas.

Tablas InnoDB

Según la cita del libro de certificación mencionada anteriormente, hay muchos factores que rigen cómo hacer una copia de seguridad de una tabla InnoDB específica. En aras de la simplicidad, la claridad y la brevedad, simplemente realice un mysqldump de la tabla deseada utilizando los parámetros de transacción única para tener un volcado perfecto de la tabla en un momento determinado. No es necesario darse el gusto con la semántica de InnoDB si solo desea una tabla. Puede volver a cargar ese archivo de volcado en cualquier servidor MySQL que elija.

Dado que dos preguntas se fusionaron aquí (jcolebrand): EDITAR

Si está más que dispuesto a vivir con un rendimiento de base de datos lento, puede realizar una serie de rsyncs desde el antiguo servidor (ServerA) al nuevo servidor (ServerB) incluso mientras mysql todavía se está ejecutando en ServerA.

Paso 01) instale la misma versión de mysql en ServerB que ServerA tiene

Paso 02) En ServerA, ejecute SET GLOBAL innodb_max_dirty_pages_pct = 0;desde mysql y aproximadamente 10 minutos (Esto purga páginas sucias del InnoDB Buffer Pool. También ayuda a realizar un apagado de mysql más rápido) Si su base de datos es todo MyISAM, puede omitir este paso.

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

Paso 04) Repita el Paso 03 hasta que un rsync tome menos de 1 minuto

Paso 05) service mysql stopen el ServidorA

Paso 06) Realice un rsync más

Paso 07) scp ServerA:/etc/my.cnf ServerB:/etc/

Paso 08) service mysql starten ServerB

Paso 08) service mysql starten el servidor A (opcional)

Darle una oportunidad !!!

CONSIDERACIÓN

Puede crear un esclavo de replicación como este. Solo recuerde tener el ID de servidor establecido explícitamente en el maestro /etc/my.cnf y un número diferente para el ID de servidor en el esclavo /etc/my.cnf

RolandoMySQLDBA
fuente
29

Ni siquiera necesita mysqldump si está moviendo un esquema de base de datos completo, y está dispuesto a detener la primera base de datos (por lo que es coherente cuando se transfiere)

  1. Detener la base de datos (o bloquearla)
  2. Vaya al directorio donde están los archivos de datos mysql.
  3. Transfiera la carpeta (y su contenido) al directorio de datos mysql del nuevo servidor
  4. Iniciar una copia de seguridad de la base de datos
  5. En el nuevo servidor, emita un comando 'crear base de datos'.
  6. Vuelva a crear los usuarios y otorgue permisos.

No recuerdo si mysqldump maneja usuarios y permisos, o solo los datos ... pero incluso si lo hace, esto es mucho más rápido que hacer un volcado y ejecutarlo. Solo lo usaría si tuviera que volcar una base de datos mysql para luego volver a insertarla en algún otro RDBMS, si tuviera que cambiar las opciones de almacenamiento (innodb vs. myisam), o tal vez si estuviera cambiando las principales versiones de mysql (pero Aunque creo que he hecho esto entre 4 y 5)

Joe
fuente
Esto es más eficiente, especialmente si uno es un administrador de sistemas / DBA. Por cierto, mysqldump usa --all-databasesvolcados del esquema mysql. Al iniciar mysql en la siguiente máquina, aparecen los permisos siempre que haya transferido la carpeta de datos a la otra máquina con la misma versión principal de MySQL. (MySQL 5.5.x a MySQL 5.5.x, MySQL 5.1.x a MySQL 5.1.x, MySQL 5.0.x a MySQL 5.0.x)
RolandoMySQLDBA
44
@ Joe, sí, mysqldumpmaneja usuarios y permisos, ya que estos se almacenan dentro del mysqlesquema.
Shlomi Noach
Este enfoque es especialmente útil con el alojamiento en la nube, como AWS. Puede detener mysql, desmontar y desconectar del servidor actual; adjunte y monte al nuevo servidor e inicie mysql. Sin gastos generales de copia si el volumen permaneció en la misma granja de servidores.
LateralFractal
12

Si solo desea mover una tabla específica, intente:

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

Puede especificar más nombres de tabla arriba, en el mismo comando. Una vez que se complete el comando, mueva el archivo databasename.tablename.sql al otro servidor y luego restaure usando:

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

Tenga en cuenta que el archivo .sql posterior se crea utilizando el programa mysqldump , y la restauración se realiza directamente en mysql .

StanleyJohns
fuente
7
  1. Si tiene acceso ssh, puede usar mysqldump desde la línea de comando
  2. Si no tiene acceso ssh pero tiene acceso phpMyAdmin, puede usarlo para exportar / importar
  3. Si no tiene acceso a phpMyAdmin, hay algunos scripts de php útiles que se volcarán e importarán (sin embargo, desde mi propia experiencia, nunca encontré uno que sea tan confiable como phpMyAdmin).

Puede existir esta posibilidad de mover los archivos de la base de datos real (para mi instalación se encuentran en / var / lib / mysql), pero no estoy realmente seguro de cómo actuará / funcionará.

poelinca
fuente
5

Tendrá que tomarse un tiempo de inactividad. Va a tomar un tiempo dependiendo de la velocidad de su red. Asumiré que estás ejecutando MySQL en Linux / Unix. Aquí está el proceso que uso:

  1. Detenga el demonio mysql en el host de origen.
  2. Haga una carpeta tmp en su host de destino para recibir los archivos.
  3. Use la pantalla para hacer una sesión de shell que sobrevivirá si su ssh se desconecta.
  4. Use rsync para transferir los archivos entre hosts. Algo así como: rsync -avhP usuario de origen @ targetthost: / ruta / a / carpeta /
  5. Ejecute sus casos de prueba para asegurarse de que no perdió nada en la transferencia.

Luego proceda de la forma habitual para configurar MySQL local.

* Nota: también puede usar el parámetro -c con rsync para agregar una suma de verificación a la transferencia, sin embargo, esto será muy lento dependiendo de la velocidad de la CPU.

randomx
fuente
4

Puedo confirmar que el método de DTest también funciona para copiar entre ubuntu y osx.

Para copiar todas las bases de datos sin tener que hacer ningún volcado o similar:

Asegúrese de tener un mysql limpio de mysql (instalado el dmg descargado de mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg ), eso (MUY IMPORTANTE) nunca se ha ejecutado.

Copie el contenido de la carpeta / var / lib / mysql / de la máquina ubuntu en la parte superior de / usr / local / mysql / data / contents en la mac. Para obtener acceso para obtener la carpeta en la máquina ubuntu, tuve que usar sudo, es decir:

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

Copié la carpeta usando scp.

Antes de comenzar, tome una copia de la carpeta mysql en el mac para asegurarse de no estropear nada.

Después de copiar la carpeta, haga lo siguiente en la máquina 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/

Inicie el servidor mysql por primera vez (desde el panel de preferencias en Preferencias del sistema-> mysql). Todos los usuarios y bases de datos ahora deben configurarse correctamente.

Esto funcionó con mysql 5.1.61 en ubuntu 64 bit 11.10 y mysql 5.1.63 en osx lion (macbook pro).

paalvibe
fuente
4

Creo que todas las respuestas anteriores probablemente funcionen bien, pero en realidad no abordan el problema de establecer un nombre de base de datos durante la transferencia.

Así es como lo hice con bash:

Usted puede ser mejor usar rsyncque scp, y no comprimir el archivo si está haciendo esto a menudo.

En mi servidor de origen:

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

En mi servidor de destino:

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

En cualquiera de las máquinas para ver el progreso:

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

Todo esto supone que tiene el archivo de configuración de MySQL en su directorio de inicio en ambas máquinas y establece los permisos:

$ echo "
[client]
user=drupal6
password=metoknow
host=ord-mysql-001-sn.bananas.com
[mysql]
database=nz_drupal" > .my.cnf
$ chmod 0600 ~/.my.cnf
ErichBSchulz
fuente
3

¿Lo estás moviendo a otro servidor MySQL DB? si es así, realice una exportación

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

fuente
Mysqldump? ¿Entonces es cuando se trata de una pequeña cantidad de datos?
Oh Chin Boon
2
Creo que pequeño / grande es bastante subjetivo en estos días. Cuando vi el título de la pregunta, esperaba que la base de datos fuera mucho más grande que 20 gb para ser considerada "grande" ...
Aaron Bertrand
3

Método genérico de Linux:

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

edite el datadir (y el socket) para mysqld y mysqld_safe (si corresponde) para apuntar a la nueva ubicación, luego

/etc/init.d/mysql start

Publiqué esto porque nadie parecía simplemente enumerar la menor cantidad de pasos para hacer esto y siento que es la forma más sencilla personalmente.

pez vela
fuente
2

Quizás esta sea una mejor manera de hacerlo:

Versión 1 : copia de archivos de datos (solo MYISAM)

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

ssh server2 service restart mysql

  • Si los archivos de su base de datos son de solo lectura, puede omitir la detención del servidor.

Versión 2 : mysqldump

Instale pigz: en los procesadores modernos Xeon u Opteron, especialmente cuando tiene 2 o más CPU, es MUCHO más rápido que 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 ..

Versión 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

guión:

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

PD:

para copiar tablas pequeñas use:

tabla de esquema ssh server1 mysqldump | esquema sq server2 mysql

parf
fuente
2

Sugeriría los dos pasos simples para transferir la base de datos completa de un servidor a otro.

Paso 1 : Realice una copia de seguridad completa de las bases de datos en el servidor de origen utilizando mysqldump .

Paso 2 : puede usar el comando rsync para transferir todas las bases de datos al servidor de destino.

Rudra
fuente