linux下mysql單向/雙向主從同步(轉(zhuǎn))
2010年04月09日 星期五 11:40
本文轉(zhuǎn)自:http://yushan./blog/409603
最近因項(xiàng)目要求,在linux服務(wù)器上設(shè)置mysql的數(shù)據(jù)同步,幸好網(wǎng)絡(luò)資源多啊,google一下全有了,不過(guò)實(shí)際操作起來(lái),就麻煩了,遇到很多問(wèn)題,不過(guò)多google一下也解決了, 同時(shí)學(xué)習(xí)了很多相關(guān)方面的知識(shí),現(xiàn)將總結(jié)于此,以備后用,希望對(duì)有此需要的JE們有所幫助; 一、準(zhǔn)備環(huán)境 自己做練習(xí)硬件資源少,只能在虛擬器上操作了哈哈! linux 版本:Red Hat Enterprise Linux Server release 5.1 mysql 版本:MySQL-server-community-5.0.67-0.rhel5.i386.rpm MySQL-client-community-5.0.67-0.rhel5.i386.rpm (PS:mysql的同步機(jī)制是基于二進(jìn)制日志binlog,不同的mysql版本會(huì)導(dǎo)致其格式的不同,從而導(dǎo)致不能實(shí)現(xiàn)數(shù)據(jù)同步,因此最好的搭配組合是Master的MySQL版本和Slave的 版本相同或者Slave的版本高于Master的版本,因?yàn)閙ysql是向下兼容的,為此Master的版本不能高于Slave版本,否則有可能不能實(shí)現(xiàn)功能;如果要實(shí)現(xiàn)雙向同步,最好mysql是同 一版本) 虛擬機(jī)版本:VMware6.0 在虛擬機(jī)上安裝兩個(gè)linux系統(tǒng),并分別安裝上mysql(mysql安裝在俺博客的mysql安裝有詳細(xì)說(shuō)明) mysql默認(rèn)安裝的文件分別為: /var/lib/mysql/ (數(shù)據(jù)庫(kù)目錄,其所創(chuàng)建的數(shù)據(jù)庫(kù)文件都在該目錄下) /usr/share/mysql (mysql相關(guān)配置文件) /usr/bin (mysql相關(guān)命令,如mysql mysqladmin等) 為了區(qū)分系統(tǒng),給系統(tǒng)命名一下,便于后面的說(shuō)名: LinuxA 系統(tǒng): Ip:192.168.59.123 (Master) LinuxB 系統(tǒng): Ip:192.168.59.124 (Slave) 關(guān)閉LinuxA 和 LinuxB 的防火墻 #service iptables stop (保證系統(tǒng)互相可以ping的通) 二、設(shè)置單向mysql數(shù)據(jù)同步(LinuxA(Master)->LinuxB(Slave)) 1、 LinuxA 為 master LinuxB 為 slave (同步LinuxA 上mysql上指定的test數(shù)據(jù)庫(kù)中的數(shù)據(jù)); 由于剛安裝的mysql,因此分別在LinuxA 和 LinuxB 的 mysql 上創(chuàng)建相同的數(shù)據(jù)庫(kù)如 test(表有 stu , class,teacher),保證兩個(gè)mysql上的數(shù)據(jù)庫(kù)名一致其表名及表的 結(jié)構(gòu)一致,若有一個(gè)不同,將導(dǎo)致無(wú)法實(shí)現(xiàn)同步; (PS: 要使數(shù)據(jù)同步,必須保證數(shù)據(jù)庫(kù)名一致其表名及表的結(jié)構(gòu)一致) 2、在作為master(即LinuxA)的mysql上建立一個(gè)賬戶專門用于slave(即LinuxB)來(lái)進(jìn)行數(shù)據(jù)同步 # mysql (默認(rèn)用戶,如設(shè)置了root密碼,使用mysql -u root -p 登入mysql) mysql>grant file on *.* to backa@'192.168.59.124' identified by 'backa' mysql>flush privileges; (PS:此backa賬戶只能通過(guò)ip為192.168.59.124的訪問(wèn)) 在LinuxB上測(cè)試賬戶backa是否可以訪問(wèn)LinxuA上的mysql: #mysql -u backa -p -h 192.168.59.123(輸入密碼backa,可以訪問(wèn)說(shuō)明設(shè)置正確) 3、修改 my.cnf 文件 由于剛安裝的mysql ,在/etc目錄下可能無(wú)my.cnf文件,從/user/share/mysql目錄中拷貝my-medium.cnf 到/etc并修改成my.cnf (LinuxA 和LinuxB 上一樣) 如 # cp /user/share/mysql/my-medium.cnf /etc/my.cnf 修改在LinuxA(Master)上的/etc/my.cnf log-bin=mysql-bin (日志文件,默認(rèn)存在/var/lib/mysql下日志文件以mysql-bin為開頭) #log_bin= /var/log/mysql/mysql-bin.log(也可以自己指定,在此用# 表示注釋掉了) binlog-do-db =test(需要同步的數(shù)據(jù)庫(kù)名,如需同步多個(gè)數(shù)據(jù)庫(kù),可以另起行如binlog-do-db =test1 ) server-id= 1 (mysql標(biāo)示) 修改完后保存退出,并重啟mysql 如#service mysql restart (重啟正常,表示配置沒(méi)錯(cuò)誤) 修改在LinxuB(Slave)上的/etc/my.cnf server-id= 2 (mysql標(biāo)示,唯一否則啟動(dòng)會(huì)出錯(cuò)誤) master-host=192.168.59.123 (同步Master的ip地址) master-user=backa (同步所需的賬號(hào)) master-password=backa (同步賬號(hào)的密碼) master-port=3306 (LinuxA 中mysql的訪問(wèn)端口) replicate-do-db=test (所需同步的數(shù)據(jù)庫(kù)名,如果是同步多個(gè)數(shù)據(jù)庫(kù),可以另起一行如 replicate-do-db=test1) #replicate-do-table=test.stu (如果只需同步test數(shù)據(jù)庫(kù)中的stu表) #replicate-do-table=test.teacher(如果只需同步test數(shù)據(jù)庫(kù)中的stu表) master-connect-retry=60 (主服務(wù)器(Master)宕機(jī)或連接丟失的情況下,從服務(wù)器(slave)線程重新嘗試連接主服務(wù)器之前睡眠的秒數(shù)) 修改完后保存退出,并重啟mysql 如#service mysql restart (重啟正常,表示配置沒(méi)錯(cuò)誤) 4.啟動(dòng)同步 進(jìn)到LinuxA(Master)的mysql上: mysql>show master status\G (查看master當(dāng)前狀態(tài)) 運(yùn)行完以上命令顯示結(jié)果如下: File: mysql-bin.000001 (當(dāng)前binlog日志文件) Position: 98 (但前binlog日志文件位置) Binlog_Do_DB: test (同步數(shù)據(jù)庫(kù)) Binlog_Ignore_DB: (不需同步的數(shù)據(jù),當(dāng)前為設(shè)置) ------------------------------------------------------------- 進(jìn)到LinuxB(Slave)的mysql上: mysql>show slave status\G (查看slave同步狀態(tài)) 運(yùn)行完以上命令顯示結(jié)果如下: Slave_IO_State: Waiting for master to send event (slave 的io線程,獲取master的binlog的日志內(nèi)容,該為其目前的狀態(tài)) Master_Host: 192.168.59.123 (所需同步Master的ip地址) Master_User: backa(同步所需的賬號(hào)) Master_Port: 3306(同步所需的mysql端口號(hào)) Connect_Retry: 60 Master_Log_File: mysql-bin.000001 (master中的binlong的日志文件,如與master的日志文件名不同則同步失效) Read_Master_Log_Pos: 98 (master中的binlong的日志文件的位置,即mysql-bin.000001文件中的第98位置開始同步,若與master上的位置不同則同步失效) Relay_Log_File: localhost-relay-bin.000001 Relay_Log_Pos: 235 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes (Slave的io線程是否運(yùn)行) Slave_SQL_Running: Yes (slave的sql線程是否運(yùn)行,需要io線程和sql線程同為yes才有效) Replicate_Do_DB: test Replicate_Ignore_DB: 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: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 如果Slave_IO_State:不為 Waiting for master to send event 表示未現(xiàn)實(shí)同步 原因可能很多先列舉自己遇到: 1、 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos:98 日志文件和位置與LinuxA(Master)的當(dāng)前狀態(tài)不一致 解決方式:(在LinuxB的mysql操作) mysql>slave stop;(修改前先關(guān)閉slave) mysql>change master to >master_log_file='mysql-bin.000001' (ps:與LinuxA中的master的日志文件名相同) >master_log_pso=98 (ps:與LinuxA中的master的日志文件當(dāng)前位置相同) >master_user='backa' (如果同步的賬戶不一致,也可在此修改) >master_password='backa' (如果同步的賬戶密碼不一致,也可在此修改) >; (PS:如果重新修改/etc/my.cnf 中相關(guān)slave的配置信息,重新啟動(dòng)查看 slave的狀態(tài)還是顯示未修改的數(shù)據(jù),應(yīng)為第一次是讀取my.cnf,之后就會(huì)在/var/lib/mysql/下 生成一個(gè)master.info 的文件,因此第二次就不會(huì)讀取my.cnf的內(nèi)容,而是讀取master.info中的內(nèi)容,為此要想使重新修改的my.cnf生效的話,刪除master.info文件,重起mysql 即可) mysql>slave start;(重新啟動(dòng)slave) mysql>show slave status\G (查看slave狀態(tài)) 如果顯示的 Slave_IO_State: Waiting for master to send event Slave_IO_Running: Yes Slave_SQL_Running: Yes 祝賀成功實(shí)現(xiàn)單向同步即 linuxA --> linuxB 的同步; 在LinuxA的mysql上對(duì)test的 insert , delete ,update及對(duì)表結(jié)構(gòu)的修改等操作 都會(huì)同步到 LinuxB的mysql上的test數(shù)據(jù)庫(kù)上 (ps:如果在master上執(zhí)行如 insert into to stu (uuid(),'yushan') 則同步到 slave上 ,id不同,因?yàn)槠鋓d是用uuid生成的,所以會(huì)不一致,之后對(duì)這條數(shù)據(jù)的 delete 和 update則不會(huì)實(shí)現(xiàn)同步) 三、雙向同步(LinuxA<--->LinuxB) 雙向同步最好使用的mysql版本要一致,保證二進(jìn)制日志binlog的格式相同;雙向同步即對(duì)任何一方mysql的insert,update,delete,alter等操作都會(huì)影響到另一方mysql中 的數(shù)據(jù);由于前面已成功設(shè)置單向同步,在此基礎(chǔ)上,把LinuxB(Slave)的配置 添加到 LinuxA(Master) 上,把LinuxA(Master)的配置添加到LinuxB(Slave)上,然后啟動(dòng)設(shè) 置同步的binlong文件及當(dāng)前位置即可,具體操作如下: 1、 LinuxA 在原有Master的基礎(chǔ)上增加Slave (同步LinuxB 上mysql上指定的test數(shù)據(jù)庫(kù)中的數(shù)據(jù)) LinuxB 在原有Slave的基礎(chǔ)上增加Mmaster(同步LinuxA 上mysql上指定的test數(shù)據(jù)庫(kù)中的數(shù)據(jù)); 2、在作為master(即LinuxB)的mysql上建立一個(gè)賬戶專門用于slave(即LinuxA)來(lái)進(jìn)行數(shù)據(jù)同步 # mysql (默認(rèn)用戶,如設(shè)置了root密碼,使用mysql -u root -p 登入mysql) mysql>grant file on *.* to backb@'192.168.59.123' identified by 'backb' mysql>flush privileges; (PS:此backb賬戶只能通過(guò)ip為192.168.59.123的訪問(wèn)) 在LinuxA上測(cè)試賬戶backb是否可以訪問(wèn)LinxuB上的mysql: #mysql -u backb -p -h 192.168.59.124(輸入密碼backb,可以訪問(wèn)說(shuō)明設(shè)置正確) 3、修改 my.cnf 文件 在LinuxA 上的/etc/my.cnf 文件上添加Slave的配置 #server-id= 2 (mysql標(biāo)示,唯一否則啟動(dòng)會(huì)出錯(cuò)誤,因?yàn)樵纫延袠?biāo)示為1,在此就可以注釋掉,一個(gè)mysql只需一個(gè)標(biāo)示即可) master-host=192.168.59.124 (同步LinuxB (Master)的ip地址) master-user=backb (同步所需的賬號(hào)) master-password=backb (同步賬號(hào)的密碼) master-port=3306 (LinuxB 中mysql的訪問(wèn)端口) replicate-do-db=test (所需同步的數(shù)據(jù)庫(kù)名,如果是同步多個(gè)數(shù)據(jù)庫(kù),可以另起一行如 replicate-do-db=test1) #replicate-do-table=test.stu (如果只需同步test數(shù)據(jù)庫(kù)中的stu表) #replicate-do-table=test.teacher(如果只需同步test數(shù)據(jù)庫(kù)中的stu表) master-connect-retry=60 (主服務(wù)器(Master)宕機(jī)或連接丟失的情況下,從服務(wù)器(slave)線程重新嘗試連接主服務(wù)器之前睡眠的秒數(shù)) 修改完后保存退出,并重啟mysql 如#service mysql restart (重啟正常,表示配置沒(méi)錯(cuò)誤) 在LinxuB上的/etc/my.cnf文件上添加Master的配置 #server-id= 1 (mysql標(biāo)示,唯一否則啟動(dòng)會(huì)出錯(cuò)誤,因?yàn)樵纫延袠?biāo)示為2,在此就可以注釋掉,一個(gè)mysql只需一個(gè)標(biāo)示即可) log-bin=mysql-bin (日志文件,默認(rèn)存在/var/lib/mysql下日志文件以mysql-bin為開頭) #log_bin= /var/log/mysql/mysql-bin.log(也可以自己指定,在此用# 表示注釋掉了) binlog-do-db =test(需要同步的數(shù)據(jù)庫(kù)名,如需同步多個(gè)數(shù)據(jù)庫(kù),可以另起行如binlog-do-db =test1 ) 修改完后保存退出,并重啟mysql 如#service mysql restart (重啟正常,表示配置沒(méi)錯(cuò)誤) 4.啟動(dòng)同步 進(jìn)到LinuxB(Master)的mysql上: mysql>show master status\G (查看master當(dāng)前狀態(tài)) 運(yùn)行完以上命令顯示結(jié)果如下: File: mysql-bin.000003 (當(dāng)前binlog日志文件) Position: 231 (但前binlog日志文件位置) Binlog_Do_DB: test (同步數(shù)據(jù)庫(kù)) Binlog_Ignore_DB: (不需同步的數(shù)據(jù),當(dāng)前為設(shè)置) ------------------------------------------------------------- 進(jìn)到LinuxA(Slave)的mysql上: mysql>show slave status\G (查看slave同步狀態(tài)) 運(yùn)行完以上命令顯示結(jié)果如下: Slave_IO_State: Waiting for master to send event (slave 的io線程,獲取master的binlog的日志內(nèi)容,該為其目前的狀態(tài)) Master_Host: 192.168.59.124 (所需同步Master的ip地址) Master_User: backb(同步所需的賬號(hào)) Master_Port: 3306(同步所需的mysql端口號(hào)) Connect_Retry: 60 Master_Log_File: mysql-bin.000003 (master中的binlong的日志文件,如與master的日志文件名不同則同步失效) Read_Master_Log_Pos: 98 (master中的binlong的日志文件的位置,即mysql-bin.000001文件中的第98位置開始同步,若與master上的位置不同則同步失效) Relay_Log_File: localhost-relay-bin.000001 Relay_Log_Pos: 231 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes (Slave的io線程是否運(yùn)行) Slave_SQL_Running: Yes (slave的sql線程是否運(yùn)行,需要io線程和sql線程同為yes才有效) Replicate_Do_DB: test Replicate_Ignore_DB: 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: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 以上顯示為正確同步 如果顯示的一下數(shù)據(jù)不是 Slave_IO_State: Waiting for master to send event Slave_IO_Running: Yes Slave_SQL_Running: Yes 若與以上的三個(gè)狀態(tài)表示不同,則未實(shí)現(xiàn)同步;可以采用以上單向同步中的 change master 進(jìn)行重新設(shè)置(ps:防火墻需關(guān)閉) 以上都能正確配置完且顯示的狀態(tài)一致,那么祝賀您成功實(shí)現(xiàn)雙向同步即 linuxA <--> linuxB 的同步; |
|