MySQL的主從複製

Null指標發表於2018-11-29

介紹

為什麼要主從複製

  • 做資料的熱備

  • 如果主資料庫當機,可以快速將業務系統切換到從資料庫上,可避免資料丟失。

  • 業務量越來越大,I/O訪問頻率過高,單機無法滿足,此時做多庫的儲存,降低磁碟I/O訪問的頻率,提高單個機器的I/O效能。如果對資料庫的讀和寫都在同一個資料庫伺服器中操作,業務系統效能會降低。

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

原理

MySQL的主從複製

  • 步驟一:主庫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 執行緒。
複製程式碼

主從複製

準備工作

  • 主從資料庫版本最好一致
  • 主從資料庫內資料保持一致
  • 主資料庫:10.168.1.248 從資料庫:10.168.1.249

配置主庫Master

修改MySQL配置

找到主資料庫的配置檔案my.cnf,我的在/etc/my.cnf

vi /etc/my.cnf
複製程式碼

在[mysqld]部分插入

[mysqld]
log-bin=mysql-bin #開啟二進位制日誌
server-id=1 #設定server-id,必須唯一
複製程式碼

**配置說明 **

  1. log-bin:設定二進位制日誌檔案的基本名;
  2. log-bin-index:設定二進位制日誌索引檔名;
  3. binlog_format:控制二進位制日誌格式,進而控制了複製型別,三個可選值
  4. ​ -STATEMENT:語句複製
  5. ​ -ROW:行復制
  6. ​ -MIXED:混和複製,預設選項
  7. server-id:伺服器設定唯一ID,預設為1,推薦取IP最後部分;
  8. sync-binlog:預設為0,為保證不會丟失資料,需設定為1,用於強制每次提交事務時,同步二進位制日誌到磁碟上。

建立使用者

重啟服務,建立用於同步的使用者

開啟mysql會話shell

mysql -uroot -p
複製程式碼

建立使用者並授權:使用者:repl密碼:repl'

# 建立使用者
create user 'repl'@'10.168.1.249' identified by 'repl';

# 授權,只授予複製和客戶端訪問許可權
grant replication slave on *.* to 'repl'@'10.168.1.249';#分配許可權
複製程式碼

檢視master狀態

記錄二進位制檔名(mysql-bin.000001)和位置(154):

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     1416 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
複製程式碼

配置從庫Slave

修改MySQL配置

找到主資料庫的配置檔案my.cnf,我的在/etc/my.cnf

vi /etc/my.cnf
複製程式碼

在[mysqld]部分插入

[mysqld]
server-id=2 #設定server-id,必須唯一
複製程式碼

執行同步SQL語句

重啟mysql,開啟mysql會話,執行同步SQL語句(需要主伺服器主機名,登陸憑據,二進位制檔案的名稱和位置):

mysql> CHANGE MASTER TO
    -> MASTER_HOST='10.168.1.248',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='repl',
    -> MASTER_LOG_FILE='mysql-bin.000001',
    -> MASTER_LOG_POS=1416;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
複製程式碼

啟動slave同步程式

mysql>start slave;
複製程式碼

檢視slave狀態

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.168.1.248
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1917
               Relay_Log_File: sl249-relay-bin.000003
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
          				......
複製程式碼

當Slave_IO_Running和Slave_SQL_Running都為YES的時候就表示主從同步設定成功了。

驗證

  • 主伺服器

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    4 rows in set (0.00 sec)
    
    mysql> create database mysql_test;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | mysql_test         |
    | performance_schema |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)
    複製程式碼
  • 從伺服器

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    4 rows in set (0.00 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | mysql_test         |
    | performance_schema |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)
    複製程式碼

相關文章