Làm thế nào bạn có thể ngăn chặn nô lệ MySQL sao chép các thay đổi vào cơ sở dữ liệu 'mysql'?


9

Tôi đã thiết lập nô lệ của mình để không sao chép cơ sở dữ liệu 'mysql' như được mô tả trong phần này SHOW SLAVE STATUS\G;

           Slave_IO_State: Waiting for master to send event
              Master_Host: 127.0.0.1
              Master_User: replication
              Master_Port: 3306
            Connect_Retry: 60
          Master_Log_File: master-bin.000001
      Read_Master_Log_Pos: 1660
           Relay_Log_File: mysql-relay-bin.000004
            Relay_Log_Pos: 478
    Relay_Master_Log_File: master-bin.000001
         Slave_IO_Running: Yes
        Slave_SQL_Running: Yes
          Replicate_Do_DB: 
      **Replicate_Ignore_DB: mysql**
       Replicate_Do_Table: 
   Replicate_Ignore_Table: 
  Replicate_Wild_Do_Table: 
Replicate_Wild_Ignore_Table: 
               Last_Errno: 0
               Last_Error: 
             Skip_Counter: 0
      Exec_Master_Log_Pos: 1660
          Relay_Log_Space: 633
          Until_Condition: None
           Until_Log_File: 
            Until_Log_Pos: 0

Bây giờ, nếu tôi đi đến tổng thể máy chủ và vấn đề một GRANTFLUSH PRIVILEGES:

GRANT SELECT ON *.* TO `foo`@`localhost` IDENTIFIED BY 'bar';
FLUSH PRIVILEGES;

Sau đó tôi quay lại máy chủ SLAVE và phát hành:

SHOW GRANTS FOR `foo`@`localhost`;

và nhận được phản hồi:

+-------------------------------------------------------------------------------------------------------------+
| Grants for foo@localhost                                                                                    |
+-------------------------------------------------------------------------------------------------------------+
| GRANT SELECT ON *.* TO 'foo'@'localhost' IDENTIFIED BY PASSWORD '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB' |
+-------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Làm thế nào tôi có thể ngăn chặn nô lệ sao chép thay đổi cơ sở dữ liệu mysql? Tôi đã hình dung 'bản sao_ignore_db' sẽ có hiệu lực.

Câu trả lời:


8

Được rồi, sau một vài giờ điều tra, tôi nghĩ rằng tôi đã tìm ra nó. Thêm câu trả lời của tôi trong trường hợp này là sử dụng cho người khác.

Theo các tài liệu về sao chép-bỏ qua-db :

Nhân rộng dựa trên tuyên bố. Yêu cầu luồng SQL nô lệ không sao chép bất kỳ câu lệnh nào trong đó cơ sở dữ liệu mặc định (nghĩa là câu lệnh được chọn bởi USE) là db_name.

Tất nhiên, sao chép dựa trên câu lệnh là mặc định và những gì tôi đang sử dụng. Vì vậy, tôi đã cố gắng thay đổi định dạng bằng cách khởi động lại bản gốc binlog_format=rowđể xem điều gì sẽ xảy ra. Không có con xúc xắc. TÀI TRỢthu hồi vẫn được nhân rộng.

Nghiên cứu sâu hơn về các tài liệu về thay đổi nhân rộng trên bảng mysql đã tiết lộ

Các câu lệnh thay đổi cơ sở dữ liệu mysql gián tiếp được ghi lại dưới dạng các câu lệnh bất kể giá trị của binlog_format. Điều này liên quan đến các câu lệnh như GRANT, REVOKE, SET PASSWORD, RENAME USER, CREATE (tất cả các hình thức ngoại trừ CREATE TABLE ... SELECT), ALTER (tất cả các hình thức) và DROP (tất cả các hình thức).

Trời ạ! Ok, vì vậy tôi đã kiểm tra binlog bằng cách sử dụng mysqlbinlogGRANTcâu lệnh của tôi không phát sinh USE mysqlcuộc gọi cơ sở dữ liệu (tại sao lại như vậy?). Vì vậy, replicate-ignore-dbkhông thể trong lương tâm tốt bỏ qua tuyên bố.

Giải pháp của tôi là cắt hoàn toàn các thay đổi đối với bảng mysql khỏi nhật ký nhị phân bằng cách thêm binlog-ignore-db=mysqlvào my.cnf và khởi động lại máy chủ. Làm việc như người ở.


Cẩn thận nghiên cứu các thuật toán nếu bạn có cả _do__ignore_các điều khoản. Nó trở nên khó khăn.
Rick James

4

Vấn đề với câu trả lời của Derek Downey trên bài đăng này là nó sẽ luôn hoạt động theo cùng một cách (bật hoặc tắt).

Nếu bạn đang ở trong một tình huống mà bạn muốn sao chép hầu hết các khoản tài trợ nhưng không phải là tài trợ này - hoặc bạn không muốn trả lại mysql (cần thiết để tải tệp my.conf đã sửa đổi), bạn có thể thực hiện theo cách này:

SET session sql_log_bin = 0;

GRANT SELECT ON *.* TO `foo`@`localhost` IDENTIFIED BY 'bar';

SET session sql_log_bin = 1;

Xin nhớ - cài đặt dòng cuối cùng sql_log_bin = 1là rất quan trọng bởi vì không có nó, bạn sẽ không sao chép bất cứ điều gì.


2
khi tham khảo các câu trả lời khác, bạn nên tham chiếu theo tên của người dùng đã thêm câu trả lời thay vì "câu trả lời ở trên". Thứ tự câu trả lời thay đổi khi câu trả lời được bình chọn lên xuống, v.v.
Max Vernon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.