Bagaimana cara menyinkronkan kembali Mysql DB jika Master dan slave memiliki basis data yang berbeda untuk replikasi Mysql?


139

Mysql Server1berjalan sebagai MASTER .
Mysql Server2berjalan sebagai BUDAK .

Sekarang replikasi DB terjadi dari MASTER ke SLAVE .

Server2dihapus dari jaringan dan sambungkan kembali setelah 1 hari. Setelah ini ada ketidakcocokan dalam database di master dan slave.

Bagaimana cara menyinkronkan kembali DB karena setelah memulihkan DB yang diambil dari Master ke Slave juga tidak menyelesaikan masalah?

Jawaban:


287

Ini adalah prosedur langkah-demi-langkah lengkap untuk melakukan sinkronisasi ulang replikasi master-slave dari awal:

Di master:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Dan salin nilai hasil dari perintah terakhir di suatu tempat.

Tanpa menutup koneksi ke klien (karena itu akan melepaskan kunci baca) mengeluarkan perintah untuk mendapatkan dump master:

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql

Sekarang Anda dapat melepaskan kunci, bahkan jika dump belum berakhir. Untuk melakukannya, lakukan perintah berikut di klien MySQL:

UNLOCK TABLES;

Sekarang salin file dump ke slave menggunakan scp atau alat pilihan Anda.

Di budak:

Buka koneksi ke mysql dan ketik:

STOP SLAVE;

Muat dump data master dengan perintah konsol ini:

mysql -uroot -p < mysqldump.sql

Sinkronkan slave dan master log:

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;

Di mana nilai dari bidang di atas adalah yang Anda salin sebelumnya.

Akhirnya, ketikkan:

START SLAVE;

Untuk memeriksa apakah semuanya berfungsi kembali, setelah mengetik:

SHOW SLAVE STATUS;

Anda harus melihat:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

Itu dia!


8
Dengan jenis Dabatase yang diketik INNODB dan jenis kolom kompleks lainnya seperti BLOB dan DATE, saya sarankan menggunakan sakelar berikut:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
Ken Pega

4
Apakah RESET_SLAVEperlu? Perhatikan bahwa petunjuk ini mengatur ulang pengguna dan kata sandi replikasi, jadi Anda harus memasukkannya kembali denganCHANGE MASTER TO...
Mike S.

25
Jika Anda menggunakan flag --master-data saat memanggil mysqldump pada master, perintah CHANGE MASTER TO ditulis ke dalam file dump dan dengan demikian menyimpan langkah menjalankannya setelah mengimpor file dump ke dalam slave.
udog

3
Tidak mengunci master (tidak memerlukan Percona) plusbryan.com/mysql-replikasi-without-downtime Manfaat lain dari ini adalah SQL dump juga dilengkapi dengan baris "CHANGE MASTER" yang diperlukan (dikomentari)
mahemoff

2
Apakah ada cara untuk mengotomatisasi ini?
Metafaniel

26

Dokumentasi untuk ini di situs MySQL sangat ketinggalan zaman dan penuh dengan senjata kaki (seperti interactive_timeout). Mengeluarkan FLUSH TABLES DENGAN READ LOCK sebagai bagian dari ekspor master Anda umumnya hanya masuk akal ketika dikoordinasikan dengan snapshot penyimpanan / sistem file seperti LVM atau zfs.

Jika Anda akan menggunakan mysqldump, Anda harus mengandalkan opsi --master-data untuk menjaga dari kesalahan manusia dan melepaskan kunci pada master secepat mungkin.

Asumsikan masternya adalah 192.168.100.50 dan budaknya adalah 192.168.100.51, masing-masing server memiliki server-id yang berbeda yang dikonfigurasi, master memiliki pencatatan biner dan budak memiliki read-only = 1 di my.cnf

Untuk menjalankan slave agar dapat memulai replikasi tepat setelah mengimpor dump, jalankan perintah CHANGE MASTER tetapi hilangkan nama file log dan posisi:

