MySql之主從複製

爲什麼要做主從複製?

  1. 在業務複雜的系統中,有這麼一個情景,有一句sql語句需要鎖表,導致暫時不能使用讀的服務,那麼就很影響運行中的業務,使用主從複製,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現了鎖表的情景,通過讀從庫也可以保證業務的正常運作。通過做主從複製(讀寫分離)來減輕主數據庫的負載

  2. 做數據的熱備
  3. 業務量越來越大,I/O訪問頻率過高,單機無法滿足,此時做多庫的存儲,降低磁盤I/O訪問的頻率,提高單個機器的I/O性能。如果對數據庫的讀和寫都在同一個數據庫服務器中操作,業務系統性能會降低

 主從複製的原理

  • 主庫db的更新事件(update、insert、delete)被寫到binlog
  • 從庫發起連接,連接到主庫
  • 此時主庫創建一個binlog dump thread,把binlog的內容發送到從庫
  • 從庫啓動之後,創建一個I/O線程,讀取主庫傳過來的binlog內容並寫入到relay log
  • 還會創建一個SQL線程,從relay log裏面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db

注:上面的解釋是解釋每一步做了什麼,整個mysql主從複製是異步的,不是按照上面的步驟執行的。

同步操作通過 3 個線程實現,其基本步驟如下:

主服務器將數據的更新記錄到二進制日誌中(記錄被稱作二進制日誌事件)-- 主庫線程;
從庫將主庫的二進制日誌複製到本地的中繼日誌(relay log)-- 從庫 I/O 線程;
從庫讀取中繼日誌中的事件,將其重放到數據中 -- 從庫 SQL 線程。

本篇博客記錄的是一主一從模式

環境搭建

準備工作

  • 主從數據庫版本最好一致
  • 主從數據庫內數據保持一致
  • 主數據庫:192.168.190.131 從數據庫:192.168.190.132

配置主庫Master

  • 修改MySQL配置

mysql查看默認配置文件:mysql --help|grep 'my.cnf',找到主數據庫的配置文件my.cnf,我的在/etc/my.cnf

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 

#主服務器唯一ID
server-id=1
#設置需要複製的數據庫
binlog-do-db=testdb
#二進制日誌
#配置開啓 binlog日誌,日誌的文件前綴爲mysqlbin生成的文件名如: mysqlbin.000001, mysqlbin.000002
log_bin=mysqlbin
#配置二進制日誌的格式
binlog_format=STATEMENT
#自動刪除的過期天數
expire_logs_days=3

#該選項用來開啓查詢日誌,可選值:0關閉;1開啓
general_log=1
#設置日誌的文件名,如果沒有指定,默認的文件名爲host_name.log
general_log_file=mysql_query.log

#該參數用來控制慢查詢日誌是否開啓:1開啓,0關閉
slow_query_log=1
#該參數用來指定慢查詢日誌的文件名
slow_query_log_file=slow_query.log
#該選項用來配置查詢的時間限制,超過這個時間將認爲是慢查詢,需要進行日誌記錄,默認是10s
long_query_time=3

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
  • 創建用戶 

 重啓服務,創建用於同步的用戶,用戶:salve密碼:123456

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
  • 查看master狀態

mysql> show master status;
+-----------------+----------+--------------+------------------+-------------------+
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------+----------+--------------+------------------+-------------------+
| mysqlbin.000007 |     2400 | testdb       |                  |                   |
+-----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

配置從庫Slave

  • 修改MySQL配置
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 

#從服務器唯一ID
server-id=2
#啓用中繼日誌
relay-log=mysql-relay
#二進制日誌
#配置開啓 binlog日誌,日誌的文件前綴爲mysqlbin生成的文件名如: mysqlbin.000001, mysqlbin.000002
log_bin=mysqlbin
#配置二進制日誌的格式
binlog_format=STATEMENT
#自動刪除的過期天數
expire_logs_days=3

#該選項用來開啓查詢日誌,可選值:0關閉;1開啓
general_log=1
#設置日誌的文件名,如果沒有指定,默認的文件名爲host_name.log
general_log_file=mysql_query.log

