双主双从
- 环境准备:4台CentOS7主机
- master1:192.168.152.71
- master2:192.168.152.72
- slave1:192.168.152.73
- slave2:192.168.152.74
- 实验环境,方便操作记得关闭防火墙,自动关闭防火墙脚本
说明:
从 1 复制 主1 ,从 2 复制 主 2
主 1 复制 主 2,主 2 复制主 1
一、安装MySQL
在四台服务器上分别安装数据库
配置 MySQL 的 yum 仓库;MySQL官方 yum 仓库地址
yum install -y https://dev.mysql.com/get/mysql84-community-release-el7-1.noarch.rpm
上面命令执行完毕后只能安装 MySQL84 版本,要想安装 MySQL80 版本还需执行下面三条命令
yum-config-manager --enable mysql80-community
yum-config-manager --disable mysql-8.4-lts-community
yum makecache
如果在yum makecache这一步报错先运行
rm -rf /etc/yum.repos.d/*
再运行
yum reinstall -y https://dev.mysql.com/get/mysql84-community-release-el7-1.noarch.rpm
再从第一行 yum-config-manager 开始
安装MySQL
yum install -y mysql-community-server
二、修改配置文件
修改配置文件,通常在 /etc/my.cnf
或 /etc/mysql/my.cnf
原内容不要删,直接在后面写
vim /etc/my.cnf
master1 配置文件
# 开启二进制日志,并指定二进制日志文件的存储位置及前缀名称
log-bin = /var/lib/mysql/binlog
# 服务ID,用于标识MySQL服务器实例,主从复制环境中每个MySQL服务器的server-id必须唯一
server-id = 1
# 主从复制忽略的数据库,这些系统数据库通常不需要复制
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
# 指定需要复制的数据库,这里只复制mydb2数据库。不写表示除忽略的数据库全部复制
binlog-do-db = mydb
# 二进制日志格式
# STATEMENT:基于SQL语句的复制,可能因时间函数等导致主从不一致
# ROW:基于行的复制,记录每一行的变化,效率较低
# MIXED:混合模式,默认STATEMENT,但在某些情况下使用ROW
binlog_format = statement
# 二进制日志自动删除/过期的天数,默认值为0表示不自动删除
expire_logs_days = 7
# 跳过主从复制中遇到的所有错误或指定类型的错误,这里跳过主键或唯一索引冲突的错误(错误码1062)
slave_skip_errors = 1062
# 在作为从数据库时,允许对从库的写入操作也更新二进制日志文件,以便链式复制或双主复制
log-slave-updates
# 自增长字段的步长,用于主从复制环境中避免主键冲突
auto-increment-increment = 2
# 自增长字段的起始值,用于设置从库的自增长字段起始值,与主库不同步长递增
auto-increment-offset = 1
# 连续发生的连接错误数超过了设置的阈值,服务器将出于安全考虑封锁自身,默认值通常是10万次左右,但具体值可能因MySQL版本而异
max_connect_errors = 1000
master2 配置文件
# 开启二进制日志,并指定二进制日志文件的存储位置及前缀名称
log-bin = /var/lib/mysql/binlog
# 服务ID,用于标识MySQL服务器实例,主从复制环境中每个MySQL服务器的server-id必须唯一
server-id = 2
# 主从复制忽略的数据库,这些系统数据库通常不需要复制
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
# 指定需要复制的数据库,这里只复制mydb2数据库。不写表示除忽略的数据库全部复制
binlog-do-db = mydb
# 二进制日志格式
# STATEMENT:基于SQL语句的复制,可能因时间函数等导致主从不一致
# ROW:基于行的复制,记录每一行的变化,效率较低
# MIXED:混合模式,默认STATEMENT,但在某些情况下使用ROW
binlog_format = statement
# 二进制日志自动删除/过期的天数,默认值为0表示不自动删除
expire_logs_days = 7
# 跳过主从复制中遇到的所有错误或指定类型的错误,这里跳过主键或唯一索引冲突的错误(错误码1062)
slave_skip_errors = 1062
# 在作为从数据库时,允许对从库的写入操作也更新二进制日志文件,以便链式复制或双主复制
log-slave-updates
# 自增长字段的步长,用于主从复制环境中避免主键冲突
auto-increment-increment = 2
# 自增长字段的起始值,用于设置从库的自增长字段起始值,与主库不同步长递增
auto-increment-offset = 2
# 连续发生的连接错误数超过了设置的阈值,服务器将出于安全考虑封锁自身,默认值通常是10万次左右,但具体值可能因MySQL版本而异
max_connect_errors = 1000
slave1 配置文件
# 服务ID,用于主从复制中的唯一标识
server-id = 3
# 中继日志配置
# 指定中继日志的文件名前缀为 relay
relay-log = mysql-relay
slave2 配置文件
# 服务ID,用于主从复制中的唯一标识
server-id = 4
# 中继日志配置
# 指定中继日志的文件名前缀为 relay
relay-log = mysql-relay
三、登录MySQL
启动 MySQL
systemctl start mysqld
systemctl enable mysqld
获取初始密码
grep 'passwork' /var/log/mysqld.log
结果大概为 2024-08-19T08:59:46.026947Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: vrP+yyDAI2lE
行尾的 vrP+yyDAI2lE
即为初始密码
或者运行下面命令直接获得,(只要日志格式不变,原理上是可以用的)
grep 'password' /var/log/mysqld.log | awk '{print $NF}'
更改密码
mysqladmin -uroot -p'初始密码' password '新密码'
确保安全可以在运行一下 history -h 清空一下命令行历史记录
四、创建授权账号
创建主主同步账号repl_user
主从同步账号slave_sync_user
master1和master2都分别执行一遍下面内容
-- 创建一个名为'repl_user'的用户,允许从'192.168.152.%'子网内的任意IP地址连接
-- 使用mysql_native_password作为认证方式,并设置密码为'Lty@123456'
CREATE USER 'repl_user'@'192.168.152.%' IDENTIFIED WITH mysql_native_password BY 'Lty@123456';
-- 创建一个名为'slave_sync_user'的用户,同样允许从'192.168.152.%'子网内的任意IP地址连接
-- 使用mysql_native_password作为认证方式,并设置与'repl_user'相同的密码(注意:实际环境中应避免使用相同密码)
CREATE USER 'slave_sync_user'@'192.168.152.%' IDENTIFIED WITH mysql_native_password BY 'Lty@123456';
-- 授予'repl_user'用户REPLICATION SLAVE和REPLICATION CLIENT权限
-- 这允许'repl_user'执行复制从服务器所需的操作以及查询复制状态
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl_user'@'192.168.152.%';
-- 授予'slave_sync_user'用户相同的REPLICATION SLAVE和REPLICATION CLIENT权限
-- 这同样允许'slave_sync_user'执行复制相关的操作并查询复制状态
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave_sync_user'@'192.168.152.%';
五、链接主机
链接master与slave
- master1 → slave1
- master2 → slave2
- 操作步骤相同,如下:
在master主机中执行以下 SQL 语句,记录下 File 和 Position 的值
SHOW MASTER STATUS;
登录 slave 主机的 mysql,执行下面命令
CHANGE MASTER TO
MASTER_HOST='master主机IP地址',
MASTER_USER='slave_sync_user',
MASTER_PASSWORD='Lty@123456',
MASTER_LOG_FILE='master服务器的File值',
MASTER_LOG_POS=master服务器的Position值;
如果报错,看下面内容
注意:在MySQL 8.0中,CHANGE MASTER TO
语句用于配置复制。但是,从MySQL 8.0.14开始,该语句已经被弃用,并建议使用新的语句CHANGE REPLICATION SOURCE TO
启动复制进程
START SLAVE;
执行以下 SQL 语句确认复制状态是否正常
SHOW SLAVE STATUS\G;
其中的两项如下,表示已经成功了
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
如果不是,查看字段 Last_IO_Error 和 Last_SQL_Error 看具体原因
链接master与master
两台master都按如下操作
在一个master主机中执行以下 SQL 语句,记录下 File 和 Position 的值
SHOW MASTER STATUS;
在另一个master主机中执行
CHANGE MASTER TO
MASTER_HOST='master主机IP地址',
MASTER_USER='repl_user',
MASTER_PASSWORD='Lty@123456',
MASTER_LOG_FILE='记录的File值',
MASTER_LOG_POS=记录的Position值;
启动复制进程
START SLAVE;
执行以下 SQL 语句确认复制状态是否正常
SHOW SLAVE STATUS\G;
其中的两项如下,表示已经成功了
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
如果不是,查看字段 Last_IO_Error 和 Last_SQL_Error 看具体原因
六、测试
在master1中创建数据库
CREATE DATABASE mydb;
CREATE TABLE mydb.test (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50));
INSERT INTO mydb.test (name) VALUES ("LTY");
查看其它服务器是否同步
SELECT * FROM mydb.test;