[mysql終極優化]之主從復制與讀寫分離詳細設置教程


讀寫分離與主從復制是提升mysql性能的重要及必要手段,大中型管理系統或網站必用之。
一、什么是讀寫分離與主從復制
先看圖
(圖1  圖片來源於網絡)
 
      如上圖所示,當web server1/2/3要寫入數據時,則向mysql db Master(主服務器)發出寫入請求(即寫入到master),如果要進入讀操作時,則只向從服務器 mysql DB Slave1或2或3發出讀取請求。如此將原本讀寫在同一台服務器的工作量分攤到了一台負責寫入,N台負責讀取(大部分的網站都是讀取請求遠大於寫入請求),從而從一定程度時實現了負載均衡(如果有N台從服務器,則由主從代理系統自動分配某個具體請求從哪一個從服務器讀取)。
      讀寫分離是靠主從復制來實現的。即當一個數據寫入到主服務器后,主服務器會將寫入信息寫入到binlog(二進制日志)里,同時同步(或異步或半同步)到從服務器里。從服務器根據主服務器傳來的binlog,生成relay-log(中繼日志),然后mysql服務器再用relay-log的信息將數據寫入到數據庫。
      如此做的優點除了實現負責均衡之外,還為我們保留了兩份實時熱備的數據binlog和relay-log。當服務器發生災難時,我們可以用他們將數據恢復到任何一個時間點。
 
二、准備
1、在linux上安裝好兩台mysql服務器(mysql至少5.5以上),且兩台服務器最好在一個機房(如此通過內網進行主從復制,速度遠遠大於通過外網。如果web服務器也在同一機房,則也可內網訪問,還不用向ISP買帶寬)。
假定主的IP為10.121.0.110,從的IP為10.121.0.220.
2、關閉兩台服務器的防火牆(稍后再配置):
# service iptables stop  (這是centos6.5關閉方法,其他系統請問度娘)
3、如果你沒有創建數據庫,則進行如下操作
(1)在主服務器上登錄mysql
# mysql -uroot -p你的密碼
(2)創建數據庫
mysql> create database test1;
mysql> create database test2;
(3)如果已經有歷史數據,則將歷史數據備份成sql文件上傳到主服務器,運行如下命令
mysql> source /disk/test1.sql;('/disk/test1.sql '換成你自己的路徑即可)
 
三、主服務器配置
mysql已經提供了完美的讀寫分離與主從復制支持,我們只需要作如下設置即可。
1、配置my.cnf
# vi /etc/my.cnf
(1)去掉log-bin=mysql-bin前的“#”號。這一行的意思是允許mysql使用binlog,同時為主從復制打開了大門。這是關鍵中的關鍵中的關鍵。
(2)如果有多個數據庫,則添加如下行:
binlog-do-db=數據庫名1
binlog-do-db=數據庫名2
binlog-do-db=數據庫名3
binlog-ignore-db=mysql(忽略mysql自身用的數據庫)
(3)查看server-id是后的數字並記住。slave(從服務器)的server-id不能與該值重復。
(4)查看expire-log-day。binlog過期時間,默認為10天。你可以根據你硬盤空間大小及每天產生的數據量修改。如果你有冷備,則一般設成2-3天即可。
 
2、操作數據庫
(1)在linux命令行下登錄mysql
# mysql -uroot -p(你的root密碼)
(2)創建並授權一個帳號
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_account'@'10.121.0.220' identified by '123456'
這句的意思是,允許從服務器'10.121.0.220 '使用'slave-account'及'123456'這個帳號密碼對對主服務器的所有數據庫(*.*)進行主從復制('REPLICATION SLAVE').
(3)重啟mysql使上述配置生效 
# etc/init.d/mysql restart   或
# service mysql restart
(4)查看主服務器binlog狀態
mysql> show master stauts;
                                   (圖2)
記下File及Position下的值。以備在配置從服務器時使用。
注:File:當前binlog的文件名,每重啟一次mysql,就會生成一個新binlog文件
      Position:當前binlog的指針位置
 