#該參數用來控制慢查詢日誌是否開啓:1開啓,0關閉
slow_query_log=1
#該參數用來指定慢查詢日誌的文件名
slow_query_log_file=slow_query.log
#該選項用來配置查詢的時間限制,超過這個時間將認爲是慢查詢,需要進行日誌記錄,默認是10s
long_query_time=3

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
  •  重啓mysql,打開mysql會話,執行同步SQL語句(需要主服務器主機名,登陸憑據,二進制文件的名稱和位置)
mysql> CHANGE MASTER TO
    -> MASTER_HOST='192.168.190.131',
    -> MASTER_USER='salve',
    -> MASTER_PASSWORD='123456',
    -> MASTER_LOG_FILE='mysqlbin.000007',
    -> MASTER_LOG_POS=2400;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
  •  啓動slave同步進程
mysql>start slave;

 停止stop slave;重新配置主從reset master;

  • 查看slave狀態
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.190.131
                  Master_User: salve
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysqlbin.000007
          Read_Master_Log_Pos: 2400
               Relay_Log_File: mysql-relay.000003
                Relay_Log_Pos: 2277
        Relay_Master_Log_File: mysqlbin.000007
             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: 2400
              Relay_Log_Space: 2446
              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
                  Master_UUID: 9510d25d-7d7b-11ea-9a71-000c29980d35
             Master_Info_File: /var/lib/mysql/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)

當Slave_IO_Running和Slave_SQL_Running都爲YES的時候就表示主從同步設置成功了。如果是虛擬機克隆的情況下,注意修改/var/lib/mysql/auto.cnf中的uuid

注意事項

master主節點
在主節點的二進制事件日誌中僅記錄與指定數據庫(數據表)相關的事件日誌,但是主節點的二進制日誌不完整,沒有記錄所有對主節點的修改操作。如果要使用該方式,則在主節點的配置文件中添加如下參數:

binlog_do_db="***,***,***";      #數據庫白名單列表,二進制日誌記錄的數據庫(多數據庫用逗號隔開或重複設置多行),即需要同步的庫.不在內的不同步。(不添加這行表示同步所有)
binlog_ingore_db="***,***,***";  #數據庫黑名單列表, 二進制日誌中忽略的數據庫 (多數據庫用逗號隔開或重複設置多行),即不需要同步,要過濾掉的庫.

 slave從節點
從服務器SQL Thread在Replay中繼日誌中的事件時僅讀取於特定數據庫相關的事件,並應用於本地. (但是浪費I/O ,浪費帶寬) 推薦使用從節點複製過濾相關設置項:

replicate_do_db ="webdb";         #複製庫的白名單. 設定需要複製的數據庫(多數據庫使用逗號隔開或重複設置多行)
replicate_ingore_db ="mysql";     #複製庫的黑名單. 設定需要忽略的複製數據庫 (多數據庫使用逗號隔開或重複設置多行)
replicate_do_table="webdb.user";  #複製表的白名單. 設定需要複製的表(多數據庫使用逗號隔開或重複設置多行)
relicate_ingore_table="webdb.uw"; #複製表的黑名單. 設定需要忽略的複製的表(多數據庫使用逗號隔開或重複設置多行)
   
replicate-wild-do-table           #同replication-do-table功能一樣,但是可以通配符. 更高級別的應用,通配符,應用到哪一類表的。
replicate-wild-ignore-table       #同replication-ignore-table功能一樣,但是可以加通配符.

 當在主庫存在的庫而從庫不存在的庫同步時,會出現sql錯誤,這時候可以排除或者從庫手動導入主庫數據庫。從庫可以使用通配符"庫名.%"方式過濾主從同步時某個庫的設置

replicate-wild-do-table=webdb.%      #只複製webdb庫下的所有表
replicate-wild-ignore-table=mysql.%  #忽略mysql庫下的所有表

 特別注意: 生產庫上一般不建議設置過濾規則, 如果非要設置, 強烈建議從庫使用通配符方式過濾某個庫

replicate-wild-do-table= "庫名.%"
replicate-wild-ignore-table= "庫名.%"

而不建議從庫使用DB方式過濾某個庫

replicate_do_db ="庫名"
replicate_ingore_db ="庫名"

驗證

在主服務器創建testdb數據庫,新建mytbl表,插入幾條數據,發現從服務器也能查詢到testdb數據庫,mytbl表,以及表中的數據

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