浏览知识库目录

MySQL

环境、版本与客户端基线

用官方 MySQL 9.7.1 容器和客户端固定 SQL 模式、字符集、时区与会话,建立可重复实验环境,并在可重复的 StudyStore 实验中验证结果、失败边界与恢复方式。

环境、版本与客户端基线

相同 SQL 在不同版本、SQL 模式、字符集、时区和隔离级别下可能得到不同结果。环境基线不是安装清单,而是一组能被查询、保存和重建的服务端与会话状态。Docker 让三种桌面系统共享同一服务端,但 shell 和文件挂载仍需分别说明。


一、学习目标

  • 启动固定版本的官方 MySQL Community 容器
  • 区分服务端、客户端、连接和会话变量
  • 固定严格 SQL 模式、utf8mb4 与 UTC
  • 安全处理初始化密码与普通应用账户
  • 保存可重复的健康检查和清理步骤

二、启动固定版本容器

使用明确名称、网络和临时卷:

docker run --name studystore-mysql   -e MYSQL_ROOT_PASSWORD=test-root-password   -e TZ=UTC   -p 127.0.0.1:33060:3306   -d mysql:9.7.1

示例密码只用于一次性本地实验,不提交到仓库或 shell 历史。生产环境应使用秘密管理。绑定 127.0.0.1 避免实验端口暴露到所有接口;CI 可让客户端与服务端处于私有 Docker 网络,不发布宿主端口。

等待健康不能只 sleep 固定秒数,应循环执行 mysqladmin ping 并设置总超时。


三、客户端与连接

在镜像内运行客户端可避免宿主安装差异:

docker exec -it studystore-mysql   mysql -uroot -p --protocol=socket

-p 后不直接写密码,避免进程列表和历史泄漏。脚本可用受控环境文件或客户端配置,但要限制权限并在结束后删除。连接成功后用 STATUSSELECT CONNECTION_ID() 确认协议、服务端和会话。

服务端版本与客户端版本可以不同,诊断问题时两者都要记录。


四、全局与会话变量

查询关键状态:

SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode;
SELECT @@GLOBAL.time_zone, @@SESSION.time_zone;
SELECT @@character_set_client, @@character_set_connection,
       @@character_set_results, @@collation_connection;

全局变量通常影响新连接,不一定改变已存在会话;会话变量只作用当前连接。实验脚本在开头显式设置需要的会话状态,不能假定管理员刚修改全局值后当前窗口自动生效。

本系列使用严格模式,遇到截断、非法日期和溢出应失败,而不是依赖警告后继续。


五、初始化数据库与账户

管理员负责建库和授权,应用账户只拥有需要的对象权限:

CREATE DATABASE study_store
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_0900_ai_ci;

CREATE USER 'studystore_app'@'%' IDENTIFIED BY 'local-only-password';
GRANT SELECT, INSERT, UPDATE, DELETE
  ON study_store.* TO 'studystore_app'@'%';

DDL 迁移账户与运行账户应分离。root 不用于普通查询或应用连接。实验结束删除账户、数据库和容器,但只针对本次明确名称。


六、健康检查与故障证据

健康检查至少验证服务可接受认证连接和简单查询:

SELECT 1;
SELECT VERSION();

容器“running”不代表 MySQL 已完成初始化。失败时保存容器日志、健康状态、端口绑定和客户端错误码,不要反复重启清除证据。常见问题包括旧卷与新密码不匹配、端口冲突、架构镜像不支持和初始化脚本只在空数据目录执行。


七、从知识点到工程契约

本篇 SQL 最终要运行在长期存在的 schema、连接和事务中,而不是只在一个临时查询窗口里得到一次正确结果。先写清输入表与行数、会话设置、事务边界、允许的锁、期望结果和失败后的状态,再决定使用约束、查询、索引、存储对象还是运维命令。数据库行为同时受到版本、隔离级别、字符集、统计信息和并发会话影响,示例必须把这些前提显式化。

可以用以下顺序把知识点落到 StudyStore:

  1. 在全新数据库按迁移顺序建立最小 schema,保存 SHOW CREATE TABLE 与关键会话变量。
  2. 加入一个与“使用浮动 mysql:latest,导致同一脚本随时间改变”相关的反例,记录错误码、SQLSTATE、事务是否仍可用以及数据是否改变。
  3. 为正常、空集、边界值、重复值和并发冲突准备确定性种子,不依赖手工残留数据。
  4. 对读查询检查结果集和 EXPLAIN ANALYZE;对写操作同时检查受影响行数、约束、提交与回滚。
  5. 最后才讨论性能优化。索引和参数调整必须有执行计划、等待事件或容量数据支持,并保留变更前基线。