slaveserver> CHANGE MASTER TO MASTER_HOST='192.168.100.50', MASTER_USER='replica', MASTER_PASSWORD='asdmk3qwdq1';

Keluarkan GRANT pada master untuk digunakan budak:

masterserver> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.100.51' IDENTIFIED BY 'asdmk3qwdq1';

Ekspor master (di layar) menggunakan kompresi dan secara otomatis menangkap koordinat log biner yang benar:

mysqldump --master-data --all-databases --flush-privileges | gzip -1 > replication.sql.gz

Salin file replication.sql.gz ke slave dan kemudian impor dengan zcat ke instance MySQL yang berjalan di slave:

zcat replication.sql.gz | mysql

Mulai replikasi dengan mengeluarkan perintah ke slave:

slaveserver> START SLAVE;

Secara opsional perbarui /root/.my.cnf pada slave untuk menyimpan kata sandi root yang sama dengan master.

Jika Anda menggunakan 5.1+, yang terbaik adalah terlebih dahulu mengatur binlog_format master ke MIXED atau ROW. Berhati-hatilah bahwa acara yang dicatat baris lambat untuk tabel yang tidak memiliki kunci utama. Ini biasanya lebih baik daripada konfigurasi alternatif (dan default) dari binlog_format = statement (on master), karena kecil kemungkinannya untuk menghasilkan data yang salah pada slave.

Jika Anda harus (tetapi mungkin tidak boleh) menyaring replikasi, lakukan dengan opsi slave replikasi-wild-do-table = dbname.% Atau replikasi-wild-ign-table = badDB.% Dan gunakan hanya binlog_format = baris

Proses ini akan menahan kunci global pada master selama durasi perintah mysqldump tetapi tidak akan berdampak pada master.

Jika Anda tergoda untuk menggunakan mysqldump - master-data --all-databases --single-transaction (karena Anda hanya menggunakan tabel InnoDB), Anda mungkin lebih baik menggunakan MySQL Enterprise Backup atau implementasi open source yang disebut xtrabackup (milik Percona)


3
Jika Anda hanya ingin membangun kembali budak yang ada, Anda dapat mengikuti proses di atas, melompati beberapa langkah: Perintah GRANT dan manual CHANGE MASTER
usang

Pertanyaan 1: Di windows, apa yang setara dengan zcat. Pertanyaan 2: Bagaimana mysqldumptarif ini dengan database besar dalam hal kinerja? Adakah cara untuk menggunakan SELECT INTO OUTFILEdan LOAD DATAdengan lancar dalam proses yang Anda sarankan? (Karena mereka umumnya melakukan lebih cepat)
Ifedi Okonkwo

Tidak perlu ke STOP SLAVEsuatu tempat dalam proses?
David V.

16

Kecuali Anda menulis langsung ke slave (Server2), satu-satunya masalah adalah Server2 tidak memiliki pembaruan apa pun yang telah terjadi sejak terputus. Cukup mulai ulang budak dengan "MULAI BUDAK;" harus mendapatkan semuanya kembali dengan kecepatan.


2
Anda dapat memeriksa log sampah dan melihat apakah mereka mencakup periode waktu di mana sistem Anda tidak sinkron. Jika hari Anda hilang, ini mungkin masalah yang lebih besar dan mengharuskan Anda melakukan dump lengkap untuk memulihkan data yang hilang.
nelaaro

7

Saya pikir, memanfaatkan Maatkit membantu untuk Anda! Anda dapat menggunakan mk-table-sync. Silakan lihat tautan ini: http://www.maatkit.org/doc/mk-table-sync.html


Saya pikir dia perlu berhenti menulis sementara menjalankan skrip.
Ztyx

Ini masih bekerja dengan baik. Alat telah diubah namanya dan sekarang disebut pt-table-sync. Sebenarnya, saya telah menemukan bahwa alat pt-slave-restart mereka berfungsi seperti sulap.
mlerley

