From c086e5c32a6eb7bbc7eceb94b0909b9a451b31c5 Mon Sep 17 00:00:00 2001 From: Toyas Date: Thu, 12 Mar 2026 23:22:20 +0800 Subject: [PATCH] fix(database): Correct MySQL replica read-only configuration --- config/mysql/my-slave.cnf | 6 +- docs/DEBIAN12-DEPLOYMENT-GUIDE.md | 277 +++++++++++++++++++++++++----- 2 files changed, 239 insertions(+), 44 deletions(-) diff --git a/config/mysql/my-slave.cnf b/config/mysql/my-slave.cnf index f7aeceb..b295d67 100644 --- a/config/mysql/my-slave.cnf +++ b/config/mysql/my-slave.cnf @@ -38,8 +38,10 @@ binlog_format = ROW binlog_row_image = FULL relay-log = relay-bin relay-log-index = relay-bin.index -read_only = ON -super_read_only = ON +# 注意: read_only 和 super_read_only 应在主从复制配置完成后手动启用 +# 避免阻止容器初始化脚本执行 +# read_only = ON +# super_read_only = ON # GTID配置 gtid-mode = ON diff --git a/docs/DEBIAN12-DEPLOYMENT-GUIDE.md b/docs/DEBIAN12-DEPLOYMENT-GUIDE.md index 2208572..a06c7f9 100644 --- a/docs/DEBIAN12-DEPLOYMENT-GUIDE.md +++ b/docs/DEBIAN12-DEPLOYMENT-GUIDE.md @@ -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 +``` + --- ## 七、日常运维