基於docker 搭建mysql8.0主從複製

如何基於docker搭建mysql8.0主從複製從而實現讀寫分離

前言

1、 docker的安裝與mysql8.0鏡像的打包這裏不做詳細介紹。以後有時間再出詳細教程。安裝好docker運行環境拉去mysql8鏡像,我使用的是自己源碼編譯的mysql8.0。docker-hub地址如下

docker pull gongxulei/centos-lnmp:mysql8

2、主從複製原理

mysql的主從複製是基於bin-log實現的,因此需要開啓bin-log配置,另外mysql8.0默認是開啓bin-log的。
如下圖所示mysql的主從複製主要分三步實現:

  • Master 主庫在事務提交時,會把數據變更作爲時間 Events 記錄在二進制日誌文件 Binlog 中。
  • 主庫推送二進制日誌文件 Binlog 中的日誌事件到從庫的中繼日誌 Relay Log 。
  • slave重做中繼日誌中的事件,將改變反映它自己的數據。
    在這裏插入圖片描述
    知道了原理我們下面開始搭建
搭建mysql8.0主從複製
1、master搭建
  • 修改配置並啓動一個msql的容器
    (1)my.cnf 配置如下
# bin-log二進制日誌設置
log-bin=/usr/local/mysql/log/mysqlbin/mysql-bin
# logging format: mixed|statement|row
binlog_format=statement

# 主從配置master
# required unique id between 1 and 2^32 - 1 defaults to 1 if master-host is not set
server-id = 1
#是否只讀,1 代表只讀, 0 代表讀寫
read-only=0
#忽略的數據, 指不需要同步的數據庫
binlog-ignore-db=mysql
#指定同步的數據庫
#binlog-do-db=db01

(2) 啓動容器

我這裏使用的 -v 來掛載了mysql 的data數據目錄、etc配置目錄、log日誌目錄
並映射的容器的3306端口到宿主機3306端口

# docker-mysql-master
docker run -d -it --privileged=true -p 3306:3306  -v /Users/gongxulei/docker/mysql/master/data:/usr/local/mysql/data   -v  /Users/gongxulei/docker/mysql/master/etc:/usr/local/mysql/etc -v /Users/gongxulei/docker/mysql/master/log:/usr/local/mysql/log --name my-app-mysql8-master 449f953ecd8b

(3) 初始化mysql並啓動mysql

我這裏初始化指定了mysql的 --log-bin 文件路徑,是因爲我沒有采用默認的目錄(data目錄)
如果指定會無法初始化。具體原因見我的之前的一篇文章

# 初始化data目錄
/usr/local/mysql/bin/mysqld --initialize-insecure --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --log-bin=/usr/local/mysql/log/mysqlbin/mysql-bin --user=mysql
# 以守護進程方式啓動mysql
/usr/local/mysql/bin/mysqld_safe --user=mysql &

(4) 設置mysql主從複製賬戶

# 登錄mysql
/usr/local/mysql/bin/mysql -uroot -p
# 設置master的root賬戶密碼 並且允許外部連接mysql
alter mysql.user set host='%' where user='root' and host='localhost';
alter user 'root'@'%' identified by 'root123456';

# 設置當前master授予slave的賬戶(用於從庫複製)
# 注意:這裏的ip爲slave的ip地址。意思是允許此ip通過賬戶slave1來訪問master數據庫
create user 'slave1'@'172.17.0.5' identified by 'slave1123456';
# 授予slave權限並刷新權限
grant replication slave on *.* to 'slave1'@'172.17.0.5';
flush privileges;

此時可以使用 show master status命令查看master數據庫狀態

# 後面設置slave會用到下面的字段
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |     869 |              | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+
字段含義:
File : 從哪個日誌文件開始推送日誌文件 
Position : 從哪個位置開始推送日誌
Binlog_Ignore_DB : 指定不需要同步的數據庫
2、slave搭建

(1)my.cnf 配置如下

# bin-log二進制日誌設置
log-bin=/usr/local/mysql/log/mysqlbin/mysql-bin
# logging format: mixed|statement|row
binlog_format=statement

# 主從配置slave
# required unique id between 1 and 2^32 - 1 defaults to 1 if master-host is not set
server-id = 2

(2) 啓動容器

我這裏使用的 -v 來掛載了mysql 的data數據目錄、etc配置目錄、log日誌目錄
並映射的容器的3306端口到宿主機3307端口

# docker-mysql-slave
docker run -d -it --privileged=true -p 3307:3306 -v /Users/gongxulei/docker/mysql/slave1/data:/usr/local/mysql/data   -v  /Users/gongxulei/docker/mysql/slave1/etc:/usr/local/mysql/etc -v /Users/gongxulei/docker/mysql/slave1/log:/usr/local/mysql/log  --name my-app-mysql8-slave1 449f953ecd8b

(3) 初始化mysql並啓動mysql

初始化與上面master一致

(4) 設置slave賬戶並開啓salve複製

下面用到的master_host地址爲master服務器的IP地址。
master_user,master_password 是之前在master服務器設置的用於主從複製的賬戶密碼
master_log_file,master_log_pos 是master服務器中執行show master status的信息

# 設置密碼: 參考上面master的root賬戶設置
# 設置slave賬戶
change master to master_host= '172.17.0.4', master_user='slave1', master_password='slave1123456', master_log_file='mysql-bin.000006', master_log_pos=869;
# 開啓slave模式
start slave;

此時可通過 show slave status命令查看slave是否設置成功

Slave_IO_Running: Yes Slave_SQL_Running: Yes 說明slave設置成功

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.4
                  Master_User: slave1
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 1713
               Relay_Log_File: 4a63c19c8af1-relay-bin.000002
                Relay_Log_Pos: 1168
        Relay_Master_Log_File: mysql-bin.000006
             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: 1713
              Relay_Log_Space: 1384
              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: 7f06a326-b845-11ea-85b9-0242ac110002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified
3、測試主從是否成功

在mysql的master服務器中創建數據庫並查看是否同步到slave中

# 在master中創建數據庫並新增一張測試表
CREATE DATABASE `master_test`
DROP TABLE IF EXISTS `test1`;
CREATE TABLE `test1` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='這是一張測試master-slave的表';

在這裏插入圖片描述
如圖上圖所示,在slave服務器也有了對應的庫跟表,那麼恭喜你搭建成功了

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