主从复制是指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中
对于多级复制,数据库服务器即可充当主机,也可充当从机
MySQL 主从复制的基础是主服务器对数据库修改记录二进制日志,从服务器通过主服务器的二进制日志自动执行更新
1. 集群部署
1 2 3 $ cd /opt/app/docker/mysql8 $ mkdir -p {master,slave1,slave2}/{conf,data,logs}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 $ cd master $ vi conf/my.cnf [mysqld] server-id=1 binlog-ignore-db=mysql log-bin=app-mysql-bin binlog_cache_size=1M binlog_format=mixed binlog_expire_logs_seconds=604800 replica_skip_errors=1062 character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci secure-file-priv=/var/lib/mysql skip-name-resolve [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 $ vi start.sh docker run -d -p 3307:3306 --name mysql-master \ -v $PWD /logs:/var/log/mysql \ -v $PWD /data:/var/lib/mysql \ -v $PWD /conf:/etc/mysql \ --cap-add=sys_nice \ -e MYSQL_ROOT_PASSWORD=root \ mysql:8 $ chmod +x start.sh $ ./start.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 $ cd slave1 $ vi conf/my.cnf [mysqld] server-id=2 binlog-ignore-db=mysql log-bin=app-mysql-slave-bin binlog_cache_size=1M binlog_format=mixed binlog_expire_logs_seconds=604800 replica_skip_errors=1062 relay_log=app-mysql-relay-bin log_replica_updates=1 read_only=1 log_bin_trust_function_creators=true character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci secure-file-priv=/var/lib/mysql skip-name-resolve [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 $ vi start.sh docker run -d -p 3308:3306 --name mysql-slave1 \ -v $PWD /logs:/var/log/mysql \ -v $PWD /data:/var/lib/mysql \ -v $PWD /conf:/etc/mysql \ --cap-add=sys_nice \ -e MYSQL_ROOT_PASSWORD=root \ mysql:8 $ chmod +x start.sh $ ./start.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 $ cd slave2 $ vi conf/my.cnf [mysqld] server-id=3 binlog-ignore-db=mysql log-bin=app-mysql-slave-bin binlog_cache_size=1M binlog_format=mixed binlog_expire_logs_seconds=604800 replica_skip_errors=1062 relay_log=app-mysql-relay-bin log_replica_updates=1 read_only=1 log_bin_trust_function_creators=true character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci secure-file-priv=/var/lib/mysql skip-name-resolve [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 $ vi start.sh docker run -d -p 3309:3306 --name mysql-slave2 \ -v $PWD /logs:/var/log/mysql \ -v $PWD /data:/var/lib/mysql \ -v $PWD /conf:/etc/mysql \ --cap-add=sys_nice \ -e MYSQL_ROOT_PASSWORD=root \ mysql:8 $ chmod +x start.sh $ ./start.sh
2. 集群配置
1 2 3 4 5 6 7 8 9 10 11 $ docker exec -it mysql-master /bin/bash root@9fcd4440d1bb:/ mysql> CREATE USER 'slave' @'%' IDENTIFIED BY '123456' ; mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave' @'%' ; mysql> FLUSH PRIVILEGES; mysql> show master status; +----------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +----------------------+----------+--------------+------------------+-------------------+ | app-mysql-bin.000003 | 880 | | mysql | | +----------------------+----------+--------------+------------------+-------------------+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 $ docker exec -it mysql-slave1 /bin/bash root@338d4b2a47af:/ mysql> change master to master_host='10.4.7.101' , master_port=3307, master_user='slave' , master_password='123456' , master_log_file='app-mysql-bin.000003' , master_log_pos=880, master_connect_retry=30, get_master_public_key=1; mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Master_Host: 10.4.7.101 Master_User: slave Master_Port: 3307 Connect_Retry: 30 Master_Log_File: app-mysql-bin.000003 Read_Master_Log_Pos: 880 Relay_Log_File: app-mysql-relay-bin.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: app-mysql-bin.000003 Slave_IO_Running: No Slave_SQL_Running: No ...... mysql> start slave; mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for source to send event Master_Host: 10.4.7.101 Master_User: slave Master_Port: 3307 Connect_Retry: 30 Master_Log_File: app-mysql-bin.000003 Read_Master_Log_Pos: 880 Relay_Log_File: app-mysql-relay-bin.000002 Relay_Log_Pos: 328 Relay_Master_Log_File: app-mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes ...... mysql> mysql>
3. 集群测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 mysql> show slave hosts; +-----------+------+------+-----------+--------------------------------------+ | Server_id | Host | Port | Master_id | Slave_UUID | +-----------+------+------+-----------+--------------------------------------+ | 3 | | 3306 | 1 | f5a894d5-7c88-11ee-9031-0242ac110004 | | 2 | | 3306 | 1 | bb438a7c-7c88-11ee-b920-0242ac110003 | +-----------+------+------+-----------+--------------------------------------+ mysql> create database test ; mysql> use test ; mysql> create table t1(id int, name varchar(20)); mysql> insert into t1(id , name) values (1,'hello' ); mysql> select * from t1; mysql> use test ; mysql> select * from t1;
4. 部署问题 (1) Authentication plugin ‘caching_sha2_password’ reported error: Authentication require secure connection
在 MySQL 8 之前,身份验证的插件是 mysql_native_password
,在 MySQL 8 中,caching_sha2_password
是默认的身份验证插件,安全性更高
如果复制用户的身份验证插件是 caching_sha2_password
,则需要指定 GET_MASTER_PUBLIC_KEY=1
;如果是 mysql_native_password
则不需要指定
1 2 3 4 5 mysql> CREATE USER 'slave' @'%' IDENTIFIED WITH mysql_native_password BY '123456' ; mysql> ALTER USER 'slave' @'%' IDENTIFIED WITH mysql_native_password BY '123456' ; $ vi my.cnf default_authentication_plugin=mysql_native_password
(2) mbind: Operation not permitted
5. 5.7 集群部署 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 $ mkdir -p {3307..3309}/{logs,data,conf} $ cd 3307 $ vi start.sh docker run -p 3307:3306 --name mysql-master \ -v $PWD /logs:/var/log/mysql \ -v $PWD /data:/var/lib/mysql \ -v $PWD /conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=root \ -d mysql:5.7 $ vi conf/my.cnf [mysqld] server_id=101 binlog-ignore-db=mysql log-bin=mall-mysql-bin binlog_cache_size=1M binlog_format=mixed expire_logs_days=7 slave_skip_errors=1062 $ chmod +x start.sh $ ./start.sh $ docker exec -it mysql-master /bin/bash root@1cf918631596:/ mysql> CREATE USER 'slave' @'%' IDENTIFIED BY '123456' ; mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave' @'%' ; mysql> FLUSH PRIVILEGES; $ cd 3308 $ vi start.sh docker run -p 3308:3306 --name mysql-slave \ -v $PWD /logs:/var/log/mysql \ -v $PWD /data:/var/lib/mysql \ -v $PWD /conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=root \ -d mysql:5.7 $ vi conf/my.cnf [mysqld] server_id=102 binlog-ignore-db=mysql log-bin=mall-mysql-slave1-bin binlog_cache_size=1M binlog_format=mixed expire_logs_days=7 slave_skip_errors=1062 relay_log=mall-mysql-relay-bin log_slave_updates=1 read_only=1 $ chmod +x start.sh $ ./start.sh $ docker exec -it mysql-master /bin/bash root@1cf918631596:/ mysql> show master status; +-----------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-----------------------+----------+--------------+------------------+-------------------+ | mall-mysql-bin.000003 | 617 | | mysql | | +-----------------------+----------+--------------+------------------+-------------------+ $ docker exec -it mysql-slave /bin/bash root@8c339c111456:/ mysql> change master to master_host='10.4.7.101' , master_port=3307, master_user='slave' , master_password='123456' , master_log_file='mall-mysql-bin.000003' , master_log_pos=617, master_connect_retry=30; mysql> start slave; mysql> show slave status \G;
参考