Reduce deadlocks on inserting custom data by only using 'ON DUPLICATE' when it is...
authoreileen <emcnaughton@wikimedia.org>
Fri, 21 Jun 2019 22:26:35 +0000 (18:26 -0400)
committereileen <emcnaughton@wikimedia.org>
Sat, 22 Jun 2019 21:50:51 +0000 (09:50 +1200)
commit46fe0a66dc6bfc0fb63bfc0344ea6ff70ca40c8c
treec130d56761b111bb58d9771c5c26c5117688f902
parentf1bde545eb19d193ca10206487fbf1a767ee0f23
Reduce deadlocks on inserting custom data by only using 'ON DUPLICATE' when it is not a new row

ON Duplicate is used in the customData.create function so that a row can be inserted and if it exists
mysql adapts and updates the existing row. This is more expensive and more prone to deadlocks than a straight
'INSERT' but is probably better than figuring it out at the php layer when you don't know if it could be
an update rather than an insert.

However, in many of the cases we already know this information - ie. if we are creating a new contribution
the custom data is created afterwards so we can use this information from Contribution.create to opt for the
cheaper & less deadlocky version.

We deployed this fix before our main fundraiser due to handful of daily deadlocks on this under peak load
and this form of deadlock did not bother us again during our main fundraiser when we were processing large volumes.
The patch has been in production around 6 months at this point.

Note that the reason deadlocks are encountered is that the 'next row' index is locked when inserting, and
it's either locked for longer or more aggressively when it;'s also checking for a deadlock at the same time (not
sure which)
CRM/Contribute/BAO/Contribution.php
CRM/Core/BAO/CustomValueTable.php