2012-03-08 11 views
11

Ho un'applicazione che ho progettato dove i dati relazionali si trovano e si adatta naturalmente a MySQL. Ho altri dati che hanno uno schema in continua evoluzione e che non hanno dati relazionali, quindi ho pensato che il modo naturale di archiviare questi dati fosse in MongoDB come documento. Il mio problema qui è uno dei miei documenti fa riferimento a un ID primario MySQL. Finora questo ha funzionato senza problemi. La mia preoccupazione è che quando arriva il traffico di produzione e iniziamo a lavorare con i backup, che potrebbe esserci un'incoerenza per quando il documento cambia, potrebbe non puntare all'ID corretto nel database MySQL. L'unico modo per garantirlo in una certa misura sarebbe quello di chiudere l'applicazione e prendere i backup, il che non ha molto senso.Mantenimento dell'integrità tra due archivi dati separati durante i backup (MySQL e MongoDB)

Ci devono essere altre persone che distribuiscono una strategia simile. Qual è il modo migliore per garantire l'integrità dei dati tra i due archivi dati, in particolare durante i backup?

+2

Non intendendo girare questo in quanto non sono super esperto con Mongo, e mi piacerebbe sentire qualcuno che ha provato questo e ha avuto successo, ma la mia impressione è che avrete grandi difficoltà se siete cercando di mantenere una stretta integrità relazionale su dati MongoDB come quello. Specificamente progettato per fare il commercio di sacrificare l'integrità per la scala:/ –

+0

Che cosa hai finito per fare? – Aerik

risposta

2

Non penso che ci sia un modo semplice per farlo. Mongo non ha transazioni complesse con il supporto del rollback, quindi è molto difficile mantenere tale integrità. Un modo per avvicinarsi a questo sarebbe pensarlo come due libri mastri, registrare tutti gli aggiornamenti su mysql ledger e quindi riprodurlo su mongo ledger per mantenere l'integrità. L'altra soluzione possibile è di farlo a livello di applicazione e interrompere le scritture.

4

MySQL Prospettiva

Tutti i vostri dati di MySQL avrebbe dovuto usare InnoDB. Poi si potrebbe fare un un'istantanea dei dati MySQL come segue:

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

Questo creerà un ambiente pulito snapshot point-in-time di tutti i dati MySQL come una singola transazione.

Ad esempio, se si avvia questo mysqldump a mezzanotte, tutti i dati nell'output mysqldump saranno da mezzanotte. I dati possono ancora essere aggiunti a MySQL (a condizione che tutti i tuoi dati utilizzino il motore di archiviazione InnoDB) e puoi fare in modo che MongoDB faccia riferimento a qualsiasi nuovo dato aggiunto a MySQL dopo mezzanotte, anche se è durante il backup.

Se si dispone di tabelle MyISAM, è necessario convertirle in InnoDB. Andiamo al sodo. Ecco come si effettua uno script per convertire tutti i vostri tabelle 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} 

basta eseguire questo script quando si è pronti per convertire tutte le tabelle MyISAM definite dall'utente. Qualsiasi tabella MyISAM correlata al sistema viene ignorata e non deve essere comunque toccata.

MongoDB Prospettiva

Non posso parlare per MongoDB perché io so molto poco. Tuttavia, per il lato MongoDB, se si imposta un Set di repliche per qualsiasi dato MongoDB, si potrebbe semplicemente usare mongodump su una replica. Dato che mongodump non è point-in-time, dovresti disconnettere la replica (per impedire che le modifiche arrivino) e quindi eseguire il mongodump sulla replica. Quindi ristabilire la replica sul suo master. Scopri dai tuoi sviluppatori o da 10gen se mongodump può essere utilizzato contro un set di repliche disconnesse.

obiettivi comuni

Se point-in-time veramente conta per voi, per favore si assicura tutti gli orologi del sistema operativo hanno lo stesso tempo sincronizzato e fuso orario. Se devi eseguire tale sincronizzazione, devi riavviare mysqld e mongod. Quindi, i tuoi lavori di crontab per mysqldump e mongodump si spegneranno contemporaneamente. Personalmente, ritarderei un mongodump di circa 30 secondi per assicurare che gli id ​​da mysql che vuoi vengano pubblicati in MongoDB vengano presi in considerazione.

Se mysqld e mongod sono in esecuzione sullo stesso server, non è necessaria alcuna replica MongoDB. Basta avviare un mysqldump alle 00:00:00 (mezzanotte) e il mongodump alle 00:30:00 (30 secondi dopo mezzanotte).

0

Non c'è davvero modo di farlo senza una sorta di controllo esterno o applicazione.

Se è davvero necessario garantire la perfetta integrità tra i due, un modo per farlo è utilizzare i timestamp sia per i propri dati mysql (tutti i record) che per i record mongo, quindi eseguire il backup di ciascuno filtrato dai timestamp usando gli strumenti per ciascuna di selezionare solo i record esistenti a destra prima del backup programmato (vedi http://www.electrictoolbox.com/mysqldump-selectively-dump-data/ per come utilizzare mysqldump con una clausola WHERE e http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongodump di scaricare una collezione MongoDB con una query)

a seconda di come si sta usando ogni dei tuoi archivi dati, potresti essere in grado di fare qualcos'altro ... Ad esempio, se stai scrivendo solo sul tuo MongoDB e non stai mai aggiornando o eliminando, sarebbe ragionevole fare il backup del tuo database MySQL, quindi eseguire il backup di MongoDB (che può ora avere alcuni record extra in esso perché viene eseguito il backup in seguito) e quindi eliminare i record MongoDB che non corrispondono a nulla in MySQL. Come ho detto, dipende da come li stai usando.

Ma la funzione di timestamp funzionerà a prescindere - si ha solo il sovraccarico extra dei timestamp.

+1

È possibile utilizzare ID di incremento automatico alternativi, a condizione che siano inclusi nello schema. 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_YYYYMMDDHHSSSS.sql.gz È quindi possibile utilizzare l'utility mongodump per selezionare solo i record compreso l'intervallo di ID del documento selezionato. – wisefish

Problemi correlati