一、 方案概述
本手册是为基于Debian 11和Docker的Typecho博客量身定制的、最完整的高可用(HA)部署指南。它将指导您完成从调整现有架构到实现全自动故障切换并进行万无一失的数据恢复的每一个步骤。
核心技术架构:
| 组件 | 技术实现 | 目的 |
|---|---|---|
| 网络层 | Tailscale | 建立安全的虚拟私有网络,加密数据库同步流量。 |
| 应用代理 | Caddy | 提供安全、自动化的HTTPS反向代理,解决521/525错误。 |
| 数据同步 | MariaDB主从复制 (ROW格式) | 实时、精确地同步数据库(文章、评论等),保证数据绝对一致。 |
| rsync + cron + 包装脚本 | 定时同步文件(主题、插件、上传文件等),并安全地修复权限。 | |
| 故障切换 | Cloudflare API + 有状态监控脚本 | 自动检测主服务器故障,切换DNS,自动配置备库,并避免循环告警。 |
| 告警通知 | Telegram Bot API | 在故障切换成功后,立即发送通知到您的Telegram。 |
二、 占位符说明 (操作前必读)
在开始操作前,请准备好以下信息。在后续文档中,所有需要您填写的地方都会用 [占位符] 的形式清晰标出。
| 占位符 | 说明 | 示例 |
|---|---|---|
[服务器A的公网IP] |
您的主服务器的公网IP地址。 | 123.45.67.89 |
[服务器B的公网IP] |
您的备用服务器的公网IP地址。 | 98.76.54.32 |
[自定义SSH端口] |
您服务器的自定义SSH端口。 | 22022 |
[自定义数据库端口] |
您希望暴露给Tailscale网络的数据库端口,建议非3306。 | 33061 |
[Typecho暴露给主机的端口] |
您希望Typecho服务暴露给本机的端口,用于Caddy反代。 | 8080 |
[您的登录用户名] |
您用SSH登录服务器时使用的用户名。 | debian_user |
[您的邮箱地址] |
用于生成SSH密钥注释,方便识别。 | user@example.com |
[您的博客域名] |
您在Cloudflare上配置的完整域名。 | blog.yourdomain.com |
[Cloudflare区域ID] |
在Cloudflare域名概览页找到的Zone ID。 | a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 |
[Cloudflare API令牌] |
您创建的用于编辑DNS的API Token。 | gH1iJ2kL3mN4oP5qR6sT7uV8wX9yZ0aB1c |
[Cloudflare DNS记录ID] |
您要修改的A记录的ID。 | f1e2d3c4b5a6f1e2d3c4b5a6f1e2d3c4 |
[TG机器人令牌] |
您从@BotFather获取的Telegram机器人Token。 |
123456:ABC-DEF1234ghIkl-zyx57W2v1u |
[TG频道或用户的ChatID] |
您希望接收通知的对话ID。 | 123456789 |
[数据库ROOT密码] |
您docker-compose.yml中设置的MYSQL_ROOT_PASSWORD。 |
Strong_DB_Root_Password |
[Typecho数据库密码] |
您docker-compose.yml中为Typecho设置的MYSQL_PASSWORD。 |
Strong_Typecho_DB_Password |
[数据库复制用的密码] |
用于主从复制的专用数据库用户密码。 | Replica_Pa$$w0rd_2025! |
三、 步骤一:环境初始化
-
在服务器A上准备架构 本方案要求数据库文件和应用文件使用绑定挂载(Bind Mount)以便于同步和管理。请确保您的
docker-compose.yml文件结构与下方类似。此示例包含了所有必要服务及其端口映射。version: '3.8' services: typecho: image: joyqi/typecho:1.2.1-php8.2-apache container_name: typecho_app restart: always ports: - "[Typecho暴露给主机的端口]:80" volumes: - ./app:/app depends_on: - mariadb mariadb: image: mariadb:10.11 container_name: typecho_db restart: always ports: - "[服务器A的Tailscale IP]:[自定义数据库端口]:3306" environment: MYSQL_ROOT_PASSWORD: '[数据库ROOT密码]' MYSQL_DATABASE: 'typecho_blog' MYSQL_USER: 'typecho_user' MYSQL_PASSWORD: '[Typecho数据库密码]' volumes: - ./mariadb/data:/var/lib/mysql - ./mariadb/conf.d:/etc/mysql/conf.d -
初始化服务器B环境 (克隆架构)
- 在服务器A上打包:
cd ~/docker/typecho/ tar -czvf typecho_arch.tar.gz . - 传输到服务器B:
scp -P [自定义SSH端口] typecho_arch.tar.gz [您的登录用户名]@[服务器B的公网IP]:~/ - 在服务器B上解压:
mkdir -p ~/docker/typecho mv ~/typecho_arch.tar.gz ~/docker/typecho/ cd ~/docker/typecho/ tar -xzvf typecho_arch.tar.gz
- 在服务器A上打包:
-
配置安全网络 (Tailscale) 在服务器A和服务器B上都执行:
curl -fsSL https://tailscale.com/install.sh | sh && sudo tailscale up【记录】 分别在两台服务器上用
tailscale ip -4获取并记下各自的Tailscale IP (TS_IP_A和TS_IP_B)。 -
环境与防火墙准备 (两台服务器均需执行)
- 安装必要工具:
sudo apt update sudo apt install -y rsync - 配置防火墙:
在 服务器A 上执行:
在 服务器B 上执行:sudo ufw allow [自定义SSH端口]/tcp sudo ufw allow [自定义数据库端口]/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcpsudo ufw allow [自定义SSH端口]/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp
- 安装必要工具:
四、 步骤二:应用层代理配置 (Caddy)
此步骤用于解决Cloudflare的521/525错误,两台服务器均需执行以保持环境一致。
-
安装Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy -
配置Caddyfile
- 编辑Caddyfile:
sudo nano /etc/caddy/Caddyfile - 删除所有默认内容,粘贴以下配置:
[您的博客域名] { reverse_proxy localhost:[Typecho暴露给主机的端口] } - 重载Caddy:
sudo systemctl reload caddy
- 编辑Caddyfile:
五、 步骤三:数据持续同步
5.1 数据库同步 (MariaDB主从复制)
1. 在服务器A (Master) 上操作
- 创建数据库配置文件:
粘贴以下内容并保存。【关键】mkdir -p ~/docker/typecho/mariadb/conf.d nano ~/docker/typecho/mariadb/conf.d/master.cnfbinlog_format = ROW是保证数据绝对一致性的核心。[mysqld] log-bin=mysql-bin server-id=1 binlog_format=ROW - 重启并创建复制用户:
在MariaDB中执行:cd ~/docker/typecho/ && docker-compose up -d --force-recreate mariadb docker-compose exec mariadb mysql -u root -pCREATE USER 'repl'@'%' IDENTIFIED BY '[数据库复制用的密码]'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;
2. 在服务器B (Slave) 上操作
- 创建配置文件:
粘贴以下内容并保存。mkdir -p ~/docker/typecho/mariadb/conf.d nano ~/docker/typecho/mariadb/conf.d/slave.cnf[mysqld] log-bin=mysql-bin server-id=2 read_only=1 binlog_format=ROW - 重启容器:
cd ~/docker/typecho/ && docker-compose up -d --force-recreate mariadb
3. 【金标准】初始化从库同步
此流程将保证从库是主库的完美克隆。
- 在服务器A(主库)上,创建带坐标的完美快照:
cd ~/docker/typecho/ docker-compose exec mariadb mysqldump -u root -p'[数据库ROOT密码]' --single-transaction --master-data=2 typecho_blog > ~/master_definitive_dump.sql - 将快照传输到服务器B(从库):
scp -P [自定义SSH端口] ~/master_definitive_dump.sql [您的登录用户名]@[服务器B的公网IP]:~/ - 在服务器B(从库)上,清空并恢复:
- 进入MariaDB容器:
docker-compose exec mariadb mysql -u root -p - 执行清空操作:
DROP DATABASE typecho_blog; CREATE DATABASE typecho_blog; EXIT; - 从快照恢复数据 (注意
-p后没有空格):cat ~/master_definitive_dump.sql | docker-compose exec -T mariadb mysql -u root -p'[数据库ROOT密码]' typecho_blog
- 进入MariaDB容器:
- 在服务器B上,使用精确坐标启动同步:
- 从快照文件中提取坐标:
grep "CHANGE MASTER TO" ~/master_definitive_dump.sql - 复制
CHANGE MASTER TO...后面的内容,修改连接信息后,在B的MariaDB中执行:-- 示例,请根据您自己的信息和上一步grep出的坐标修改 CHANGE MASTER TO MASTER_HOST='[服务器A的Tailscale IP]', MASTER_USER='repl', MASTER_PASSWORD='[数据库复制用的密码]', MASTER_PORT=[自定义数据库端口], MASTER_LOG_FILE='[从快照文件里看到的文件名]', MASTER_LOG_POS=[从快照文件里看到的Position]; START SLAVE;
- 从快照文件中提取坐标:
- 验证:在B的MariaDB中执行
SHOW SLAVE STATUS\G;,确保Slave_IO_Running: Yes,Slave_SQL_Running: Yes和Seconds_Behind_Master: 0。
5.2 文件同步 (rsync)
1. 在服务器B上生成SSH密钥并授权到服务器A
- 在服务器B上生成密钥:
(一路回车,不要设置密码)ssh-keygen -t ed25519 -C "[您的邮箱地址]" - 将公钥复制到服务器A:
ssh-copy-id -p [自定义SSH端口] [您的登录用户名]@[服务器A的公网IP]
2. 在服务器B上创建权限修复脚本
- 创建脚本文件:
sudo nano /usr/local/bin/fix_typecho_perms.sh - 粘贴内容:
#!/bin/bash # 【注意】chown的目标用户和组,应与您Typecho容器内Apache/PHP-FPM进程的运行用户一致。 # 对于Debian/Ubuntu基础的镜像,通常是 www-data。 # 对于CentOS/RHEL基础的镜像,可能是 apache 或 nginx。 /bin/chown -R www-data:www-data /home/[您的登录用户名]/docker/typecho/app/ - 授予执行权限:
sudo chmod +x /usr/local/bin/fix_typecho_perms.sh
3. 在服务器B上配置Sudo免密执行权限
- 执行
sudo visudo -f /etc/sudoers.d/rsync-chown-permission。 - 粘贴规则:
[您的登录用户名] ALL=(ALL) NOPASSWD: /usr/local/bin/fix_typecho_perms.sh
4. 在服务器B上创建定时同步任务
- 执行
crontab -e(不要加sudo),添加以下行:*/5 * * * * rsync -avz -e 'ssh -p [自定义SSH端口]' --delete --exclude='config.inc.php' [您的登录用户名]@[服务器A的公网IP]:~/docker/typecho/app/ ~/docker/typecho/app/ && sudo /usr/local/bin/fix_typecho_perms.sh >/dev/null 2>&1
六、 步骤四:配置自动故障切换
此部分操作均在服务器B上进行。
1. 获取Telegram与Cloudflare凭证
1.1 获取Telegram凭证
我们需要从Telegram获取两项信息:
- 机器人令牌 (Bot Token):用于授权脚本通过您的机器人发送消息。
- 对话ID (Chat ID):用于指定机器人将消息发送到哪个聊天窗口。
-
步骤 1:创建机器人并获取令牌 (Token)
- 在Telegram中,搜索并打开与官方机器人
@BotFather的对话。 - 发送命令
/newbot,并按照提示为您的机器人设置名称和唯一的用户名(必须以bot结尾)。 - 创建成功后,
@BotFather会发送一条包含机器人令牌的消息。 - 【记录】 复制并安全地保存这个令牌,它就是
[TG机器人令牌]。
- 在Telegram中,搜索并打开与官方机器人
-
步骤 2:获取您的对话ID (Chat ID)
- 在Telegram中搜索您刚刚创建的机器人,并向它发送一条
/start消息。 - 将您获取的机器人令牌替换到以下URL中:
https://api.telegram.org/bot[TG机器人令牌]/getUpdates - 在浏览器中访问该URL,您会看到一段JSON文本。
- 在文本中找到
"chat": {"id": XXXXXX, ...},这个id的值就是您的对话ID。 - 【记录】 复制这个ID(通常是一串数字),它就是
[TG频道或用户的ChatID]。
- 在Telegram中搜索您刚刚创建的机器人,并向它发送一条
1.2 获取Cloudflare凭证
我们需要从Cloudflare获取三项信息:
- 区域ID (Zone ID):代表您的域名。
- API令牌 (API Token):用于授权脚本修改DNS。
- DNS记录ID (DNS Record ID):您博客域名A记录的唯一标识。
-
步骤 1:获取区域ID (Zone ID)
- 登录Cloudflare,选择您的域名。
- 在域名的“概览”(Overview) 页面右下方,找到并复制区域ID (Zone ID)。
- 【记录】 这就是
[Cloudflare区域ID]。
-
步骤 2:创建API令牌 (API Token)
- 在Cloudflare仪表盘,进入“我的个人资料” -> “API令牌”,点击“创建令牌”。
- 选择“编辑区域DNS”(Edit Zone DNS) 模板。
- 为令牌命名,并在“区域资源”部分选择您博客所在的域名。
- 点击“继续以显示摘要”,然后“创建令牌”。
- 【记录】 Cloudflare会显示生成的API令牌(仅显示一次),请立即复制,它就是
[Cloudflare API令牌]。
-
步骤 3:获取DNS记录ID (DNS Record ID)
- 打开您的Linux终端,将已获取的凭证替换到以下命令中:
curl -X GET "https://api.cloudflare.com/client/v4/zones/[Cloudflare区域ID]/dns_records?name=[您的博客域名]" \ -H "Authorization: Bearer [Cloudflare API令牌]" \ -H "Content-Type:application/json" - 执行命令,在返回的JSON结果中,找到
"type": "A"的那条记录。 - 【记录】 这条记录的
"id"字段的值,就是[Cloudflare DNS记录ID]。
- 打开您的Linux终端,将已获取的凭证替换到以下命令中:
2. 创建并配置监控切换脚本
在获取完所有凭证后,执行 sudo nano /usr/local/bin/cf_failover.sh,粘贴以下脚本,并仔细替换脚本配置区域的所有占位符:
#!/bin/bash
# --- 配置区域 ---
CF_API_TOKEN="[Cloudflare API令牌]"
CF_ZONE_ID="[Cloudflare区域ID]"
CF_RECORD_ID="[Cloudflare DNS记录ID]"
DOMAIN_NAME="[您的博客域名]"
PRIMARY_IP="[服务器A的公网IP]"
SECONDARY_IP="[服务器B的公网IP]"
TG_BOT_TOKEN="[TG机器人令牌]"
TG_CHAT_ID="[TG频道或用户的ChatID]"
DB_ROOT_PASSWORD="[数据库ROOT密码]"
DOCKER_COMPOSE_PATH="/home/[您的登录用户名]/docker/typecho/docker-compose.yml"
# --- 脚本行为配置 ---
FAILURE_THRESHOLD=3
LOG_FILE="/tmp/cf_failover.log"
COUNTER_FILE="/tmp/failover_counter"
STATE_FILE="/tmp/failover_active.lock"
# --- 脚本主体 ---
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"; }
if [ -f "$STATE_FILE" ]; then
log "Failover is already active (lock file exists). Skipping health check."
exit 0
fi
if [ ! -f "$COUNTER_FILE" ]; then echo 0 > "$COUNTER_FILE"; fi
HEALTH_CHECK_URL="https://$DOMAIN_NAME/"
HTTP_STATUS=$(curl --connect-timeout 5 --max-time 10 -s -o /dev/null -w "%{http_code}" --resolve "$DOMAIN_NAME:443:$PRIMARY_IP" "$HEALTH_CHECK_URL")
if [ "$HTTP_STATUS" -eq 200 ]; then
log "Health check PASSED for $PRIMARY_IP (Status: $HTTP_STATUS)."
echo 0 > "$COUNTER_FILE"
else
log "Health check FAILED for $PRIMARY_IP (Status: $HTTP_STATUS)."
FAIL_COUNT=$(<"$COUNTER_FILE")
FAIL_COUNT=$((FAIL_COUNT + 1))
echo $FAIL_COUNT > "$COUNTER_FILE"
log "Failure count is now $FAIL_COUNT."
if [ "$FAIL_COUNT" -ge "$FAILURE_THRESHOLD" ]; then
log "Failure threshold reached. Triggering failover to $SECONDARY_IP."
UPDATE_RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$CF_RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type:application/json" \
--data '{"type":"A","name":"'$DOMAIN_NAME'","content":"'$SECONDARY_IP'","ttl":60,"proxied":true}')
log "Cloudflare API response: $UPDATE_RESPONSE"
if echo "$UPDATE_RESPONSE" | grep -q '"success":true'; then
log "Cloudflare DNS updated successfully."
log "Attempting to disable read-only mode on Server B."
docker-compose -f "$DOCKER_COMPOSE_PATH" exec -T mariadb mysql -u root -p"$DB_ROOT_PASSWORD" -e "SET GLOBAL read_only = OFF;"
log "Read-only mode disabled successfully. Server B is now fully operational."
touch "$STATE_FILE"
log "Lock file created at "$STATE_FILE". Monitoring is now paused."
if [[ -n "$TG_BOT_TOKEN" && -n "$TG_CHAT_ID" ]]; then
NOTIFICATION_MESSAGE="🚨 **Typecho 故障切换成功** 🚨%0A%0A**状态**: 主服务器A无响应,流量已自动切换至备用服务器B。**数据库已设为可写,服务完全接管。**%0A%0A**域名**: \`$DOMAIN_NAME\`%0A%0A请尽快检查主服务器A的状态!"
curl -s -o /dev/null -X POST "https://api.telegram.org/bot$TG_BOT_TOKEN/sendMessage" -d chat_id="$TG_CHAT_ID" -d text="$NOTIFICATION_MESSAGE" -d parse_mode="Markdown"
log "Telegram notification sent."
fi
echo 0 > "$COUNTER_FILE"
else
log "Cloudflare API call FAILED. Please check API response above. Failover aborted."
fi
fi
fi
3. 启动监控
执行 sudo chmod +x /usr/local/bin/cf_failover.sh 和 sudo crontab -e,添加: * * * * * /usr/local/bin/cf_failover.sh
七、 步骤五:测试与验证
- 正常状态检查: 访问博客。检查B的数据库同步状态和文件同步情况。
- 模拟故障: 在服务器A上执行
cd ~/docker/typecho/ && docker-compose stop。 - 观察切换: 在服务器B上执行
tail -f /tmp/cf_failover.log。 - 验证结果: 几分钟后,刷新博客应仍可访问且功能正常。Cloudflare后台DNS记录应已更新,同时您的Telegram应收到告警。
八、 步骤六:故障恢复与回切 (终极可靠流程)
当服务器A修复后,严格按以下步骤手动切回,确保数据万无一失。
1. 阶段一:准备
- 在服务器B上,执行
sudo crontab -e,注释掉监控脚本行。 - 在服务器B上,删除状态锁文件:
sudo rm /tmp/failover_active.lock
2. 阶段二:数据反向同步 (B -> A)
此流程将保证服务器A是服务器B的完美克隆。
- 在服务器B(临时主库)上,创建带坐标的完美快照:
- 暴露数据库端口: 编辑
nano ~/docker/typecho/docker-compose.yml,在mariadb服务下添加ports部分,然后docker-compose up -d。 - 放行防火墙:
sudo ufw allow [自定义数据库端口]/tcp - 创建快照:
cd ~/docker/typecho/ docker-compose exec mariadb mysqldump -u root -p'[数据库ROOT密码]' --single-transaction --master-data=2 typecho_blog > ~/reverse_definitive_dump.sql
- 暴露数据库端口: 编辑
- 在服务器B上,执行一次性的文件同步,将故障期间上传的文件推送到服务器A:
rsync -avz -e 'ssh -p [自定义SSH端口]' --delete --exclude='config.inc.php' ~/docker/typecho/app/ [您的登录用户名]@[服务器A的公网IP]:~/docker/typecho/app/ - 将数据库快照传输到服务器A(临时从库):
scp -P [自定义SSH端口] ~/reverse_definitive_dump.sql [您的登录用户名]@[服务器A的公网IP]:~/ - 在服务器A上,清空并恢复:
- 进入MariaDB容器:
docker-compose exec mariadb mysql -u root -p - 执行清空操作:
STOP SLAVE; DROP DATABASE typecho_blog; CREATE DATABASE typecho_blog; EXIT; - 从快照恢复数据:
cat ~/reverse_definitive_dump.sql | docker-compose exec -T mariadb mysql -u root -p'[数据库ROOT密码]' typecho_blog
- 进入MariaDB容器:
- 在服务器A上,使用精确坐标启动同步:
- 从快照文件中提取坐标:
grep "CHANGE MASTER TO" ~/reverse_definitive_dump.sql - 复制
CHANGE MASTER TO...后面的内容,修改连接信息后,在A的MariaDB中执行:-- 示例,请根据您自己的信息和上一步grep出的坐标修改 CHANGE MASTER TO MASTER_HOST='[服务器B的Tailscale IP]', MASTER_USER='repl', -- 复用'repl'用户 MASTER_PASSWORD='[数据库复制用的密码]', -- 复用之前的密码 MASTER_PORT=[自定义数据库端口], MASTER_LOG_FILE='[从快照文件里看到的文件名]', MASTER_LOG_POS=[从快照文件里看到的Position]; START SLAVE;
- 从快照文件中提取坐标:
- 【保险锁】验证同步完成:在A的MariaDB中反复执行
SHOW SLAVE STATUS\G;,直到Seconds_Behind_Master稳定为0。
3. 阶段三:服务切回
- 当且仅当完成以上数据库和文件两个反向同步步骤后,登录Cloudflare网站,手动将DNS记录改回**
[服务器A的公网IP]**。
4. 阶段四:恢复原始架构
在流量已经成功切回服务器A后,我们需要将主从关系恢复到最初的 A(Master) -> B(Slave) 状态。
-
在服务器A上 (恢复Master角色):
- 进入服务器A的MariaDB容器:
docker-compose exec mariadb mysql -u root -p - 执行以下命令,停止其作为临时从库的角色,并重置为主库:
STOP SLAVE; RESET MASTER; - 现在,获取A作为主库的新的、干净的日志坐标,以供B来跟随:
SHOW MASTER STATUS; - 【记录】记下A服务器上显示的新的
File和Position值。
- 进入服务器A的MariaDB容器:
-
在服务器B上 (恢复Slave角色):
- 进入服务器B的MariaDB容器:
docker-compose exec mariadb mysql -u root -p - 执行以下命令,彻底重置其状态,并重新指向服务器A:
STOP SLAVE; RESET SLAVE ALL; -- 清理所有旧的、临时的复制状态 SET GLOBAL read_only = ON; -- 【重要】重新将数据库设为只读模式 -- 使用您刚刚从服务器A记录下的新坐标 CHANGE MASTER TO MASTER_HOST='[服务器A的Tailscale IP]', MASTER_USER='repl', MASTER_PASSWORD='[数据库复制用的密码]', MASTER_PORT=[自定义数据库端口], MASTER_LOG_FILE='[A服务器新的File值]', MASTER_LOG_POS=[A服务器新的Position值]; START SLAVE;
- 进入服务器B的MariaDB容器:
5. 阶段五:收尾与最终验证
-
在服务器B上,清理临时配置:
- 关闭数据库端口暴露: 编辑
nano ~/docker/typecho/docker-compose.yml,删除或注释掉为反向同步临时添加的ports部分。 - 应用配置:
cd ~/docker/typecho/ && docker-compose up -d - 关闭防火墙端口:
sudo ufw deny [自定义数据库端口]/tcp
- 关闭数据库端口暴露: 编辑
-
在服务器B上,恢复自动监控:
- 执行
sudo crontab -e,取消对cf_failover.sh脚本的注释,恢复自动故障切换功能。
- 执行
-
最终验证:
- 在服务器B的MariaDB中,最后一次检查状态:
SHOW SLAVE STATUS\G; - 您应该能看到一个完全健康的、指向服务器A的主从关系,并且
Seconds_Behind_Master为0。
- 在服务器B的MariaDB中,最后一次检查状态: