MySQL主從複製實戰

一、複製準備

  (1)定義機器角色:

         主庫    192.168.11.34 port 3306

[root@master ~]# cat /etc/sysconfig/network

           HOSTNAME=master

         從庫    192.168.11.35 port 3306

[root@slave ~]#cat /etc/sysconfig/network

  HOSTNAME=slave

提示:一般做主從,主從服務器在不同的機器上,監聽端口爲3306。可以根據實際情況進行修改。

  

  (2)主庫上執行操作

         設置server-id值並開啓binlog設置

 根據mysql的同步原理,我們知道複製的關鍵因素就是binlog日誌。

         執行[root@master ~]# vim /etc/my.cnf,編輯my.cnf配置文件,添加兩個參數

 [mysqld]

         server_id = 34

         log_bin =/usr/local/data/mysql-bin

注意:上述兩個參數必須放在my.cnf配置文件[mysqld]中,否則報錯。

server_id = 34可以是服務器IP後以爲,避免重複。

修改配置文件後需要重啓mysql。

        [root@master data]# grep -E "server-id|log-bin" /etc/my.cnf  檢查配置結果

        server-id = 34

        log-bin = /usr/local/data/mysql-bin

   

 (3)建立用於從庫複製的賬號tangbo

    mysql> grant replication slave on *.* to 'tangbo'@'192.168.11.%' identified by '111111';

     Query OK, 0 rows affected (0.00 sec)

     mysql>replication slave 爲mysql同步必須權限,此處不要授權all。*.*表示所有庫所有表。

     查看已經創建的用戶

    mysql> select user,host from mysql.user;

+--------+---------------+

| user   | host          |

+--------+---------------+

| root   | 127.0.0.1     |

| tangbo | 192.168.11.% 


 (4)鎖表只讀(當前窗口不要關掉)

生產環境執行鎖表操作時,會影響業務。   需申請停機時間

  mysql> flush tables with read lock;

           Query OK, 0 rows affected (0.00 sec)

  mysql> 

  

  mysql> create database test1;

        ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock 創建不了庫,鎖表成功


mysql> select * from renchuan.caiwu;   執行查詢無任何問題

+----+--------+------+----------+------+------------+

| id | name   | ages | job      | pay  | time       |

+----+--------+------+----------+------+------------+

|  1 | tangbo | 27   | wangguan | 3000 | 2015-12-20 |

+----+--------+------+----------+------+------------+

1 row in set (0.00 sec)


mysql> 


提示:這個鎖表命令的時間,在不同引擎的情況,有可鞥受如下參數的控制。鎖表時,如果超過設置時間不操作會自動解鎖。

       interactive_timeout = 60

  wait_timeout = 60 

  默認時常爲: 

  

 mysql> show variables like '%timeout%';

+-----------------------------+----------+

| Variable_name               | Value    |

+-----------------------------+----------+

| connect_timeout             | 10       |

| delayed_insert_timeout      | 300      |

| innodb_flush_log_at_timeout | 1        |

| innodb_lock_wait_timeout    | 50       |

| innodb_rollback_on_timeout  | OFF      |

| interactive_timeout         | 28800    |

| lock_wait_timeout           | 31536000 |

| net_read_timeout            | 30       |

| net_write_timeout           | 60       |

| rpl_stop_slave_timeout      | 31536000 |

| slave_net_timeout           | 3600     |

| wait_timeout                | 28800    |

+-----------------------------+----------+

12 rows in set (0.00 sec)

mysql> 

      

(5)查看主庫狀態  即查看當前日誌文件名和二進制偏移量

 mysql> show master status;命令顯示的信息要記錄下來,後面從庫的複製是從這個位置開始的。

 mysql> show master status;

+------------------+----------+--------------+------------------+-------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000013 |      331 |              |                  |                   |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)


mysql> 


(6)新開窗口,導出數據庫數據,如果量很大(+100G),且可以停機,直接打包數據遷移。

