De MySQL a MongoDB

Viernes 19 de febrero de 2016, por Aitor Roma Vázquez

En algunas ocasiones nos encontramos con máquinas con un alto impacto de carga y cuando nos ponemos a investigar descubrimos que el servicio de MySQL está consumiendo muchos recursos de la máquina en su mayoría de CPU y IO de disco. Lo primero que realizamos es activar las slow querys en mysql.

Podemos activar las slow query logs editando el fichero /etc/my.cnf
Añadiendo estas lineas en bajo la directiva [mysqld]

slow-query-log = 1
slow-query-log-file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log-queries-not-using-indexes

Reiniciamos mysql

# service mysqld restart

Una vez reiniciado, ya podemos ver el log donde se reflejan que tablas están haciendo un uso intensivo de MySQL, para poder migrar-las a MongoDB si esa base de datos no tiene ningún tipo de relación podremos fácilmente usarla con MongoDB.

Preparando las herramientas

Antes que nada, debemos preparar las herramientas para la migración, para ello nos apoyaremos sobre un conjunto de scripts del usuario lovette en GitHub.

# git clone https://github.com/lovette/mysql-to-mongo
# cd mysql-to-mongo
# make install

Una vez instalado dispondremos de 3 nuevas herramientas en nuestro sistema

  • my2mo-fields
  • my2mo-export
  • my2mo-import

Preparando el entorno

Recomiendo crear un entorno donde trabajar cómodamente, en mi caso lo que realizo es lo siguiente:

# mkdir -p /opt/my2mo/csvdata
# cd /opt/my2mo

Siempre que realizo una migración la hago desde este directorio.

Creación del Schema

El Schema es una copia de la estructura de la base de datos, pero sin los datos.

# mysqldump --no-data toolboox > schema.sql

Migración de los campos de las tablas

Con el siguiente comando, crearemos la estructura de datos para ser importada a MongoDB.

# my2mo-fields  schema.sql
Generating tables and fields from schema.sql...
...country                         7 fields
...ip2nation                       2 fields
...language                        5 fields
...offer                          15 fields
...source                          2 fields
...updater                        18 fields
...updater_country                 3 fields
...updater_offer                   2 fields
...updater_user                   13 fields
...version                         4 fields
Found 10 tables
Output saved to /srv/mgo
Tables saved to import.tables
Field files saved to fields/*.fields

Creación del Archivo de importación

El siguiente comando no modifica nada de la base de datos existente, lo único que hace es crear el fichero export.sql que ejecuta los comandos necesarios para poder generar los csv.

# my2mo-export csvdata/ toolbox
Generating SQL to export 10 tables...
export.sql saved to /srv/mgo
Data files will be saved to /srv/mgo/csvdata on the
MySQL server, make sure this directory exists, and is empty

Creación de los ficheros CSV para la importación

Al ejecutar el siguiente comando importaremos los datos de la BD MySQL hacia ficheros csv de cada tabla.

# mysql -uroot -p < export.sql

Migración de CSV a Mongodb

# my2mo-import csvdata toolboox
Importing 10 tables into Mongo database 'toolboox'...
...country
...ip2nation
...language
...offer
...source
...updater
...updater_country
...updater_offer
...updater_user
...version
Done!

Comprobamos que este importado

# mongo
MongoDB shell version: 2.4.14
connecting to: test
> use toolboox;
switched to db toolboox
> show collections;
country
ip2nation
language
offer
source
updater
updater_country
updater_offer
updater_user
version

Resolución de incidencias.

Errores con RamDisk en Mysql

Si usáis un ram disk para las tablas temporales de MySQL, os encontrareis que al hacer la importación no os deja escribir, para ello lo que realizaremos será lo siguiente:

Imagina que el ram disk está montado en /srv/mysqltemp
para solucionar el problema que nos dará de importación haremos justamente esto.

# mkdir  /srv/mysqltemp/csvdata
# chmod 777  /srv/mysqltemp/csvdata
# cd /opt/my2mo
# mount -o bind  /srv/mysqltemp/csvdata csvdata

Con esto bindearemos el directorio del ramdisk y no tendremos de realizar cambios al script y será más cómodo para nosotros.

Problemas de importación de tablas

Alguna vez al hacer el import nos encontramos que da algún error podemos solucionarlo así.

editamos el fichero import.sql

SELECT idPortal, idInstaller, idLicense, idDeveloper, name, codSoftware, size, version, requirement, detail, brief, featured, hot, showbanner, rating, icon, image, image2, image3, created, updated, active, visible, uri, exeType, metaTitle, metaDescription, metaKeywords, scriptDownloadPage, synced, scriptThankyouPage, externalSource, scriptLandingPage, externalBundle, externalBundleUrl FROM software INTO OUTFILE "/opt/my2mo/csvdata/software.csv" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';

Y lo dejamos así.

SELECT * FROM software INTO OUTFILE "/opt/my2mo/csvdata/software.csv" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';

Este es un fichero de ejemplo tan solo tendrías de eliminar los campos antes del select de tu exportación.

Esto es todo!

Comentar este artículo