在 MySQL 中,写入一条数据的流程可以概括为以下几个步骤:

MySQL插入一条数据是怎么执行的?_mysql

1. 客户端提交请求

客户端通过 MySQL 的连接协议向服务器发送一条INSERTUPDATE 或DELETE 等写操作的 SQL 语句。


2. 链接器

  • 连接管理:MySQL Server使用线程池来处理并发连接。在MySQL 8.0中,线程池得到了显著优化,可以更好地处理大量并发连接。
  • 身份验证:MySQL 8.0引入了新的默认认证插件caching_sha2_password,提供了更强的安全性。此外,支持多种身份验证方法,包括PAM、LDAP等。

3. 语法解析与优化

  • 解析器:将SQL语句解析成内部的数据结构,并进行语法检查。
  • 预处理器:进一步检查语句是否合法,例如表是否存在,字段类型是否匹配等。
  • 查询优化器
  • MySQL 8.0对查询优化器进行了多项改进,比如更好的索引选择、更智能的成本估算模型。
  • 对于INSERT语句,虽然相对简单,但优化器仍然会考虑是否有可用的索引来加速后续可能的查找操作。

4. 执行器

执行器根据生成的执行计划执行写入操作:

  • 判断目标表是否存在。
  • 根据表的结构和索引信息定位需要写入的行。

5. 引擎层处理

MySQL 通过存储引擎完成数据写入,以下以 InnoDB 引擎为例:

  1. 生成日志
  • 写入操作首先会生成redo log(重做日志) 和undo log(回滚日志)
  • Redo Log:用于保障宕机恢复。
  • Undo Log:用于支持事务的回滚和 MVCC(多版本并发控制)。
  1. 修改内存中的数据页
  • MySQL 会先将数据写入到Buffer Pool(内存中的缓存区域)。
  • 通过change buffer 优化非唯一索引的写操作。
  1. 标记脏页
  • 修改的数据页会被标记为脏页,定期通过刷脏(flush)操作写入磁盘。

6. 提交事务

如果使用了事务(例如BEGIN...COMMIT),事务提交时会完成以下步骤:

  1. Redo Log 的状态标记为提交(Commit)。
  2. 将数据从Buffer Pool 刷新到磁盘文件(如.ibd 文件)。

如果未开启事务控制(autocommit=1),每条写入语句都会自动提交。


7. Binlog 写入

  • MySQL 会将操作记录写入Binlog(归档日志)
  • Binlog 的作用:
  1. 数据备份和恢复。
  2. 主从复制。

8. 客户端确认

MySQL 将写入操作的执行结果返回给客户端,至此一次写入流程完成。


写入优化点

  1. 合理设计索引:减少索引维护的开销。
  2. 使用批量插入:减少事务提交的频率。
  3. 调优参数:如innodb_log_buffer_size 和innodb_buffer_pool_size
  4. 异步刷盘:优化innodb_flush_log_at_trx_commit 参数。