[root@master data]# mkdir /server/backup/ -p  創建備份目錄

[root@master /]# mysqldump -uroot -ptangbo -A -B|gzip > /server/backup/mysql.bak.$(date +%F).sql.gz

執行備份命令,  -A表示備份所有庫,-B表示增加use 數據庫名和drop等(導庫時會直接覆蓋原有的)。

  

  導爲了確保導庫期間,數據庫沒有數據插入,可以再檢查下主庫狀態信息。

  mysql> show master status;

+------------------+----------+--------------+------------------+-------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000013 |      331 |              |                  |                   |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

           提示:無特殊情況,binlog文件及文件點事保持不變的。

mysql> 

    

(7)導庫完成後,解鎖主庫,恢復可寫。

   mysql> unlock table;

  

二、開始遷移數據

  (1)把主庫備份的mysql數據遷移到從庫,通常可以使用scp,rsync

    [root@master backup]# scp mysql.bak.2015-12-22.sql.gz [email protected]:/tmp

     [email protected]'s password: 

     mysql.bak.2015-12-22.sql.gz                      100%  164KB 163.9KB/s   00:00    

    [root@master backup]# 


三、主庫設置完畢,可以開始操作從庫;

   (1)設置server-id值並關閉binlog設置

   [mysqld]

        server_id = 34

        #log_bin =/usr/local/data/mysql-bin

    注意:上述兩個參數必須放在my.cnf配置文件[mysqld]中,否則報錯

      server_id = 34可以是服務器IP後以爲,避免重複。

  修改配置文件後需要重啓mysql


   (2)檢查配置文件

   [root@master data]# grep -E "server-id|log-bin" /etc/my.cnf  檢查配置結果

   [root@slave tmp]# grep -E "server-id|log-bin" /etc/my.cnf

    server-id = 35

    #log-bin =/usr/local/data/mysql-bin

   [root@slave tmp]# 

   

   (3)還原主庫導出的數據庫到從庫

   [root@slave tmp]# gzip -d mysql.bak.2015-12-22.sql.gz  解壓

   [root@slave tmp]# mysql -uroot -ptangbo <mysql.bak.2015-12-22.sql 恢復數據導從庫

   下面可以去檢查下恢復的數據是否成功。

   mysql> desc caiwu; 

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(30)     | NO   | PRI | NULL    | auto_increment |

| name  | varchar(60) | NO   |     | NULL    |                |

| ages  | varchar(60) | YES  |     | NULL    |                |

| job   | varchar(30) | YES  |     | NULL    |                |

| pay   | float       | YES  |     | NULL    |                |

| time  | date        | YES  |     | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

6 rows in set (0.00 sec)

mysql> 

   

 (4)登陸從庫配置同步參數:或不登陸數據庫,在命令行快速執行change master的語句(適合在腳本中批量創建slave庫用)

    登陸數據庫執行:

change master to    #連接master庫

        master_host='192.168.11.34',  #主庫的IP

master_port=3306,             #這裏是主庫的端口,從庫端口可以和主庫不同

master_user='tangbo',         #主庫上建立的用於複製的用戶名

master_password='111111',     ##主庫上建立的用於複製的密碼

master_log_file='mysql-bin.000013', #show master status時看到的查看二進制日誌文件名稱,不能多出空格來

master_log_pos=331;                 #show master status時看到的二進制日誌的偏移量,不能多出空格來

下面這個可以直接複製:

   change master to 

        master_host='192.168.11.34',

master_port=3306,

master_user='tangbo',

master_password='111111',

master_log_file='mysql-bin.000013',

master_log_pos=331; 

腳本下寫法:

  cat | mysql -uroot -ptangbo << EOF  

  change master to 

        master_host='192.168.11.34',

master_port=3306,

master_user='tangbo',

master_password='111111',

master_log_file='mysql-bin.000013',

master_log_pos=331; 

EOF


