主从复制有如下一些优势:
分担负载:对业务进行读写分离,减轻主库I/O负载,将部分压力分担到从库上,缩短客户查询响应时间。
增加健壮性:在主库出现问题时,可通过多种方案将从库设置为主库,替换主库支撑业务,缩短停机窗口。
有利备份:在从库上备份,即不影响主库的事务,也不影响主库性能和磁盘空间。
查询分析:从库可以作为统计、报表等数据分析工作所使用的的OLAP库。
异地备份:将从库放置在异地可作为异地数据同步备份所用。
从MySQL的5.7版本开始支持多源主从复制技术(Multi-Source Replication),就是将多个数据库(Master)的数据集中发送到1台从库(Slave)上,该技术也具有刚才上文提到的主从复制的优势,除了这些,它的独特性还在于:
汇聚数据:尤其是在分库分表的一些场景中,数据集中统计分析操作可以在1台从库服务器上实现。
节省成本:数据集中存放可避免服务器等软硬件资源浪费,5.7之前1主1从或者1主多从的方案需要为每个主机都安置一台备机;5.7推出多源复制之后,可以将多个从库进行合并,至于是合并存放在高端还是低端服务器上,取决于分析、统计等业务在整体业务中的优先级、繁忙程度等因素。
集中备份:方便在一台服务器备份所有已收到的数据库数据。
异地灾备:将从库放在距离远的地方,可用于异地备份项目。
一、本次实验将使用MySQL 5.7.x作为多“主”。
〇 测试环境:
OS:CentOS 7.5
master_1: 192.168.1.185(MySQL 5.7.30)
master_2: 192.168.1.186(MySQL 5.7.30)
slave: 192.168.1.1.187(MySQL 5.7.35)
〇 配置:
master_1相关配置:
master_2相关配置:
slave相关配置:
〇 为master_1 & master_2上建立复制用户:
〇 测试数据准备:
master_1测试数据:
master_2测试数据:
〇 在slave上执行:
最后通过start slave status即可查到复制状态
〇 测试:
master_1上操作:
master_2上操作:
slave上操作:
〇 其他相关语法:
ps.
与上述传统position方式类似,GTID方式配置起来也类似,开启GTID后,需要注意使用FOR CHANNEL 'xxx'关键字即可,比如:
多台主机的schema名字不可以一样,(比如master_1为db_00 ... db_09共10库,master_2为db_10 ... db_19,master_3为db_20 ... db_29 ……)
1: 创建集中库: 主要就是存储历史数据。作为查询使用。
2:创建多个业务库:满足项目高并发的能力。
1: VM ware 虚拟机 - centOS 7
centOS-1: 192.168.194.3 主 100-------业务库
centOS-2: 192.168.194.4 主 200-------业务库
centOS-3: 192.168.194.5 从 300-------相当于集中库
2:mysql 5.7
1: 主库100
设置my.cnf。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
设置slave用户
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
2: 主库200
设置my.cnf。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
设置slave用户
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
3: 从库300
设置my.cnf。
1 2 3 4 5 6 7 8 9 10 |
|
设置主库信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
标识同步成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
测试。
随意主库:创建表,插入一条数据。
1 2 3 4 5 6 7 8 9 10 11 |
|
从库查询
1 2 3 4 5 |
|
mysql基于docker-compose进行安装,使用服务器(局域网)
Master1:192.168.100.1
Master2:192.168.100.2
Slave:192.168.100.3
安装docker
安装dosker-compose
Docker相关操作,安装部分进行单独管理,在服务器新建相关管理目录
a) /usr/local/docker/mysql
b) mysql下新建目录master(/usr/local/docker/mysql/master)用于挂载mysql配置和数据相关文件,防止docker重启数据丢失
c) 新建docker-compose.yml文件,内容如下:
注意,镜像一定指定版本,不要使用last
d) 在master/conf/mycnf目录下新建文件 my.cnf,此文件为多数据库配置关键文件,配置如下:
master-1-mycnf.png
e) 启动镜像(需在当前目录下,含yml文件)
docker-compose up –d
以上命令是yml文件名称为docker-compose的情况下使用,使用其他名称,需要加-f,如:docker-compose –f mysql.yml up –d
注:可以先docker-compose up启动,此时可以查看启动日志,看是否存在问题,确认成功后加 –d ,含义为后台运行
master1和master2都为以上配置
slave配置
a) mysql安装配置一致
b) 挂载目录不同 /usr/local/docker/mysql/slave
,目录为slave,其余目录都一致,配置和数据在slave目录下
c) 在slave/conf/mycnf目录下新建文件 my.cnf,此文件为多数据库配置关键文件,配置如下:
slave-mycnf.png
d) 启动docker镜像
mysql设置主从相关数据权限和配置(内部配置)
a) 进入mysql容器docker exec –it mysql bash
b) 登录mysqlmysql –uroot -proot
c) master 相关配置命令
新建用户并设置权限(该用户用于主从复制)grant replication slave on *.* to 'slave'@'%' identified by '123456';
d) 刷新mysql权限flush privileges;
e) 主从复制有两种模式,binlog模式 和 GTID模式,两种模式都可以完成复制,此处采用GTID模式,并以此说明,binlog模式有需要了解可以@me
f) 采用GTID模式,master配置即完成
g) Slave配置
命令:change master to master_host='192.168.100.221',master_port=3306,master_user='slave', master_password='123456',master_auto_position = 1 for channel 'master-3';
h) 开启主从复制模式start slave for channel master-3;
i) 查看主从同步状态是否成功show slave status\G;
只有【Slave_IO_Running】和【Slave_SQL_Running】都是Yes,则同步是正常的。
如果是No或者Connecting都不行,可查看mysql-error.log,以排查问题。
主库配置如下:
lower_case_table_names = 1
# 表名不区分大小写
server_id = 1533306
log_bin = mysql-bin
#开始binlog记录
binlog_format = MIXED
#每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最大的设置。
#这样的话,在数据库所在的主机操作系统损坏或者突然掉电的情况下,系统才有可能丢失1个事务的数据
#但是binlog虽然是顺序IO,但是设置sync_binlog=1,多个事务同时提交,
#同样很大的影响MySQL和IO性能。按需设置。
sync_binlog = 1
auto_increment_increment=2
auto_increment_offset=1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
# 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days = 7
binlog_cache_size = 128m
max_binlog_cache_size = 512m
max_binlog_size = 256M
# 需要同步库
#binlog-do-db = emp
# 不需要同步库
binlog-ignore-db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performation_schema
binlog_ignore_db = sys
# GTID mode
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
主库上创建复制用户如下:
1)创建用户
set global validate_password_policy=0;
set global validate_password_length=1;
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
update mysql.user set authentication_string=password('123456') where user='root';
UPDATE mysql.user SET Host='%' WHERE User='root';
flush privileges;
select host,user,authentication_string from mysql.user;
2)创建复制用户
set global validate_password_policy=0;
set global validate_password_length=1;
create user 'rep'@'%' identified by '123456';
grant replication slave, replication client on *.* to 'rep'@'%';
FLUSH PRIVILEGES;
从库配置如下:
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
server_id=1563306
log-bin=mysql-bin
#relay-log = mysql-relay-bin
#replicate-wild-ignore-table=mysql.%
#replicate-wild-ignore-table=test.%
#replicate-wild-ignore-table=information_schema.%
#master_info_repository = table
#relay_log_info_repository = table
replicate-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=sys
replicate-rewrite-db=emp->source
replicate-rewrite-db=emp1->source
replicate-rewrite-db=emp2->source
#replicate-rewrite-db=emp3->source
#replicate-rewrite-db=emp4->source
#replicate-rewrite-db=emp5->source
#replicate-rewrite-db=emp6->source
#replicate-rewrite-db=emp7->source
slave_net_timeout=60
slave_parallel_workers=16
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
slave-skip-errors=1062,1053,1146,1213,1264,1205,1396,1032
master_info_repository = table
relay_log_info_repository = table
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
从库上配置主库复制连接如下
主库: show master status;
# 设置主库信息,从库执行;
CHANGE MASTER TO
MASTER_HOST='192.168.86.153',
MASTER_PORT=3306, MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=194 for channel 'master153';
CHANGE MASTER TO
MASTER_HOST='192.168.86.154',
MASTER_PORT=3306, MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=194 for channel 'master154';
CHANGE MASTER TO
MASTER_HOST='192.168.86.155',
MASTER_PORT=3306, MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=194 for channel 'master155';
# 设置主库信息,从库执行;
flush privileges;
start slave;
show slave status \G;
标识同步成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
注: GTID复制MASTER_auto_position=1
# 设置主库信息,从库执行;
CHANGE MASTER TO
MASTER_HOST='192.168.86.153',
MASTER_PORT=3306, MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_auto_position=1 for channel 'master153';
CHANGE MASTER TO
MASTER_HOST='192.168.86.154',
MASTER_PORT=3306, MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_auto_position=1 for channel 'master154';
CHANGE MASTER TO
MASTER_HOST='192.168.86.155',
MASTER_PORT=3306, MASTER_USER='rep',
MASTER_PASSWORD='123456',
MASTER_auto_position=1 for channel 'master155';
stop slave ;
reset slave all ;
change master to MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=1987 for channel 'master153';
change master to MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=1388 for channel 'master154';
change master to MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=1388 for channel 'master155';
start slave;
二、MySQL多源复制,将多台Master端库以“主从复制”的方式同步到一台Slave端,可以有效的节省主机资源。
操作系统 | 数据库版本 | 角色 | IP | 主机名 |
CentOS 7.6 | MySQL 8.0.29 | Master A | 192.168.1.71 | host71 |
CentOS 7.6 | MySQL 8.0.29 | Master B | 192.168.1.72 | host72 |
CentOS 7.6 | MySQL 8.0.29 | Master C | 192.168.1.73 | host73 |
1. 配置my.cnf(根据个人环境调整其他参数)
server_id = 71 #三台保持唯一性
port = 3380
log_bin = /data/mysql/log_bin
binlog_expire_logs_seconds = 259200
gtid_mode = on
log-slave-updates = on
enforce-gtid-consistency = on
2. host72端备份+创建复制用户repll
[root]# mysqldump host72 > host72.sql
mysql> create user 'rep'@'192.168.1.%' identified by 'Replication@80';
mysql> grant repication slave,replication client on host72.* to 'repl'@'192.168.1.%';
3. host73端备份+创建复制用户repl
mysqldump host73 > host73.sql
mysql> create user 'rep'@'192.168.1.%' identified by 'Replication@80';
mysql> grant repication slave,replication client on host72.* to 'repl'@'192.168.1.%';
4. host71端恢复数据
[root]# mysql -e "reset master;" && mysql < host72.sql
[root]# mysql -e "reset master;" && mysql < host73.sql
5. 配置主从
mysql> change master to MASTER_HOST='192.168.1.72',MASTER_USER='repl',MASTER_PASSWORD='Gaoyu@029',MASTER_PORT=3380,MASTER_AUTO_POSITION=1 for channel 'host72';
mysql> change master to MASTER_HOST='192.168.1.73',MASTER_USER='repl',MASTER_PASSWORD='Gaoyu@029',MASTER_PORT=3380,MASTER_AUTO_POSITION=1 for channel 'host73';
6. 配置复制过滤
配置复制过滤只从192.168.1.72上复制host72库
mysql> change replication filter REPLICATE_DO_DB=(host72) for channel 'host72';
配置复制过滤只从192.168.1.73复制host73库
mysql> change replication filter REPLICATE_DO_DB=(host73) for channel 'host73';
7. 启动slave
mysql> start slave for channel 'host72';
mysql> start slave for channel 'host73';
8. 查看slave状态
mysql> show slave status\G
三、MySQL5.7 多主一从(多源复制)同步配置
多主一从,也称为多源复制,数据流向:
注:使用 docker 部署 mysql 实例,方便快速搭建演示环境。但本文重点是讲解主从配置,因此简略描述 docker 环境构建 mysql 容器实例。
vim /etc/sysconfig/selinux
SELINUX=disabled
# 若不关闭,使用docker启动mysql5.7镜像容器时启动不起来,查看日志会有如下错误显示:
ERROR: mysqld failed while attempting to check config
command was: "mysqld --verbose --help"
mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
ERROR: mysqld failed while attempting to check config
command was: "mysqld --verbose --help"
mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
yum install epel-release
yum -y install docker
systemctl start docker.service
mkdir -p /datavol/mysql-300/{mysql,conf}
mkdir -p /datavol/mysql-400/{mysql,conf}
mkdir -p /datavol/mysql-500/{mysql,conf}
mkdir -p /datavol/mysql-10345/{mysql,conf}
把该文件放到主库所在配置文件路径下:/datavol/mysql-300/conf
[client]
port = 3306
default-character-set = utf8mb4
[mysql]
port = 3306
default-character-set = utf8mb4
[mysqld]
##########################
# summary
##########################
#bind-address = 0.0.0.0
#port = 3306
#datadir=/datavol/mysql/data #数据存储目录
##########################
# log bin
##########################
server-id = 300 #必须唯一
log_bin = mysql-bin #开启及设置二进制日志文件名称
binlog_format = MIXED
sync_binlog = 1
expire_logs_days =7 #二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
#binlog_cache_size = 128m
#max_binlog_cache_size = 512m
#max_binlog_size = 256M
binlog-do-db = test3 #要同步的数据库
binlog-ignore-db = mysql #不需要同步的数据库
binlog_ignore_db = information_schema
binlog_ignore_db = performation_schema
binlog_ignore_db = sys
##########################
# character set
##########################
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[root@localhost ~]# docker run -d -p 4300:3306 --name=mysql-300 -v /datavol/mysql-300/conf:/etc/mysql/conf.d -v /datavol/mysql-300/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
5691bac538e646db00273e3cad5b350dbe6cce0bd176346b7eefd9a6f9e3a9ad
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5691bac538e6 mysql:5.7 "docker-entrypoint..." 44 seconds ago Up 43 seconds 33060/tcp, 0.0.0.0:4300->3306/tcp mysql-300
[root@localhost ~]# docker exec -it mysql-300 /bin/bash
root@5691bac538e6:/# mysql -u root -p
Enter password:
注:若不熟悉 docker,可使用传统方式安装 mysql,效果相同。
连接 mysql 主数据库,键入命令 mysql -u root -p,输入密码后登录数据库。创建用户用于从库同步复制,授予复制、同步访问的权限
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'slave'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set
mysql> show master status \G
*************************** 1. row ***************************
File: mysql-bin.000003
Position: 438
Binlog_Do_DB: test3
Binlog_Ignore_DB: mysql,information_schema,performation_schema,sys
把该文件放到主库所在配置文件路径下:/datavol/mysql-400/conf
[client]
port = 3306
default-character-set = utf8mb4
[mysql]
port = 3306
default-character-set = utf8mb4
[mysqld]
##########################
# summary
##########################
#bind-address = 0.0.0.0
#port = 3306
#datadir=/datavol/mysql/data #数据存储目录
##########################
# log bin
##########################
server-id = 400 #必须唯一
log_bin = mysql-bin #开启及设置二进制日志文件名称
binlog_format = MIXED
sync_binlog = 1
expire_logs_days =7 #二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
#binlog_cache_size = 128m
#max_binlog_cache_size = 512m
#max_binlog_size = 256M
binlog-do-db = test4 #要同步的数据库
binlog-ignore-db = mysql #不需要同步的数据库
binlog_ignore_db = information_schema
binlog_ignore_db = performation_schema
binlog_ignore_db = sys
##########################
# character set
##########################
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[root@localhost ~]# docker run -d -p 4400:3306 --name=mysql-400 -v /datavol/mysql-400/conf:/etc/mysql/conf.d -v /datavol/mysql-400/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
19e93b6d93ca4e6ca0d540e3f6c831b835cdbb35362733867c3977aee4d33bf7
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19e93b6d93ca mysql:5.7 "docker-entrypoint..." 4 seconds ago Up 3 seconds 33060/tcp, 0.0.0.0:4400->3306/tcp mysql-400
[root@localhost ~]# docker exec -it mysql-400 /bin/bash
root@19e93b6d93ca:/# mysql -u root -p
Enter password:
创建用户用于从库同步复制,授予复制、同步访问的权限
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'slave'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set
mysql> show master status \G;
*************************** 1. row ***************************
File: mysql-bin.000003
Position: 438
Binlog_Do_DB: test4
Binlog_Ignore_DB: mysql,information_schema,performation_schema,sys
把该文件放到主库所在配置文件路径下:/datavol/mysql-500/conf
[client]
port = 3306
default-character-set = utf8mb4
[mysql]
port = 3306
default-character-set = utf8mb4
[mysqld]
##########################
# summary
##########################
#bind-address = 0.0.0.0
#port = 3306
#datadir=/datavol/mysql/data #数据存储目录
##########################
# log bin
##########################
server-id = 500 #必须唯一
log_bin = mysql-bin #开启及设置二进制日志文件名称
binlog_format = MIXED
sync_binlog = 1
expire_logs_days =7 #二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
#binlog_cache_size = 128m
#max_binlog_cache_size = 512m
#max_binlog_size = 256M
binlog-do-db = test5 #要同步的数据库
binlog-ignore-db = mysql #不需要同步的数据库
binlog_ignore_db = information_schema
binlog_ignore_db = performation_schema
binlog_ignore_db = sys
##########################
# character set
##########################
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[root@localhost ~]# docker run -d -p 4500:3306 --name=mysql-500 -v /datavol/mysql-500/conf:/etc/mysql/conf.d -v /datavol/mysql-500/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
19e93b6d93ca4e6ca0d540e3f6c831b835cdbb35362733867c3977aee4d33bf7
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19e93b6d93ca mysql:5.7 "docker-entrypoint..." 4 seconds ago Up 3 seconds 33060/tcp, 0.0.0.0:4500->3306/tcp mysql-500
[root@localhost ~]# docker exec -it mysql-500 /bin/bash
root@19e93b6d93ca:/# mysql -u root -p
Enter password:
创建用户用于从库同步复制,授予复制、同步访问的权限
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'slave'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set
mysql> show master status \G
*************************** 1. row ***************************
File: mysql-bin.000003
Position: 438
Binlog_Do_DB: test5
Binlog_Ignore_DB: mysql,information_schema,performation_schema,sys
把该文件放到主库所在配置文件路径下:/datavol/mysql-10345/conf
[client]
port = 3306
default-character-set = utf8mb4
[mysql]
port = 3306
default-character-set = utf8mb4
[mysqld]
##########################
# summary
##########################
#bind-address = 0.0.0.0
#port = 3306
#datadir=/datavol/mysql/data #数据存储目录
##########################
# log bin
##########################
server-id = 10345
master_info_repository = table
relay_log_info_repository = table
##########################
# character set
##########################
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[root@localhost ~]# docker run -d -p 4345:3306 --name=mysql-10345 -v /datavol/mysql-10345/conf:/etc/mysql/conf.d -v /datavol/mysql-10345/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
19e93b6d93ca4e6ca0d540e3f6c831b835cdbb35362733867c3977aee4d33bf7
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19e93b6d93ca mysql:5.7 "docker-entrypoint..." 4 seconds ago Up 3 seconds 33060/tcp, 0.0.0.0:4345->3306/tcp mysql-10345
[root@localhost ~]# docker exec -it mysql-10345 /bin/bash
root@19e93b6d93ca:/# mysql -u root -p
Enter password:
登录【从库 10345】,进入 mysql 命令行。
mysql> stop slave;
Query OK, 0 rows affected
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.10.212',
MASTER_PORT=4300,
MASTER_USER='slave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=438
for channel '300';
Query OK, 0 rows affected
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.10.212',
MASTER_PORT=4400,
MASTER_USER='slave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=438
for channel '400';
Query OK, 0 rows affected
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.10.212',
MASTER_PORT=4500,
MASTER_USER='slave',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=438
for channel '500';
Query OK, 0 rows affected
mysql> start slave;
Query OK, 0 rows affected
stop slave; // 停止同步 start slave; // 开始同步 // 必须和【主库】的信息匹配。
CHANGE MASTER TO MASTER_HOST='192.168.10.212', // 主库 IP MASTER_PORT=4300, // 主库端口 MASTER_USER='slave', // 访问主库且有同步复制权限的用户 MASTER_PASSWORD='123456', // 登录密码 //【关键处】从主库的该 log_bin 文件开始读取同步信息,主库 show master status 返回结果 MASTER_LOG_FILE='mysql-bin.000003', //【关键处】从文件中指定位置开始读取,主库 show master status 返回结果 MASTER_LOG_POS=438 **for channel '300'; // 定义通道名称 **
mysql> show slave status \G
可以看见设置三个的主从同步通道的所有状态信息。 只有【Slave_IO_Running】和【Slave_SQL_Running】都是 Yes,则同步是正常的。 如果是 No 或者 Connecting 都不行,可查看 mysql-error.log,以排查问题。
mysql> show variables like 'log_error%';
+---------------------+--------+
| Variable_name | Value |
+---------------------+--------+
| log_error | stderr |
| log_error_verbosity | 3 |
+---------------------+--------+
2 rows in set
配置完成,则【从库 10345】开始自动同步。
若需要单独启动或停止某个同步通道,可使用如下命令: start slave for channel '300'; // 启动名称为 300 的同步通道 stop slave for channel '300'; // 停止名称为 300 的同步通道
使用 root 账号登录【主库 300】,创建 test3 数据库
mysql> CREATE DATABASE test3;
Query OK, 1 row affected (0.00 sec)
mysql> USE test3;
Database changed
在【主库 300】中创建 user 表
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`age` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
在【主库 300】中向 user 表插入一条数据:
mysql> use test3;
Database changed
mysql> INSERT INTO user (id, name, age) VALUES (300, 'Tom', 18);
Database changed
mysql> SELECT * FROM user;
+-----+------+-----+
| id | name | age |
+-----+------+-----+
| 300 | Tom | 18 |
+-----+------+-----+
1 row in set (0.00 sec)
在【从库 10345】中查询 user 表数据:
mysql> use test3;
Database changed
mysql> SELECT * FROM user;
+-----+------+-----+
| id | name | age |
+-----+------+-----+
| 300 | Tom | 18 |
+-----+------+-----+
1 row in set (0.00 sec)
新增记录同步成功。
在【主库 300】中修改刚才插入的数据:
mysql> UPDATE user SET name='Peter' where id=300;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from user;
+-----+-------+-----+
| id | name | age |
+-----+-------+-----+
| 300 | Peter | 18 |
+-----+-------+-----+
1 row in set (0.00 sec)
在【从库 10345】中查询 user 表数据:
mysql> select * from user;
+-----+-------+-----+
| id | name | age |
+-----+-------+-----+
| 300 | Peter | 18 |
+-----+-------+-----+
1 row in set (0.00 sec)
更新记录同步成功。
在【主库 300】中删除刚才更新的数据:
mysql> DELETE FROM user WHERE id=300;
Query OK, 1 row affected (0.00 sec)
mysql> select * from user;
Empty set (0.00 sec)
在【从库 10345】中查询 user 表数据:
mysql> select * from user;
Empty set (0.00 sec)
删除记录同步成功。 注:【主库 400】、【主库 500】的验证操作与上述类似。
补充:
四、设置MYSQL主从同步场景
1.业务场景
一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中。对于多级复制,数据库服务器即可充当主机,也可充当从机。
一句话表示就是,主数据库做什么,从数据库就跟着做什么。
我们的主从复制基于Mysql Replication来进行实现
Replication可以实现将数据从一台数据库服务器(master)复制到一台或多台数据库服务器(slave)
简单的说就是master将数据库的改变写入二进制日志,slave同步这些二进制日志,并根据这些二进制日志进行数据操作。
注意:
整体上来说,复制有3个步骤:
(1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events)
(2) slave将master的binary log events拷贝到它的中继日志(relay log)
(3) slave重做中继日志中的事件,修改salve上的数据。
第一步:master记录二进制日志
在每个事务更新数据完成之前,master在二进制日志记录这些改变。MySQL将事务写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
第二步:slave将master的binary log拷贝到它自己的中继日志
首先,slave开始一个工作线程—I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经执行完master产生的所有文件,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。
第三步:SQL slave thread(SQL从线程)处理该过程的最后一步
SQL线程从中继日志读取事件,并重新执行其中的事件而更新slave的数据,使其与master中的数据一致。
一般用来做读写分离的,master写,其他slave读,这种架构最大问题I/O压力集中在Master上<多台同步影响IO>
使用一台slave作为中继,分担Master的压力,slave中继需要开启bin-log,并配置log-slave-updates
Slave中继可使用Black-hole存储引擎,不会把数据存储到磁盘,只记录二进制日志。
每个服务器需要做同样的同步更新,破坏了事物的隔离性和数据的一致性。
天生的缺陷:复制延迟,slave上同步要慢于master,如果大并发的情况那延迟更严重。
mysql在5.6已经自身可以实现fail over故障切换
好处:节省成本,将多个master数据自动化整合
缺陷:对库和表数据的修改较多
本地安装两个mysql,或者使用虚拟机,或者使用docker安装,需要准备两个mysql,本文使用docker安装
在docker中先创建两个mysql服务器
主服务器:3308
从服务器:3309
#mysql master1 config
[mysqld]
server-id = 1 # 节点ID,确保唯一
# log config
log-bin = mysql-bin #开启mysql的binlog日志功能
sync_binlog = 1 #控制数据库的binlog刷到磁盘上去 , 0 不控制,性能最好,1每次事物提交都会刷到日志文件中,性能最差,最安全
binlog_format = mixed #binlog日志格式,mysql默认采用statement,建议使用mixed
expire_logs_days = 7 #binlog过期清理时间
max_binlog_size = 100m #binlog每个日志文件大小
binlog_cache_size = 4m #binlog缓存大小
max_binlog_cache_size= 512m #最大binlog缓存大
binlog-ignore-db=mysql #不生成日志文件的数据库,多个忽略数据库可以用逗号拼接,或者 复制这句话,写多行
auto-increment-offset = 1 # 自增值的偏移量
auto-increment-increment = 1 # 自增值的自增量
slave-skip-errors = all #跳过从库错误
[mysqld]
server-id = 2
log-bin=mysql-bin
relay-log = mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
依次执行
CREATE USER repl_user IDENTIFIED BY 'root';
CREATE USER 'repl_user'@'172.17.0.1' IDENTIFIED BY 'root';
CREATE USER 'repl_user'@'192.168.1.2' IDENTIFIED BY 'root';
你只需要修改的是将 192.168.1.2改为你自己主机的ip地址即可
查看自己创建用户是否成功
SELECT User, Host FROM mysql.user;
依次执行
grant replication slave on *.* to 'repl_user'@'%';
grant replication slave on *.* to 'repl_user'@'172.17.0.1';
grant replication slave on *.* to 'repl_user'@'192.168.1.2';
FLUSH PRIVILEGES;
注意:我们接下来进行一个很重要的步骤,就是修改主库repl_user的plugin
依次执行以操作:
alter user 'repl_user'@'%' identified with mysql_native_password by 'root';
alter user 'repl_user'@'172.17.0.1' identified with mysql_native_password by 'root';
alter user 'repl_user'@'192.168.1.2' identified with mysql_native_password by 'root';
show master status;
登录进入从库的mysql服务内执行以下命令
CHANGE MASTER TO
MASTER_HOST = 'localhost',
MASTER_USER = 'repl_user',
MASTER_PASSWORD = 'root',
MASTER_PORT = 3308,
MASTER_LOG_FILE='binlog.000002',
MASTER_LOG_POS=1374,
MASTER_RETRY_COUNT = 60,
MASTER_HEARTBEAT_PERIOD = 10000;
start slave;
show slave status\G
当这两个信息 都为yes时说明你配置成功啦。
然后刷新salve
然后会发现salve中也会出现一个test1数据库
主库:
从库:
主库:
从库:
relay_log_basename=/data/3308/data/db01-relay-bin
,从而指定文件位置和前缀名称master_info_repository=FILE/TABLE
来指定信息存在文件中或存在表中relay_log_info_repository=FILE/TABLE
来指定信息存在文件中或存在表中
文字说明:
小细节:
relay_log_purge=ON
,定期删除应用过的relay-logmysql> show processlist;
mysql> show slave hosts;
mysql> show slave status \G;
要监视复制通道的状态,存在以下选项:
使用复制性能架构表。这些表的第一列是Channel_Name。可以根据Channel_Name键编写复杂的查询。
SHOW REPLICA | SLAVE STATUS FOR CHANNELchannel
在 performance_schema 库中,提供了复制相关的一些视图,可供查看复制相关的信息。