当前位置: 首页 > news >正文

理解MySQL的原理

1. MySQL 是什么?为什么用 MySQL

MySQL 是一个流行的开源关系型数据库管理系统(RDBMS)。
优点:成熟、稳定、生态丰富、SQL 标准支持良好、社区与商业支持(MariaDB、Percona、Oracle MySQL)、适合 OLTP 场景、事务支持强(InnoDB)。

什么时候用 MySQL

  • 需要强一致性与事务(金融、订单)
  • 结构化数据、关系模型清晰
  • 中小规模到大多数企业级业务(配合分库分表或 HTAP 产品可扩展)

2. 核心角色与组件总览

  • 客户端(mysql CLI / 应用驱动)
  • Server(mysqld):连接管理、SQL 解析、优化、执行调度
  • SQL 解析器 + 优化器 + 执行器:决定如何执行 SQL(选择索引/顺序扫描/连接顺序等)
  • 存储引擎(Storage Engine):InnoDB(默认)、MyISAM(历史)、Memory、CSV 等 —— 负责数据读写与锁实现
  • InnoDB 子系统:Buffer Pool(缓存页)、Redo Log(重做日志)、Undo Log、Doublewrite、Adaptive Hash Index、FLUSH/Checkpoint
  • I/O 子系统:磁盘、OS 缓存、文件系统
  • 复制/二进制日志(binlog):支持异步复制、增量备份

3. 执行流程(客户端发送 SQL 到数据落盘)——逐步拆解(重点)

下面以一个简单 SELECT 和一个 INSERT+事务为例,讲清每一步在干什么 / 怎么干 / 为什么 / 不这么干会怎样 / 注意点

场景 A:SELECT * FROM orders WHERE id = 123;

步骤 1:客户端发起连接并发送 SQL
  • 在干什么:客户端(JDBC)建立 TCP 连接到 mysqld,发送 SQL 文本。
  • 怎么干的:JDBC -> Connector/J -> TCP -> mysqld。
  • 为什么:需要会话上下文、事务、用户鉴权等。
  • 不这么干:无连接则无法执行;无鉴权会导致安全问题。
  • 注意:长连接 vs 短连接决定延迟与资源使用;使用连接池(HikariCP)是推荐做法。
步骤 2:身份验证与权限检查
  • 在干什么:mysqld 校验用户与权限(GRANTs)。
  • 怎么干的:查 mysql.usermysql.db 表,或读取缓存的认证信息。
  • 为什么:保证安全访问。
  • 注意:权限配置不当会导致查询无法执行或泄露数据。
步骤 3:SQL 解析(Parser)
  • 在干什么:将 SQL 文本解析成 AST(抽象语法树)。
  • 怎么干的:词法分析 -> 语法分析 -> 生成解析树(parser)。
  • 为什么:把 SQL 转为机器可操作的结构。
  • 注意:极长或复杂 SQL 可能导致解析开销增加。
步骤 4:改写与预处理(Preprocessor)
  • 在干什么:标量替换、解析表/列名、权限检查、视图展开。
  • 怎么干的:根据解析树查询表元数据(InnoDB/Information Schema)。
  • 注意:视图与子查询会影响优化器选择。
步骤 5:查询优化(Optimizer / Planner)
  • 在干什么:生成执行计划:选择索引、决定连接顺序(Nested Loop / Hash Join)、估算代价。
  • 怎么干的:基于统计信息(cardinality)、索引可用性、表大小估算代价,使用 Rule-based / Cost-based 方法。
  • 为什么:不同的执行计划性能差别巨大。
  • 不这么干:可能全表扫描、巨慢。
  • 注意:统计不准时(ANALYZE TABLE / auto analyze)会导致次优计划;USE INDEXFORCE INDEX 可临时强制索引。
步骤 6:执行器(Executor)
  • 在干什么:按执行计划逐步读取数据;如果使用索引则通过索引定位页并读取行。
  • 怎么干的:访问 Buffer Pool(若缓存命中则不访问磁盘),组织结果集。
  • 注意:若 Buffer Pool 未命中则触发磁盘 I/O,慢。
步骤 7:网络返回结果
  • 在干什么:mysqld 把结果行封包并通过 TCP 返回给客户端。
  • 注意:结果太大要使用分页(LIMIT、游标)避免内存爆炸。

场景 B:事务写入(INSERT)与持久化

SQL:

START TRANSACTION;
INSERT INTO orders (id, user_id, amount) VALUES (123, 42, 100.0);
COMMIT;
步骤 1-4:解析/预处理/优化(同 SELECT)
步骤 5:事务开始(InnoDB TX)
  • 在干什么:为会话创建事务上下文(thread/ trx)。
  • 怎么干的:分配事务 id(trx_id),记录事务信息。
  • 为什么:支持 ACID,尤其原子性与隔离。