审查数据库设计时至少回答四个问题:谁能写,哪条约束保护不变量,事务在哪一层结束,失败后如何恢复。MySQL 能保证声明范围内的事务和持久性,却不会替应用补上缺失约束、幂等键、备份演练或最小权限。只要这些问题没有明确答案,就不要把一次成功执行当成生产方案。

本篇最重要的能力是“启动固定版本的官方 MySQL Community 容器”。能由主键、唯一键、外键、CHECK 或数据类型表达的规则,应优先落到数据库;需要跨聚合或外部系统判断的规则,再由应用和事务协调。不要用注释或约定替代可执行约束。


八、验证策略与复盘

验证分为 schema、数据、并发和恢复四层。schema 层检查定义与会话基线;数据层断言结果和约束;并发层至少用两个独立连接观察锁与隔离;恢复层在新实例重放迁移、备份与恢复。只看客户端显示“Query OK”不能证明结果正确,更不能证明在另一组数据和并发时仍正确。

建议保存下面的实验记录:

项目 需要记录的证据
版本 SELECT VERSION() 与镜像标签
会话 sql_mode、time_zone、事务隔离与字符集
输入 schema 版本、种子行数和参数值
输出 结果集、受影响行数、警告、错误码与 SQLSTATE
性能 执行计划、实际行数、耗时与等待
恢复 COMMIT/ROLLBACK 结果、备份校验和与恢复行数

每组脚本都应能在空数据库从头执行,并通过显式断言退出非零。涉及权限时分别用管理员和最小权限账户连接;涉及锁时设置有限等待,避免测试永久挂起;涉及复制时等待 GTID 状态而不是固定 sleep。清理只删除本次创建的临时容器、网络和数据库。

本篇可以用以下目标做验收:区分服务端、客户端、连接和会话变量;固定严格 SQL 模式、utf8mb4 与 UTC;安全处理初始化密码与普通应用账户。把每个目标转换为一条可重复 SQL、一个预期错误或一项恢复检查。若优化后结果正确但计划退化,应把执行计划也纳入回归证据。

发布前再从三个方向反向审查:把数据量放大两个数量级,判断扫描、锁和日志是否仍可控;让两个会话以最不利顺序并发,判断约束和事务是否仍保护不变量;让执行在任意一步失败,判断备份、回滚或幂等键能否恢复。只在十几行数据和单连接中成功的 SQL 仍只是功能草稿。

最后把脚本交给一个只知道镜像版本和入口命令的干净环境执行。脚本不得依赖图形客户端自动设置、个人默认数据库或先前会话变量;所有对象名、字符集、事务和预期错误都应明确。对仅用于说明、不可直接执行的片段要标注上下文,避免把省略条件的示意 SQL 当作完整迁移。

还要保存一份“结果为什么可信”的说明:约束证明哪些坏数据无法进入,事务证明哪些变化共同提交,执行计划证明访问了哪些行,权限测试证明哪些身份无法越界,恢复演练证明故障后能重新得到可用状态。这五类证据缺一时,都应在结论旁写明限制。数据库实验的价值不只是得到答案,而是让另一位操作者在不同机器、不同时间仍能重现同一判断。

若结论依赖当前数据分布或配置,应把适用范围写在 SQL 旁,并安排数据增长或版本升级后的复测条件;不要把一次测量永久固化为规则。


九、StudyStore 实验

用固定镜像启动临时实例,循环等待可用,创建数据库与最小权限账户。分别用 root 和应用账户验证 DDL 允许/拒绝行为,保存会话基线,最后删除本次容器和临时卷。

完成本节后,不要只保存代码或 SQL。请同时保存执行命令、关键输出和失败案例;学习笔记真正有价值的部分,是能够说明输入、状态变化、输出以及失败后的恢复方式。


十、常见错误

  • 使用浮动 mysql:latest,导致同一脚本随时间改变
  • 在命令行明文拼接密码
  • 修改全局变量后假定当前会话立即改变
  • 应用始终使用 root 连接
  • 固定 sleep 后直接执行迁移,偶发初始化未完成

十一、练习与自测

  1. 比较全局和会话 sql_mode,并新建连接验证变化时机。
  2. 让应用账户尝试 CREATE TABLE,确认被拒绝。
  3. 制造端口冲突并根据 Docker 与客户端输出定位。
  4. 写一个有总超时的 mysqladmin 健康等待脚本。

自测时应在干净的临时目录或临时数据库中重新执行,而不是依赖上一节遗留的状态。如果结果与预期不同,先记录实际输出,再缩小问题范围。


十二、官方资料

版本行为与二手文章不一致时,以本系列固定版本的官方文档、命令输出和可重复测试结果为准。

上一篇:MySQL 完整学习路线 下一篇:关系模型、数据类型与字符集