Bagaimana Anda bisa menghentikan MySQL slave dari mereplikasi perubahan ke database 'mysql'?

9

Saya memiliki set budak saya untuk tidak mereplikasi database 'mysql' seperti yang dijelaskan dalam ini 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

Sekarang, jika saya pergi ke server MASTER dan mengeluarkan a GRANTdan FLUSH PRIVILEGES:

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

Saya kemudian kembali ke server SLAVE dan mengeluarkan:

SHOW GRANTS FOR `foo`@`localhost`;

dan menerima respons:

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

Bagaimana saya bisa menghentikan budak dari mereplikasi perubahan database mysql? Saya pikir 'replicate_ignore_db' sudah cukup.

Derek Downey
sumber

Jawaban:

8

Baiklah, setelah beberapa jam penyelidikan, saya pikir saya sudah menemukannya. Menambahkan jawaban saya jika ini berguna bagi orang lain.

Menurut dokumen pada replicate-ign-db :

Replikasi berbasis pernyataan. Memberitahu slave SQL thread untuk tidak mereplikasi pernyataan apa pun di mana database default (yaitu, yang dipilih oleh USE) adalah db_name.

Tentu saja, replikasi berbasis pernyataan adalah default dan apa yang saya gunakan. Jadi saya melakukan upaya untuk mengubah format dengan me-restart master dengan binlog_format=rowuntuk melihat apa yang akan terjadi. Tidak ada dadu. HIBAH dan mencabut masih direplikasi.

Investigasi lebih lanjut ke dalam dokumen tentang perubahan replikasi pada tabel mysql terungkap

Pernyataan yang mengubah database mysql secara tidak langsung dicatat sebagai pernyataan terlepas dari nilai binlog_format. Ini berkaitan dengan pernyataan seperti GRANT, REVOKE, SET PASSWORD, RENAME USER, CREATE (semua bentuk kecuali CREATE TABLE ... SELECT), ALTER (semua bentuk), dan DROP (semua bentuk).

Gah! Ok, jadi saya memeriksa binlog menggunakan mysqlbinlogdan GRANTpernyataan saya tidak mengeluarkan USE mysqlpanggilan database (mengapa harus itu?). Begitureplicate-ignore-db tidak bisa dengan hati nurani mengabaikan pernyataan itu.

Solusi saya adalah memotong perubahan pada tabel mysql dari log biner sepenuhnya dengan menambahkan binlog-ignore-db=mysqlke my.cnf dan restart server. Bekerja seperti pesona.

Derek Downey
sumber
Pelajari algoritma dengan cermat jika Anda memiliki keduanya _do_dan _ignore_klausa. Itu menjadi rumit.
Rick James
4

Masalah dengan jawaban Derek Downey di pos ini adalah ia akan selalu bekerja dengan cara yang sama (hidup atau mati).

Jika Anda berada dalam situasi di mana Anda ingin sebagian besar hibah ditiru tetapi tidak yang ini - atau Anda tidak ingin memantulkan mysql (diperlukan untuk memuat file my.conf yang dimodifikasi), Anda dapat melakukannya dengan cara ini:

SET session sql_log_bin = 0;

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

SET session sql_log_bin = 1;

Harap diingat - bahwa pengaturan baris terakhir sql_log_bin = 1sangat penting karena tanpanya Anda tidak akan mereplikasi apa pun.

pengguna13170
sumber
2
saat merujuk jawaban lain, Anda harus merujuk dengan nama pengguna yang menambahkan jawaban alih-alih "jawaban di atas". Urutan jawaban berubah ketika jawaban dipilih naik turun, dll.
Max Vernon