7

Saya sangat terlambat untuk pertanyaan ini, namun saya memang menghadapi masalah ini dan, setelah banyak mencari, saya menemukan informasi ini dari Bryan Kennedy: http://plusbryan.com/mysql-replikasi-without-downtime

Pada Master, ambil cadangan seperti ini:
mysqldump --skip-lock-tables --single-transaction --flush-logs - hex-blob - master-data = 2 -A> ~ / dump.sql

Sekarang, periksa kepala file dan catat nilai-nilai untuk MASTER_LOG_FILE dan MASTER_LOG_POS. Anda akan membutuhkannya nanti: head dump.sql -n80 | grep "MASTER_LOG"

Salin file "dump.sql" ke Slave dan kembalikan: mysql -u mysql-user -p <~ / dump.sql

Sambungkan ke Slave mysql dan jalankan perintah seperti ini: CHANGE MASTER TO MASTER_HOST = 'master-server-ip', MASTER_USER = 'pengguna-replikasi', MASTER_PASSWORD = 'kata sandi server-budak', MASTER_LOG_FILE = 'nilai dari atas', MASTER_LOG_POS = nilai dari atas; MULAI BUDAK;

Untuk memeriksa kemajuan Slave: SHOW SLAVE STATUS;

Jika semuanya baik-baik saja, Last_Error akan kosong, dan Slave_IO_State akan melaporkan "Menunggu master untuk mengirim acara". Cari Seconds_Behind_Master yang menunjukkan seberapa jauh di belakangnya. YMMV. :)


3
Ini berfungsi, dan jika budak sudah diatur dan hanya gagal sinkron, Anda tidak perlu menjalankan CHANGE MASTER; tentukan saja --master-data=1(atau adil --master-data).
LSerni

5

Inilah yang biasanya saya lakukan ketika seorang budak mysql keluar dari sinkronisasi. Saya telah melihat mk-table-sync tetapi berpikir bagian Risiko itu tampak menakutkan.

Tentang Guru:

SHOW MASTER STATUS

Kolom yang dihasilkan (File, Posisi) akan berguna bagi kita dalam sedikit.

Pada Budak:

STOP SLAVE

Kemudian buang master db dan impor ke slave db.

Kemudian jalankan yang berikut ini:

CHANGE MASTER TO
  MASTER_LOG_FILE='[File]',
  MASTER_LOG_POS=[Position];
START SLAVE;

Di mana [File] dan [Posisi] adalah nilai-nilai yang dikeluarkan dari "SHOW MASTER STATUS" yang dijalankan di atas.

Semoga ini membantu!


5
Ini tampaknya rusak, karena ternyata Anda tidak melakukannya FLUSH TABLES WITH READ LOCK;sebelum Anda SHOW MASTER STATUSdan membuang database master. Saya pikir ini mungkin menghasilkan misalnya kesalahan duplikat kunci pada slave karena Anda secara efektif mengatur status master ke titik waktu sebelum dump diambil, jadi Anda akan memutar ulang sejarah yang sudah termasuk dalam dump. (Jika Anda melakukan hal-hal sesuai dengan urutan yang Anda jelaskan.)
KajMagnus

5

Menindaklanjuti jawaban David ...

Menggunakan SHOW SLAVE STATUS\Gakan memberikan output yang dapat dibaca manusia.


Adakah cara untuk menampilkan output?
Josiah

'pager lebih banyak' Saya pikir akan melakukannya
Ian

3

terkadang Anda hanya perlu memberi tendangan pada budak juga

mencoba

stop slave;    
reset slave;    
start slave;    
show slave status;

cukup sering, hamba, mereka hanya macet :)


... dan monitor Positionpada master yang digunakan show master status;melawan Exec_Master_Log_Pos:pada Slave menggunakan show slave status \G. Budak harus mengejar master. Bekerja untuk saya menggunakan mysql 5.6 sekarang setelah pemadaman jaringan singkat.
Mike S

10
Ini menyesatkan, setelah Anda mengatur ulang budak, salep benar-benar kehilangan pengetahuan tentang di mana master berada.
Qian Chen

2

Berikut ini adalah jawaban lengkap yang diharapkan akan membantu orang lain ...


Saya ingin mengatur replikasi mysql menggunakan master dan slave, dan karena satu-satunya yang saya tahu adalah menggunakan file log untuk menyinkronkan, jika slave offline dan keluar dari sinkronisasi, secara teori seharusnya hanya perlu menyambung kembali untuk masternya dan terus membaca file log dari tempat terakhir, seperti yang disebutkan pengguna malonso.

Jadi di sini adalah hasil tes setelah mengkonfigurasi master dan slave sebagaimana disebutkan oleh: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

Asalkan Anda menggunakan konfigurasi master / slave yang disarankan dan tidak menulis ke slave, ia dan saya berada di tempat yang benar (sejauh menyangkut mysql-server 5.x). Aku bahkan tidak perlu menggunakan "MULAI BUDAK;", itu hanya sampai ke tuannya. Tapi ada 88000 default coba lagi setiap 60 detik jadi saya kira jika Anda kehabisan tenaga, Anda mungkin harus memulai atau memulai kembali slave. Ngomong-ngomong, bagi mereka seperti saya yang ingin tahu apakah memiliki budak akan offline dan mencadangkan lagi memerlukan intervensi manual .. tidak, tidak.

Mungkin poster aslinya mengalami kerusakan pada log-file? Tetapi kemungkinan besar bukan hanya server yang offline selama sehari.


ditarik dari /usr/share/doc/mysql-server-5.1/README.Debian.gz yang mungkin masuk akal juga ke server non debian:

* CATATAN LEBIH LANJUT TENTANG REPLIKASI
===============================
Jika server MySQL bertindak sebagai budak replikasi, Anda seharusnya tidak melakukannya
atur --tmpdir untuk menunjuk ke direktori pada sistem file berbasis memori atau ke
direktori yang dihapus ketika host server restart. Replikasi
slave membutuhkan beberapa file sementara untuk bertahan dari mesin restart begitu
bahwa itu dapat mereplikasi tabel sementara atau LOAD DATA INFILE operasi. Jika
file dalam direktori file sementara hilang ketika server restart,
replikasi gagal.

Anda dapat menggunakan sesuatu seperti sql: tampilkan variabel seperti 'tmpdir'; untuk mencari tahu.


Apakah kedua basis data akan disinkronkan secara otomatis satu sama lain? Misalnya saya Menulis kepada Guru, Apakah Budak akan diperbarui secara otomatis?
TransformBinary

2

Menambahkan ke jawaban populer untuk memasukkan kesalahan ini:

"ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO",

Replikasi dari slave dalam satu tembakan:

Dalam satu jendela terminal:

mysql -h <Master_IP_Address> -uroot -p

Setelah menghubungkan,

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Statusnya muncul sebagai berikut: Perhatikan bahwa nomor posisi bervariasi!

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      98  | your_DB      |                  |
+------------------+----------+--------------+------------------+

Ekspor dump mirip dengan bagaimana dia menggambarkan " menggunakan terminal lain "!

Keluar dan sambungkan ke DB Anda sendiri (yang merupakan budak):

mysql -u root -p

Ketik perintah di bawah ini:

STOP SLAVE;

Impor Dump seperti yang disebutkan (di terminal lain, tentu saja!) Dan ketik perintah di bawah ini:

RESET SLAVE;
CHANGE MASTER TO 
  MASTER_HOST = 'Master_IP_Address', 
  MASTER_USER = 'your_Master_user', // usually the "root" user
  MASTER_PASSWORD = 'Your_MasterDB_Password', 
  MASTER_PORT = 3306, 
  MASTER_LOG_FILE = 'mysql-bin.000001', 
  MASTER_LOG_POS = 98; // In this case

