2012-03-08 19 views
11

Tôi có một ứng dụng tôi thiết kế nơi dữ liệu quan hệ nằm và khớp tự nhiên vào MySQL. Tôi có dữ liệu khác có lược đồ không ngừng phát triển và không có dữ liệu quan hệ, vì vậy tôi đã tìm ra cách tự nhiên để lưu trữ dữ liệu này sẽ ở trong MongoDB dưới dạng tài liệu. Vấn đề của tôi ở đây là một trong các tài liệu của tôi tham chiếu đến một ID chính của MySQL. Cho đến nay điều này đã làm việc mà không có bất kỳ vấn đề. Mối quan tâm của tôi là khi lưu lượng sản xuất đến và chúng tôi bắt đầu làm việc với các bản sao lưu, có thể có sự mâu thuẫn khi tài liệu thay đổi, nó có thể không trỏ tới ID chính xác trong cơ sở dữ liệu MySQL. Cách duy nhất để đảm bảo nó ở một mức độ nào đó là tắt ứng dụng và thực hiện sao lưu, điều này không có ý nghĩa gì nhiều.Giữ tính toàn vẹn giữa hai kho dữ liệu riêng biệt trong quá trình sao lưu (MySQL và MongoDB)

Phải có những người khác triển khai một chiến lược tương tự. Cách tốt nhất để đảm bảo tính toàn vẹn dữ liệu giữa hai kho dữ liệu, đặc biệt là khi sao lưu là gì?

+2

Không có ý nghĩa để bắn hạ vì tôi không siêu kinh nghiệm với Mongo, và tôi muốn nghe từ bất cứ ai đã thử điều này và đã thành công, nhưng linh cảm của tôi là bạn sẽ đấu tranh rất nhiều nếu bạn cố gắng giữ tính toàn vẹn quan hệ chặt chẽ trên dữ liệu MongoDB như thế. Thiết kế đặc biệt của nó để làm cho giao dịch hy sinh tính toàn vẹn cho quy mô:/ –

+0

Bạn đã làm gì? – Aerik

Trả lời

2

Tôi không nghĩ rằng có một cách dễ dàng để thực hiện việc này. Mongo không có giao dịch phức tạp với hỗ trợ rollback nên rất khó để duy trì tính toàn vẹn như vậy. Một cách để tiếp cận điều này sẽ là nghĩ về nó như hai sổ cái, ghi lại tất cả các cập nhật trên sổ cái mysql và sau đó phát lại nó trên sổ cái mongo để duy trì tính toàn vẹn. Các giải pháp có thể khác là làm điều này ở cấp ứng dụng và dừng ghi.

4

Phối cảnh MySQL

Tất cả dữ liệu MySQL của bạn sẽ phải sử dụng InnoDB. Sau đó, bạn có thể tạo một bản chụp Dữ liệu MySQL như sau:

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

Điều này sẽ tạo một ảnh chụp nhanh tất cả dữ liệu MySQL dưới dạng một giao dịch.

Ví dụ: nếu bạn khởi động mysqldump vào lúc nửa đêm, tất cả dữ liệu trong đầu ra mysqldump sẽ là từ nửa đêm. Dữ liệu vẫn có thể được thêm vào MySQL (miễn là tất cả dữ liệu của bạn sử dụng Công cụ lưu trữ InnoDB) và bạn có thể tham khảo MongoDB bất kỳ dữ liệu mới nào được thêm vào MySQL sau nửa đêm, ngay cả khi nó đang trong quá trình sao lưu.

Nếu bạn có bất kỳ bảng MyISAM nào, bạn cần phải chuyển đổi chúng thành InnoDB. Hãy cắt theo đuổi. Đây là cách bạn thực hiện một kịch bản để chuyển đổi tất cả các bảng MyISAM của bạn để 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} 