四、啓動從庫同步開關

    啓動從庫同步開關,並查看同步狀態

    登陸數據庫後執行: start slave 

 mysql> show slave status\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.11.34      #當前mysql master服務器主機

                  Master_User: tangbo

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000013

          Read_Master_Log_Pos: 634818

               Relay_Log_File: slave-relay-bin.000002

                Relay_Log_Pos: 634770

        Relay_Master_Log_File: mysql-bin.000013

             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: 634818

              Relay_Log_Space: 634943

              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: 34

                  Master_UUID: 3a53cf38-9a9f-11e5-bdc9-52540055b912

             Master_Info_File: /usr/local/data/master.info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

           Master_Retry_Count: 86400

                  Master_Bind: 

      Last_IO_Error_Timestamp: 

     Last_SQL_Error_Timestamp: 

               Master_SSL_Crl: 

           Master_SSL_Crlpath: 

           Retrieved_Gtid_Set: 

            Executed_Gtid_Set: 

                Auto_Position: 0

1 row in set (0.00 sec)

      判斷是否搭建成功就看IO和SQL兩個線程是否顯示爲yes狀態。

 Slave_IO_Running: Yes  #負責從庫去主庫讀取BINLOG日誌,並寫入從庫的中繼日誌中

      Slave_SQL_Running: Yes #負責讀取並執行中繼日誌的binlog,轉換SQL語句後應用到數據庫彙總

      提示:有關show master status 查看mysql手冊 

測試複製結果


五、相關mysql技術技巧概覽

   (1)配置忽略權限庫同步參數

     binlog-ignore-db=information_schema

     binlog-ignore-db=mysql 

   

   (2)主從複製故障解決

    show slave status;   

有報錯:Error xxxx desn't  exist

且 mysql> show slave status\G

*************************** 1. row ***************************

          Slave_IO_Running: Yes    

          Slave_SQL_Running: No 

 Seconds_Behind_Master: NULL 

    解決辦法:

   stop slave;

set global sql_slave_skip_counter =1;   #=n表示忽略執行N個更新

start slave;

   這樣,Slave就會和Master去同步:主要看點:

     mysql> show slave status\G

*************************** 1. row ***************************

          Slave_IO_Running: Yes    

          Slave_SQL_Running: YES 

 Seconds_Behind_Master: 0 #0表示已經同步狀態  

    

(3)讓mysql slave 記錄binlog方法 

在從庫my.cnf中加入如下參數

log-slave-updates

log-bin=mysql13307-bin 

expire logs days = 7

   應用場景:級聯複製或從庫做數據備份

(4)嚴格設置從庫只讀   

 read-only的妙用,詳情出查看文檔

 

(5)生產環境確保從庫只讀?

  1.mysql從服務器中加入 read-only參數

  2.忽略mysql庫已經information_schema庫同步

  3.授權從庫用戶時僅僅授權selesct權限。

(6)生產環境主庫用戶的授權;

grant select,insert,update,delete on bbpay.* to 'test'@'localhost' identified by '111111';

       

(7)生產環境從庫用戶的授權

  1.grant select on bbpay.* to 'test'@'localhost' identified by '111111';

  2.在my.cnf中添加read-only參數

六、生產環境主從庫注意事項:

    (1)第一次做從庫如何做?

 假如你的服務器只有主庫,而且跑了應用了,現在由於業務需要第一個做從庫,此時可能需要申請停機維護世界,;可以再

 用戶訪問量最小,且不影響內部其他業務運轉的時間點來停機配置主從複製,一般都在凌晨進行。

 

 當然,也可以不申請,在定時任務備份時,每天夜裏定時備份時做一些任務。

(2)不加班工作時間從容配置從庫

 當然了,也可以不申請,在定時任務備份時,每天的夜裏服務器壓力小時定時備份時做一些措施即可。

 

 1.鎖表備份全備一份

 2.鎖表前後取得show  master status值記錄到日誌裏。

 這樣就可以再白天從容的實現主從同步了,這個腳本還是比較簡單:如

 [root@master tmp]# cat mysql_bak.sh 

