2012-03-08 15 views
11

Tengo una aplicación que diseñé donde se encuentran los datos relacionales y se ajusta naturalmente a MySQL. Tengo otros datos que tienen un esquema en constante evolución y no tiene datos relacionales, por lo que pensé que la manera más natural de almacenar estos datos sería en MongoDB como documento. Mi problema aquí es que uno de mis documentos hace referencia a una identificación primaria de MySQL. Hasta ahora, esto ha funcionado sin problemas. Mi preocupación es que cuando llegue el tráfico de producción y comencemos a trabajar con copias de seguridad, que haya una incoherencia cuando cambie el documento, podría no apuntar a la identificación correcta en la base de datos MySQL. La única manera de garantizarlo hasta cierto punto sería cerrar la aplicación y realizar copias de seguridad, lo que no tiene mucho sentido.Mantener la integridad entre dos almacenes de datos separados durante las copias de seguridad (MySQL y MongoDB)

Tiene que haber otras personas que implementen una estrategia similar. ¿Cuál es la mejor manera de garantizar la integridad de los datos entre los dos almacenes de datos, especialmente durante las copias de seguridad?

+2

No quiero decir nada porque no tengo mucha experiencia con Mongo, y me encantaría saber de alguien que haya probado esto y haya tenido éxito, pero mi corazonada es que vas a tener muchas dificultades si eres tratando de mantener una estrecha integridad relacional en datos de MongoDB como ese. Está específicamente diseñado para hacer el oficio de sacrificar la integridad por la escala:/ –

+0

¿Qué terminaste haciendo? – Aerik

Respuesta

2

No creo que haya una manera fácil de hacerlo. Mongo no tiene transacciones complejas con soporte de reversión, por lo que es muy difícil mantener dicha integridad. Una forma de abordar esto sería considerarlo como dos libros mayores, registrar todas las actualizaciones en el libro mayor de MySQL y luego volver a reproducirlo en el libro mayor de mongo para mantener la integridad. La otra solución posible es hacer esto en el nivel de aplicación y detener las escrituras.

4

MySQL perspectiva

Todos sus datos de MySQL tendrían que utilizar InnoDB. Posteriormente, se podría hacer una instantánea de los datos de MySQL de la siguiente manera:

MYSQLDUMP_OPTIONS="--single-transaction --routines --triggers" 
mysqldump -u... -p... ${MYSQLDUMP_OPTIONS} --all-databases > MySQLData.sql 

Esto creará una instantánea limpia de punto en el tiempo de todos los datos MySQL como una sola transacción.

Por ejemplo, si inicia este mysqldump a medianoche, todos los datos en la salida mysqldump serán desde la medianoche. Los datos aún se pueden agregar a MySQL (siempre que todos sus datos utilicen el motor de almacenamiento InnoDB) y puede hacer que MongoDB haga referencia a cualquier dato nuevo agregado a MySQL después de la medianoche, incluso si es durante la copia de seguridad.

Si tiene tablas MyISAM, debe convertirlas a InnoDB. Vamos a cortar por lo sano. Aquí es cómo hacer un script para convertir todas las tablas MyISAM a InnoDB:

MYISAM_TO_INNODB_CONVERSION_SCRIPT=/root/ConvertMyISAMToInnoDB.sql 
echo "SET SQL_LOG_BIN = 0;" > ${MYISAM_TO_INNODB_CONVERSION_SCRIPT} 
mysql -u... -p... -AN -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length)" >> ${MYISAM_TO_INNODB_CONVERSION_SCRIPT} 

Sólo tiene que ejecutar esta secuencia de comandos cuando esté listo para convertir todas las tablas MyISAM definidos por el usuario. Cualquier tabla MyISAM relacionada con el sistema se ignora y no se debe tocar de todos modos.

MongoDB perspectiva

No puedo hablar por MongoDB porque sé muy poco. Sin embargo, para el lado de MongoDB, si configura un conjunto de réplicas para cualquier información de MongoDB, podría usar mongodump contra una réplica. Como mongodump no es un punto en el tiempo, debería desconectar la réplica (para evitar que los cambios se repitan) y luego realizar el mongodump en la réplica. Luego restablezca la réplica a su maestro. Averigüe de sus desarrolladores o de 10gen si mongodump se puede usar contra un conjunto de réplicas desconectado.

Objetivos Comunes

Si un punto en el tiempo realmente importa a usted, por favor, se asegura de que todos los relojes del sistema operativo tienen el mismo tiempo sincronizado y la zona horaria. Si tiene que realizar dicha sincronización, debe reiniciar mysqld y mongod. Luego, sus trabajos de crontab para mysqldump y mongodump se activarán al mismo tiempo. Personalmente, demoraría un mongodump de aproximadamente 30 segundos para asegurar que los identificadores de mysql que desea publicar en MongoDB se contabilicen.

Si ha mysqld y mongod que se ejecuta en el mismo servidor, entonces usted no necesita ninguna replicación MongoDB. Simplemente inicie un mysqldump a las 00:00:00 (medianoche) y el mongodump a las 00:30:00 (30 segundos después de la medianoche).

0

Realmente no hay forma de hacerlo sin algún tipo de control externo o cumplimiento.

Si realmente necesita garantizar la integridad perfecta entre los dos, una forma de hacerlo es usar marcas de tiempo para sus datos de mysql (todos los registros) y registros de mongo, luego haga una copia de seguridad de cada filtro de las marcas de tiempo usando las herramientas para cada uno para seleccionar sólo los registros de las existentes inmediatamente antes de la copia de seguridad programada (ver http://www.electrictoolbox.com/mysqldump-selectively-dump-data/ para saber cómo utilizar mysqldump con una cláusula WHERE y http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongodump para volcar una colección MongoDB con una consulta)

Dependiendo de cómo se está utilizando en realidad cada uno de sus almacenes de datos, es posible que pueda hacer otra cosa ... Por ejemplo, si solo está escribiendo en su MongoDB y nunca lo actualiza o elimina, entonces sería razonable hacer una copia de seguridad de su base de datos MySQL, luego hacer una copia de seguridad de MongoDB (que ahora puede tener algunos registros adicionales porque se respalda después) y purgar los registros de MongoDB que no corresponden a nada en MySQL. Como dije, depende de cómo los estés usando.

Pero lo marca de tiempo funcionará independientemente - sólo tienen la sobrecarga adicional de las marcas de tiempo.

+1

Podría usar identificadores de autoincremento de uso alternativo siempre que los tenga en su esquema. mysqldump -uuser -p mydb -tables my_documents_table --where = "id <= 2000122" | gzip> my_documents_table_YYYYMMDDHHMMSS.sql.gz mysqldump -uuser -p mydb -ignore-table = mydb.my_documents_table | gzip> mydb_YYYYMMDDHHMMSS.sql.gz A continuación, puede usar la utilidad mongodump para seleccionar solo los registros, incluido el rango de identificación del documento seleccionado. – wisefish

Cuestiones relacionadas