第2章:搭建只会破坏自己的四实例实验
恢复教学必须真的删除数据、停止复制和结束数据库进程。如果命令可能连到日常开发数据库,读者就无法放心验证负面结果。本书先建立一个封闭拓扑,再把所有破坏性命令绑定到本次创建的资源。实验不是让你在现有MySQL上执行几条危险SQL,而是从空白环境完整建立、观测和拆除。
四个实例各有一项职责
source是原始写入库,replica通过GTID异步复制接收事务。restore用于导入并发写入期间取得的逻辑快照,证明备份本身一致;pitr从第二份安静基线开始回放日志,证明误删前目标能够重建。四个角色不能混用,否则在源库上查询正确数据,可能被误当作恢复实例已经正确。
每次执行生成随机前缀,创建独占Docker bridge网络。容器只有这个私有网络,没有向宿主机发布数据库端口。实例使用不同server-id,数据库初始化生成各自server_uuid。程序执行SQL时带上完整容器名,不接受用户提供任意生产地址。容器标签也写入本次前缀,便于异常后识别资源。
销毁只遍历程序本次成功创建并记录的容器名,删除这些容器及其匿名卷,然后删除自己的网络。没有全局prune,没有按模糊名称批量删除。正常异常会进入finally清理;宿主机强杀或机器断电可能阻止清理,此时需要根据已知前缀逐项核查。不能因为一次实验遗留资源,就执行清空所有卷的快捷命令。
固定镜像仍要记录实际版本
镜像使用完整sha256摘要,避免浮动的8.4标签在重跑时悄悄切换内容。报告同时保存实际SELECT VERSION结果和RepoDigests。摘要确定分发对象,版本字符串帮助理解数据库语义,两者各有用途。仅在说明里写“使用MySQL八点四”,不能证明这次运行确实用了相同软件。
实例开启GTID与一致性约束,使用ROW格式的完整行镜像,并记录sync_binlog与innodb_flush_log_at_trx_commit。实验没有通过断电和损坏文件系统证明这些参数的物理持久性;记录参数只是让提交语义有明确条件。缓冲池缩小,关闭Performance Schema以适应教学CI,不能据此推导生产调优建议。
Python只使用标准库调用Docker命令,不需要额外数据库驱动。mysql与mysqldump来自固定服务器镜像;该精简镜像没有mysqlbinlog,因此程序另从官方固定8.4.11客户端RPM提取工具,校验下载SHA-256并记录实际工具版本。工具镜像沿用相同基础镜像,在无网络容器内只读挂载归档。等待就绪靠实际SELECT 1成功,而非固定睡十秒。启动失败、恢复失败或断言不成立都会返回非零,不会因为环境不满足就把硬实验标成跳过。
口令与日志的边界
实验口令是公开教学常量,账户仅存在于临时网络。它不适用于任何共享环境。程序通过docker exec的环境变量向客户端传入口令,避免把口令直接写成命令行参数;这并不构成完整秘密管理,能控制Docker的用户仍然拥有很高权限。报告不收集生产凭据,也不接触现有容器。
业务写入使用ledger_app,只授予ledger库的SELECT、INSERT、UPDATE和DELETE,没有SUPER、CONNECTION_ADMIN或全局管理权限;备份与角色编排才使用root。复制账户只授予复制需要的权限,源主机在私有网络内解析。GET_SOURCE_PUBLIC_KEY使教学连接能完成认证,并不等于配置了传输加密或证书验证。生产需要结合网络信任边界、TLS和账户来源限制处理,不能照搬通配主机名和公开密码。我们把这些明确列为未实现能力。
真实运行与静态构建分开
作者本机没有Docker服务,无法在那里声称执行了数据库实验。最早的提交只有实验CI,先让真实四实例跑通,再继续出版。完整发布流水线重新执行实验,把报告复制到书籍下载区,之后构建EPUB和网页。ZIP解压到新目录后,又建立全新随机资源执行一次,证明下载包不依赖源码目录中偶然存在的文件。
本地阅读器可以静态预览,移动布局和EPUB结构也能检查,但这类检查不能证明mysqldump参数有效。相反,数据库实验通过也不能证明在线章节完整。两种证据最后汇合到同次发布工件,读者才能确认自己下载到的代码、书稿与运行记录属于同一个交付版本。
开始前的容量准备
建议至少留出约两GB可用内存、三GB磁盘以及下载镜像的网络。四个实例同时存在,备份会包含用于延长导出的填充数据。填充表不参与业务验收,只帮助观测导出期间确实有事务提交。若资源不足,先调整运行环境;把并发实验去掉后依然声称验证一致快照,会改变本书要证明的命题。