程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> 關於MYSQL數據庫 >> 利用MySQL的master and slave功能實現實時數據同步

利用MySQL的master and slave功能實現實時數據同步

編輯:關於MYSQL數據庫

實現MySQL的Replication
         在MySQL 3.23.15版本之後,MySQL提供了數據庫復制的功能,可以實現兩個數據庫實時同步,增強了MySQL數據庫的穩定性條件:
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數據庫.


4、最後重新啟動192.168.37.188和192.168.37.189兩台機器的MySQL.


第三部分   分配權限
1、在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;
刷新權限設置; 2、在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

--------------------------------------------------------------------------------------------------------------------------

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved