2009-01-16 33 views
6

Tôi mới sử dụng MySQL và tôi đang tìm ra cách tốt nhất để thực hiện sao lưu hợp lý nóng trực tuyến bằng cách sử dụng mysqldump. This page cho thấy dòng lệnh này:Làm thế nào để có được một bãi chứa chính xác bằng cách sử dụng mysqldump và giao dịch đơn khi DDL được sử dụng cùng một lúc?

mysqldump --single-transaction --flush-logs --master-data=2 
      --all-databases > backup_sunday_1_PM.sql 

nhưng ... nếu bạn đọc tài liệu một cách cẩn thận you find that:

Trong khi một bãi chứa --single-transaction đang trong quá trình, để đảm bảo một tập tin dump hợp lệ (nội dung bảng đúng và vị trí nhật ký nhị phân), không có kết nối nào khác nên sử dụng các tuyên bố sau: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE. A đọc nhất quán không bị cô lập từ những tuyên bố đó, do đó, sử dụng chúng trên bảng để được bán phá giá có thể gây ra SELECT được thực hiện bởi mysqldump để truy xuất nội dung bảng để có được nội dung không chính xác hoặc không thành công.

Vì vậy, có cách nào để ngăn chặn trường hợp tham nhũng đổ có thể xảy ra này không? I.e. một lệnh có thể chặn tạm thời các câu lệnh đó.

PS: lối vào lỗi MySQL về chủ đề này http://bugs.mysql.com/bug.php?id=27850

+0

Hi, do thực tế rằng, trong tháng, không ai đăng một cách để ngăn chặn các kịch bản tôi giả định rằng không phải là có thể. Tôi chấp nhận câu trả lời của Bill là tốt. –

+0

http: // stackoverflow.com/a/21870537/1815624 – CrandellWS

Trả lời

8

mở một cửa sổ lệnh mysql và ban hành lệnh này:

mysql> FLUSH TABLES WITH READ LOCK; 

này sẽ khóa tất cả bảng trong tất cả cơ sở dữ liệu trên MySQL dụ này cho đến khi bạn phát hành UNLOCK TABLES (hoặc chấm dứt kết nối máy khách chứa các khóa đọc này).

Để xác nhận điều này, bạn có thể mở một cửa sổ lệnh khác và cố gắng thực hiện một ALTER, DROP, RENAME hoặc TRUNCATE. Các lệnh này treo, chờ khóa đọc được phát hành. Nhấn Ctrl-C để chấm dứt sự chờ đợi.

Nhưng trong khi các bảng có khóa đọc, bạn vẫn có thể thực hiện sao lưu mysqldump.

Lệnh FLUSH TABLES WITH READ LOCKcó thể giống như sử dụng tùy chọn --lock-all-tablesmysqldump. Nó không hoàn toàn rõ ràng, nhưng this doc dường như để hỗ trợ nó:

Một sử dụng cho UNLOCK BẢNG là nhả khóa đọc toàn cầu mua với BẢNG FLUSH VỚI READ LOCK.

Cả hai FLUSH TABLES WITH READ LOCK--lock-all-tables sử dụng cụm từ "khóa đọc chung", vì vậy tôi nghĩ có khả năng chúng cũng giống như vậy. Do đó, bạn sẽ có thể sử dụng tùy chọn đó để mysqldump và bảo vệ chống lại ALTER đồng thời, DROP, RENAME và TRUNCATE.


Re.nhận xét của bạn: Sau đây là từ Guilhem Bichot trong nhật ký lỗi MySQL mà bạn đã liên kết tới:

