1. 程式人生 > >mysql主從同步及讀寫分離

mysql主從同步及讀寫分離

mysql主從同步

作用:

可以對指定的資料庫進行異地同步

可以實現主從複製架構

可以對指定伺服器的只讀控制

同步原理

 
master slave  啟用兩個執行緒
記錄資料更改操作

slave_IO:複製master主機binlog日誌檔案的SQL到本機的relay-log檔案裡

啟用binlog日誌,設定日誌格式,server_id(可用主機名)

slave_SQL:執行本機relay-log檔案裡的SQL語句,重現master的資料操作

構建主從同步

  • 確保資料相同   從庫必須要有主庫上的資料(從庫設定為mysql52主機,同mysql51)
    [[email protected]~]#mysqldump -uroot -p密碼 -A  > mysqlbak.sql     #進行所有庫備份
    [[email protected]~]#scp mysqlbak.sql   [email protected]:/root/   #拷貝到從伺服器上
    [[email protected]~]#mysql -uroot -p密碼 
    mysql>drop database 庫名;                                      #清空庫,以便匯入時資料一樣
    [
    [email protected]
    ~]#mysql -uroot -p密碼 < /root/mysqlbak.sql #匯入51上的資料 [[email protected]~]#mysql -uroot -p密碼 mysql>show databases; #檢視庫

    注:如果都是初始庫,就不用備份了

  • 配置主伺服器   啟用binlog日誌,授權使用者,檢視當前正使用的日誌(mysql51)
    mysql> system vim /etc/my.cnf
    [mysqld]
    log_bin=master51                          #設定日誌名
    server_id=51
    mysql> system systemctl restart mysqld
    mysql>grant replication slave on *.* to 
    [email protected]
    "%" identified by "123456"; #授權給repluser使用者, 密碼為123456(需符合當前密碼許可權,本機之前改過許可權0) mysql> show master status; #檢視啟動的日誌狀態 +------------------------+-----------+ | Log_name | File_size | +------------------------+-----------+ | master51.000001 | 446 | +------------------------+-----------+
  • 配置從伺服器   設定server_id,指定主庫資訊
    mysql> system vim /etc/my.cnf
    [mysqld]
    server_id=52
    mysql> system systemctl restart mysqld
    mysql> change master to
        -> master_host="192.168.4.51",
        -> master_user="repluser",
        -> master_password="123456",
        -> master_log_file="master51.000001",    //關聯主伺服器的日誌檔案
    -> master_log_pos=446;                       //關聯主伺服器的偏移量
    mysql> start slave;
    mysql> show slave status\G;                  //檢視從伺服器資訊
                      ....
                Slave_IO_Running: Yes            //yes為正常
               Slave_SQL_Running: Yes            //yes為正常

    注:

      1. 如果io執行緒為no或者connecting,檢視 Last_IO_Errno:錯誤原因 

          先stop slave 再改正錯誤,在start slave

       2. 還有一種情況為配置檔案的sever_id 一樣

       3. 還有一種uuid相同的(一般為克隆過來的帶資料庫的主機),檢視/var/lib/mysql/auto.fs  可以更改,但是位數要相同。

           1.如果sql執行緒為no,則可能是從庫進行了寫操作,或者重啟後,事務回滾出現了問題,可以 stop slave,設定全域性變 

              量 set global sql_slave_skip_counter=1然後start slave

  • 測試配置           客戶端連結主庫寫入資料,在從庫上也能查詢到
mysql> create database db6;               
mysql> create table db6.a(id int);
mysql>show databases;
grant insert,update,select  on db6.*  to [email protected]"%"  identified by "123456";
mysql> select user,host from mysql.user;                #在主從庫分別檢視使用者
+---------------+------------+
| user          | host       |
+---------------+------------+
| webuser       | %          |
| mysql.sys     | localhost  |
| root          | localhost  |
+---------------+------------+
[[email protected] ~]# mysql -uwebuser  -h192.168.4.51  -p123456     
#客戶機訪問主庫,寫入檔案,驗證主從庫是否更新
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db6                |
+--------------------+
mysql> use db6    
mysql> insert into a values(111),(222);
mysql> update table a  set id=222;   
mysql> select * from db6.a;                //在主從庫上分別檢視   
  • 相關檔案
    檔名(從庫上預設有的) 說明
    master.info 主庫資訊
    relay-log.info 中繼日誌資訊(預設儲存後兩個)
    主機名-relay-bin.xxxxxx

    中繼日誌

    主機名-relay-bin.index

    索引檔案
  • 還原從庫
[[email protected]~]# cd /var/lib/mysql
[[email protected]~]# rm -rf master.info  relay-log.info 
[[email protected]~]# rm -rf mysql52-relay-bin.*
[[email protected]~]# systemctl restart mysqld
[[email protected]~]# mysql -uroot -p123456
mysql> show slave status;
Empty set (0.00 sec)

主從同步讀寫分離

讀寫分離原理

主資料庫處理事務查詢,從資料庫處理select查詢。資料庫複製被用來把事務性查詢導致的變更同步到叢集中的從資料庫。但不當然,主伺服器也可以提供查詢功能。讀寫分離最大的作用就是緩解環境伺服器壓力

多臺MySQL伺服器,分別提供讀,寫服務,均衡流量

讀寫分離的好處

增加冗餘,增強機器處理能力,極大程度的緩解X鎖和S鎖爭用

.對於讀操作為主的應用,使用讀寫分離是最佳選擇,可以確保寫的伺服器壓力更小,而讀又可以接受點時間上的延遲。

配置方法

client 192.168.4.50 /24  mysql50

MySQL Proxy  maxacale 192.168.4.100/24

master 192.168.4.51/24 mysql51

slave  192.168.4.52/24  mysql52

第一部分:搭建主從同步結構(51為主庫,52為從庫),配置方式如上所示:

第二部分:搭建MySQL讀寫分離伺服器

在讀寫分離伺服器192.168.4.100/24  安裝  maxscale-2.1.2-1.rhel.7.x86_64.rpm

[[email protected] ~]# rpm -ivh maxscale-2.1.2-1.rhel.7.x86_64.rpm

配置maxscale

[[email protected] ~]# vim /etc/maxscale.cnf.template
[maxscale]
threads=auto                //執行的執行緒的數量
 ...
[server1]                   //定義資料庫伺服器
type=server
address=192.168.4.51        //資料庫伺服器的ip
port=3306
protocol=MySQLBackend       //後端資料庫
...
[server2]
type=server
address=192.168.4.52
port=3306
protocol=MySQLBackend
...
[MySQL Monitor]                   //定義監控的資料庫伺服器
type=monitor
module=mysqlmon
servers=server1, server2          //監控的資料庫列表,不能寫ip
user=scalemon                    //監視資料庫伺服器時連線的使用者名稱scalemon
passwd=123456                    //密碼123456
monitor_interval=10000           //監視的頻率 單位為秒
...
#[Read-Only Service]             //不定義只讀伺服器
...
#router_options=slave
...
[Read-Write Service]             //定義讀寫分離服務
type=service
router=readwritesplit
servers=server1, server2
user=maxscale                //使用者名稱 驗證連線代理服務時訪問資料庫伺服器的使用者是否存在
passwd=123456                //密碼
max_slave_connections=100%
...
[MaxAdmin Service]            //定義管理服務
type=service
router=cli
...
#[Read-Only Listener]        //不定義只讀服務使用的埠號
...
#port=4008
...
[Read-Write Listener]            //定義讀寫服務使用的埠號
type=listener
service=Read-Write Service
protocol=MySQLClient
port=4006
...
[MaxAdmin Listener]        //管理服務使用的埠號
type=listener
service=MaxAdmin Service
protocol=maxscaled
socket=default
port=4016                  //手動新增,不指定時使用的是預設埠

根據配置,在主庫上新增監視和訪問使用者

[[email protected] ~]# mysql -uroot  -h192.168.4.51  -p123456    
mysql> grant replication slave,replication client on *.* to  [email protected]'%' identified by "123456";           
 //監控資料庫伺服器時,連線資料庫伺服器的使用者

mysql> grant select on mysql.* to [email protected]"%" identified by "123456"; 
//驗證訪問資料時,連線資料庫伺服器使用的使用者,是否在資料庫伺服器上存在的,連線使用者

在主庫51和從庫52上分別檢視使用者scalemon,maxscale

mysql> select user,host from mysql.user where user in ("scalemon","maxscale");
+-----------+------+
| user      | host |
+-----------+------+
| maxscale  | %    |
| scalemon  | %    |
+-----------+------+
2 rows in set (0.00 sec)

在主從庫上分別檢視授權使用者

[[email protected] ~]# mysql -h 192.168.4.51 -u scalemon -p123456
[[email protected] ~]# mysql -h 192.168.4.52 -u scalemon -p123456
[[email protected] ~]# mysql -h 192.168.4.51 -u maxscale -p123456
[[email protected] ~]# mysql -h 192.168.4.52 -u maxscale -p123456

啟動服務並檢視監控狀態(maxadmin -P埠 -u使用者名稱  -p密碼)

[[email protected] ~]# maxscale -f  /etc/maxscale.cnf   
[[email protected] ~]# ps -C  maxscale                      //檢視程序
[[email protected] ~]# netstat  -antup | grep maxscale      //檢視埠
tcp6       0      0 :::4099                 :::*                    LISTEN      12340/maxscale      
tcp6       0      0 :::4006                 :::*                    LISTEN      12340/maxscale
[[email protected] ~]# yum -y install mariadb mariadb-server
[[email protected] ~]# systemctl start mariadb 
[[email protected] ~]# maxadmin -P4016 -uadmin   -pmariadb
MaxScale> list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server             | Address         | Port  | Connections | Status              
-------------------+-----------------+-------+-------------+--------------------
server1            | 192.168.4.51    |  3306 |           0 | Master, Running
server2            | 192.168.4.52    |  3306 |           0 | Slave, Running
-------------------+-----------------+-------+-------------+--------------------

在50主機客戶端訪問讀寫分離伺服器 mysql  -h讀寫分離伺服器 -P4006 -pmima

[[email protected] ~]# mysql -h192.168.4.100  -P4006 -urepluser -p123456   //主從配置連結使用者
mysql> select  @@hostname;            //檢視當前主機名
+------------+
| @@hostname |
+------------+
| mysql52    |
+------------+
1 row in set (0.00 sec) 
mysql> create table t2(id int(4) );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into db6.t2 values(888);
Query OK, 1 row affected (0.01 sec)

在主從庫51和52上分別檢視資料

mysql> use db6
mysql> select * from t2;
+------+
| id   |
+------+
|  888 |
+------+
1 row in set (0.00 sec)

主從同步結構模式

  • 基本應用:單向複製:主----->從                       主要
  • 擴充套件:       鏈式複製:主----->從------>從
  •                    互為主從:主<----->主
  •                    一主多從:從< -----主----->從           主要

主從同步配置選項

適用於master檔案
選項 用途
binlog_do_db=name 設定master對哪些庫記日誌
binlog_ignore_db=name 對哪些庫不記日
適用於slave伺服器
選項 用途
log_slave_upstates 記錄從庫更新,允許鏈式複製(A-B-C)
relay_log=dbsvr2-relay-bin 指定中繼日誌檔名
replicate_do_db=mysql 僅設定指定庫,可設定多條
replicate_ignore_db=test

不復制哪些庫,和上面的僅需選一種

 

主從同步配置應用之一主兩從

模式:mysql53為主庫 mysql54,55為從庫(配置見上面案例)mysql50使用者端,驗證上述配置選項

  1. 授予使用者許可權(可以省略)
    [[email protected]~]#grant all on *.* to [email protected]"%" identified by "123456";
     #實驗驗證,真實可以根據實際情況賦予許可權

     

  2. 客戶端登入建立測試庫,表
    [[email protected]~]#mysql -uwind -p123456 -h192.168.4.53
    mysql>create database test1;create database test2;create database test3;
    mysql>create table test1.a;create table test2.a;create table test3.a;

     

  3. 關閉主從庫,修改主庫配置檔案(注,如果之前改過日誌格式檔案最好註釋-不是必要操作,有的會有這個問題,或者最好全部關閉)
    [[email protected]~]#systemctl stop mysqld     //54/55同操作
    [[email protected]~]#vim /etc/my.cnf
    [mysqld]
    ......
    log_bin=master53
    server_id=53
    binlog_do-db=test1                          #僅對test1庫記日誌

     

  4. 重啟主從庫
    [[email protected]~]#systemctl restart mysqld          # 54/55同步操作

     

  5. 進入主庫,檢視日誌檔案記錄對應庫,檢視從庫IO,SQL是否啟動
    mysql> show master status;
    +---------- ----+----------+--------------+------------------+-------------------+
    | File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +---------------+----------+--------------+------------------+-------------------+
    | master53.000002|    154  | test1        |                  |                   |
    +---------------+----------+--------------+------------------+-------------------+
    mysql> show slave status;

     

  6. 在主庫測試表中分別寫入資料
    mysql>insert into test1.a  values(111);
    mysql>insert into test2.a  values(111);

     

  7. 在從庫驗證(54/55)
    mysql> select * from test2.a;
    mysql> select * from test1.a;
    +------+
    |  id  |
    +------+
    |  111 |
    +------+

     

  8. 註釋/刪除主庫剛才配置的指定庫記錄日誌,重啟
    [[email protected]~]#vim /etc/my.cnf
    [mysqld]
    ......
    #binlog_do-db=test1
    [[email protected]~]#systemctl restart mysqld

     

  9. 主庫寫入資料到測試檔案
    mysql> insert into test1.a values(222);
    mysql> insert into test3.a values(222);

     

  10. 從庫(僅驗證55),修改配置檔案,指定複製庫,重啟
    [[email protected]~]# vim /etc/my.cnf
    [mysqld]
    server_id=55
    replicate_do_db=test3                        #僅同步test3庫
    [[email protected]~]#systemctl restart mysqld

     

  11. 進入從庫,檢視對應測試檔案。
    mysql> select * from test1.a;
    +------+
    | id   |
    +------+
    |  111 |
    +------+
    mysql> select * from test3.a;
    +------+
    | id   |
    +------+
    | 111  | 
    | 222  |
    +------+