基於Docker-Compose的MySQL5.6 5.7 8.0高可用集群安裝

docker-compose構建 mysql 主從複製(讀寫分離)集群,此集群由3個MySQL實例組成,一個Master節點,2個Slave節點。Master可讀寫,Secondary可讀。集群之間會自動同步數據。

Master位於192.168.0.142服務器上, 兩個Slave位於192.168.0.11服務器上。


1. 下載MySQL鏡像

MySQL5.6是以朗尊軟件的的MySQL5.6鏡像作為標準。

docker pull mysql:5.7
docker pull mysql:8.0.17

2. docker-compose.yml


MySQL5.6的master

?

version:"3"

services:

### mysql container #########################################

mysql142:

container_name: mysql142

image: harbor.legendshop.cn/legendshop-public/mysql:5.6

restart: always

volumes:

- ./db/mysql/data:/var/lib/mysql

- ./db/mysql/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: xxxxxx

TZ: Asia/Shanghai

command:

--max_allowed_packet=128M

ports:

- 3306:3306

MySQL5.7的Master配置

?

version:"3"

services:

### mysql container #########################################

mysql5.7-142:

container_name: mysql5.7-142

image: mysql:5.7

restart: always

volumes:

- ./db/mysql/data:/var/lib/mysql

- ./db/mysql/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: xxxxxx

TZ: Asia/Shanghai

command:

--max_allowed_packet=128M

--default-authentication-plugin=mysql_native_password

--character-set-server=utf8mb4

--collation-server=utf8mb4_general_ci

--explicit_defaults_for_timestamp=true

--lower_case_table_names=1

ports:

- 3376:3306

MySQL8.0的Master配置

?

version:"3"

services:

### mysql container #########################################

mysql8-142:

container_name: mysql8-142

image: mysql:8.0.17

restart: always

volumes:

- ./db/mysql/data:/var/lib/mysql

- ./db/mysql/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: xxxxxx

TZ:"Asia/Shanghai"

command:

--max_allowed_packet=128M

--default-authentication-plugin=mysql_native_password

--character-set-server=utf8mb4

--collation-server=utf8mb4_general_ci

--explicit_defaults_for_timestamp=true

--lower_case_table_names=1

ports:

- 3386:3306


注意編碼是採用utf8mb4,mysql的配置項在/db/mysql/conf.d目錄下,該目錄下增加mysql.cnf文件

MySQL5.6的配置

?

[client]

default-character-set=utf8mb4

[mysql]

default-character-set=utf8mb4

[mysqld]

init_connect='SET collation_connection = utf8mb4_unicode_ci'

init_connect='SET NAMES utf8mb4'

character-set-server=utf8mb4

lower_case_table_names=1

collation-server=utf8mb4_unicode_ci

skip-character-set-client-handshake=FALSE

log-bin=mysql-bin

server-id=1

max_connections=2000

MySQL5.7的配置

?

[client]

default-character-set=utf8

[mysql]

default-character-set=utf8

[mysqld]

transaction-isolation=READ-COMMITTED

init_connect='SET collation_connection = utf8_unicode_ci'

init_connect='SET NAMES utf8'

character-set-server=utf8

lower_case_table_names=1

collation-server=utf8_unicode_ci

skip-character-set-client-handshake

log-bin=mysql-bin

server-id=1

relay-log =relay-bin

relay-log-index = slave-relay-bin.index

max_connections=2000

innodb_log_file_size = 512M

MySQL8.0的配置

?

[client]

default-character-set=utf8mb4

[mysql]

default-character-set=utf8mb4

[mysqld]

default-time-zone='+08:00'

character-set-server = utf8mb4

default_authentication_plugin=mysql_native_password

lower_case_table_names=1

log-bin=mysql-bin

server-id=1

relay-log =relay-bin

relay-log-index = slave-relay-bin.index


記得要填寫上server-id,用於做為集群的服務ID

以下對Slave節點的docker-compose配置羅列出來。

MySQL5.6的SLAVE配置

?

version:"3"

services:

### mysql container #########################################

mysql101:

container_name: mysql101

image: harbor.legendshop.cn/legendshop-public/mysql:5.6

restart: always

volumes:

- ./db/mysql101/data:/var/lib/mysql

