primary 把 course_check 的新记录写入 InnoDB,并产生二进制日志事件。
外观
外观
约 3172 字大约 11 分钟
MariaDB主从复制逻辑备份恢复验证
2026-07-30
[Windows PowerShell] wsl ~:打开本机默认的 WSL2 Ubuntu;出现 用户名@主机名:~$ 后再执行标为 [WSL] 的命令。[WSL] ssh root@你的ECS公网IP:从 WSL 连接自己的 ECS;如果登录用户不是 root,请换成控制台显示的实际用户,看到远端提示符后再执行标为 [ECS] 的命令。第六次课已经把 Web 和 API 拆成两个服务,但业务真正重要的数据还没有得到保护。本课重点关注两台 MariaDB:primary 接收写入,replica 持续接收主库的二进制日志。
复制正常时,在主库新增一条课程记录,从库很快就能查到。可是如果有人在主库误删数据库,这条删除操作也会被复制过去。
关键提醒
从库提高了在线数据的可用性,却不能代替一份经过恢复验证的独立备份。
安全边界
本课只操作 cloud-course-lab-07 项目中的 course_db 测试库。执行 DROP DATABASE 前,必须同时确认当前 Compose 项目、目标库名和备份校验值;不得连接或删除服务器上的其他数据库。
主从复制(主库把数据变更记录发送给从库,从库按顺序重放这些变更) 解决的是在线高可用问题,比如增加只读副本、分担查询压力,或者为故障切换做准备。它的核心关注点是“持续流动的在线数据”。
逻辑备份(把库表结构和数据导出为可重新执行的 SQL) 解决的是时点数据保存问题。适合数据量适中、需要查看内容或者跨环境迁移的场景。它的核心关注点是“某个历史时刻可独立归档的静态材料”。
恢复验证(把备份导入隔离目标并核对结构、记录和业务结果) 解决的是“这份备份究竟能不能救命”的问题。备份文件躺在磁盘里、sha256sum 对得上,绝不等于数据真的能成功恢复。
三者各司其职,谁也替不了谁:
| 能力 | 主要价值 | 典型限制 |
|---|---|---|
| 主从复制 | 保留在线副本,支持只读查询与故障切换 | 误删库、坏 SQL 会立刻同步到从库 |
| 逻辑备份 | 得到可离线保存的 SQL 文件 | 大库导出导入较慢,需注意敏感数据脱敏 |
| 恢复验证 | 确认结构和数据能完整重建 | 需要隔离演练环境、时间与验收标准 |
观看时留意:主库和从库之间的数据流向是什么,复制主要解决什么问题?
与本课的关系:复制可以提供数据副本,但误删也会传播,因此不能把从库当成备份。
实训包定义两个 MariaDB 11.4 服务:
primary --二进制日志--> replica
| |
primary-data replica-dataprimary 与 replica 分别指定不同的 server-id。主库开启二进制日志(binlog),从库使用专用账号连接主库同步。出于安全考虑,两项服务都不对外暴露宿主机 3306 端口。
在 ECS 复制配置文件并完成检查:
[ECS] mkdir -p ~/cloud-course/lab-07
[ECS] cd ~/cloud-course/lab-07
[ECS] cp starter/compose.yaml starter/seed.sql .
[ECS] cp starter/.env.example .env
[ECS] chmod 600 .env这里的 .env 用来存放本次实验的临时密码,只保存在本地 ECS。请用密码管理器或 openssl rand -base64 24 生成强密码,不要直接照抄示例里的占位符。compose.yaml 和 seed.sql 来自实训包(从智慧职教课程资源区下载 lab-07-starter.zip 解压)。
[ECS] docker compose config --services该命令只读取并解析配置,预期输出 primary 和 replica。此时数据库还没真正启动,复制线程还没通。
[ECS] docker compose config --quiet若命令静默返回且退出码为 0,说明 YAML 格式与变量语法正确。如果提示变量缺失,先到 .env 中补全;明文密码不要写进 compose.yaml。
启动服务前,先查看系统资源与项目边界:
[ECS] free -h重点关注 available 剩余内存。两个数据库实例同时运行会吃掉一定内存,如果系统剩余资源不足,应先暂停后续部署并留存检查日志。
[ECS] docker compose ls确认当前操作的项目是 cloud-course-lab-07,别把命令敲到了其他线上项目里。
接着启动并观察容器健康状态:
[ECS] docker compose up -d
[ECS] docker compose ps当 primary 与 replica 都显示 healthy 时,说明数据库进程自身的健康检查已通过。但这还不够,必须深入查看主从复制线程的运行指标:
[ECS] docker compose exec -T replica sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" -e "SHOW REPLICA STATUS\G"' \
| grep -E 'Slave_(IO|SQL)_Running|Seconds_Behind_Master'预期 Slave_IO_Running: Yes、Slave_SQL_Running: Yes。Seconds_Behind_Master 是观察项,不应把一次为 0 解释成”以后永远没有延迟”。它通过比较主库写入事件的时间戳和从库当前处理进度来计算——如果主库长时间没有新写入,即使从库之前远远落后,这个值也可能显示 0。所以不能只看这一个数字,必须和业务数据查询互相印证。
云主机 B 隔离 Compose 项目 · 2026-07-28 真实运行
root@SYG680400:/opt/xpk-course-demos/lesson-07$ docker compose psSERVICE IMAGE STATUS PORTSprimary mariadb:11.4 Up (healthy) 3306/tcpreplica mariadb:11.4 Up (healthy) 3306/tcp这条命令读取运行状态。应关注服务名称、健康状态、就绪数量和端口映射,不要只凭命令返回了表格就判断业务正常。
这一步是“两项数据库健康、无宿主机端口映射、复制 IO/SQL 线程为 Yes”证据链中的一环。
只证明捕获时刻的复制状态,不能证明以后无延迟或无数据冲突

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
观看时留意:binlog、中继日志和复制线程怎样把主库变更送到从库?
与本课的关系:看完后再读 SHOW REPLICA STATUS 输出,把状态字段和数据流对应起来。
沿着主库写入、二进制日志、从库重放和逻辑备份,区分在线复制与离线恢复材料。
primary 把 course_check 的新记录写入 InnoDB,并产生二进制日志事件。
先查看 starter 中的 seed.sql,确认它只创建 course_check 表并写入一条测试记录。然后把它交给主库客户端执行:
[ECS] docker compose exec -T primary sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" course_db' \
< seed.sqlseed.sql 只针对 course_db.course_check。其中的 ON DUPLICATE KEY UPDATE 使重复执行不会因为主键已存在而中断。
随后在从库查询:
[ECS] docker compose exec -T replica sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" course_db \
-e "SELECT id,item FROM course_check ORDER BY id;"'从库出现 1 primary-write,才说明这条具体业务数据已经到达副本。SHOW REPLICA STATUS 和业务查询是一组互补证据:前者看复制机制,后者看实际数据。
云主机 B 隔离 course_db · 2026-07-28 真实数据流
...$ docker compose exec -T primary sh -lc 'mariadb ... course_db' < seed.sql# seed.sql 创建 course_check,并写入 id=1“向主库写入测试数据”保留了完整命令和与它相邻的输出。判断时应直接引用输出中的字段或状态,不要把步骤名称当成结论。
这一步是“主库写入 id=1 后,从库查询到相同主键和内容”证据链中的一环。
只验证一条小记录,不代表大事务或持续高负载没有复制延迟

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
本课用一份很小的逻辑备份走通恢复流程。先在主库容器内导出,再把标准输出写到 ECS 的课程备份目录:
[ECS] mkdir -p backup
[ECS] docker compose exec -T primary sh -lc \
'mariadb-dump -uroot -p"$MARIADB_ROOT_PASSWORD" \
--single-transaction --routines --events --databases course_db' \
> backup/course_db.sql--single-transaction 适用于本课 InnoDB 表,在导出期间尽量保持一致视图;--routines 和 --events 明确包含存储过程与事件。SQL 文件可能含业务数据,不能上传到公开位置。
检查文件和校验值:
[ECS] ls -lh backup/course_db.sql
[ECS] sha256sum backup/course_db.sql | tee backup/course_db.sql.sha256ls 用于确认文件大小,sha256sum 为后续传输或恢复前比较内容提供依据。校验正确仍不等于恢复成功。
观看时留意:备份文件怎样离开正在运行的数据库,恢复时又怎样重新写入目标库?
与本课的关系:具体工具参数和运行位置以本课隔离容器为准,恢复后必须重新查询数据。
在执行删除前完成三项确认:
[ECS] docker compose ls确认当前项目名。
[ECS] docker compose exec -T primary sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" -Nse \
"SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME=\"course_db\";"'输出必须严格为 course_db,不能是空值或其他名称。
[ECS] sha256sum -c backup/course_db.sql.sha256必须返回 OK。然后才删除这一个测试库:
[ECS] docker compose exec -T primary sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" -e "DROP DATABASE course_db;"'稍等后,从库上的 course_db 也会消失。这说明复制如实同步了错误操作。
把 SQL 重新导入主库:
[ECS] docker compose exec -T primary sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD"' \
< backup/course_db.sql这里使用 mariadb 客户端执行备份中的建库、建表和插入语句。导入命令退出码为 0 后,继续核对主库:
[ECS] docker compose exec -T primary sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" course_db \
-e "SELECT id,item FROM course_check ORDER BY id;"'主库重新出现记录后,再到从库查询同一张表:
[ECS] docker compose exec -T replica sh -lc \
'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" course_db \
-e "SELECT id,item FROM course_check ORDER BY id;"'主库恢复成功、从库再次收到恢复产生的变更,整个恢复流程才算完整走通。
命令和相邻输出按原始捕获顺序拆开显示。切换步骤时,先看命令,再从输出中找判断依据。
...$ mariadb-dump ... --databases course_db > backup/course_db.sql-rw-r--r-- 1 root root 2.3K Jul 28 04:11 backup/course_db.sqledfc5386...c9aa507 backup/course_db.sql“导出数据库备份”保留了完整命令和与它相邻的输出。判断时应直接引用输出中的字段或状态,不要把步骤名称当成结论。
这一步是“备份文件与校验、误删向从库传播、从逻辑备份恢复后主从记录一致”证据链中的一环。
只验证课程小库;生产库仍需容量、停机窗口、权限、保留周期与异地副本设计

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
这组记录把导出、确认项目、检查数据库、核对校验和、删除测试库和导入备份放在同一条时间线上。命令中的 ... 是脱敏后的省略符,不能直接复制;实训时应使用前文给出的完整命令。
云主机 B · cloud-course-lab-07 · 2026-07-28
root@SYG680400:/opt/xpk-course-demos/lesson-07$ sha256sum -c backup/course_db.sql.sha256backup/course_db.sql: OK备份文件的当前字节内容与校验文件一致
备份文件的当前字节内容与校验文件一致
不能证明 SQL 一定可以成功导入,也不能证明备份包含全部业务数据

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
读图时先看命令,再看唯一一行输出。OK 只说明当前 course_db.sql 与校验文件记录的字节一致;它还没有回答 SQL 能否导入,所以后面仍要做恢复和业务查询。
云主机 B · cloud-course-lab-07 · 2026-07-28
root@SYG680400:/opt/xpk-course-demos/lesson-07$ docker compose exec -T replica sh -lc 'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" course_db -e "SELECT id,item FROM course_check ORDER BY id;"'id item1 primary-write逻辑备份导入主库后,同一条测试记录再次传播到从库
逻辑备份导入主库后,同一条测试记录再次传播到从库
只验证本课一条记录,不代表生产数据库的全部表、权限和一致性已经恢复

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
表头下重新出现 1 primary-write,说明备份导入主库后,这一条测试记录再次到达从库。这里只核对了课程表中的一条记录,不能把它扩大解释成生产库的表结构、账号权限和全部数据都已经恢复。
输入脱敏后的复制状态、查询、备份或恢复结果,让助教区分连接、重放、数据和恢复证据。
本实验的原始聊天仅保存在当前标签页,不会写入全局课程助教上下文。
两项容器都 Up,但复制 IO 线程为 No
先查看从库日志和 Last_IO_Error。常见原因是主库服务名、复制账号或网络连接问题。不要先删除数据卷,否则会丢失最有价值的故障现场。
IO 为 Yes,SQL 为 No
从库能收到日志,但重放时遇到 SQL 错误。查看 Last_SQL_Error 和失败位置,先理解冲突对象,不要盲目跳过事件。
备份文件存在,但导入失败
先运行 head 查看文件开头、sha256sum -c 核对内容,再确认导出和导入使用的 MariaDB 客户端版本。MariaDB 11 的容器中应使用 mariadb-dump,不要依赖已经移除的 mysqldump 别名。
恢复后主库有数据,从库暂时没有
重新查看复制线程和延迟,等待短暂传播后再查一次。若 SQL 线程停止,应保留错误,而不是把“稍等”当成固定修复方法。
完整流程见实训 07:数据库复制与恢复验证。
保底任务
SHOW REPLICA STATUS 判断 IO、SQL 线程;标准任务
course_db,再导入并核对主从数据;verify.sh,清理课程项目并保留报告证据。挑战任务
--all-databases 的范围差异;提交前清理实验环境:
[ECS] docker compose down
[ECS] rm -rf ~/cloud-course/lab-07提交文件:
班级_学号_姓名_第07次课_数据库复制与恢复报告.docx只上传一个 Word 到智慧职教“第07次课”。不上传 .env、SQL 备份、公网地址、账号、密码或数据库数据卷。
检查项目边界、复制状态、主写从读、备份校验、恢复和提交规范。
完成后可立即查看反馈和解析。
mariadb-dump 生成逻辑备份,mariadb 客户端负责导入恢复。下一次课将把两台后端服务接到 Nginx 负载均衡器之后,观察正常轮询、单后端故障和恢复。
以下资料在 2026-07-28 核对:
助教会读取当前课程页面和结构化学习记录,但不会读取正文实验框里的原始聊天。