Xin chào. --lock-all-tables gọi FLUSH BẢNG ĐƠN VỚI READ LOCK. Vì vậy, nó được dự kiến ​​chặn ALTER, DROP, RENAME, hoặc TRUNCATE (trừ khi có lỗi hoặc Tôi sai). Tuy nhiên, --lock-all-table --chuyển giao-giao dịch không thể hoạt động (mysqldump ném thông báo lỗi): vì khóa tất cả các bảng khóa tất cả bảng của máy chủ chống viết trong thời gian sao lưu, trong khi giao dịch đơn lẻ được dự định để cho phép ghi xảy ra trong quá trình sao lưu (bằng cách sử dụng lệnh SELECT được đọc nhất quán trong giao dịch), chúng không tương thích trong tự nhiên.

Từ đó, có vẻ như bạn không thể truy cập đồng thời trong khi sao lưu và đồng thời chặn ALTER, DROP, RENAME và TRUNCATE.

+1

Cảm ơn Bill, nhưng tôi muốn có bản sao lưu nóng: DB phải có thể truy cập được cho các câu lệnh SELECT và INSERT trong khi tiến trình sao lưu đang được tiến hành. Đây là lý do đằng sau việc sử dụng giao dịch đơn lẻ (và InnoDB). –

+0

Cảm ơn bạn đã trả lời, tôi hơi bối rối khi sử dụng mysqldump, nếu bạn đã viết ở trên (không cần phải mở một phiên riêng với FLUSH TABLES WITH READ LOCK;) được xác nhận sau đó tôi có thể tạo tập tin batch cho bãi chứa kịp thời. , sau đó làm thế nào tôi có thể xác nhận nó hoặc làm thế nào tôi có thể tạo tập tin thực thi mà có thể tạo ra hai phiên khác nhau theo nhu cầu (để giữ khóa); –

1

Bạn không thể nhận được một bãi chứa nhất quán mà không có bảng khóa. Tôi chỉ làm của tôi trong một thời gian trong ngày mà 2 phút nó cần để làm bãi không được nhận thấy.

Một giải pháp là thực hiện sao chép, sau đó sao lưu bộ tớ thay cho bản gốc. Nếu nô lệ nhớ ghi trong quá trình sao lưu, nó sẽ chỉ bắt kịp sau. Điều này cũng sẽ để lại cho bạn một máy chủ sao lưu trực tiếp trong trường hợp chủ không thành công. Cái gì là tốt.

+0

Trong ánh sáng của tất cả mọi thứ thảo luận này có vẻ như các tuyến đường thông minh nhờ cho đề nghị này. – CrandellWS

2

Tôi nghĩ điều tương tự đọc phần tài liệu đó, tôi tìm thấy thêm thông tin:

4.5.4. mysqldump - Một chương trình Database Backup http://dev.mysql.com/doc/en/mysqldump.html

Đối với các bảng InnoDB, mysqldump cung cấp một cách để làm cho một trực tuyến sao lưu:

shell> mysqldump --all-databases --single-transaction > all_databases.sql 

sao lưu này có được một khóa đọc toàn cầu trên tất cả các bảng (sử dụng FLUSH TABLES VỚI READ LOCK) ở đầu bãi chứa. Ngay sau khi khóa này được mua, các tọa độ nhật ký nhị phân được đọc và khóa được giải phóng. Nếu các câu lệnh cập nhật dài đang chạy khi câu lệnh FLUSH được phát hành, máy chủ MySQL có thể bị trì hoãn cho đến khi các câu lệnh đó kết thúc. Sau đó, bãi chứa trở thành khóa miễn phí và không làm phiền đọc và ghi trên các bảng. Nếu bản cập nhật tuyên bố rằng máy chủ MySQL nhận được ngắn (về thời gian thực hiện ), thời gian khóa ban đầu không được chú ý, thậm chí với nhiều cập nhật.

Có một cuộc xung đột với các tùy chọn --opt--single-transaction:

--opt

Tùy chọn này là viết tắt. Nó giống như chỉ định --thêm-thả-bảng --thêm khóa --tạo-tùy chọn --disable-keys --extended-insert --lock-tables --quick --set-charset. Nó sẽ cung cấp cho bạn một hoạt động đổ nhanh và tạo một tệp kết xuất có thể được tải lại vào máy chủ MySQL một cách nhanh chóng.

