[MDEV-17377] invalid gap in auto-increment values after LOAD DATA Created: 2018-10-05 Updated: 2019-07-18 Resolved: 2018-11-01 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Data Manipulation - Insert |
| Affects Version/s: | 5.5, 10.0, 10.1, 10.2, 10.3 |
| Fix Version/s: | 10.3.11, 10.2.19, 10.1.38, 5.5.63, 10.0.38 |
| Type: | Bug | Priority: | Major |
| Reporter: | Sergei Golubchik | Assignee: | Sergei Golubchik |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||
| Description |
|
probably 5.5 is affected too, I didn't check this is the test case:
What happens here, insert tells the engine to reserve 4 auto-increment values. This "4" number is never reset, so the following load data also reserves four values, even if it needs only two. And the next insert creates a gap in the auto-increment sequence. Most engines do not reserve auto-increment values, and generate one value at a time. So with MyISAM, for example, there is no gap in this test. The fix would be to reset the list at the end of the insert statement. |
| Comments |
| Comment by Aleksey Midenkov [ 2018-10-10 ] | |||||||||||
|
The suggested fix fails for this (rpl.rpl_auto_increment,innodb,mix):
I'd suggest: Longer fix (for 10.3 and lower appropriate versions)Expand Sql_cmd hierarchy for INSERT command and isolate its private data such as LEX::many_values, LEX::insert_list, LEX::field_list, LEX::values_list as well as interface tvc_start(), tvc_finalize(), tvc_finalize_derived() (and whatever else). This would work because Sql_cmd lifetime will be for parsed trigger, not for single INSERT statement. Shorter fix (for versions where Longer fix is impossible)Check for sql_command around many_values. | |||||||||||
| Comment by Sergei Golubchik [ 2018-10-10 ] | |||||||||||
|
Checking for sql_command won't help if you have many tables and sub-statements all using INSERT but with their own lists of auto-increment values. The simple fix would be not to reserve many values in these complex cases. A more involved fix would be to do it properly, per table and per statement. E.g. not in THD or LEX, but in the handler. | |||||||||||
| Comment by Aleksey Midenkov [ 2018-10-10 ] | |||||||||||
|
serg Can you give an example? Each substatement is parsed separately, so it has its own private `LEX` and therefore `many_values`. Multiple `INSERT` into different tables again parsed separately: `many_values` is reset on start of each `INSERT`. | |||||||||||
| Comment by Aleksey Midenkov [ 2018-10-16 ] | |||||||||||
|
tvc_ interface is for SELECT from values-constructed table:
This is also an implicit SELECT:
Thus many_values is used for 2 commands INSERT and SELECT so making it private to Sql_cmd is a larger subject which should not go with this bugfix. I still believe that checking for sql_command is sufficient because of reasons in previous comment (unless there are some SQL constructs I'm not aware of). | |||||||||||
| Comment by Sergei Golubchik [ 2018-10-29 ] | |||||||||||
|
what about this simple fix:
| |||||||||||
| Comment by Aleksey Midenkov [ 2018-11-01 ] | |||||||||||
|
Yes, that's better. |