Setelah masuk, setel parameter server_id (biasanya, untuk DB baru / non-replikasi, ini tidak disetel secara default),

set global server_id=4000;

Sekarang, mulai budak itu.

START SLAVE;
SHOW SLAVE STATUS\G;

Outputnya harus sama dengan yang dia jelaskan.

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

Catatan: Setelah direplikasi, master dan slave membagikan kata sandi yang sama!


Apakah kedua basis data akan disinkronkan secara otomatis satu sama lain? Misalnya saya Menulis kepada Guru, Apakah Budak akan diperbarui secara otomatis?
TransformBinary

1

Membangun kembali budak menggunakan LVM

Berikut adalah metode yang kami gunakan untuk membangun kembali budak MySQL menggunakan Linux LVM. Ini menjamin snapshot yang konsisten sambil membutuhkan downtime yang sangat minimal pada master Anda.

Atur innodb max halaman kotor persen ke nol pada server master MySQL. Ini akan memaksa MySQL untuk menulis semua halaman ke disk yang secara signifikan akan mempercepat restart.

set global innodb_max_dirty_pages_pct = 0;

Untuk memantau jumlah halaman kotor, jalankan perintah

mysqladmin ext -i10 | grep dirty

Setelah angka berhenti menurun, Anda telah mencapai titik untuk melanjutkan. Selanjutnya, atur ulang master untuk menghapus log tempat sampah / log relai lama:

RESET MASTER;

Jalankan lvdisplay untuk mendapatkan LV Path

lvdisplay

Output akan terlihat seperti ini

--- Logical volume ---
LV Path                /dev/vg_mysql/lv_data
LV Name                lv_data
VG Name                vg_mysql

Matikan database master dengan perintah

service mysql stop

Selanjutnya, ambil snaphot, mysql_snapshot akan menjadi nama volume logis baru. Jika binlog ditempatkan pada drive OS, maka perlu snapshot juga.

lvcreate --size 10G --snapshot --name mysql_snapshot /dev/vg_mysql/lv_data

Mulai master lagi dengan perintah

service mysql start

Kembalikan pengaturan halaman kotor ke default

set global innodb_max_dirty_pages_pct = 75;

Jalankan lvdisplay lagi untuk memastikan snapshot ada dan terlihat

lvdisplay

Keluaran:

--- Logical volume ---
LV Path                /dev/vg_mysql/mysql_snapshot
LV Name                mysql_snapshot
VG Name                vg_mysql

Pasang snapshot

mkdir /mnt/mysql_snapshot
mount /dev/vg_mysql/mysql_snapshot /mnt/mysql_snapshot

Jika Anda memiliki slave MySQL yang ada, Anda harus menghentikannya

service mysql stop

Selanjutnya Anda perlu menghapus folder data MySQL

cd /var/lib/mysql
rm -fr *

Kembali ke master. Sekarang rsync snapshot ke slave MySQL

rsync --progress -harz /mnt/mysql_snapshot/ targethostname:/var/lib/mysql/

Setelah rsync selesai, Anda dapat melepas dan menghapus snapshot

umount /mnt/mysql_snapshot
lvremove -f /dev/vg_mysql/mysql_snapshot

Buat pengguna replikasi pada master jika pengguna replikasi lama tidak ada atau kata sandi tidak diketahui

GRANT REPLICATION SLAVE on *.* to 'replication'@'[SLAVE IP]' identified by 'YourPass';

Verifikasi bahwa file data / var / lib / mysql dimiliki oleh pengguna mysql, jika demikian Anda dapat menghilangkan perintah berikut:

chown -R mysql:mysql /var/lib/mysql

Selanjutnya, rekam posisi binlog

ls -laF | grep mysql-bin

Anda akan melihat sesuatu seperti