步骤 6:生成 Undo / Redo 日志(逻辑)
  • 在干什么:在内存中生成 Undo(用于回滚)和重做(Redo)日志条目。

  • 怎么干的

    • Undo:记录旧值以便回滚(MVCC 也依赖它提供快照)。
    • Redo:记录对页的修改用于恢复(写入 Redo Log Buffer)。
  • 为什么:保证可回滚与崩溃恢复。

步骤 7:修改内存页(Buffer Pool)
  • 在干什么:将数据页加载到 Buffer Pool,修改内存中的页(脏页)。
  • 怎么干的:直接在内存页上修改相应记录并设置标志为脏页。
  • 注意:如果没有在内存修改,会频繁磁盘写入,性能差。
步骤 8:写 Redo Log 到重做日志文件(顺序写)
  • 在干什么:将 Redo Buffer 刷入重做日志文件(ib_logfile*)。
  • 怎么干的:顺序写入磁盘,通常由 fsync 刷盘保证持久性(由 innodb_flush_log_at_trx_commit 控制行为)。
  • 为什么:保证 COMMIT 时可恢复(崩溃后通过 Redo 恢复提交事务)。
  • 注意:这是持久化的关键开销点,调整该参数权衡性能与持久性。
步骤 9:提交(COMMIT)
  • 在干什么:事务标记为已提交,释放锁。
  • 怎么干的:如果配置为 innodb_flush_log_at_trx_commit=1,在 commit 时必须 fsync Redo Log。
  • 为什么:确保事务持久化并对其他事务可见。
步骤 10:异步刷脏页(Checkpoint / Background)
  • 在干什么:后台线程将脏页刷新到磁盘(数据文件 ibdata / .ibd)。
  • 怎么干的:Doublewrite + Checkpoint 机制保证崩溃恢复安全。
  • 注意:脏页刷新是异步的,但过多脏页会导致 checkpoint 压力,影响性能。

4. 存储引擎:以 InnoDB 为主的内部机制(重点)

4.1 InnoDB 数据布局

  • 页(Page):通常 16KB(可配置),是 I/O 最小单位。
  • 段 / 表空间:ibdata 或 per-table .ibd 文件(innodb_file_per_table)。
  • 索引组织表( clustered index ):主键聚集(PK 决定行在 B+Tree 中的位置)。
  • 二级索引(非聚集):二级索引项包含主键作为回表键。

4.2 Buffer Pool(内存)

  • 缓存数据页与索引页,减少磁盘 I/O。
  • 调优 innodb_buffer_pool_size(生产建议占机器内存的 60~80%)。

4.3 Redo Log / Doublewrite

  • Redo 顺序写用于崩溃恢复;Doublewrite 避免半写页问题。
  • 参数:innodb_log_file_size, innodb_log_files_in_group, innodb_flush_log_at_trx_commit

4.4 Undo Log & MVCC

  • Undo 用于回滚与实现 MVCC 快照读(非阻塞读)。
  • MVCC 使读操作不阻塞写操作(Read Committed / Repeatable Read 的实现底层)。

4.5 锁机制

  • 行级锁(next-key lock) + 插入意向锁(intention locks) + gap locks(幻读防护)。
  • 所有锁在 InnoDB 层实现,使用 trx id 与 lock table 管理。

5. 索引原理与最佳实践

5.1 常见索引类型

  • B-Tree(B+Tree):默认索引,适合范围查询、排序、等值查询。
  • Hash(Memory 引擎或 InnoDB adaptive hash):适合等值查询,但不支持范围。
  • Fulltext:全文搜索(InnoDB/MyISAM 支持),用于文本搜索。
  • Spatial(R-Tree):地理空间索引。

5.2 索引使用规则

  • WHERE 条件列、JOIN 子句、ORDER BY、GROUP BY 都是索引候选。
  • 组合索引遵循最左前缀原则(a,b,c) 可用于 aa,ba,b,c 的查询。
  • 避免在索引列上做函数/运算(会导致索引失效)。
  • 小表不必过多索引;写密集型表要慎重增加索引(每个索引都会写开销)。

5.3 EXPLAIN & 使用优化

EXPLAIN FORMAT=JSON SELECT * FROM orders WHERE user_id=42 AND created_at > '2025-01-01';

观察:type、possible_keys、key、rows、extra(Using index, Using filesort, Using temporary)。


6. 事务、隔离级别与 MVCC

6.1 ACID

  • A:原子性(Atomic)
  • C:一致性(Consistency)
  • I:隔离性(Isolation)
  • D:持久性(Durability)

6.2 隔离级别(SQL 标准)

  • READ UNCOMMITTED:脏读
  • READ COMMITTED:防止脏读(Oracle 默认),InnoDB 可配置
  • REPEATABLE READ (InnoDB 默认):防止脏读与不可重复读(通过 MVCC),但存在幻读时 InnoDB 通过 gap lock 防护
  • SERIALIZABLE:最高隔离,性能开销大

6.3 MVCC(多版本并发控制)

  • 读取时使用版本号(trx id)与 Undo 信息生成一致性快照,避免读锁。
  • 写时使用行锁(记录/Gap Lock)保证一致性。
  • 常见问题:长事务导致 Undo 阻塞、Prune/History 长期存在影响性能。