#!/bin/bash 

##############################

#scripts by tangbo

#qq 79313760

##############################

mkdir -p /server/backup

MYUSER=root

MYPASS="tangbo"

MAIN_PATH=/server/backup

DATA_PATH=/server/backup

LOG_FILE=${DATA_PATH}/mysqllogs_`date +%F`.log

DATA_FILE=${DATA_PATH}/mysql_backup_`date +%F`.sql.gz



MYSQL_PATH=/usr/local/mysql/bin

MYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS"

MYSQL_DUMP="$MYSQL_PATH/mysqldump -u$MYUSER -p$MYPASS -A -B --flush-logs --single-transaction -e"



$MYSQL_CMD -e "flush tables with read lock;"

echo "----------show master status result----------" >> $LOG_FILE

$MYSQL_CMD -e "show master status;" >> $LOG_FILE

${MYSQL_DUMP} | gzip > $DATA_FILE

$MYSQL_CMD -e "unlock tables;"

mail -s "mysql slave log" [email protected] < $LOG_FILE

[root@master tmp]# 

提示:腳本實際上就是把主從製作的過程自動化。

   執行過程與結果:

    [root@master tmp]# ls -l /server/backup/

    total 336

    -rw-r--r--. 1 root root 170596 Dec 22 21:32 mysql_backup_2015-12-22.sql.gz

    -rw-r--r--. 1 root root 167799 Dec 22 00:52 mysql.bak.2015-12-22.sql.gz

    -rw-r--r--. 1 root root    135 Dec 22 21:32 mysqllogs_2015-12-22.log

    [root@master tmp]# 

[root@master tmp]# cat /server/backup/mysqllogs_2015-12-22.log 

     ----------show master status result----------

File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set

mysql-bin.000013 634818

[root@master tmp]# 

     (3)有了主庫備份文件和mysql-bin.000013內容做從庫就很簡單了。

    下面開始不停主庫一鍵批量創建從庫;首先,把mysql_backup_2015-12-22.sql.gz發佈到想做從庫的機器上,也許N臺。

開始製作批量做從庫腳本,一鍵完成多臺從庫的製作:

[root@master tmp]# cat mysql_slave.sh 

#!/bin/bash 

##############################

#scripts by tangbo

#qq 79313760

##############################

MYUSER=root

MYPASS="tangbo"


MAIN_PATH=/server/backup

DATA_PATH=/server/backup

LOG_FILE=${DATA_PATH}/mysqllogs_`date +%F`.log

DATA_FILE=${DATA_PATH}/mysql_backup_`date +%F`.sql.gz



MYSQL_PATH=/usr/local/mysql/bin

MYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS"


#reconver

  cd ${DATA_PATH}

  gzip -d mysql_backup_`date +%F`.sql.gz

  $MYSQL_CMD < mysql_backup_`date +%F`.sql.gz


#config slave

  cat | $MYSQL_CMD << EOF  

  change master to 

        master_host='192.168.11.34',

        master_port=3306,

master_user='tangbo',

master_password='111111',

master_log_file='mysql-bin.000013',

master_log_pos=331; 

EOF


echo "----------show master status result----------" >> $LOG_FILE

$MYSQL_CMD -e "show slave status\G" |grep "IO_Running|SQL_Running" >> $LOG_FILE

mail -s "mysql slave log" [email protected] < $LOG_FILE

[root@master tmp]# 

  注意:上面腳本中change master 參數要根據mysqllogs_2015-12-22.log修改。

      

(4)主從庫給開發人員讀寫分離用戶的設置:

   如:  主庫(提供寫服務): blog tangbo123 ip=192.168.111.1 port=3306

  從庫(僅僅提供讀服務): blog tangbo123 ip=192.168.111.2 port=3306


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章