OpenEuler 系统 MySQL 主从复制 + MyCat 读写分离超详细教程
本教程全程适配OpenEuler 20.03/22.03/24.03 LTS 版本,针对安装在 /usr/local/mysql 路径下的 MySQL 5.7/8.0 版本深度适配,全程无 MySQL 安装步骤,覆盖主从复制全流程、MyCat 读写分离核心配置、效果验证与生产级避坑指南,所有命令可直接复制执行。
一、环境规划与前置准备
1. 节点与环境说明
表格
| 节点角色 | 节点 IP | 核心配置 | 安装路径 |
|---|---|---|---|
| Master 主库(写节点) | 192.168.1.100 | OpenEuler 系统、MySQL 服务正常运行、端口 3306 | /usr/local/mysql |
| Slave 从库(读节点) | 192.168.1.101 | OpenEuler 系统、MySQL 服务正常运行、端口 3306 | /usr/local/mysql |
| MyCat 中间件节点 | 192.168.1.102 | OpenEuler 系统、JDK8 + 环境 | /usr/local/mycat |
核心前提:
- 主从库 MySQL大版本必须完全一致(如均为 8.0.36),避免主从复制兼容性问题
- 所有节点之间网络互通,防火墙已放行对应端口,时间已同步
- 所有操作均使用 root 用户或具备 sudo 全权限的用户执行
2. 前置环境配置(所有节点必做)
(1)防火墙端口放行
bash
# 主从库节点放行MySQL 3306端口
firewall-cmd --permanent --add-port=3306/tcp
# MyCat节点放行数据端口8066、管理端口9066
firewall-cmd --permanent --add-port=8066/tcp --add-port=9066/tcp
# 所有节点重载防火墙规则生效
firewall-cmd --reload
(2)时间同步(主从库必做)
主从库时间不一致会导致主从复制失败、数据同步异常,OpenEuler 默认使用 chronyd 同步时间
bash
# 启动chronyd并设置开机自启
systemctl enable --now chronyd
# 强制同步系统时间
chronyc -a makestep
# 验证时间同步状态
timedatectl
(3)MySQL 命令环境变量配置(可选,简化操作)
若未配置环境变量,后续所有 MySQL 命令需使用绝对路径,建议配置全局环境变量
bash
# 写入环境变量配置
echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
# 生效配置
source /etc/profile
# 验证配置成功(输出版本号即为正常)
mysql --version
二、MySQL 主从复制配置(/usr/local/mysql 路径专属适配)
采用 MySQL 官方标准的基于 binlog 的异步主从复制方案,ROW 行级模式,数据一致性最高,适配 MyCat 读写分离场景。
1. 主库(Master)核心配置
(1)编辑 MySQL 主配置文件
MySQL 配置文件默认路径为/usr/local/mysql/etc/my.cnf,若不存在则为/usr/local/mysql/my.cnf,根据实际路径调整
bash
vim /usr/local/mysql/etc/my.cnf
(2)在 [mysqld] 段落中添加以下主从专属配置
ini
[mysqld]
# 必须配置:MySQL安装根目录(与你的实际安装路径一致)
basedir = /usr/local/mysql
# 必须配置:MySQL数据目录(与你的实际数据路径一致)
datadir = /usr/local/mysql/data
# 核心配置1:服务器唯一ID,主库固定为1,从库不能重复
server-id = 1
# 核心配置2:开启binlog二进制日志(主从复制必备),日志文件存放在数据目录
log_bin = mysql-bin
# 核心配置3:binlog格式,强制ROW行模式(数据恢复、主从同步无数据丢失风险)
binlog_format = ROW
# 核心配置4:binlog自动过期清理时间,单位天,避免磁盘占满
expire_logs_days = 7
# 核心配置5:每次事务提交立即刷写binlog到磁盘,极致数据安全
sync_binlog = 1
# 核心配置6:InnoDB事务刷盘策略,与sync_binlog配合实现双1安全模式
innodb_flush_log_at_trx_commit = 1
# 配置7:忽略不需要同步的系统库,避免主从同步异常
binlog_ignore_db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema
binlog_ignore_db = sys
# 配置8:关闭DNS反向解析,提升主从连接速度
skip_name_resolve = 1
# 配置9:主库关闭只读(超级管理员可写)
read_only = 0
# 字符集配置,避免主从同步乱码
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
(3)重启主库 MySQL 服务使配置生效
bash
# 方式1:使用MySQL自带启动脚本(推荐)
/usr/local/mysql/support-files/mysql.server restart
# 方式2:若已配置systemctl服务
systemctl restart mysql
(4)验证 binlog 是否开启成功
bash
/usr/local/mysql/bin/mysql -u root -p -e "SHOW VARIABLES LIKE 'log_bin';"
返回结果中Value为ON,即为开启成功。
(5)创建主从复制专用用户(最小权限原则)
-
登录主库 MySQL 命令行 bash
/usr/local/mysql/bin/mysql -u root -p -
创建复制专用用户并授权(适配 MySQL 5.7/8.0) sql
-- 创建复制用户,仅允许从库IP访问,替换为你的从库实际IP,%为全网段(不推荐生产使用) CREATE USER 'repl'@'192.168.1.101' IDENTIFIED WITH mysql_native_password BY 'Repl@123456'; -- 授予主从复制专属最小权限 GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'192.168.1.101'; -- 刷新权限生效 FLUSH PRIVILEGES;关键说明:MySQL 8.0 默认认证插件为
caching_sha2_password,MyCat 和主从复制可能出现兼容性问题,因此显式指定mysql_native_password认证插件。
(6)主库数据锁表与备份(主从数据基准同步)
核心目的:保证主从库初始数据完全一致,记录主库 binlog 同步位点
-
在当前 MySQL 终端执行锁表命令(锁表后不要退出当前终端,否则锁会自动释放,位点会变化)
sql
-- 全局读锁,锁表后主库仅可读,不可写,保证数据一致性 FLUSH TABLES WITH READ LOCK; -
新开一个终端,查看并记录主库 binlog 位点信息(必须记录,后续从库配置必填)
bash
/usr/local/mysql/bin/mysql -u root -p -e "SHOW MASTER STATUS;"示例返回结果,需记录
File(binlog 文件名)和Position(位点号):表格
File Position Binlog_Do_DB Binlog_Ignore_DB mysql-bin.000003 154 mysql,... -
备份主库业务数据(新开终端执行,不要退出锁表的终端)
bash
# 全库备份(推荐,保证主从数据完全一致) /usr/local/mysql/bin/mysqldump -u root -p \ --all-databases \ --single-transaction \ --routines --triggers --events \ --default-character-set=utf8mb4 \ > /root/master_full_backup.sql # 若仅需同步指定业务库,使用以下命令(替换为你的业务库名) # /usr/local/mysql/bin/mysqldump -u root -p --databases test_db > /root/master_test_db_backup.sql -
备份完成后,回到锁表的 MySQL 终端,解锁表恢复主库读写
sql
UNLOCK TABLES; exit; -
将主库的备份 SQL 文件传输到从库服务器
bash
scp /root/master_full_backup.sql root@192.168.1.101:/root/
2. 从库(Slave)核心配置
(1)编辑从库 MySQL 主配置文件
bash
vim /usr/local/mysql/etc/my.cnf
(2)在 [mysqld] 段落中添加从库专属配置
ini
[mysqld]
# 必须配置:MySQL安装与数据目录,与主库保持一致
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
# 核心配置1:服务器唯一ID,必须与主库不同,且集群内唯一,此处设为2
server-id = 2
# 核心配置2:开启中继日志(从库主从复制必备)
relay_log = relay-bin
# 核心配置3:中继日志自动恢复,从库宕机重启后自动修复中继日志
relay_log_recovery = 1
# 核心配置4:从库只读(仅超级管理员只读,普通用户不可写,避免写入从库导致主从同步异常)
read_only = 1
# 核心配置5:禁止超级管理员在从库写入(生产环境必加,彻底避免从库写入)
super_read_only = 1
# 配置6:关闭binlog日志(级联复制场景需开启,普通一主一从无需开启)
# log_bin = mysql-bin
# 配置7:与主库保持一致的binlog格式
binlog_format = ROW
# 配置8:忽略系统库同步,与主库保持一致
replicate_wild_ignore_table = mysql.%
replicate_wild_ignore_table = information_schema.%
replicate_wild_ignore_table = performance_schema.%
replicate_wild_ignore_table = sys.%
# 配置9:关闭DNS反向解析,提升主从连接速度
skip_name_resolve = 1
# 字符集配置,与主库完全一致
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
(3)重启从库 MySQL 服务使配置生效
bash
/usr/local/mysql/support-files/mysql.server restart
(4)从库导入主库基准备份数据
保证主从库初始数据完全一致,避免主从同步主键冲突
bash
# 全库备份导入
/usr/local/mysql/bin/mysql -u root -p < /root/master_full_backup.sql
# 若为单库备份,先创建库再导入
# /usr/local/mysql/bin/mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS test_db DEFAULT CHARACTER SET utf8mb4;"
# /usr/local/mysql/bin/mysql -u root -p test_db < /root/master_test_db_backup.sql
(5)从库配置主从复制关联
-
登录从库 MySQL 命令行
bash
/usr/local/mysql/bin/mysql -u root -p -
先停止从库复制线程(若之前配置过主从,必须执行)
sql
STOP SLAVE; RESET MASTER; RESET SLAVE ALL; -
配置主库连接信息(核心步骤,替换为你的实际信息)
sql
CHANGE MASTER TO -- 主库IP地址 MASTER_HOST='192.168.1.100', -- 主库MySQL端口 MASTER_PORT=3306, -- 主库创建的复制专用用户名 MASTER_USER='repl', -- 复制用户的密码 MASTER_PASSWORD='Repl@123456', -- 之前记录的主库binlog文件名 MASTER_LOG_FILE='mysql-bin.000003', -- 之前记录的主库binlog位点号 MASTER_LOG_POS=154, -- 开启主库宕机重连机制 MASTER_CONNECT_RETRY=10, -- 关闭SSL连接(若主库未开启SSL) MASTER_SSL=0; -
启动从库复制线程
sql
START SLAVE;
3. 主从复制状态验证与故障排查
(1)核心状态验证(从库 MySQL 终端执行)
sql
SHOW SLAVE STATUS\G
必须满足两个核心 Yes,主从复制才算配置成功:
Slave_IO_Running: Yes(IO 线程正常,负责拉取主库 binlog)Slave_SQL_Running: Yes(SQL 线程正常,负责重放 binlog 数据)- 附加验证:
Seconds_Behind_Master: 0(主从同步无延迟)
(2)主从同步功能验证
-
主库创建测试库和测试表,插入数据 sql
-- 主库执行 CREATE DATABASE test_rw; USE test_rw; CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50)); INSERT INTO t1 (name) VALUES ('master_test'); -
从库查询数据,若能查到,说明主从同步正常 sql
-- 从库执行 SELECT * FROM test_rw.t1;
(3)常见故障排查
表格
| 故障现象 | 核心原因 | 解决方案 |
|---|---|---|
| Slave_IO_Running: Connecting | 网络不通、防火墙未放行、主库 IP / 端口错误、复制用户密码错误 | 检查主从网络互通、防火墙端口、复制用户权限与密码、MASTER_HOST 配置 |
| Slave_IO_Running: No | binlog 文件名 / 位点错误、主库 binlog 未开启、server-id 重复 | 重新核对主库 MASTER_LOG_FILE 和 MASTER_LOG_POS、检查 server-id 唯一、主库 binlog 开启状态 |
| Slave_SQL_Running: No | 主从数据不一致、主键冲突、从库手动写入数据、库表不存在 | 先停止从库同步,重新导入主库基准数据,再重新配置主从复制,开启从库 super_read_only 禁止写入 |
三、MyCat 读写分离部署与配置
MyCat 是开源的数据库中间件,通过配置实现写请求自动路由到主库、读请求自动负载均衡到从库,对业务代码完全透明,无需修改业务代码即可实现读写分离。
1. MyCat 运行环境(JDK)安装
MyCat 1.6 稳定版依赖 JDK 1.8 及以上版本,OpenEuler 下直接通过 dnf 安装即可
bash
# 安装JDK 1.8
dnf install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
# 验证安装成功
java -version
输出版本号信息即为安装成功。
2. MyCat 安装与目录说明
(1)下载并安装 MyCat
推荐使用 MyCat 1.6.7.4 稳定版,兼容性最好,适配 MySQL 5.7/8.0
bash
# 下载MyCat安装包
wget http://dl.mycat.org.cn/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
# 解压到/usr/local目录
tar -zxvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /usr/local/
# 赋予执行权限
chmod -R 755 /usr/local/mycat/bin/
(2)MyCat 核心目录说明
表格
| 目录路径 | 作用说明 |
|---|---|
| /usr/local/mycat/conf/ | 核心配置文件目录,读写分离配置均在此目录 |
| /usr/local/mycat/bin/ | 启停脚本目录,mycat 启停命令在此 |
| /usr/local/mycat/logs/ | 日志目录,启动报错、运行日志均在此 |
| /usr/local/mycat/lib/ | 依赖包目录,MySQL 驱动包在此 |
3. MySQL 创建 MyCat 专用访问用户
需在主库创建 MyCat 访问用户,主从同步后从库会自动同步该用户,用于 MyCat 连接主从库
sql
-- 主库MySQL终端执行,创建MyCat专用用户,替换为你的MyCat节点IP
CREATE USER 'mycat_user'@'192.168.1.102' IDENTIFIED WITH mysql_native_password BY 'Mycat@123456';
-- 授予业务库的全部读写权限,替换为你的业务库名,生产环境禁止授予*.*权限
GRANT ALL PRIVILEGES ON test_rw.* TO 'mycat_user'@'192.168.1.102';
-- 刷新权限生效
FLUSH PRIVILEGES;
4. MyCat 核心配置文件详解(读写分离专属)
只需修改 3 个核心配置文件,均在/usr/local/mycat/conf/目录下,按顺序配置。
(1)配置 1:server.xml(MyCat 用户与逻辑库配置)
核心作用:配置 MyCat 的登录用户、密码、逻辑库名称,业务代码连接 MyCat 时使用该账号密码
bash
vim /usr/local/mycat/conf/server.xml
找到<user>标签段,替换为以下配置,其余默认配置保持不变:
xml
<!-- 配置MyCat管理员用户,业务代码连接使用此账号 -->
<user name="mycat_root" defaultAccount="true">
<!-- MyCat登录密码,可自定义 -->
<property name="password">MycatRoot@123456</property>
<!-- 逻辑库名称,必须和后续schema.xml中的schema name完全一致 -->
<property name="schemas">test_rw</property>
<!-- 只读权限关闭,允许读写 -->
<property name="readOnly">false</property>
</user>
<!-- 可选:配置只读用户,给报表/查询业务使用 -->
<user name="mycat_read">
<property name="password">MycatRead@123456</property>
<property name="schemas">test_rw</property>
<property name="readOnly">true</property>
</user>
关键说明:
schemas中的test_rw是 MyCat 的逻辑库名,可与 MySQL 真实业务库名一致,降低业务适配成本。
(2)配置 2:schema.xml(读写分离核心配置,重中之重)
核心作用:配置逻辑库与真实 MySQL 库的映射、读写节点、负载均衡策略、主从切换规则,是读写分离的核心配置文件。
bash
vim /usr/local/mycat/conf/schema.xml
清空原有默认配置,替换为以下读写分离专属配置,根据你的实际环境修改 IP、库名、账号密码:
xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 1. 配置逻辑库,name与server.xml中的schemas完全一致 -->
<!-- checkSQLschema="false":禁止自动去除库名前缀,避免SQL执行异常 -->
<!-- sqlMaxLimit="100":默认查询结果限制100条,可自定义 -->
<!-- dataNode="dn1":绑定数据节点,单库读写分离只需1个节点 -->
<schema name="test_rw" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
</schema>
<!-- 2. 配置数据节点,关联真实MySQL数据库 -->
<!-- name="dn1":节点名称,与schema中的dataNode一致 -->
<!-- dataHost="dh1":绑定数据库主机配置 -->
<!-- database="test_rw":MySQL中真实的业务库名,必须真实存在 -->
<dataNode name="dn1" dataHost="dh1" database="test_rw" />
<!-- 3. 配置数据库主机,读写分离核心参数都在此 -->
<!-- name="dh1":主机名称,与dataNode中的dataHost一致 -->
<!-- maxCon="1000":最大连接数,minCon="10":最小空闲连接数 -->
<!-- balance="1":读负载均衡策略,核心参数,详见下方说明 -->
<!-- writeType="0":写策略,所有写请求发往第一个writeHost(主库) -->
<!-- dbType="mysql":数据库类型为MySQL -->
<!-- dbDriver="native":驱动类型,MySQL使用native原生驱动 -->
<!-- switchType="1":主库宕机自动切换,基于心跳检测 -->
<!-- slaveThreshold="100":从库延迟阈值,超过100ms的从库不参与读负载 -->
<dataHost name="dh1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
<!-- 心跳检测SQL,用于检测MySQL节点是否存活 -->
<heartbeat>select user()</heartbeat>
<!-- 写节点配置:主库Master,所有写请求都会发往此节点 -->
<!-- host="hostM1":节点名称,自定义 -->
<!-- url="主库IP:3306":主库MySQL连接地址 -->
<!-- user="mycat_user":之前在MySQL创建的MyCat专用用户名 -->
<!-- password="Mycat@123456":MyCat专用用户的密码 -->
<writeHost host="hostM1" url="192.168.1.100:3306" user="mycat_user" password="Mycat@123456">
<!-- 读节点配置:从库Slave,所有读请求会负载均衡到此节点 -->
<!-- 可配置多个readHost标签,实现一主多从读负载均衡 -->
<readHost host="hostS1" url="192.168.1.101:3306" user="mycat_user" password="Mycat@123456" />
</writeHost>
<!-- 可选:备用写节点,主库宕机后自动切换到此节点,双主模式使用 -->
<!-- <writeHost host="hostM2" url="192.168.1.103:3306" user="mycat_user" password="Mycat@123456"></writeHost> -->
</dataHost>
</mycat:schema>
核心参数详解(读写分离关键)
表格
| 参数 | 取值与作用 | 生产推荐值 |
|---|---|---|
balance |
0:不开启读写分离,所有读请求都发往主库1:所有 readHost 从库 + 备用主库 参与读负载均衡(一主多从 / 双主模式首选)2:读请求随机分发到主库 + 从库3:读请求仅发往从库,主库不承担任何读压力(读压力大的场景首选) | 1 或 3 |
writeType |
0:所有写请求发往第一个配置的 writeHost(主库),主库宕机切换到备用主库1:写请求随机分发,已废弃不推荐 | 0 |
switchType |
-1:不自动切换,主库宕机需手动干预1:默认值,自动切换,主库宕机后自动切换到备用主库2:基于主从同步状态切换 | 1 |
(3)配置 3:rule.xml(分片规则配置)
读写分离场景无需分库分表,该文件保持默认配置即可,无需任何修改。
5. MyCat 服务启停与状态检查
(1)MyCat 启停命令
bash
# 启动MyCat
/usr/local/mycat/bin/mycat start
# 停止MyCat
/usr/local/mycat/bin/mycat stop
# 重启MyCat
/usr/local/mycat/bin/mycat restart
# 查看运行状态
/usr/local/mycat/bin/mycat status
(2)启动成功验证
-
查看运行状态,返回
Mycat-server is running.即为启动成功 -
若启动失败,查看错误日志定位问题 bash
# 查看启动日志 tail -f /usr/local/mycat/logs/wrapper.log # 查看运行日志 tail -f /usr/local/mycat/logs/mycat.log常见启动失败原因:配置文件 XML 标签闭合错误、MySQL 账号密码错误、MySQL 节点无法连接、JDK 未安装。
四、读写分离效果验证与功能测试
1. 连接 MyCat 服务
使用 MySQL 客户端即可连接 MyCat,连接方式与普通 MySQL 完全一致
bash
# 连接MyCat数据端口8066,使用server.xml中配置的MyCat账号密码
mysql -h 192.168.1.102 -P 8066 -u mycat_root -p
连接成功后,可像操作普通 MySQL 一样执行 SQL 语句。
2. 读写分离核心效果验证
通过@@hostname函数验证 SQL 路由节点,该函数会返回当前 MySQL 实例的主机名,主从库主机名不同,可精准判断 SQL 执行的节点。
(1)验证读请求路由到从库
-
先分别查看主库和从库的主机名 sql
-- 主库执行,记录主库主机名 SELECT @@hostname; -- 从库执行,记录从库主机名 SELECT @@hostname; -
在 MyCat 连接终端执行查询语句 sql
SELECT @@hostname;若返回结果为从库的主机名,说明读请求已成功路由到从库,读写分离生效。
(2)验证写请求路由到主库
-
在 MyCat 连接终端执行写入语句 sql
-- 写入数据 INSERT INTO t1 (name) VALUES ('mycat_write_test'); -- 查询数据 SELECT * FROM t1 WHERE name='mycat_write_test'; -
分别在主库和从库查看数据,主库有数据、从库同步到数据,说明写请求路由到主库,主从同步正常。
3. MyCat 管理端验证
通过 9066 管理端口,可查看 MyCat 的数据源状态、读写统计信息
bash
# 连接MyCat管理端口9066
mysql -h 192.168.1.102 -P 9066 -u mycat_root -p
常用管理命令:
sql
-- 查看所有数据源状态
show @@datasource;
-- 查看读写分离路由统计
show @@datanode;
-- 查看MyCat运行状态
show @@server;