7. 复制、备份与高可用(常用运维知识)

7.1 逻辑备份(mysqldump)

# 全量备份
mysqldump -u root -p --single-transaction --routines --triggers --events --databases mydb > mydb.sql
# 恢复
mysql -u root -p < mydb.sql

--single-transaction 对 InnoDB 做一致快照(非阻塞)。

7.2 二进制日志(binlog)

  • binlog 用于复制与点时间恢复(PITR)。
  • 推荐使用 ROW 模式(binlog_format=ROW)保证复制精确性。

7.3 主从复制(异步 / 半同步)

  • 主(master) 写 binlog;从(slave) 拉取并执行。
  • 半同步可使用 rpl_semi_sync 插件保证至少一个从确认后才返回成功,提高安全性。

7.4 GTID(全局事务 ID)

  • 便于 failover 与自动化管理(Percona / MariaDB / MySQL 支持)。

7.5 高可用方案

  • 主从 + MHA(Master High Availability):检测主故障并自动切换(老方案)。
  • Group Replication / InnoDB Cluster(MySQL 官方):基于组复制的更现代 HA。
  • ProxySQL / HAProxy + Keepalived:流量代理 + VIP 做接入层。

8. 性能诊断与优化实战

8.1 常用工具与命令

  • EXPLAIN / EXPLAIN ANALYZE(MySQL 8.0)
  • SHOW PROCESSLIST; 查看慢查询或锁等待
  • SHOW ENGINE INNODB STATUS\G(锁与事务信息)
  • SHOW GLOBAL STATUS / SHOW VARIABLES(性能统计)
  • Percona Toolkit:pt-query-digest(慢查询分析)

8.2 常见调优项(参数)

  • innodb_buffer_pool_size(关键)
  • innodb_log_file_size
  • innodb_flush_log_at_trx_commit
  • max_connections
  • query_cache(已弃用,建议使用缓存层 Redis)
  • thread_cache_size
  • tmp_table_size / max_heap_table_size

8.3 优化技巧

  • 给慢查询加索引 / 重写 SQL(避免 SELECT *)
  • 分页改进:keyset pagination(基于索引的分页)
  • 热表分区(PARTITION BY RANGE)适用于时间序列大表
  • 读写分离(读从库)与中间缓存(Redis / Memcached)
  • 使用连接池与预编译语句(避免频繁解析)

9. 常见坑与注意事项

  • 不要盲目增加索引(会影响写性能)
  • 长事务导致 undo/ibdata 膨胀(避免长时间未提交的事务)
  • 不建议把 innodb_buffer_pool_size 设置过高以致系统 swap(会极慢)
  • 全文索引差异:MyISAM 与 InnoDB 行为差别(配置)
  • 不使用 SELECT * 做分页或大数据查询
  • binlog_format 不当导致从库差异:ROW 推荐用于精确复制
  • 字符集问题:使用 utf8mb4 支持 4 字节字符(Emoji)

http://www.dtcms.com/a/553403.html

相关文章:

  • Mac通过命令行开启ssh服务
  • 哈尔滨有哪些做网站的公司站长工具seo综合查询问题
  • 珠海做网站的wordpress 写作
  • 【计算机基础】之核心架构
  • 临西网站建设公司公司核名查询官网
  • PPIO独家上新GPU实例模板,一键部署Kimi-Linear
  • 工业级电池健康管理利器:GRX-3000 系列电池诊断站技术解析
  • 旅游网站建设功能意义wordpress 模板 免费
  • 周口市住房和城市建设局网站自做网站打开速度慢
  • STM32H743-ARM例程35-DHCP
  • 概率论直觉(一):大数定律
  • 数据结构—栈和队列
  • JavaSE知识分享——继承(下)
  • Linux性能分析:常用工具与指令
  • 软件测试面试的排序算法问题如何回答
  • Verilog和FPGA的自学笔记8——按键消抖与模块化设计
  • 深入解析 display: flow-root:现代CSS布局的隐藏利器
  • 汕头网站制作方法购物网站价格
  • 电商网站建设精准扶贫的目的建筑施工特种证书查询入口官网
  • spring-ai advisors 使用与源码分析
  • 关键词解释:点积(Dot Product)在深度学习中的意义
  • 本地部署DeepSeek-OCR:打造高效的PDF文字识别服务
  • 机器视觉系统中工业相机的常用术语解读
  • 【论文精读】GenRec:基于扩散模型统一视频生成与识别任务
  • seo提高网站排名wordpress内容页不显示
  • Velero(原名Heptio Ark) 是一个专为 Kubernetes 设计的开源备份恢复工具
  • 企业网站模板中文 产品列表深圳福田区住房和建设局网站
  • 制作网站的价格一般由什么组成
  • Spring MVC 架构总览与请求处理流程
  • 网站推广的优势有做二手厨房设备的网站吗