Closed TroyPatteson closed 7 years ago
Thanks for this feedback Troy.
We will review this an provide our thoights asap
By the way, we haven't had another deadlock since creating that index on any of our 3 stores.
Hello,
Thanks for your feedback. We will implement this in the next version.
Regards.
In _sendEcommerceBatch() called from handleEcommerceBatches() in the _mailchimp_bulksync_ecommercedata cron job there are two queries against the _mailchimp_ecommerce_syncdata table where _batchid is NULL via calls to deleteUnsentItems() and markItemsAsSent(). As there is no index on the _batchid column of _mailchimp_ecommerce_syncdata table these queries essentially require write locks on all rows. This can result in a deadlock with queries issued via the transaction from core/Mage/Sales/Model/Service/Quote.php when placing an order during the checkout process. That transaction includes saving the customer, customer address and quote models and the order model before and after payment has been made which can take many seconds. Each of those saves invokes the corresponding MailChimp observer methods to update records in the _mailchimp_ecommerce_syncdata table. If the cron job runs during the checkout process it can get locks on rows in the _mailchimp_ecommerce_syncdata table required by the checkout transaction causing a deadlock. From experience this causes the order save in the checkout transaction to be rolled back and when the order status is subsequently saved it results in a foreign key constraint violation as the order ID the status refers to no longer exists. The end result is that the payment has been taken but the order fails. Attempting to checkout again causes a duplicate payment transaction error as the payment has already been made.
To further clarify this is happening here is the part of the output on SHOW ENGINE INNODB STATUS relating to the last deadlock at a time when the checkout failed after payment was taken with an integrity constraint violation on order_status_history:
Note that DELETE causing 707831 row locks....
And a second one on the UPDATE query on a different magento store:
The UPDATE caused 211782 row locks before the deadlock discovered.
The solution is obviously to create an index on _batchid with something like:
Note that we are using the Idev_OneStepCheckout extension but I am not sure it will matter which checkout extension is used.
I don't know whether the index will eliminate all deadlocks but it is certainly a good start and also speeds up those DELETE and UPDATE queries run in the CRON job.