我想了解InnoDB如何处理多个同时进行的读/写操作。
请考虑以下情形:
您正在执行非常密集的批处理写入。任何即将出现的读取请求都必须等到批写入完成。在此期间,表上还会请求写请求。因此,到批处理写入完成时,有多个读取请求和未决写入请求。 innodb以什么顺序解析请求。在大多数情况下,我希望从表中获取最新的结果集。因此,等待写请求将是解决问题的方法,但是这可能导致读取请求匮乏。
所有写请求都是非更新行请求。我相信更新请求获得行级锁,而插入请求则需要表级锁。
您能否解释一下在InnoDB中将如何进行?
谢谢
最佳答案
在InnoDB中,INSERTs
不获取表锁。 (MyISAM是一个不同的故事。)
粗略地说,对InnoDB表的每次读取或写入将仅锁定所需的行。如果一个查询的行与另一个查询的行之间没有重叠,则无需等待。使它“粗糙”的一些问题:
一些锁是“间隙”锁。想想INSERTing
在两个现有行之间的新行。
共享读取锁(在同一行上)不会互相阻塞
排他锁的作用有点像您描述的那样。
“ MVCC”允许多个事务“查看”同一行的不同版本。假设某笔交易我是SELECTing
一行,而另一笔交易是UPDATEing
它。在完成两个事务之前,该行实际上有两个版本。在两个事务均为COMMITed
或ROLLBACKed
之后,事情将被清除。
所有这些行级锁定和检查都是昂贵的,这可能毫无价值。如果您有数十个连接中断,它们都会变慢。在较旧的版本中,实际限制为4-8个连接。对于5.7,大约可以处理64。尽管如此,InnoDB每秒仍可处理数千个事务,最终受到磁盘I / O速度缓慢的限制。
“批量插入”-如果您真的要在单个表中使用INSERT
,那么最好创建包含100-1000行的单个INSERT
语句。这减少了通信,解析,优化和事务处理的开销。这也增加了与读取冲突的风险,但是加速(通常)超过了碰撞延迟。
确保在每个InnoDB语句之后检查错误。可能会发生死锁。通常,它们由ROLLBACK
处理,然后重新运行BEGIN...COMMIT
。
关于mysql - InnoDB并发读写,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30176326/