2012-03-08 9 views
11

Mam zaprojektowaną przeze mnie aplikację, w której dane relacyjne są umieszczone i pasują w naturalny sposób do MySQL. Mam inne dane, które mają ciągle ewoluujący schemat i nie mają danych relacyjnych, więc uznałem, że naturalnym sposobem przechowywania tych danych będzie MongoDB jako dokument. Mój problem tutaj jest jeden z moich dokumentów odwołuje się do podstawowego ID MySQL. Do tej pory działało to bez żadnych problemów. Obawiam się, że kiedy pojawia się ruch produkcyjny i zaczynamy pracować z kopiami zapasowymi, może to oznaczać niespójność w przypadku zmiany dokumentu, może to nie wskazywać na poprawny identyfikator w bazie danych MySQL. Jedynym sposobem na zagwarantowanie jej w pewnym stopniu jest zamknięcie aplikacji i wykonanie kopii zapasowych, co nie ma większego sensu.Zachowanie integralności dwóch oddzielnych magazynów danych podczas tworzenia kopii zapasowych (MySQL i MongoDB).

Muszą być inne osoby, które zastosują podobną strategię. Jaki jest najlepszy sposób zapewnienia integralności danych między dwoma magazynami danych, szczególnie podczas tworzenia kopii zapasowych?

+2

Nie chcę tego zestrzeliwać, ponieważ nie jestem super doświadczony w Mongo, i bardzo chciałbym usłyszeć od kogoś, kto próbował tego i odniósł sukces, ale moim przeczuciem jest to, że będziesz walczył bardzo, jeśli jesteś próbując zachować ścisłą relacyjną integralność danych MongoDB w ten sposób. Został specjalnie zaprojektowany, aby uczynić handel poświęcający uczciwość na skalę:/ –

+0

Co robiłeś w końcu? – Aerik

Odpowiedz

2

Nie sądzę, jest łatwy sposób to zrobić. Mongo nie ma skomplikowanych transakcji z obsługą wycofywania, więc bardzo trudno jest utrzymać taką integralność. Jednym ze sposobów podejścia do tego byłoby myślenie o nim jako o dwóch księgach rachunkowych, rejestrowanie wszystkich aktualizacji w ksiedze mysql, a następnie powtórzenie go w księdze mongo, aby zachować integralność. Drugim możliwym rozwiązaniem jest zrobienie tego na poziomie aplikacji i zatrzymanie zapisu.

4

MySQL Perspektywa

wszystkich danych MySQL będzie musiał użyć InnoDB. Następnie można zrobić zrzut danych MySQL w następujący sposób:

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

To stworzy czystą migawkę punktu w czasie wszystkich danych MySQL w ramach jednej transakcji.

Na przykład, jeśli uruchomisz ten plik mysqldump o północy, wszystkie dane w wynikach mysqldump będą miały miejsce od północy. Dane mogą nadal być dodawane do MySQL (pod warunkiem, że wszystkie twoje dane używają InnoDB Storage Engine) i możesz mieć referencje MongoDB o wszelkich nowych danych dodanych do MySQL po północy, nawet jeśli jest to podczas tworzenia kopii zapasowej.

Jeśli masz tabele MyISAM, musisz je przekonwertować na InnoDB. Przejdźmy do sprawy. Oto jak zrobić skrypt do konwersji wszystkich tabel MyISAM do 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} 

Wystarczy uruchomić ten skrypt, gdy jesteś gotowy do konwersji wszystkich tabel MyISAM zdefiniowane przez użytkownika. Wszystkie tabele MyISAM związane z systemem są ignorowane i nie należy ich dotykać.

MongoDB Perspektywa

Nie mogę mówić za MongoDB bo wiem bardzo niewiele. Jednak po stronie MongoDB, jeśli skonfigurujesz zestaw replik do dowolnego pliku MongoDB, możesz po prostu użyć mongodumpa do repliki. Ponieważ mongodump nie jest punkt-w-czasie, musisz odłączyć replikę (aby zatrzymać zmiany od nadejścia), a następnie wykonać mongodump na replice. Następnie przywróć replikę do swojego mastera. Dowiedz się od programistów lub od 10gen, czy mongodump może być użyty przeciwko odłączonemu zestawowi replik.

wspólnych celów

Jeśli point-in-time naprawdę liczy się dla Ciebie, sprawia, że ​​wszystkie zegary systemowe mają ten sam zsynchronizowany czas i strefę czasową. Jeśli musisz wykonać taką synchronizację, musisz ponownie uruchomić mysqld i mongod. Następnie twoje zadania crontab dla mysqldump i mongodump będą wyłączane w tym samym czasie. Osobiście opóźniam mongodump o 30 sekund, aby zapewnić identyfikację identyfikatorów z mysql, które chcesz opublikować w MongoDB.

Jeśli masz mysqld i mongod działa na tym samym serwerze, to nie potrzebujesz replikacji MongoDB. Po prostu uruchom mysqldump o 00:00:00 (północ) i mongodump o 00:30:00 (30 sekund po północy).

0

Naprawdę nie ma sposobu, aby to zrobić bez jakiejś zewnętrznej kontroli lub egzekwowania.

Jeśli naprawdę potrzebujesz zapewnić doskonałą spójność między nimi, jednym ze sposobów jest użycie znaczników czasu zarówno dla danych mysql (wszystkie rekordy), jak i rekordów mongo, a następnie wykonaj kopię zapasową każdego przefiltrowanego przez znaczniki czasu za pomocą narzędzi dla każdego, aby wybrać tylko te rekordy istniejące tuż przed planowanym kopii zapasowej (patrz http://www.electrictoolbox.com/mysqldump-selectively-dump-data/ dla sposobu korzystania mysqldump z klauzuli WHERE i http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongodump zrzucić zbiór MongoDB z kwerendy)

zależności od tego jak jesteś rzeczywiście przy każdym swoich magazynów danych, możesz być w stanie zrobić coś innego ... Na przykład, jeśli piszesz tylko na MongoDB i nigdy nie aktualizujesz ani usuwając, to rozsądne jest wykonanie kopii zapasowej bazy danych MySQL, a następnie utworzenie kopii zapasowej MongoDB (który może teraz mieć kilka dodatkowych rekordów, ponieważ jest później zapisywana), a następnie czyszczenie rekordów MongoDB, które nie odpowiadają niczym w MySQL. Jak już powiedziałem, zależy to od tego, jak ich używasz.

Ale znacznik czasu będzie działał niezależnie - po prostu masz dodatkowy narzut znaczników czasu.

+1

Można użyć alternatywnych identyfikatorów auto-increment pod warunkiem oczywiście, że masz je w swoim schemacie. mysqldump -uuser -p mydb - tabele 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 Następnie można użyć narzędzia mongodump, aby wybrać tylko rekordy obejmujące wybrany zakres ID dokumentu. – wisefish

Powiązane problemy