- ./db/mysql101/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: xxxxxx

TZ: Asia/Shanghai

command:

--max_allowed_packet=128M

ports:

- 3306:3306

### redis container #########################################

mysql102:

container_name: mysql102

image: harbor.legendshop.cn/legendshop-public/mysql:5.6

restart: always

volumes:

- ./db/mysql102/data:/var/lib/mysql

- ./db/mysql102/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: xxxxxx

TZ: Asia/Shanghai

command:

--max_allowed_packet=128M

ports:

- 3307:3306

MySQL5.7的配置

?

version:"3"

services:

### mysql container #########################################

mysql5.7-101:

container_name: mysql5.7-101

image: mysql:5.7

restart: always

volumes:

- ./db/mysql101/data:/var/lib/mysql

- ./db/mysql101/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: xxxxxx

TZ: Asia/Shanghai

command:

--max_allowed_packet=128M

ports:

- 3376:3306

### redis container #########################################

mysql5.7-102:

container_name: mysql5.7-102

image: mysql:5.7

restart: always

volumes:

- ./db/mysql102/data:/var/lib/mysql

- ./db/mysql102/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: xxxxxx

TZ: Asia/Shanghai

command:

--max_allowed_packet=128M

ports:

- 3377:3306

MySQL8.0的配置

?

version:"3"

services:

### mysql container #########################################

mysql8-101:

container_name: mysql8-101

image: mysql:8.0.17

restart: always

volumes:

- ./db/mysql101/data:/var/lib/mysql

- ./db/mysql101/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: Ls@12345678@

TZ:"Asia/Shanghai"

command:

--max_allowed_packet=128M

--default-authentication-plugin=mysql_native_password

--character-set-server=utf8mb4

--collation-server=utf8mb4_general_ci

--explicit_defaults_for_timestamp=true

--lower_case_table_names=1

ports:

- 3386:3306

### backup mysql container #########################################

mysql8-102:

container_name: mysql8-102

image: mysql:8.0.17

restart: always

volumes:

- ./db/mysql102/data:/var/lib/mysql

- ./db/mysql102/conf.d:/etc/mysql/conf.d

restart: always

environment:

MYSQL_ROOT_PASSWORD: Ls@12345678@

TZ:"Asia/Shanghai"

command:

--max_allowed_packet=128M

--default-authentication-plugin=mysql_native_password

--character-set-server=utf8mb4

--collation-server=utf8mb4_general_ci

--explicit_defaults_for_timestamp=true

--lower_case_table_names=1

ports:

- 3387:3306


對應SLAVE的mysql.conf的配置

MySQL5.6SLAVE第一個節點配置

?

[client]

default-character-set=utf8

[mysql]

default-character-set=utf8

[mysqld]

init_connect='SET collation_connection = utf8_unicode_ci'

init_connect='SET NAMES utf8'

character-set-server=utf8

lower_case_table_names=1

collation-server=utf8_unicode_ci

skip-character-set-client-handshake

log-bin=mysql-bin

server-id=101

read_only=1

MySQL5.6SLAVE第二個節點的配置

?

[client]

default-character-set=utf8

[mysql]

default-character-set=utf8

[mysqld]

init_connect='SET collation_connection = utf8_unicode_ci'

init_connect='SET NAMES utf8'

character-set-server=utf8

lower_case_table_names=1

collation-server=utf8_unicode_ci

skip-character-set-client-handshake

log-bin=mysql-bin

server-id=102

read_only=1

Slave節點配置為read only模式, 由於篇幅問題這裡不再羅列mysql5.7,5.8的配置。

3. 配置 MySQL 主從複製

在master和2個slave都啟動完畢的狀態下, 進入master的mysql環境。

1. 首先連接 master 服務器,查看數據庫狀態

SHOW MASTER STATUS

基於Docker-Compose的MySQL5.6 5.7 8.0高可用集群安裝

記錄master上的日誌文件名、position兩個值需要記住後面要用。

2. 在master中創建用戶

MySQL5.6 5.7的寫法:
GRANT REPLICATION SLAVE ON *.* TO 'backup'@'%' IDENTIFIED BY 'xxxxxx';
或者IP地址
GRANT REPLICATION SLAVE ON *.* TO 'backup'@'192.168.0.11' IDENTIFIED BY 'xxxxxx';

