[MDEV-6663] Assertion `0' failed in Protocol::end_statement() on concurrent UPDATE and ALTER TABLE .. PERSISTENT Created: 2014-08-29 Updated: 2022-10-21 Resolved: 2022-10-21 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Data Manipulation - Update, Optimizer, Partitioning |
| Affects Version/s: | 10.0.13 |
| Fix Version/s: | N/A |
| Type: | Bug | Priority: | Major |
| Reporter: | Elena Stepanova | Assignee: | Vicențiu Ciorbaru |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | eits, partioning | ||
| Issue Links: |
|
||||||||
| Sprint: | 10.0.20, 10.0.26, 10.0.30 | ||||||||
| Description |
|
Stack trace from:
RQG grammar (assertion.yy):
RQG data template (assertion.zz):
RQG command line:
|
| Comments |
| Comment by Sergei Petrunia [ 2015-02-17 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
cvicentiu, please check this (after We need to get rid of the assertion, first. The second part of the bug is why ANALYZE TABLE causes errors in concurrent UPDATEs. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2015-06-12 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Finally tracked down where the bug occurs: sql_update.cc:585
Calling quick->reset() returns HA_ERR_LOCK_DEADLOCK. I've tried a small hack:
With this hack in place, we no longer get assertion errors. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2015-06-12 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
correction: cur_quick->get_next() in sql/opt_range.cc:11303 return the HA_ERR_LOCK_DEADLOCK | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2015-06-12 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Backtrace when encountering the HA_ERR_LOCK_DEADLOCK error.
| ||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2015-10-01 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
can we get rid of the assertion as step 1? Looks like its still there in 10.1 at least. | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Vicențiu Ciorbaru [ 2017-02-27 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Analyzing this further, with current 10.0.29 release. I am able to pin-point the place where the race condition leads to XtraDB reporting DB_DEADLOCK. The use case features a partitioned table, with 2 partitions. XtraDB detects a deadlock when performing UPDATE, during QUICK_RANGE_SELECT as seen in backtrace above. The other concurrent query is ANALYZE statement. The other thread (running the Analyze statement) is performing the while loop within the following function:
This code is executed after any specific xtradb handler::analyze. ANALYZE TABLE attempts to acquire a READ lock, while UPDATE naturally acquires a WRITE lock. Changing ANALYZE TABLE to acquire a WRITE lock fixes the problem. My theory as to why the deadlock happens is the following: UPDATE needs to get WRITE lock for Index P1 (from partition 1), blocked by Analyze Due to my limited understanding of xtradb internals I am unable to verify this, however there doesn't seem to be any other sequence of locks that would cause a deadlock. The bottom line is that we need to handle the deadlock error within quick_select logic so that our initial protocol assertion is not fired. The deadlock is expected, given a partitioned table, with the current lock system. To avoid it, force analyze to lock with a write lock, or make index locks atomic within partition storage engine. psergey thoughts? | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2022-10-21 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Not reproducible on 10.2+ (still reproducible on 10.1, but it's long EOL-ed). |