Migración MySQL de un servidor a otro

Esta semana he tenido que cambiar de proveedor de VPS y con ello he tenido que migrar todos los datos de un servidor a otro. PAra el tema de ficheros la cosa ha estado fácil, un simple rsync nos irá moviendo los archivos que necesitemos junto con sus permisos. El comando es algo complicado pero funcional:

root@improvisa:~# rsync -alHpogDtv -e «ssh -p 22» –numeric-ids –delete-after –stats root@serrvidor_origen:/var/www/ /var/www/

Con esto obtendremos una copia exacta de nuestro directorio para apache. Decir que también copiara enlaces simbólicos, con lo que podremos hacer copias de lo que queramos, por ejemplo el directorio de configuración de apache2 /etc/apache2/. Los pasos de usuarios propietarios y grupos propietarios lo hago de modo numérico, con lo cual lo mejor es repasar que los números coinciden con los nombres de usuario correspondientes. Fijaros que los permisos coinciden con la anterior nota que creé en improvisa sobre los premisos óptimos del directorio /var/www/ de apache2: Permisos óptimos para apache2 en Debian

Una vez que tenemos todos los archivos debemos migrar las bases de datos de MySQL, para ello debemos generarnos un script que sacará el nombre de la base de datos, el usuario que tiene permisos sobre ella y la password, una vez hecho creará dicha base de datos en el servidor remoto junto con su usuario correspondiente y copiará los datos al servidor nuevo. El script es el siguiente, un modificado de :

#!/bin/bash
# Se debe ejecutar en el servidor origen
# Script creado por Juanmi de la versión de nixCraft project <http://cyberciti.biz/fb/>
# ------------------------------------------------------------
# Configurar primero - MySQL local usuario/password
_lusr="root"
_lpass="password_local"
_lhost="localhost"

# Configurar primero - MySQL remoto usuario/password
_rusr="root"
_rpass="password_remoto"
_rhost="localhost"

# Configurar primero - Acceso SSH remoto usuario/password/puerto
# Lo ideal sería tener acceso ssh sin password como dicen aquí: http://www.doctoresdelpc.com/noticias/conectarse-por-ssh-sin-password/
_rsshusr="root"
_rsshhost="17.126.128.142"
_rsshport="22"

# Fichero SQL que pasaremos al servidor remoto con los datos
_tmp="/tmp/output.mysql.$$.sql"
_tmp_con="/tmp/output_con.mysql.$$.sql"

# Debemos quitar del for las bases de datos que NO queramos copiar con grep -v, si solo queremos una usar grep
for i in $( mysql -u "$_rusr" -p"$_lpass" -e "show databases;"|grep -v information_schema|grep -v Database|grep -v mysql|grep -v phpmyadmin ); do

# Creación de accesos a la bbdd
_db="$i"
_user=`echo $i|cut -c1-16`

echo ""
echo "##### $i #####" |tr '[a-z]' '[A-Z]'
echo ""

# Nos aseguramos que podemos entrar a la base de datos
mysqladmin -u "$_lusr" -p"$_lpass" -h "$_lhost" ping &>/dev/null || { echo "Error: El servidor MySQL no está online o estos datos: _lusr, _lpass, y _lhost no son correctos"; exit 2; }

# Nos aseguramos que la base de datos existe
mysql -u "$_lusr" -p"$_lpass" -h "$_lhost" -N -B -e'show databases;' | grep -q "^${_db}$" || { echo "Error: DBase de datos: $_db no encontrada."; exit 3; }

##### OJO, en el paso 1 el $_db debe ir escapado con \, debe quedar así sin espacios \ ` $_db \ ` Se muestra sin \ por el plugin de wordpress
##### Paso 1: Creamos el fichero sql para pasasrselo al remoto con la base de datos y el usuario/password con acceso ####
echo "*** Creando .sql con información de la base de datos $_db..."
echo "create database IF NOT EXISTS \`$_db\` " > "$_tmp"

# Creamos la query para sacar el usuario y el password que tiene permisos para usar esa base de datos.
mysql -u "$_lusr" -p"$_lpass" -h "$_lhost" -B -N \
-e "SELECT DISTINCT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') AS query FROM user" \
mysql \
| mysql -u "$_lusr" -p"$_lpass" -h "$_lhost" \
| grep "$_user" \
| sed 's/Grants for .*/#### &/' >> "$_tmp"

### Paso 2: Añadimos ; al final de todas las lineas del archivo, para que en el remoto no falle.
sed "s/$/;/" "$_tmp" > "$_tmp_con"

##### Paso 3: Mandamos el sql al servidor remoto ####
echo "*** Mandando $_db en ${_rsshhost}..."
scp -P "$_rsshport" "$_tmp_con" ${_rsshusr}@${_rsshhost}:/tmp/

#### Paso 4: Creamos la base de datos y el usuario en el servidor remoto mediante ssh ####
echo "*** Creando $_db y usuario en ${_rsshhost}..."
ssh -p "$_rsshport" ${_rsshusr}@${_rsshhost} mysql -u "$_rusr" -p"$_rpass" -h "$_rhost" < "$_tmp_con"

#### Paso 5: Llenamos la base de datos correspondiente con mysqldump ####
echo "*** Exportando los datos de $_db desde $HOSTNAME a ${_rsshhost}..."
mysqldump -u "$_lusr" -p"$_lpass" -h "$_lhost" "$_db" | ssh -p "$_rsshport" ${_rsshusr}@${_rsshhost} mysql -u "$_rusr" -p"$_rpass" -h "$_rhost" "$_db"

# Borramos los ficheros generados. 
rm -f "$_tmp"
rm -f "$_tmp_con"
ssh -p "$_rsshport" ${_rsshusr}@${_rsshhost} rm "$_tmp_con"

done

Una vez que tengamos creado el scrip le daremos permisos para poder ejecutarlo:

root@improvisa:~# chmod a+x ./migracion_mysql

Y ahora solo queda ejecutarlo en la máquina local, el script se encargará de mandar todo al nuevo servidor.

Lo único que nos quedará por hacer es ejecutar la consulta en el MySQL remoto FLUSH PRIVILEGES; para que los usuarios recientemente creados puedan empezar a utilizar las bases de datos.

Un saludo y espero que os valga.