Tùy chọn --opt được bật theo mặc định. Sử dụng --skip-opt để tắt nó.

Nếu tôi hiểu chính xác câu hỏi của bạn, bạn muốn dữ liệu thực tế và DDL (Ngôn ngữ định nghĩa dữ liệu), vì nếu bạn chỉ muốn DDL bạn sẽ sử dụng --no-data. Thông tin thêm về vấn đề này có thể được tìm thấy tại địa chỉ:

http://dev.mysql.com/doc/workbench/en/wb-reverse-engineer-create-script.html

Sử dụng tùy chọn --databases với mysqldump nếu bạn muốn tạo cơ sở dữ liệu cũng như tất cả các đối tượng của nó. Nếu không có câu lệnh dbATE DATABASE CREATE DATABASE trong tệp kịch bản lệnh của bạn, bạn phải nhập cơ sở dữ liệu đối tượng vào lược đồ hiện có hoặc, nếu không có lược đồ, một lược đồ chưa được đặt tên mới được tạo.

Theo đề nghị của The Definitive Guide to MySQL 5 By Michael Kofler tôi sẽ đề nghị các tùy chọn sau:

--skip-opt 
--single-transaction 
--add-drop-table 
--create-options 
--quick 
--extended-insert 
--set-charset 
--disable-keys 

Ngoài ra, không được nhắc đến là --order-by-primary Ngoài ra nếu bạn đang sử dụng tùy chọn --databases, bạn cũng nên sử dụng --add-drop-database đặc biệt nếu kết hợp với điều này answer Nếu bạn đang sao lưu cơ sở dữ liệu được kết nối trên các mạng khác nhau, bạn có thể cần sử dụng tùy chọn --compress.

Vì vậy, một lệnh mysqldump (mà không sử dụng --compress, --databases, hoặc --add-drop-database tùy chọn) sẽ là:

mysqldump --skip-opt --order-by-primary --single-transaction --add-drop-table --create-options --quick --extended-insert --set-charset -h db_host -u username --password="myPassword" db_name | mysql --host=other_host db_name 

tôi loại bỏ các tham chiếu đến --disable-keys đã được đưa ra trong cuốn sách vì nó là không có hiệu quả với InnoDB như Tôi hiểu rôi. Các MySql manual bang:

Đối với mỗi bảng, bao quanh các câu lệnh INSERT với/* 40000 ALTER TABLE KEYS tbl_name DISABLE /; và/! 40000 ALTER BẢNG tbl_name CÁC BẬT CÓ THỂ * /; các câu lệnh. Điều này làm cho tải tệp kết xuất nhanh hơn vì các chỉ mục được tạo sau khi tất cả các hàng được chèn vào. Tùy chọn này chỉ có hiệu lực đối với các chỉ mục không phải của các bảng MyISAM.

Tôi cũng thấy báo cáo lỗi này http://bugs.mysql.com/bug.php?id=64309 trong đó có ý kiến ​​về đáy từ Paul DuBois who also wrote a few books mà tôi không có tài liệu tham khảo về vấn đề cụ thể này khác so với những bình luận được tìm thấy trong đó báo cáo lỗi.

Bây giờ để tạo ra các "Cuối cùng Sao lưu" Tôi sẽ đề nghị xem xét một cái gì đó dọc theo dòng của shell script này

  1. https://github.com/red-ant/mysql-svn-backup/blob/master/mysql-svn.sh
+0

Tôi đã không thảo luận về Thạc sĩ/Slave như đã đề cập [ở đây] (http://stackoverflow.com/a/16508576/1815624) bởi vì đó không phải là một lựa chọn cho tôi vì tôi không thể cấu hình cơ sở dữ liệu MySql tôi đang làm việc với điều này cách thức. – CrandellWS

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