假设我写了一个类似"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
-- 数据和任何已修改索引的“表空间”。 (读取-修改-写入) (cfinnodb_file_per_table
)- 双写缓冲区(写入)
iblog*
(写)
这不包括在某些复杂的 SELECTs
中创建的“临时”表; “元数据”锁定诸如 ALTER TABLE
等之类的东西。
关于mysql - 当我执行 INSERT 时,MySQL 内部会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48625259/