Este artículo presenta dos formas alternativas para migrar los usuarios y permisos de un servidor de bases de datos MySQL o MariaDB desde un servidor hacia otro nuevo. Una técnica es semi-automatizada y un tanto arriesgada entre diferentes versiones de motor de base de datos, mientras que la otra es manual y más controlada.



Un problema que ocurre al migrar hacia un nuevo servidor Web es ¿cómo mover los usuarios de bases de datos y privilegios? Es fácil mover archivos con tar sobre SSH (para preservar ownsership, permisos y fechas de modificación) y bases de datos con mysqldump. Sin embargo, un dump de base de datos no incluye usuarios ni privilegios, estos deben ser migrados a parte.

Si hemos migrado a un nuevo servidor de bases de datos, necesitaremos entonces pasar todos los usuarios y sus privilegios luego de haber restaurado las bases de datos MySQL.

Método rápido

Cabe destacar que este NO ES EL MÉTODO RECOMENDADO para migrar usuarios y privilegios. Sin embargo, en la mayoría de los casos funciona (más adelante explico por qué). El método adecuado y robusto es el manual, explicado posteriormente.

Una alternativa rápida y sencilla consiste en exportar y restaurar la base de datos "mysql", la cual contiene las tablas que definen usuarios y determinan privilegios a nivel base, tabla, columna, etc.

En el servidor viejo ejecutar:

# mysqldump -u root -p mysql > mysql.sql

Copiar el dump vía SSH utilizando scp al servidor nuevo y luego, en el mismo, ejecutar:

# mysql -u root -p mysql < mysql.sql

De esta forma se restaura la base de datos "mysql" en el servidor nuevo. Tener en cuenta que esto destruye los datos existentes y se pierde cualquier usuario y privilegios actuales.

A continuación, es necesario correr "flush privileges" para que los cambios tomen efecto:

# mysql -u root -p
MariaDB [(none)]> flush privileges;

Verificar que los usuarios existan y sean iguales en ambos servidores:

MariaDB [(none)]> select Host,User from mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| %         | user123456       |
| 127.0.0.1 | root             |
| ::1       | root             |
| database  | root             |
| localhost | debian-sys-maint |
| localhost | root             |
| localhost | usuario          |
+-----------+------------------+
7 rows in set (0.000 sec)

Cuando se migran usuarios utilizando esta técnica entre servidores de diferentes versiones (incluso notar que en este ejemplo se ha pasado de MySQL a MariaDB), es necesario ejecutar luego el utilitario mysql_upgrade:

# mysql_upgrade -u root -p --force

Esta herramienta examina todas las tablas de todas las bases de datos en busca de incompatibilidades con la versión de servidor MySQL/MariaDB actual. Si una tabla contiene una posible incompatibilidad, se realiza un chequeo de la misma. Y si se encuentran problemas, se intenta reparar la tabla. A su vez, actualiza las tablas del sistema para habilitar nuevas características que pudieran haber sido agregadas con la nueva versión. Este comando debe ser ejecutado cada vez que se actualiza la versión del motor.

El problema con esta técnica consiste en que, si mysql_upgrade falla, habrá que restaurar la base "mysql" desde un backup, o probablemente reinstalar las bases de datos de sistema (correr mysql_install_db). Por esta razón es una técnica no recomendada y riesgosa, aunque funcione entre versiones compatibles.

Transferir usuarios y permisos manualmente

La opción segura y apropiada consiste en transferir los usuarios uno por uno de forma manual. Para ello es necesario volcar todos los GRANTS de cada usuario en la tabla mysq.user y ejecutarlos en el servidor destino:

mysql> select concat('\'',User,'\'@\'',Host,'\'') from mysql.user;
+-------------------------------------+
| concat('\'',User,'\'@\'',Host,'\'') |
+-------------------------------------+
| 'user123456'@'%'                    |
| 'root'@'127.0.0.1'                  |
| 'root'@'::1'                        |
| 'root'@'database'                   |
| 'debian-sys-maint'@'localhost'      |
| 'root'@'localhost'                  |
| 'usuario'@'localhost'               |
+-------------------------------------+
7 rows in set (0.000 sec)

Por cada fila de esta salida, ejecutar SHOW GRANTS FOR:

mysql> show grants for 'user123456'@'%';
+-----------------------------------------------------------------------------------------------------------+
| Grants for user123456@%                                                                                   |
+-----------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'user123456'@'%' IDENTIFIED BY PASSWORD '*8746578234892349283592835629734827354913' |
| GRANT ALL PRIVILEGES ON `database`.* TO 'user123456'@'%'                                                  |
| GRANT SELECT, LOCK TABLES ON `anotherdb12345`.* TO 'user123456'@'%'                                       |
+-----------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)

mysql> show grants for 'usuario'@'localhost';
+----------------------------------------------------------------------------------------------------------------+
| Grants for usuario@localhost                                                                                   |
+----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'usuario'@'localhost' IDENTIFIED BY PASSWORD '*8456872635827634937469538465256938459382' |
| GRANT ALL PRIVILEGES ON `anotherdb12345`.* TO 'usuario'@'localhost'                                            |
+----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

Copiar cada fila y ejecutar en el servidor destino, agregando un punto y coma al final:

MariaDB [(none)]> GRANT USAGE ON *.* TO 'user123456'@'%' IDENTIFIED BY PASSWORD '*8746578234892349283592835629734827354913';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON `database`.* TO 'user123456'@'%';
MariaDB [(none)]> GRANT SELECT, LOCK TABLES ON `anotherdb12345`.* TO 'user123456'@'%';
MariaDB [(none)]> GRANT USAGE ON *.* TO 'usuario'@'localhost' IDENTIFIED BY PASSWORD '*8456872635827634937469538465256938459382';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON `anotherdb12345`.* TO 'usuario'@'localhost';

Finalmente correr flush privileges;.


Tal vez pueda interesarte


Compartí este artículo