三、從服務器配置
1、配置mysql.cnf
# vi /etc/my.cnf
(1)修改server-id=2(該值不能與主服務器的server-id同。如果有多個從服務器,則該值順延)
(2)添加如下兩行:
relay-log-index=slave-relay-bin.index (中繼日志的索引文件)
relay-log=slave-relay-bin  (中繼日志的文件前綴)
(3)重啟mysql使上述配置生效
# /etc/init.d/mysql restart
(4)登錄mysql
# mysql -uroot -p你的密碼
(5)停止主從復制服務
mysql> stop slave
(6)主從關聯配置
mysql> change master to
master_host='10.121.0.110', #主服務器IP
master_user='slave_account ',  #主服務器訪問從服務器的用戶,即上述第三條第2小條第2子條所述帳號
master_password='123456', #主服務器訪問從的密碼,即上述第三條第2小條第2子條所述密碼
master_log_file='mysql-bin.000008',   #主服務器起始的binlog文件名,即圖2的file
master_log_pos=107; #主服務器binlog起始位置,即圖2的postion
上述每行都特別重要,錯一個字符都不行
(7)啟動從服務
mysql> start slave
(8) 查看從服務的狀態,判斷從服務是否生效
mysql> show slave status\G;  (G參數為縱向顯示結果)
會顯示如下結果
                Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.110
                  Master_User: slave_account
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.00008
          Read_Master_Log_Pos: 107
               Relay_Log_File: slave-relay-bin.000002
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.00008
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          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: 264
              Relay_Log_Space: 409
              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
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
 
如果Slave_IO_Running和Slave_SQL_Running都顯示YES,則表示從與主的讀寫通訊正常、主動復制已經運行,則表明我們主從復制已經設置成功。如果出現故障,則看下節“故障排除”。
然后,你再在主服務器插入一條數據,看看從服務器相應數據庫里有沒有做相應更新。如果有,則大功告成。
 
四、權限配置 
雖然某些mysql版本不進行如下操作,可能也能正常運行,但我還是強列建議你設置。否則,必有安全之慮。
1、為master分配select、insert、update、delete權限
mysql>GRANT SELECT,INSERT,UPDATE,DELETE ON *.* TO '數據庫的帳號'@'WEB服務器的IP'  identified by '密碼'。
注意,雖然master只負責寫,但也必須有select權限。原因是使用事務時,需要從master查詢,二是update/delete這些命令都需要使用select權限。
2、為slave分配select權限 
mysql> GRANT SELECT ON *.* TO '數據庫的帳號'@'WEB服務器的IP'  identified by '密碼';
這樣設置也有一個弊端,就是當主宕機時,讀寫分離機制分主動將寫操作轉到從上來,這時,就會出現寫不正常的情況。所以,slave要分配哪些權限,還看你自己選擇。
 
五、防火牆配置
剛才我們為了調試方便,先關閉了防火牆,但這樣做,非常很不安全。特別是數據庫服務器,關系公司的身家性命,更不可小視。
主從復制的防火牆,還是比較好設置的,如果你只有一台web服務器,則只需要在主、從服務器的iptables里開放2個授權即可。先在主服務器執行如下命令:
# iptables INPUT -s 10.121.0.220 -j ACCEPT  (允許從服務器訪問)
# iptables INPUT -s 10.121.2.142 -j ACCEPT   (允許web服務器訪問)
# service iptables save (保存上述規則)
# service iptables restart  (重啟iptables)
在從中將第一條換成主的IP即可。
設置完后,再在從上用show slave status看看主從復制是否正常。
 
六、一些故障排除
設置過程中,可能會出現如下幾個故障
(1) Slave_IO_Running: No
(2) Slave_IO_Running: Connect
(3)Last_IO_Error: error connecting to master 'slave-account@192.168.0.110:3306' - retry-time: 60  retries: 8640
其實上述故障,都是由IO不正常造成的,請從如下幾個步驟着手檢查。
a.配置完主或從的my.cnf后,是否重啟了mysql服務。如果重啟還不成功,則可以用reboot命令重啟服務器后再試
b.change master那一步所填寫的信息是否正確。
(4)Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).
如上是說主、從使用了相同的server-id,進入my.cnf檢查,改正之,然后重啟mysql服務。
 
七、php設置
在php的數據庫連接配置文件里作如下設置即可
     //該行讀寫分離支持
    'DB_DEPLOY_TYPE'=> 1,  
    'DB_RW_SEPARATE'=>true,  
    //主、從數據庫的IP地址,前為主,后從
    'DB_HOST'   => '10.121.0.110,10.121,0.220',
    // 數據庫類型
    'DB_TYPE'   => 'mysql',
    // 用戶名,如果主和從的用戶名相同,則 可省略一個
    'DB_USER'   => 'root root',
    // 用戶名,如果主和從密碼相同,則可省略一個
    'DB_PWD'    => '123456 123456',
    // 用戶名,如果主和從數據庫相同,則可省略一個
    'DB_NAME'   => 'test test',
 
其他設置請參照本人的《使TP框架在主從復制下“支持事務”》
 
(該文系HANYUCQ原創,歡迎轉載,但請保留該信息。)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM