fix(database): Correct MySQL replica read-only configuration

This commit is contained in:
2026-03-12 23:22:20 +08:00
parent 51a2374155
commit c086e5c32a
2 changed files with 239 additions and 44 deletions
+235 -42
View File
@@ -104,7 +104,7 @@ ssh node-03 "hostname"
### 2.1 克隆项目
### 建议配好github账号
建议提前配置好 GitHub 账号和 SSH 密钥
```bash
# 在所有节点执行
@@ -121,7 +121,7 @@ cd HA-OVP
# 构建所有模块
mvn clean install -Dmaven.test.skip=true
# 构建 Sentinel 镜像
# 构建 Sentinel 镜像 (三个节点都需要执行)
cd sentinel-dashboard
docker build -t sentinel-dashboard:1.8.6 .
cd ..
@@ -133,75 +133,146 @@ ls -la video-*/target/*.jar
### 2.3 同步构建产物
```bash
apt install rsync -y #三个节点都需要安装
# 三个节点都需要安装 rsync
apt install rsync -y
# 从 Node-01 同步到其他节点
rsync -avz --progress /opt/HA-OVP/ root@192.168.1.102:/opt/HA-OVP/
rsync -avz --progress /opt/HA-OVP/ root@192.168.1.103:/opt/HA-OVP/
```
### 2.4 启动服务
### 2.4 Node-01 部署 (主节点)
#### Node-01 启动 (主节点)
#### 步骤 1: 启动基础设施
```bash
cd /opt/HA-OVP
# 启动所有服务
docker compose -f docker-compose-node-01.yml --env-file config/.env.node-01 up -d
# 先只启动基础设施 (MySQL, Redis, Nacos 等)
docker compose -f docker-compose-node-01.yml up -d mysql redis redis-sentinel nacos rmqnamesrv rmqbroker minio sentinel
# 查看日志
docker compose -f docker-compose-node-01.yml logs -f
# 等待 MySQL 完全启动 (约 30-60 秒)
docker compose -f docker-compose-node-01.yml logs -f mysql
# 看到 "ready for connections" 后 Ctrl+C 退出
```
#### Node-02 启动 (从节点)
#### 步骤 2: 验证数据库初始化
MySQL 容器启动时会自动执行 `sql/` 目录下的初始化脚本(通过 `docker-entrypoint-initdb.d` 挂载),无需手动初始化。
```bash
cd /opt/HA-OVP
# 验证数据库已自动创建
docker exec mysql mysql -uroot -proot123456 -e "SHOW DATABASES;"
# 等待 Node-01 完全启动后 (约3分钟)
docker compose -f docker-compose-node-02.yml --env-file config/.env.node-02 up -d
# 查看日志
docker compose -f docker-compose-node-02.yml logs -f
# 应看到以下数据库:
# - video_auth
# - video_user
# - video_content
# - video_comment
# - video_recommend
# - video_admin
# - nacos_config
```
#### Node-03 启动 (备份节点)
#### 步骤 3: 等待 Nacos 启动
```bash
# 等待 Nacos 完全启动
docker compose -f docker-compose-node-01.yml logs -f nacos
# 看到 "Nacos started successfully" 后 Ctrl+C 退出
# 创建 Nacos 用户 (重要!微服务需要认证)
# 注意:如果是首次启动,Nacos 默认用户是 nacos/nacos
# 访问控制台验证: http://192.168.1.101:8848/nacos
```
#### 步骤 4: 启动微服务
```bash
# 启动所有微服务
docker compose -f docker-compose-node-01.yml up -d video-gateway video-auth video-user video-content video-comment video-recommend video-admin nginx
# 查看微服务启动日志
docker compose -f docker-compose-node-01.yml logs -f video-gateway
# 确认日志中没有错误,显示 "Started GatewayApplication" 表示成功
```
#### 步骤 5: 验证 Node-01 服务状态
```bash
# 检查所有容器状态
docker ps
# 验证 Nacos 服务注册
curl http://192.168.1.101:8848/nacos/v1/ns/service/list | grep -o '"name":"[^"]*"'
# 验证微服务健康状态
curl http://192.168.1.101:9000/actuator/health
curl http://192.168.1.101:9001/actuator/health
```
### 2.5 Node-02 部署 (从节点)
**重要**:确保 Node-01 的所有服务正常运行后再部署 Node-02
#### 步骤 1: 启动基础设施
```bash
cd /opt/HA-OVP
# 启动基础设施
docker compose -f docker-compose-node-03.yml --env-file config/.env.node-03 up -d
docker compose -f docker-compose-node-02.yml up -d mysql redis redis-sentinel nacos rmqnamesrv rmqbroker minio sentinel
# 等待 MySQL 和 Nacos 完全启动
docker compose -f docker-compose-node-02.yml logs -f mysql
# 看到 "ready for connections" 后 Ctrl+C 退出
```
### 2.5 初始化数据库
#### 步骤 2: 启动微服务
**注意**:Node-02 作为 MySQL 从节点,数据库会通过主从复制自动同步,无需手动初始化。
```bash
# 在 Node-01 执行,等待MySQL完全启动后
# 等待 Nacos 启动后,启动微服务
docker compose -f docker-compose-node-02.yml up -d video-gateway video-auth video-user video-content video-comment video-recommend video-admin
# 创建 Nacos 数据库并导入表结构
docker exec -i mysql mysql -uroot -proot123456 << 'EOF'
CREATE DATABASE IF NOT EXISTS nacos_config CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EOF
docker exec -i mysql mysql -uroot -proot123456 nacos_config < config/nacos-mysql.sql
# 导入业务数据库
docker exec -i mysql mysql -uroot -proot123456 < sql/init.sql
# 查看日志,确认 Nacos 认证成功 (应显示 username='nacos')
docker compose -f docker-compose-node-02.yml logs -f video-gateway
```
### 2.6 配置 MySQL 主从复制
### 2.6 Node-03 部署 (备份节点)
```bash
cd /opt/HA-OVP
# Node-03 只部署基础设施
docker compose -f docker-compose-node-03.yml up -d
# 等待 MySQL 和 Nacos 启动
docker compose -f docker-compose-node-03.yml logs -f mysql
# 看到 "ready for connections" 后 Ctrl+C 退出
# 验证数据库已自动创建
docker exec mysql mysql -uroot -proot123456 -e "SHOW DATABASES;"
```
### 2.7 配置 MySQL 主从复制
#### 在 Node-01 (主节点) 创建复制用户
```bash
# 在 Node-01 (主节点) 创建复制用户
docker exec mysql mysql -uroot -proot123456 << 'EOF'
CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl_password_2024';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
EOF
```
# 在 Node-02 和 Node-03 (从节点) 分别配置主从
#### 在 Node-02 和 Node-03 (从节点) 配置主从
```bash
# 在 Node-02 执行
docker exec mysql mysql -uroot -proot123456 << 'EOF'
CHANGE MASTER TO
MASTER_HOST='192.168.1.101',
@@ -213,26 +284,51 @@ SHOW SLAVE STATUS\G
EOF
# 确认 Slave_IO_Running 和 Slave_SQL_Running 都为 Yes
```
### 2.7 配置 Redis 主从复制
# 配置完成后,启用只读模式 (重要!)
docker exec mysql mysql -uroot -proot123456 -e "SET GLOBAL read_only = ON; SET GLOBAL super_read_only = ON;"
```
```bash
# 在 Node-02 和 Node-03 执行
docker exec redis redis-cli -a redis_HA_Cluster_2024 REPLICAOF 192.168.1.101 6379
# 在 Node-03 执行 (同上)
docker exec mysql mysql -uroot -proot123456 << 'EOF'
CHANGE MASTER TO
MASTER_HOST='192.168.1.101',
MASTER_USER='repl',
MASTER_PASSWORD='repl_password_2024',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\G
EOF
# 验证主从状态
docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication
docker exec mysql mysql -uroot -proot123456 -e "SET GLOBAL read_only = ON; SET GLOBAL super_read_only = ON;"
```
### 2.8 配置 Nacos
### 2.8 配置 Redis 主从复制
```bash
# 在 Node-02 执行
docker exec redis redis-cli -a redis_HA_Cluster_2024 REPLICAOF 192.168.1.101 6379
# 在 Node-03 执行
docker exec redis redis-cli -a redis_HA_Cluster_2024 REPLICAOF 192.168.1.101 6379
# 验证主从状态 (在 Node-01 执行)
docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication | grep -E "role|connected_slaves"
```
### 2.9 配置 Nacos
访问 http://192.168.1.101:8848/nacos (账号: nacos/nacos)
1. 创建命名空间: `public`
2. 添加各服务的配置文件 (参考 `config/nacos-config/` 目录)
1. **创建命名空间**: 命名空间 → 新建命名空间 → 命名空间ID: `public`, 命名空间名: `公共命名空间`
2. **添加配置文件**: 配置管理 → 配置列表 → 创建配置
- Data ID: `video-gateway.yaml`
- Group: `DEFAULT_GROUP`
- 配置内容: 参考 `config/nacos-config/` 目录下的配置文件
3. **重复以上步骤添加其他服务的配置**
### 2.9 初始化 MinIO
### 2.10 初始化 MinIO
```bash
# 安装 mc 客户端
@@ -421,6 +517,103 @@ systemctl stop mysql
systemctl stop redis
```
### Q5: 微服务报 "user not found!" 错误(Nacos 认证失败)
**问题描述**:微服务启动时报错 `com.alibaba.nacos.api.exception.NacosException: user not found!`
**原因**:Spring Boot 3.x 默认不加载 `bootstrap.yml` 文件,导致 Nacos 认证配置未生效。
**解决方案**:已在 docker-compose 中添加 Spring 环境变量:
```yaml
environment:
- SPRING_CLOUD_NACOS_DISCOVERY_USERNAME=nacos
- SPRING_CLOUD_NACOS_DISCOVERY_PASSWORD=nacos
- SPRING_CLOUD_NACOS_CONFIG_USERNAME=nacos
- SPRING_CLOUD_NACOS_CONFIG_PASSWORD=nacos
```
**验证**:启动后日志应显示 `username='nacos'` 而不是 `username=''`
### Q6: MySQL 从节点初始化失败
**问题描述**:MySQL 从节点容器启动报错 `The MySQL server is running with the --super-read-only option`
**原因**:MySQL 从节点配置了 `read_only=ON`,阻止了容器初始化脚本执行(创建数据库、用户等)。
**解决方案**:
1. 确保 `config/mysql/my-slave.cnf` 中已注释掉 `read_only` 和 `super_read_only`
2. 如果已经启动失败,需要删除数据卷重新初始化:
```bash
# 停止容器
docker compose -f docker-compose-node-02.yml down
# 删除 MySQL 数据卷
docker volume rm ha-ovp_mysql_data
# 重新启动
docker compose -f docker-compose-node-02.yml up -d
```
3. 主从复制配置完成后,手动启用只读模式:
```bash
docker exec mysql mysql -uroot -proot123456 -e "SET GLOBAL read_only = ON; SET GLOBAL super_read_only = ON;"
```
### Q7: RocketMQ NameServer 健康检查失败
**问题描述**:RocketMQ NameServer 容器显示 unhealthy
**原因**:容器内缺少 `nc` (netcat) 命令
**解决方案**:已修改健康检查命令使用 `pgrep`:
```yaml
healthcheck:
test: ["CMD-SHELL", "pgrep -f 'NamesrvStartup' || exit 1"]
```
### Q8: Redis Sentinel 报 "Read-only file system" 错误
**问题描述**:Redis Sentinel 无法写入配置文件
**解决方案**:已修改为将配置文件复制到可写的数据卷:
```yaml
volumes:
- sentinel_data:/data
- ./config/redis/sentinel.conf:/usr/local/etc/redis/sentinel.conf
command: sh -c "cp /usr/local/etc/redis/sentinel.conf /data/sentinel.conf && redis-sentinel /data/sentinel.conf"
```
### Q9: Redis 日志文件路径错误
**问题描述**:Redis 启动报错 `Can't open the log file`
**解决方案**:修改 `config/redis/redis-master.conf` 和 `redis-slave.conf`:
```conf
# 将 logfile /var/log/redis/redis-server.log 改为
logfile ""
```
### Q10: Nacos 集群模式报 "dataSource or tableName is null"
**问题描述**:Nacos 集群模式启动失败
**解决方案**:确保 docker-compose 中添加了 `SPRING_DATASOURCE_PLATFORM=mysql` 环境变量:
```yaml
environment:
- MODE=cluster
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_DB_NAME=nacos_config
```
---
## 七、日常运维