實現MySQL的Replication
在MySQL 3.23.15版本之後,MySQL提供了數據庫複製的功能,可以實現兩個數據庫實時同步,增強了MySQL數據庫的穩定性,而且可以在企業級應用的數據庫層實現Cluster…
條件:
1 Redhat 9
2 Mysql 4.0.20
3 兩臺機器ip爲192.168.37.188 192.168.37.189,分別安裝mysql
目標:
1.數據庫的雙向複製
2.在master與slave網絡不通但過後再次恢復正常,master上的數據在slave上也可以得到更新,反之亦然.
本文主要分爲以下幾個部分:
第一部分 安裝MySQL
第二部分 配置/etc/my.cnf(要查看/etc/init.d/mysql腳本判斷是/etc/my.cnf)
第三部分 給權限
第四部分 查看工作狀態,測試並驗證是否可以真正同步
第五部分 Troubleshooting
第一部分 安裝MySQL
1.得到MySQL的RPM安裝包,列表如下:
MySQL-server-4.0.20-0
MySQL-client-4.0.20-0
MySQL-shared-4.0.20-0
2.使用root身份安裝
#rpm –ivh MySQL-*-4.0.20-0
會有進度條提示安裝進度;
安裝完畢後,MySQL的數據庫配置文件在/var/lib/mysql/中,而默認的幾個配置文件在/usr/share/mysql/中,有以下幾個文件:
My-hug.cnf
My-large.cnf
My-medium.cnf
My-small.cnf
顧名思義,是爲了針對不同的應用來設計的,主要是對數據庫的一些參數作了優化,具體優化請見my.cnf內的[mysqld]中語句.
第二部分 配置/etc/my.cnf
通過RPM包安裝的mysql在/etc/init.d下會生成一個mysql的shell腳本文件,而在Redhat下我們一般用service mysql start的時候,其實就是傳給該腳本start參數並執行,那麼需要查看該文件,究竟是調用的哪個配置文件,在其中我們找到這麼一行…
conf=/etc/my.cnf
那麼可以判斷配置文件是/etc/my.cnf
假設我們的是中型應用:
#copy /usr/share/mysql/my-medium.cnf /etc/my.cnf
拷貝到/etc/my.cnf之後,就可以對其進行配置,MySQL在每次啓動的時候讀取該配置文件並按其配置方式啓動,因爲數據庫需要雙向複製,則每臺機器都需要同時是master和slave,
1、首先在192.168.37.188的/etc/my.cnf下在[mysqld]中修改,以下配置該機爲master:
server-id=1
log-bin
binlog-do-db=backup
解釋:
1)server-id=1表示是本機的序號爲1,一般來講就是master的意思.
2)log-bin表示打開binlog,打開該選項纔可以通過I/O寫到Slave的relay-log,也是可以進行replication的前提;
3)binlog-do-db=backup 表示需要備份的數據庫是backup這個數據庫,
4)如果需要備份多個數據庫,那麼應該寫多行,如下所示:
binlog-do-db=backup1
binlog-do-db=backup2
binlog-do-db=backup3
2、其次仍然在該區域修改,以下配置爲該機爲slave
master-host=192.168.37.189
master-user=backup
master-password=1234
master-port=3306
3、然後配置192.168.37.189上的my.cnf
在/etc/my.cnf下在[mysqld]中修改:
server-id=2
master-host=192.168.37.188
master-user=username
master-password=password
master-port=3306 #主服務器端口
master-connect-retry=60 #同步時間間隔爲60秒
replicate-do-db=backup
log-bin
binlog-do-db=backup
解釋:
1)server-id=2表示本機器的序號;
2)master-host=192.168.37.188 表示本機做slave時的master爲192.168.37.188;
3)master-user=username 這裏表示master上開放的一個有權限的用戶,使其可以從slave連接到master並進行復制;
4)master-password=password 表示授權用戶的密碼;
5)master-port=3306 master上MySQL服務Listen3306端口;
6)master-connect-retry=60 同步間隔時間;
7)replicate-do-db=backup 表示同步backup數據庫;
8)log-bin 打開logbin選項以能寫到slave的 I/O線程;
9)binlog-do-db=backup 表示別的機器可以同步本機的backup數據庫.
最後重新啓動192.168.37.188和192.168.37.189兩臺機器的mysql.
第三部分 分配權限
在192.168.37.188上使用mysql登陸,操作如下:
(1)Mysql>;grant all privileges on backup.* to ‘backup’@’192.168.37.189’ identified by ‘1234’;
給使用192.168.37.189連接的backup用戶以replication的權限…
(2)Mysql>;flush privileges;
刷新權限設置;
在slave上使用mysql登陸
(1)Mysql>; grant all privileges on backup.* to ‘backup’@’192.168.37.188’ identified by ‘1234’;
(2)Mysql>;flush privileges;
刷新權限設置;
說明:上面的all privileges在4.0版上應該爲replication slave,也就是grant replication slave on ........在3.23上是file,也就是grant file on ........但是我怕有別的麻煩,乾脆權限全給好啦.
在進行如上設置之後,可以看出在192.168.37.189設定好並重啓mysql以後,mysql會在數據目錄(/var/lib/mysql)下生成一個master.info文件和relay-log.info,relay-log.index文件.如果要更改master服務器,則要刪除掉這個文件,(即在更改了/etc/my.cnf中master相關信息)在my.cnf文件中重新配置,重新啓動mysql,更改纔會生效.
第四部分 查看工作狀態
1)在master上新建一個backup數據庫
Mysql>;create database backup;
2)新建一個表:
Mysql>;create table jintao (id int(10),name varchar(20));
3)查看192.168.37.189上的mysql;
Mysql>;use backup;
Mysql>;show tables;
Mysql>;desc jintao;
Mysql>;select * from jintao;
如果看到與master相同的信息,則可以證明是成功的.
同時可以改動已有的數據庫來判斷是否已經達到同步,都差不多的…只要證明數據庫同步就可以啦…這時不分master/slave,在master上改動slave上會更新,而在slave上改動,master上也可以得到更新.
第五部分 troubleshooting
在master上,其實不需要做什麼設置,只需要打開log-bin,寫上server-id=1,寫上要備份的數據庫,則自動是master模式,於是問題主要集中在slave上.那麼slave上是如何工作的呢?
Slave上Mysql的Replication工作有兩個線程,I/O thread和SQL thread,I/O 的作用是從master 3306端口上把它的binlog取過來(master在被修改了任何內容之後,就會把修改了什麼寫到自己的binlog等待slave更新),然後寫到本地的relay-log,而SQL thread則是去讀本地的relay-log,再把它轉換成本Mysql所能理解的東西,於是同步就這樣一步一步的完成.決定I/O thread的是/var/lib/mysql/master.info,而決定SQL thread的是/var/lib/mysql/relay-log.info.
請注意,因爲上邊提到了binlog裏的內容是改了什麼東東,而不是改了以後是什麼東東,所以在進行同步之前必須保證兩個數據庫是完全相同的,不然可能出錯.打個比方來說.A機上有一個表裏的元組爲2,而操作是減一,則binlog只會記錄減一這個操作,如果B機上沒有,那麼則無法得到同步,因爲B機沒有這個字段,就不知道減一是什麼操作.
對於故障診斷,我的方法是都在slave(master/slave是相對的)的mysql(指客戶端)裏完成.
方法一:show slave status;
正確情況下應該同如下類似:
mysql>; show slave status;
+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+------------+------------+--------------+---------------------+-----------------+
| Master_Host | Master_User | Master_Port | Connect_retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_do_db | Replicate_ignore_db | Last_errno | Last_error | Skip_counter | Exec_master_log_pos | Relay_log_space |
+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+------------+------------+--------------+---------------------+-----------------+
| 192.168.37.188 | backup | 3306 | 5 | Server-bin.020 | 79 | Jintao-relay-bin.001 | 45 | Server-bin.020 | Yes | Yes | backup | | 0 | | 0 | 79 | 45 |
+----------------+-------------+-------------+---------------+-----------------+---------------------+----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+------------+------------+--------------+---------------------+-----------------+
1 row in set (0.00 sec)
上邊的Jintao和Server是兩臺機器的主機名,所以真實情況應該有所分別,注意其中的YES|YES,這個是本地I/O線程及SQL線程的工作狀態,要確保都爲YES,如果不是YES,請檢查mysql是否正常運行.
方法二:show processlist;
如果正確,則應該如下所示:
Mysql>;show processlist;
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
| 4 | system user | | NULL | Connect | 398 | Waiting for master to send event | NULL |
| 5 | system user | | NULL | Connect | 398 | Has read all relay log; waiting for the I/O slave thread to update it | NULL |
| 6 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)
注意同標記過的字符類似,則是正確的,錯誤情況下應該是這個樣子:
mysql>; show processlist;
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
| 4 | system user | | NULL | Connect | 454 | Reconnecting after a failed master event read | NULL |
| 5 | system user | | NULL | Connect | 454 | Has read all relay log; waiting for the I/O slave thread to update it | NULL |
| 7 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)
當然如果這裏的Reconnecting只是錯誤的一種,有可能是connecting,則表示正在連接,那麼請檢查:
1 master上的mysql daemon是否正常運行
2 master與slave的網絡連接是否正常
3 my.cnf是否配置正確
4 在修改配置後是否刪除過master.info?(刪掉以後會自動再生成一個,別擔心刪掉),因爲如果不刪掉的話,那麼則還是使用原來的配置
5 修改配置後有沒有重新啓動mysql daemon,重新啓動過程後必須證實mysql已經正常啓動
6 master上給slave及slave給master上分配的replication用戶權限是否正確,master的主機名和dns設置
7 當前狀況兩臺數據庫是否完全相同.
方法三:show master status;
mysql>; show master status;
+----------------+----------+--------------+------------------+
| File | Position | Binlog_do_db | Binlog_ignore_db |
+----------------+----------+--------------+------------------+
| Server-bin.021 | 79 | backup | |
+----------------+----------+--------------+------------------+
1 row in set (0.00 sec)
注意上邊的這條,position不能爲0,如果爲0則表示有問題,請檢查/etc/my.cnf中的server-id及是否打開log-bin
mysql>; show processlist;
+----+--------+---------------------+------+-------------+------+----------------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+--------+---------------------+------+-------------+------+----------------------------------------------------------------+------------------+
| 1 | backup | 192.168.37.189:1067 | NULL | Binlog Dump | 284 | Has sent all binlog to slave; waiting for binlog to be updated | NULL |
| 3 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+----+--------+---------------------+------+-------------+------+----------------------------------------------------------------+------------------+
2 rows in set (0.00 sec)
如果master上不是這樣,那麼就應該是master的配置有問題啦.
方法四 查看錯誤日誌
在/var/lib/mysql下有個hostname.err文件,所有的錯誤都在其中被記錄,如下所示:
041210 12:54:51 mysqld started
041210 12:54:51 Warning: Asked for 196608 thread stack, but got 126976
InnoDB: The first specified data file ./ibdata1 did not exist:
InnoDB: a new database to be created!
041210 12:54:51 InnoDB: Setting file ./ibdata1 size to 10 MB
InnoDB: Database physically writes the file full: wait...
041210 12:54:54 InnoDB: Log file ./ib_logfile0 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile0 size to 5 MB
InnoDB: Database physically writes the file full: wait...
041210 12:54:55 InnoDB: Log file ./ib_logfile1 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile1 size to 5 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
041210 12:54:58 InnoDB: Started
/usr/sbin/mysqld: ready for connections.
Version: '4.0.20-standard-log' socket: '/var/lib/mysql/mysql.sock' port: 3306
041210 12:54:58 Slave SQL thread initialized, starting replication in log 'FIRST' at position 0, relay log './Jintao-relay-bin.001' position: 4
041210 12:54:58 Slave I/O thread: connected to master '[email protected]:3306', replication started in log 'FIRST' at position 4
以上日誌沒有錯誤,只是一個例子,但是假如數據庫同步失敗出現錯誤時,兩個數據庫不同,binlog中的記錄將不能被slave所理解,所以會出錯./var/lib/mysql/下會不停的生成hostname-bin.001及hostname-relay-bin.001之類的文件,這樣每次在重新啓動master/slave的時候都會用一個新的relay-log來取代原來的.所以該目錄會不停的生成類似文件,而hostname-relay-bin.index來控制哪個是當前所使用的relay-log.整體的同步過程上面第五部分開頭已經說清楚了,這裏不再詳述.
Btw:假如不知道本機的hostname,可以在終端下輸入
#hostname
Mysql replication的文檔
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
sql語法、關係建模
死瘦宅
2019-02-24 22:35:22
MySQL 事務、函數、觸發器、數據庫備份、權限管理
死瘦宅
2019-02-24 22:35:12
如何釋放已刪除的InnoDB磁盤空間
lvrenX
2019-02-24 13:04:33
MySQL数据库集群-PXC方案
wy53780
2020-04-23 13:55:07
《從0到1學習Flink》—— Flink 讀取 Kafka 數據批量寫入到 MySQL
zhisheng
2019-02-24 21:04:11
SpringBoot 填坑 (一) | CentOS7.4 環境下,表時間字段默認值設置失效
一個優秀的廢人
2019-02-24 15:33:55
mysql-存儲過程
雙子城
2019-02-24 13:43:57
jmeter學習指南之操作 mysql 數據庫
小強測試
2019-02-24 13:34:06
20190222全天的實驗
清歡難尋
2019-02-24 13:17:21
數據庫監控:zabbix(fpmmm)
AMGYM
2019-02-24 13:05:14
數據庫監控:nagios(check_mysql_health)
AMGYM
2019-02-24 13:05:14
MongoDB索引優化詳解
geekpy
2019-02-24 14:20:06
Sql server中一些Select檢索高級用法
wbzjacky
2019-02-24 13:12:37
將frm,myi,myd文件打包成sql文件
jason1982
2019-02-24 12:57:22