Chỉ cần chạy script này khi bạn đã sẵn sàng để chuyển đổi tất cả các bảng MyISAM người dùng định nghĩa. Mọi bảng MyISAM liên quan đến hệ thống đều bị bỏ qua và không được chạm vào.

Phối cảnh MongoDB

Tôi không thể nói cho MongoDB vì tôi biết rất ít. Tuy nhiên, đối với phía MongoDB của sự vật, nếu bạn thiết lập một bộ bản sao cho bất kỳ dữ liệu MongoDB nào, bạn chỉ có thể sử dụng mongodump trên một bản sao. Vì mongodump không phải là điểm-trong-thời gian, bạn sẽ phải ngắt kết nối các bản sao (để ngăn chặn thay đổi từ đến hơn) và sau đó thực hiện mongodump trên bản sao. Sau đó, thiết lập lại bản sao cho chủ nhân của nó. Tìm hiểu từ các nhà phát triển của bạn hoặc từ 10gen nếu mongodump có thể được sử dụng chống lại một bộ bản sao bị ngắt kết nối.

Mục tiêu chung

Nếu point-in-time thực sự quan trọng đối với bạn, xin vui lòng đảm bảo tất cả các đồng hồ hệ điều hành có thời gian đồng bộ cùng và múi giờ. Nếu bạn phải thực hiện đồng bộ hóa như vậy, bạn phải khởi động lại mysqld và mongod. Sau đó, các công việc crontab của bạn cho mysqldump và mongodump sẽ xuất hiện cùng một lúc. Cá nhân, tôi sẽ trì hoãn một mongodump khoảng 30 giây để đảm bảo các id từ mysql bạn muốn đăng trong MongoDB được chiếm.

Nếu bạn có mysqld và mongod chạy trên cùng một máy chủ, thì bạn không cần bất kỳ bản sao MongoDB nào. Chỉ cần bắt đầu một mysqldump lúc 00:00:00 (nửa đêm) và mongodump lúc 00:30:00 (30 giây sau nửa đêm).

0

Có thực sự là không có cách nào để làm điều đó mà không có một số loại kiểm tra hoặc thực thi bên ngoài.

Nếu bạn thực sự cần đảm bảo tính toàn vẹn hoàn hảo giữa hai, một cách để làm điều này là sử dụng dấu thời gian cho cả dữ liệu mysql (tất cả bản ghi) và bản ghi mongo, sau đó sao lưu từng bộ lọc bằng dấu thời gian bằng các công cụ cho mỗi để chỉ chọn các bản ghi hiện có ngay trước bản sao lưu đã lên lịch (xem http://www.electrictoolbox.com/mysqldump-selectively-dump-data/ để biết cách sử dụng mysqldump với mệnh đề WHERE và http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongodump để đổ bộ sưu tập MongoDB bằng truy vấn)

Tùy thuộc vào cách bạn đang sử dụng Ví dụ, nếu bạn chỉ viết cho MongoDB của bạn và không bao giờ cập nhật hoặc xóa, thì sẽ là hợp lý để sao lưu cơ sở dữ liệu MySQL của bạn, sau đó sao lưu bạn MongoDB (mà bây giờ có thể có một số bản ghi phụ trong đó vì nó được sao lưu sau đó) và sau đó thanh lọc các bản ghi MongoDB không tương ứng với bất kỳ thứ gì trong MySQL. Như tôi đã nói, nó phụ thuộc vào cách bạn đang sử dụng chúng.

Tuy nhiên, dấu thời gian sẽ hoạt động bất kể - bạn chỉ có thêm chi phí của dấu thời gian.

+1

Bạn có thể thay thế sử dụng ID tự động gia tăng được cung cấp tất nhiên là bạn có các ID này trong lược đồ của mình. 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 Sau đó, bạn có thể sử dụng tiện ích mongodump để chỉ chọn các bản ghi bao gồm phạm vi ID tài liệu đã chọn của mình. – wisefish

Các vấn đề liên quan