Open
Description
When two nodes are added simultaneously to the closure tree table, this results in a deadlock and the query to acquire lock runs infinitely:
(0.7ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS t46e4b4acfd42770bad34d3e2a13a458a
(0.4ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS t9eaf21f51a8c5a1f2e39f6e8c4971b27
(0.4ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS tae827dc66e71e92f4c9f6edecae1cb54
(0.3ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS t7f7d47e378ffde7f311e56fde6613ab5
(0.3ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS ta7af1b261b90cba9e4d7399c96f17e26
(0.3ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS t3ed658e2e0d3008375e7356cc8e1c4a2
(0.4ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS t080acfd6e5536c50c4917ce271671be6
(0.3ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS t850056c6b58f75d8171bdcb69def558a
(0.3ms) SELECT GET_LOCK('b218f48596dc37d16bbcd16d1e18a116c', 0) AS t1ece95b52215d7c5e420ea9c0057aa72
You can reproduce the problem easily by using the code below (where List is the closure_tree model):
Thread.new do
parent = List.find(86)
new_node = List.new(:name => "test deadlock 1")
parent.add_child(new_node)
end
Thread.new do
parent = List.find(82)
new_node = List.new(:name => "test deadlock 1")
parent.add_child(new_node)
end
We faced this problem on production, and the infinite locking loop results in mysql being unresponsive, which in turn results in unresponsive app.
closure_tree version: 6.2.0
ruby: 2.3.0
rails: 5.0.0.1