MySQL配置主從複製

初始環境

有一臺機器A安裝了MySQL5.7.20作爲主數據庫服務器,它已經運行了一段時間,具有小規模的數據。一個Web應用使用Spring+JPA+Hibernate來訪問這個數據庫。

目標

在機器B上安裝MySQL作爲slave數據庫服務器,與主數據庫形成主從複製架構。修改Web應用使讀寫分離,所有讀操作走slave數據庫,所有寫操作走master數據庫。

步驟

1.安裝備庫

在機器B上安裝MySQL5.7.20。參考官方文檔https://dev.mysql.com/doc/refman/5.7/en/linux-installation-rpm.html

2.創建複製賬號

在主庫上創建一個用戶,並賦予合適的權限。備庫將用這個用戶連接到主庫並讀取其二進制日誌。

mysql> grant replication slave,replication client on *.* to repl identified by 'Welcome1';

3. 配置主庫和備庫

在主庫上打開二進制日誌,並指定一個唯一的服務器ID。在主庫的my.cnf文件中增加或修改如下內容:

server-id               = 43(服務器id,每臺機器要唯一,最好用IP最後一位)
log_bin                 = mysql-bin(這是主服務器,必須開啓log_bin,這句就是開啓了)
binlog_format           = mixed(混合比較好,還有statements,rows)
binlog_do_db            = master(需要同步的數據庫,如果多個數據庫,重複這個配置)
binlog_ignore_db        = mysql(排除不需要同步的數據庫,如果多個數據庫,重複這個配置)
expire_logs_days        = 7(二進制日誌自動刪除或過期的天數。默認爲0,不刪除)
slave_skip_errors       = 1062 (跳過指定的錯誤,1062指主鍵重複,1032是主從數據庫不一致, 請百度更多)
binlog_cache_size       = 1M (爲每個session分配的內存)

查看二進制日誌文件是否已經在主庫上建立。

mysql> show master status;
Empty set (0.00 sec)

說明二進制日誌文件還沒有建立。需要重啓MySQL服務,

sh-4.1# /sbin/service mysqld restart
Stopping mysqld:                                           [  OK  ]
Starting mysqld:                                           [  OK  ]

再次查看,發現二進制日誌文件已經建立。

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

備庫也需要在my.cnf中增加類似的配置,然後也需要重啓MySQL服務。

log_bin=mysql-bin
server_id=45
relay_log=/var/lib/mysql/mysql-relay-bin
log_slave_updates=1 (表示slave將複製事件寫進自己的二進制日誌)
read_only=1 (表示從節點只能讀,不能寫)

4. 啓動複製

我們要告訴備庫如何連接到主庫並重放其二進制日誌。

mysql> change master to master_host='host1',
    -> master_user='repl',
    -> master_password='Welcome1',
    -> master_log_file='mysql-bin.000001',
    -> master_log_pos=0;

Query OK, 0 rows affected, 2 warnings (0.04 sec)

master_log_pos設置爲0,說明要從日誌開頭讀起。然後可以使用show slave status來檢查複製是否正確執行。

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: slc05ida.us.oracle.com
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No
              ......
        Seconds_Behind_Master: NULL
              ......
1 row in set (0.00 sec)

發現Slave_IO_State,Slave_IO_Running和Slave_SQL_Running三列顯示當前備庫複製還沒開始運行。而且日誌開頭是4,不是0。

運行下面的命令開始執行復制:

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)

再次查看

mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: slc05ida.us.oracle.com
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
           ......
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           ......

1 row in set (0.01 sec)

在主庫上執行show processlist\G可以看到複製線程。

mysql> show processlist\G
*************************** 5. row ***************************
     Id: 9
   User: repl
   Host: slc10giz.us.oracle.com:40508
     db: NULL
Command: Binlog Dump
   Time: 93
  State: Master has sent all binlog to slave; waiting for more updates
   Info: NULL

5 rows in set (0.00 sec)

在備庫上執行show processlist\G可以看到一個I/O線程和一個SQL線程。

mysql> show processlist\G
*************************** 1. row ***************************
     Id: 4
   User: root
   Host: localhost
     db: NULL
Command: Query
   Time: 0
  State: starting
   Info: show processlist
*************************** 2. row ***************************
     Id: 5
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 152
  State: Waiting for master to send event
   Info: NULL
*************************** 3. row ***************************
     Id: 6
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 151
  State: Slave has read all relay log; waiting for more updates
   Info: NULL
3 rows in set (0.00 sec)

5. 從主庫克隆數據

配置了上面的主從複製之後,我們發現備庫沒有獲得主庫原有的數據。因爲以上的主從複製只是同步配置主從複製之後發生的事件。我們需要用其他方法克隆主庫原來的數據。這裏我們使用mysqldump。它只是用於數據庫中只有InnoDB表的時候。

-bash-4.1$ /usr/bin/mysqldump --single-transaction --all-databases --master-data=1 --host=host1 -ufmwhatool -pfmwhatool| mysql --host=host2 -uroot -pWelcome1
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 3021 (HY000) at line 22: This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD FOR CHANNEL '' first.
mysqldump: Got errno 32 on write

看來我們需要先把主從複製關掉。

mysql> stop slave;
Query OK, 0 rows affected (0.03 sec)
-bash-4.1$ /usr/bin/mysqldump --single-transaction --all-databases --master-data=1 --host=1 -ufmwhatool -pfmwhatool| mysql --host=host2 -uroot -pWelcome1
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.

這次沒有報錯。

過了一會兒,我們查看備庫,發現數據已經克隆過去了。

再用start slave;命令打開主從複製。

在主庫中某個Table裏插入記錄,就會發現從庫裏的這個Table裏馬上就有這條記錄了。

OK,到此主從複製成功。

 

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