Saya menyiapkan replikasi MySQL Master-slave dan saya mencoba mencari cara untuk menangani situasi failover di mana saya mempromosikan slave to master (jika master turun).
Server aplikasi saya perlu mengarahkan semua penulisan ke master saat ini, tetapi saya tidak dapat menggunakan tingkat server HA antara master dan slave (detak jantung, terus hidup) karena dua server db berada pada subnet yang sangat berbeda di lokasi fisik yang berbeda.
Saya pikir ini adalah sesuatu yang perlu saya tangani di level aplikasi. Saya dapat meminta dua server dan bertanya yang mana adalah master, lalu melakukan semua pertanyaan dengan yang itu.
Apakah ada permintaan di MySQL untuk melihat apakah server saat ini adalah master dalam replika master-slave?
mysql
replication
Ethan Hayon
sumber
sumber
Server version: 5.5.23 MySQL Community Server (GPL)
Jawaban:
@RolandoMySQLDBA telah menjawab pertanyaan secara akurat ... tetapi ia juga menunjukkan bahwa solusinya adalah "cepat dan kotor."
Dan itu adalah pernyataan yang sangat benar. :)
Hal yang menjadi perhatian saya di sini bukanlah dengan jawaban itu, melainkan bahwa pertanyaan awal tampaknya membuat asumsi yang salah:
Masalahnya adalah bahwa dalam replikasi MySQL, master tidak pernah benar-benar menyadari bahwa itu adalah master.
Konsep "promosi untuk menguasai" sebenarnya bukan konsep replikasi asinkron MySQL. "Mempromosikan" server MySQL ke peran master adalah sesuatu yang terjadi "eksternal ke" server MySQL, sebagai lawan dari sesuatu yang terjadi "internal ke" server MySQL.
"Promosi ke master" tidak dilakukan oleh segala jenis penyediaan server, karena, secara teknis, setiap server MySQL yang mengaktifkan pencatatan biner adalah master, walaupun tidak pernah memiliki slave.
SHOW MASTER STATUS
bekerja dengan cara yang persis sama dan mengembalikan hasil yang sama persis, budak atau tidak, dan master dengan 2 budak tidak lebih atau kurang master daripada master dengan 1 budak atau 0 budak. Demikian pula, master yang semua budaknya offline tetap sama besarnya dengan master, karena ketika budak kembali online, mereka akan mengambil replikasi di mana mereka tinggalkan.Dalam arti tertentu, satu-satunya "kesadaran" pada bagian dari kedua server bukanlah apakah itu master, melainkan apakah itu adalah seorang budak (atau "tidak").
Itulah yang ditanyakan solusi Rolando: "apakah Anda seorang budak?" Jika jawabannya tidak, maka asumsinya adalah bahwa ini harus menjadi tuan ... yang ia juga tunjukkan sebagai asumsi yang salah jika
STOP SLAVE;
dikeluarkan. Tetapi budak yang dihentikan masihlah seorang budak, jadi "bukan budak" (kapan saja) tidak sama dengan "menjadi tuan."Tes serupa dapat dilakukan pada master yang diduga:
atau
Jika nilainya nol, maka utas slave slave tidak tersambung. Tes ini memiliki cacat yang sama, yaitu jika budak terputus secara administratif, terisolasi, atau gagal, maka tidak akan terhubung. Jadi ini juga tidak benar-benar menyelesaikan apa pun.
Lebih buruk lagi (untuk salah satu skenario ini) "tabel" information_schema.processlist adalah tabel virtual yang terwujud setiap kali dipilih, dan ini membutuhkan waktu dan biaya sumber daya. Semakin sibuk server Anda, semakin banyak biayanya, karena setiap aktivitas utas harus diintip ke dalam.
Solusi yang lebih ringan adalah:
Pada seorang budak, Anda dapat / harus mengatur variabel global
read_only
sehingga pengguna tanpaSUPER
hak istimewa tidak dapat menulisnya secara tidak sengaja (dan aplikasi Anda seharusnya tidak memilikinyaSUPER
). Jika Anda secara manual "mempromosikan" budak ke peran utama, AndaSET GLOBAL read_only = OFF
dapat mengaktifkan penulisan. (Replikasi selalu dapat menulis ke budak, tidak peduli bagaimana ini diatur).Tapi saya pikir, masih ada hal penting yang terlewatkan:
Saya akan mengusulkan bahwa aplikasi tidak harus membuat keputusan ini secara heuristik dalam pengaturan master / slave, dan tentu saja tidak berdasarkan koneksi-oleh-koneksi. Aplikasi harus menggunakan opsi konfigurasi yang sulit, atau aplikasi harus tetap tidak sadar dan tujuan koneksi database ditangani oleh sesuatu yang lain.
Atau, paling tidak, aplikasi tidak boleh beralih sampai master gagal, dan kemudian tidak boleh kembali dengan sendirinya.
Inilah mengapa saya mengatakan bahwa: setelah "keputusan" dibuat - oleh siapa pun atau apa pun - untuk menjadikan server lain master, aplikasi tidak dapat diizinkan dengan alasan apa pun untuk beralih kembali ke master asli, bahkan setelah itu kembali online , tanpa intervensi.
Katakanlah Anda menabrak bug dan ada crash yang dipaksakan oleh perangkat lunak;
mysqld_safe
patuh memulai kembalimysqld
, dan pemulihan kerusakan InnoDB tampil dengan sempurna. Tapi itu butuh beberapa menit.Sementara itu, master sedang down sehingga aplikasi Anda telah beralih ke slave. Transaksi telah dibuat, pesanan ditempatkan, dana ditransfer, komentar diposting, blog diedit, apa pun sistem Anda.
Sekarang, master asli kembali online.
Jika aplikasi Anda beralih kembali ke master asli, Anda berada di dunia yang benar-benar terluka, karena hal berikutnya yang mungkin terjadi adalah replikasi berhenti karena inkonsistensi, karena aplikasi Anda telah mengubah data pada slave di mean waktu. Anda sekarang memiliki dua server database dengan data tidak konsisten yang harus Anda rekonsiliasi secara manual. Jika ada dolar atau poin atau kredit yang terlibat, Anda sekarang memiliki saldo yang tidak cocok.
Jadi, sangat penting bahwa aplikasi tidak diizinkan untuk beralih kembali ke master asli tanpa campur tangan Anda.
Tunggu, apakah Anda baru saja menemukan masalah dengan skenario ini seperti yang saya jelaskan? Master telah gagal tetapi aplikasi Anda tidak akan menggunakan slave, karena ia berpikir slave masih slave dan bukan master ...
information_schema.processlist
permintaan pada slave masih akan mengembalikan non-nol bahkan jika server master dimatikan .Jadi tidak ada gunanya aplikasi menemukan sesuatu, karena Anda harus secara manual
STOP SLAVE
agar tes itu berguna.Mungkin pendekatan yang lebih baik jika Anda ingin aplikasi dapat beralih adalah mengkonfigurasi server dengan replikasi melingkar.
Replikasi melingkar memiliki masalah yang melekat sendiri, tetapi selama aplikasi Anda hanya selalu menulis ke satu server pada suatu waktu, sebagian besar masalah tersebut menjadi non-masalah. Dengan kata lain, kedua mesin selalu dan sekaligus merupakan master dan slave, dalam arti replikasi, tetapi aplikasi Anda, melalui beberapa mekanisme, selalu hanya menunjuk ke satu mesin sekaligus sebagai "master" di mana ia dapat dan harus menulis .
Anda tidak dapat menggunakan alat HA di server MySQL karena pemisahan mereka, tetapi Anda bisa menerapkannya dengan HAProxy berjalan di server aplikasi. Aplikasi terhubung ke "MySQL" di localhost, yang bukan MySQL sama sekali, tetapi sebenarnya HAProxy ... dan meneruskan koneksi TCP ke mesin MySQL yang sesuai.
HAProxy dapat menguji koneksi ke server MySQL dan hanya menawarkan lalu lintas ke mesin MySQL yang menerima koneksi dan memungkinkan otentikasi.
Kombinasi HAProxy yang berjalan di server aplikasi (permintaannya akan sumber daya tidak akan substansial dibandingkan dengan hal lain yang harus dilakukan server aplikasi - cukup banyak hanya mengikat soket dan mengabaikan muatannya) ... dan replikasi melingkar MySQL akan menjadi pendekatan yang mungkin saya ambil dalam contoh ini, berdasarkan apa yang diketahui dari pertanyaan.
Atau, untuk pengaturan ketat manual, lakukan sesuatu yang jauh lebih sederhana daripada "penemuan," seperti entri dalam
/etc/hosts
file server aplikasi dengan nama host yang digunakan aplikasi untuk terhubung ke MySQL, yang dapat Anda perbarui secara manual - dengan asumsi promosi budak menjadi master dimaksudkan untuk menjadi proses manual.Atau, sesuatu yang lebih kompleks, menggunakan Percona XtraDB Cluster. Untuk ini, Anda ingin menambahkan server ketiga, karena dengan 3 node di PXC, jika 2 server dapat melihat satu sama lain tetapi terisolasi dari 1 server (jika ketiganya masih berjalan) kedua server tetap berjalan dengan gembira tetapi 1 server meringkuk menjadi bola kecil dan menolak untuk melakukan apa pun karena menyadari itu pasti yang aneh. Ini berfungsi karena 2 menyadari mereka masih merupakan mayoritas dari node yang sedang online sebelum jaringan terpecah dan 1 menyadari bahwa itu bukan. Dengan PXC, tidak masalah server mana yang terhubung dengan aplikasi Anda.
Saya mengatakan semua ini adalah untuk mengatakan "tidak memiliki aplikasi jajak pendapat server untuk melihat mana yang merupakan master" karena itu akan menggigit Anda cepat atau lambat dan itu akan menggigit kinerja Anda sampai hari itu menggigit.
sumber
auto_increment_*
variabel masih baik untuk digunakan dalam skenario ini, "berjaga-jaga." Juga, ingatlah untuk menggunakanbinlog_format
=row
ataumixed
- tidakstatement
(bahkan jika Anda tidak melakukan lingkaran).Jika Anda hanya menggunakan Master / Budak, berikut adalah sesuatu yang cepat dan kotor:
Apa artinya ini bagimu?
SlaveThreadCount
= 0, Anda memiliki MasterSlaveThreadCount
> 0, Anda memiliki BudakCAVEAT : Ini berfungsi selama Anda tidak lari
STOP SLAVE;
Hal lain untuk dicoba adalah ini: Jika Anda menonaktifkan log biner pada Slave dan Anda menjalankan
SHOW MASTER STATUS;
, Master memberi Anda log biner saat ini. Budak tidak memberi Anda apa-apa.sumber
jalankan pernyataan ini dari mysql prompt
mysql> tampilkan status budak;
Pada slave itu menunjukkan banyak parameter dan nilai / statusnya sementara pada master itu menunjukkan set kosong
sumber