mysql - 当我执行 INSERT 时,MySQL 内部会发生什么?

标签 mysql sql sql-insert

假设我写了一个类似"INSERT INTO my_table (a,b) VALUES (1,2)" 的查询。
从客户端传递查询到将其保存在磁盘上,MySQL 内部发生了什么。

喜欢:

-> What all innodb objects(filesystem buffers/logs) affected? 
-> What're the step the data has to pass through till it reaches on table space?

换句话说,就是对数据库写入的剖析。

例如:

-> query being parsed by the parser
-> correct data page be loaded to innodb_buffer_pool
-> data being changed(dirty pages), and changes are logged to redo log buffer
-> entry on undo logs(rollback segment)
-> on commit, redo log buffer flushed to redo logfile
-> binary logging happens(if enabled)
-> dirty pages write to double write buffer
-> Finally it flushed to disk.

我相信人们有更好的方法/答案来解释这个序列。

最佳答案

这假定 InnoDB,而不是任何其他引擎...

你有一些基础知识。这里还有一些。

-> Query received by Server
-> query being parsed by the parser
-> "open" table (if not already open)
-> check for "strict mode" errors
-> Hand off the query from "Handler" to "Engine".  (The rest assumes `ENGINE=InnoDB`)
-> If part of a transaction, ...
-> If autocommitting, ...
-> If `AUTO_INCREMENT, ...
-> If `INSERT` included `PRIMARY KEY` columns, ...
-> If neither of above, create hidden AI value, ...
-> Execute `BEFORE TRIGGERs`, if any
-> Given the PK, drill down the BTree to find the location.
-> Check for Duplicate Key -- PK and any relevant UNIQUE keys.
-> obtain eXclusive lock on the row -- (maybe gap lock?)
-> correct data page be loaded to innodb_buffer_pool (if not already cached)
-> If adding this row would overflow the block, "split" the block
-> Mark block(s) "dirty" (so it will _eventually_ be flushed to disk)
-> changes are logged to redo log
-> entry on undo logs(rollback segment)
-> Secondary index changes (if any) go into Change Buffer -- possibly triggering flush to make room
-> Execute `AFTER TRIGGERs`, if any
-> (if Galera involved) Write to gcache; coordinate with other nodes
-> if autocommit, redo log buffer flushed to redo logfile
-> deal with "group commit"?
-> binary logging happens(if enabled) -- or is this before COMMIT?
-> dirty pages write to double write buffer
-> If the Query Cache is enabled (and this is a write), invalidate all QC entries for the table(s) modified.
-> release eXclusive lock
-> success or failure returned to client
-> The block containing the row will be flushed to disk _later_
-> Index block updates will be done _later_ (cached read, apply Change Buffer, cached write, plus remove from CB)

我认为还有很多细节。我不清楚确切的顺序。

迟早被触及的文件包括

  • .frm 获取模式(缓存)(只读)
  • ibdata1.ibd -- 数据和任何已修改索引的“表空间”。 (读取-修改-写入) (cf innodb_file_per_table)
  • 双写缓冲区(写入)
  • iblog*(写)

这不包括在某些复杂的 SELECTs 中创建的“临时”表; “元数据”锁定诸如 ALTER TABLE 等之类的东西。

关于mysql - 当我执行 INSERT 时,MySQL 内部会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48625259/

相关文章:

php - 我想在删除父类别时自动从数据库中删除所有子类别

php - 意外的 INSERT ... SET 查询行为

mysql - 使用codeigniter开发相册,查询选择图片?

php - MySQL 数据库的编码问题 (web2project)

SQL 计算参数定义的唯一对象

sql - 如何在sql 2008中查询的where子句中使用新定义的列名

sql - Oracle DB 中复杂的 SELECT 语句

javascript - Web SQL 向多行插入数据

mysql使用inner join和max()从两个表插入一个表

javascript - 仅识别系统