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

avi*_*eks 2 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?
Run Code Online (Sandbox Code Playgroud)

换句话说,db的解剖学写道.

例如:

-> 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.
Run Code Online (Sandbox Code Playgroud)

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

Ric*_*mes 5

假设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)
Run Code Online (Sandbox Code Playgroud)

我认为还有更多细节.而且我对确切的顺序含糊不清.

迟早会触及的文件包括

  • .frm 获取模式(缓存)(只读)
  • ibdata1.ibd- 用于数据和任何已修改索引的"表空间".(读 - 修改 - 写)(cf innodb_file_per_table)
  • doublewrite buffer(写)
  • iblog* (写)

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

  • @ iSR5 - 我遗漏了很多`SELECT`阶段; 你的链接包括其中一些.`TRUNCATE`不像'DELETE`; 它更像是DDL而不是DML.`ALTER`,`DROP`等属于另一类.`SHOW`,`EXPLAIN`等也是不同的.完整的答案需要一本书,而不是简短的论坛答案. (2认同)