..
-rw-rw----     1 mysql mysql  1073750329 Aug 28 03:33 mysql-bin.000017
-rw-rw----     1 mysql mysql  1073741932 Aug 28 08:32 mysql-bin.000018
-rw-rw----     1 mysql mysql   963333441 Aug 28 15:37 mysql-bin.000019
-rw-rw----     1 mysql mysql    65657162 Aug 28 16:44 mysql-bin.000020

Di sini file master log adalah nomor file tertinggi secara berurutan dan posisi log bin adalah ukuran file. Catat nilai-nilai ini:

master_log_file=mysql-bin.000020
master_log_post=65657162

Selanjutnya jalankan slave MySQL

service mysql start

Jalankan perintah perubahan master pada slave dengan menjalankan yang berikut:

CHANGE MASTER TO 
master_host="10.0.0.12", 
master_user="replication", 
master_password="YourPass", 
master_log_file="mysql-bin.000020", 
master_log_pos=65657162; 

Akhirnya mulai budak

SLAVE START;

Periksa status budak:

SHOW SLAVE STATUS;

Pastikan Slave IO berjalan dan tidak ada kesalahan koneksi. Semoga berhasil!

BR, Juha Vehnia

Saya baru-baru ini menulis ini di blog saya yang ditemukan di sini ... Ada beberapa detail lagi di sana tetapi ceritanya sama.

http://www.juhavehnia.com/2015/05/rebuilding-mysql-slave-using-linux-lvm.html


0

Saya membuat repo GitHub dengan skrip untuk menyelesaikan masalah ini dengan cepat. Ubah saja beberapa variabel dan jalankan (Pertama, skrip membuat cadangan dari database Anda).

Saya harap ini membantu Anda (dan orang lain juga).

Cara Mengatur Ulang (Sinkronisasi Ulang) Replikasi MySQL Master-Slave


Saya melihat script selalu mengatur posisi master log ke 1 dan nama file master log. Saya tidak cukup tahu untuk memastikan apakah saya harus khawatir dengan ini atau tidak. Bisakah Anda jelaskan? Saya memiliki posisi lebih dari 1.000.000 saat ini. Apakah ini berarti akan mencoba memutar ulang permintaan 1 mil sebelum meningkatkan kecepatan? Apakah tidak ada peluang korupsi dalam memainkan kueri terhadap data yang ada? Saya bertanya-tanya mengapa tidak dalam skrip ketika melakukan dump mysql menggunakan opsi --master-data = 2 dan kemudian tarik file dan pos keluar dari dump untuk mengaturnya?
Josiah

0

Kami menggunakan teknik replikasi master-master dari MySQL dan jika satu server MySQL mengatakan 1 dihapus dari jaringan, koneksi itu akan terhubung kembali setelah koneksi dipulihkan dan semua catatan yang dilakukan di dalam server 2 yang berada di jaringan ditransfer ke server 1 yang telah kehilangan koneksi setelah pemulihan. Slave thread di MySQL mencoba untuk terhubung ke masternya setelah setiap 60 detik secara default. Properti ini dapat diubah karena MySQL memiliki flag "master_connect_retry = 5" di mana 5 berada dalam detik. Ini berarti bahwa kami ingin mencoba lagi setelah setiap 5 detik.

Tetapi Anda perlu memastikan bahwa server yang kehilangan koneksi menunjukkan tidak membuat komit dalam database saat Anda mendapatkan duplikat Kunci kesalahan Kode kesalahan: 1062


0

Master :

mysqldump -u root -p --all-databases --master-data | gzip > /tmp/dump.sql.gz  

scp master:/tmp/dump.sql.gz slave:/tmp/ Pindahkan file dump ke server slave

Budak:

STOP SLAVE;

zcat /tmp/dump.sql.gz | mysql -u root -p

START SLAVE;
SHOW SLAVE STATUS;  

CATATAN :
Pada master Anda dapat menjalankan SET GLOBAL expire_logs_days = 3untuk menyimpan binlog selama 3 hari jika terjadi masalah slave.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.