fix(database): Correct MySQL replica read-only configuration
This commit is contained in:
@@ -38,8 +38,10 @@ binlog_format = ROW
|
|||||||
binlog_row_image = FULL
|
binlog_row_image = FULL
|
||||||
relay-log = relay-bin
|
relay-log = relay-bin
|
||||||
relay-log-index = relay-bin.index
|
relay-log-index = relay-bin.index
|
||||||
read_only = ON
|
# 注意: read_only 和 super_read_only 应在主从复制配置完成后手动启用
|
||||||
super_read_only = ON
|
# 避免阻止容器初始化脚本执行
|
||||||
|
# read_only = ON
|
||||||
|
# super_read_only = ON
|
||||||
|
|
||||||
# GTID配置
|
# GTID配置
|
||||||
gtid-mode = ON
|
gtid-mode = ON
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ ssh node-03 "hostname"
|
|||||||
|
|
||||||
### 2.1 克隆项目
|
### 2.1 克隆项目
|
||||||
|
|
||||||
### 建议配好github账号
|
建议提前配置好 GitHub 账号和 SSH 密钥
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 在所有节点执行
|
# 在所有节点执行
|
||||||
@@ -121,7 +121,7 @@ cd HA-OVP
|
|||||||
# 构建所有模块
|
# 构建所有模块
|
||||||
mvn clean install -Dmaven.test.skip=true
|
mvn clean install -Dmaven.test.skip=true
|
||||||
|
|
||||||
# 构建 Sentinel 镜像
|
# 构建 Sentinel 镜像 (三个节点都需要执行)
|
||||||
cd sentinel-dashboard
|
cd sentinel-dashboard
|
||||||
docker build -t sentinel-dashboard:1.8.6 .
|
docker build -t sentinel-dashboard:1.8.6 .
|
||||||
cd ..
|
cd ..
|
||||||
@@ -133,75 +133,146 @@ ls -la video-*/target/*.jar
|
|||||||
### 2.3 同步构建产物
|
### 2.3 同步构建产物
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
apt install rsync -y #三个节点都需要安装
|
# 三个节点都需要安装 rsync
|
||||||
|
apt install rsync -y
|
||||||
|
|
||||||
# 从 Node-01 同步到其他节点
|
# 从 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.102:/opt/HA-OVP/
|
||||||
rsync -avz --progress /opt/HA-OVP/ root@192.168.1.103:/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
|
```bash
|
||||||
cd /opt/HA-OVP
|
cd /opt/HA-OVP
|
||||||
|
|
||||||
# 启动所有服务
|
# 先只启动基础设施 (MySQL, Redis, Nacos 等)
|
||||||
docker compose -f docker-compose-node-01.yml --env-file config/.env.node-01 up -d
|
docker compose -f docker-compose-node-01.yml up -d mysql redis redis-sentinel nacos rmqnamesrv rmqbroker minio sentinel
|
||||||
|
|
||||||
# 查看日志
|
# 等待 MySQL 完全启动 (约 30-60 秒)
|
||||||
docker compose -f docker-compose-node-01.yml logs -f
|
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
|
```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
|
# - video_auth
|
||||||
|
# - video_user
|
||||||
# 查看日志
|
# - video_content
|
||||||
docker compose -f docker-compose-node-02.yml logs -f
|
# - 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
|
```bash
|
||||||
cd /opt/HA-OVP
|
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
|
```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 数据库并导入表结构
|
# 查看日志,确认 Nacos 认证成功 (应显示 username='nacos')
|
||||||
docker exec -i mysql mysql -uroot -proot123456 << 'EOF'
|
docker compose -f docker-compose-node-02.yml logs -f video-gateway
|
||||||
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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 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
|
```bash
|
||||||
# 在 Node-01 (主节点) 创建复制用户
|
|
||||||
docker exec mysql mysql -uroot -proot123456 << 'EOF'
|
docker exec mysql mysql -uroot -proot123456 << 'EOF'
|
||||||
CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl_password_2024';
|
CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl_password_2024';
|
||||||
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
|
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
SHOW MASTER STATUS;
|
SHOW MASTER STATUS;
|
||||||
EOF
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
# 在 Node-02 和 Node-03 (从节点) 分别配置主从
|
#### 在 Node-02 和 Node-03 (从节点) 配置主从
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在 Node-02 执行
|
||||||
docker exec mysql mysql -uroot -proot123456 << 'EOF'
|
docker exec mysql mysql -uroot -proot123456 << 'EOF'
|
||||||
CHANGE MASTER TO
|
CHANGE MASTER TO
|
||||||
MASTER_HOST='192.168.1.101',
|
MASTER_HOST='192.168.1.101',
|
||||||
@@ -213,26 +284,51 @@ SHOW SLAVE STATUS\G
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# 确认 Slave_IO_Running 和 Slave_SQL_Running 都为 Yes
|
# 确认 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
|
```bash
|
||||||
# 在 Node-02 和 Node-03 执行
|
# 在 Node-03 执行 (同上)
|
||||||
docker exec redis redis-cli -a redis_HA_Cluster_2024 REPLICAOF 192.168.1.101 6379
|
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 mysql mysql -uroot -proot123456 -e "SET GLOBAL read_only = ON; SET GLOBAL super_read_only = ON;"
|
||||||
docker exec redis redis-cli -a redis_HA_Cluster_2024 INFO replication
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 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)
|
访问 http://192.168.1.101:8848/nacos (账号: nacos/nacos)
|
||||||
|
|
||||||
1. 创建命名空间: `public`
|
1. **创建命名空间**: 命名空间 → 新建命名空间 → 命名空间ID: `public`, 命名空间名: `公共命名空间`
|
||||||
2. 添加各服务的配置文件 (参考 `config/nacos-config/` 目录)
|
2. **添加配置文件**: 配置管理 → 配置列表 → 创建配置
|
||||||
|
- Data ID: `video-gateway.yaml`
|
||||||
|
- Group: `DEFAULT_GROUP`
|
||||||
|
- 配置内容: 参考 `config/nacos-config/` 目录下的配置文件
|
||||||
|
3. **重复以上步骤添加其他服务的配置**
|
||||||
|
|
||||||
### 2.9 初始化 MinIO
|
### 2.10 初始化 MinIO
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 安装 mc 客户端
|
# 安装 mc 客户端
|
||||||
@@ -421,6 +517,103 @@ systemctl stop mysql
|
|||||||
systemctl stop redis
|
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
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 七、日常运维
|
## 七、日常运维
|
||||||
|
|||||||
Reference in New Issue
Block a user