Apa cara teraman untuk mengganti format binlog saat runtime?

25

Karena peringatan berikut di mysqld.log:

[Peringatan] Pernyataan tidak aman yang ditulis ke log biner menggunakan format pernyataan sejak BINLOG_FORMAT = PERNYATAAN. Pernyataan ini tidak aman karena menggunakan klausa LIMIT. Ini tidak aman karena rangkaian baris yang disertakan tidak dapat diprediksi.

Saya ingin beralih ke format replikasi MIXED.

Tetapi menurut dokumen MySQL:

Mengubah format replikasi saat runtime tidak disarankan bila ada tabel sementara, karena tabel sementara dicatat hanya saat menggunakan replikasi berbasis pernyataan, sedangkan dengan replikasi berbasis baris, mereka tidak dicatat.

Jadi, pertanyaannya adalah bagaimana saya bisa mengidentifikasi jika ada tabel sementara yang ada untuk mengganti format log biner dengan aman?

kuanta
sumber
1
Peringatan cepat. Waspadai hal ini saat beralih dari RBR-> SBR dan menggunakan read-commit: bugs.mysql.com/bug.php?id=62493
Morgan Tocker

Jawaban:

35

Karena sebuah binlog akan memiliki format spesifik pada saat Anda melakukan ini, Anda dapat memutuskan untuk tidak bertaruh dengan dua format tersebut secara bersamaan walaupun MySQL (eh Oracle [masih tidak dapat berbicara]] membangun fitur ini.

Untuk memainkannya benar-benar aman tanpa me-restart mysql, coba yang berikut ini:

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

Ini akan meninggalkan binlog terakhir dalam format 'MIXED'. Binlog penultimiate (di sebelah terakhir) ada hanya membawa penutupan binlog terakhir yang ada dalam format sebelumnya.

Semua sesi yang ada sebelum yang pertama FLUSH LOGS;akan mulai menulis di binlog terakhir setelah UNLOCK TABLES;dijalankan.

Cobalah !!!

CAVEAT

Memberi kredit di mana kredit jatuh tempo, jawaban saya benar-benar mendukung jawaban Jonathan . Saya hanya menutup dan membuka binlog di atas itu. Dia mendapat +1 karena membawa ini dulu.

UPDATE 2011-10-12 13:58 EDT

Jika Anda melakukan ini pada Master yang aktif dan ada satu atau lebih Budak yang mereplikasi dari Master itu, Anda perlu khawatir tentang log relai yang berada dalam format baru juga. Inilah yang dapat Anda lakukan:

Di Budak, jalankan STOP SLAVE;

Pada Master jalankan ini:

FLUSH TABLES WITH READ LOCK;
FLUSH LOGS;
SET GLOBAL binlog_format = 'MIXED';
FLUSH LOGS;
UNLOCK TABLES;

Di Budak, jalankan START SLAVE;

Menjalankan STOP SLAVE;dan START SLAVE;memutar log relai dan menyebabkan entri baru direplikasi dalam format apa pun. Anda mungkin ingin menerapkan perubahan binlog_format di dalam slave juga.

RolandoMySQLDBA
sumber
3
Satu hal yang perlu diingat adalah bahwa pengaturan replikasi mysql sebenarnya diatur berdasarkan per-klien-sesi. Pengaturan global binlog_format hanya mengubah nilai untuk sesi BARU. Dengan demikian, jika Anda menjalankannya pada sistem dengan klien yang terhubung terus-menerus, setiap perubahan yang Anda buat pada pengaturan tidak akan langsung berlaku bahkan jika Anda melakukan pembilasan dan penguncian seperti yang ditentukan di sini - mereka tidak akan berlaku sampai klien hubungkan kembali (atau atur nilainya dalam sesi mereka sendiri tetapi dalam pengalaman saya yang pertama lebih mungkin).
Austin Mills
Bagi yang penasaran, Anda juga bisa meletakkan "binlog_format = 'MIXED';" ke my.cnf Anda.
Christian
2
FYI, jawaban ini tidak sesuai dengan jawaban di sini: dba.stackexchange.com/questions/58539/…
HTTP500
Status manual : Ini berarti bahwa mengubah format logging pada master replikasi tidak menyebabkan seorang budak mengubah format logging-nya agar cocok. (..snip ..) Mengubah format logging biner pada master saat replikasi sedang berlangsung, atau tanpa mengubahnya juga pada slave dapat menyebabkan hasil yang tidak terduga, atau bahkan menyebabkan replikasi gagal sama sekali.
Halfgaar
@ Halfgaar Baru seminggu yang lalu, saya mengganti seorang budak dari CAMPURAN ke PERNYATAAN tiga kali tanpa efek buruk. Saya melakukan itu karena replikasi rusak karena kondisi balapan. Tabel menjadi tidak ada pada seorang budak sebelum eksekusi permintaan. Jadi, saya beralih ke PERNYATAAN ke kandang seperti itu. Tentu saja, semua penulisan dihentikan ketika saya melakukan ini. BTW saya melakukan Master juga.
RolandoMySQLDBA
6

Untuk berpindah binlog_format saat runtime dapat Anda lakukan:

set global binlog_format = 'MIXED';

Ini akan mengatur semua sesi BARU menjadi format binlog campuran. Semua sesi yang ada akan menjadi apa pun yang ditetapkan sebelumnya sampai berakhir.

Anda juga dapat melakukan set session binlog_format = 'MIXED';secara manual untuk menyelesaikan masalah dengan sesi khusus.

Jonathan
sumber
Saya tidak bertanya caranya, saya bertanya cara teraman dan bagaimana saya bisa mengecek apakah ada tabel sementara.
quanta
3
Mengatur variabel global terlebih dahulu dan menunggu sesi yang tersisa selesai, adalah cara paling aman.
Jonathan