在MySQL8下創建賬號、分配權限的做法
CREATE USER 'backup'@'%' IDENTIFIED BY 'xxxxxx';

GRANT REPLICATION SLAVE ON *.* TO 'backup'@'%' WITH GRANT OPTION;

3. 配置slave

讓slave連接master,並開始重做master二進制日誌中的事件。master_log_file的值為上面的日誌文件名;master_log_pos為position的值
CHANGE MASTER TO
MASTER_HOST='192.168.0.142',
MASTER_USER='backup',
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=518,
MASTER_PORT=3317,
MASTER_PASSWORD='xxxxxx';

查看slave的狀態

SHOW SLAVE STATUS

基於Docker-Compose的MySQL5.6 5.7 8.0高可用集群安裝

Slave_IO_State狀態位Waiting for master to send event為正常狀態。

Slave_IO_Running 正常狀態位Yes

Slave_SQL_Running正常狀態位Yes


4. 問題處理

4.1 Slave_SQL_Running和Slave_IO_Running狀態位No時無法通知Slave,執行以下腳本重新讓slave鏈接master

?

STOP SLAVE ;

SETGLOBALSQL_SLAVE_SKIP_COUNTER=1; //如果是Slave_SQL_Running:no:

CHANGE MASTERTOMASTER_LOG_FILE='xxxx', MASTER_LOG_POS=xxxx; //如果是slave_io_running:no,根據master的值重新執行一次

START SLAVE;

SHOW SLAVE STATUS //直到slave狀態位正常才行


4.2. Relay log 導致複製啟動失敗
新版本使用表來代替原來的文件,主要為了crash-safe replication,從而大大提高從庫的可靠性。為了保證意外情況下從庫的可靠性,
mysql.slave_master_info和mysql.slave_relay_log_info表必須為事務性的表,從5.6.6起,這些表默認使用InnoDB存儲引擎。在5.6.5及之前的版本默認使用MyISAM引擎,可用下面語句進行轉換:


ALTER TABLE mysql.slave_master_info ENGINE=InnoDB;
ALTER TABLE mysql.slave_relay_log_info ENGINE=InnoDB;

reset slave乾的那些事:

1、刪除slave_master_info ,slave_relay_log_info兩個表中數據;
2、刪除所有relay log文件,並重新創建新的relay log文件;
3、不會改變gtid_executed 或者 gtid_purged的值
下面解決問題:


dba:(none)> reset slave;
Query OK, 0 rows affected (0.00 sec)
1
dba:(none)> change master to ......
1
2
dba:(none)> start slave;
Query OK, 0 rows affected (0.00 sec)
到這裡問題解決了。

【經驗】:以後用冷備份恢復實例後,在啟動slave前,先進行reset slave清空下以前的舊信息。


4.3. 設置slave1和slave2為只讀

在配置文件my.cnf中的mysqld中配置read_only=1
注意:read_only=1只讀模式,可以限定普通用戶進行數據修改的操作,但不會限定具有super權限的用戶(如超級管理員root用戶)的數據修改操作。

如果想保證super用戶也不能寫操作,就可以就需要執行給所有的表加讀鎖的命令 “flush tables with read lock;”。這樣使用具有super權限的用戶登錄數據庫,想要發生數據變化的操作時,也會提示表被鎖定不能修改的報錯。


我們的一般做法是,給從庫分配一個普通用戶。

將slave數據庫read-only=1設置只讀後,在master執行GRANT USAGE ON *.* TO 'user01'@'localhost' IDENTIFIED BY'123456' WITH GRANT OPTION;(這裡要區別上面給從庫分配複製權限的寫法,這裡分配的是usage權限, 後面多了with grant option)

創建一個普通用戶,然後用普通用戶登錄從庫,執行操作會報錯。切換到root用戶後還是可以進行增刪改查的。


5. 登錄master數據庫測試

新增用戶和授權
1. 建立數據庫
CREATE DATABASE legendshop_test;
2. 創建用戶
grant all privileges on legendshop_sr1.* to legendshop_sr1@'%' identified by 'legendshop_sr1123';

在主庫做的動作同樣在從庫中會有相同的數據,否則就是無法同步數據了。


分享到:


相關文章: