Details
-
Bug
-
Status: Approved (View Workflow)
-
Critical
-
Resolution: Unresolved
-
11.8
-
None
-
Can result in unexpected behaviour
-
Q4/2026 Server Maintenance
Description
Reproduce
create table t ( |
id int primary key, |
row_start timestamp(6) generated always as row start, |
row_end timestamp(6) generated always as row end, |
period for system_time(row_start, row_end), |
key row_end_idx (row_end) |
) engine=myisam with system versioning; |
|
|
insert into t (id) values (1), (2), (3); |
delete from t; |
|
|
# Expected: no current rows remain. Actual: one row survives. |
select id from t; |
|
|
drop table t; |
Result
Last row is not deleted.
select id from t; |
id
|
3
|
Cause
commit eff16d7593c
|
Author: Sergei Golubchik <serg@mariadb.org>
|
Date: Fri Feb 9 23:50:26 2024 +0100
|
|
|
Revert "MDEV-15458 Segfault in heap_scan() upon UPDATE after ADD SYSTEM VERSIONING"
|
|
|
This partially reverts 43623f04a98
|
|
|
Engines have to set ::position() after ::write_row(), otherwise
|
the server won't be able to refer to the row just inserted.
|
This is important for high-level indexes.
|
|
|
heap part isn't reverted, so heap doesn't support high-level indexes.
|
to fix this, it'll need info->lastpos in addition to info->current_ptr
|
Caused by reappearance of HA_EXTRA_REMEMBER_POS / HA_EXTRA_RESTORE_POS in TABLE::delete_row().
Reason
A system-versioned DELETE on a MyISAM table indexed by row_end could leave the last current row undeleted. The delete scans the current rows via an equality search on row_end = MAX, which MyISAM drives with mi_rnext_same. That function keeps the search's reference key in info->lastkey2 and uses the HA_STATE_RNEXT_SAME flag to remember it has already stored it.
Deleting a versioned row is an in-place update of row_end, and mi_update reuses info->lastkey2 as scratch space for the changed key, so it clears HA_STATE_RNEXT_SAME to tell mi_rnext_same to re-store its reference on the next call. However, TABLE::delete_row wrapped the update in HA_EXTRA_REMEMBER_POS/HA_EXTRA_RESTORE_POS, and RESTORE_POS restores the whole saved info->update word — resurrecting the HA_STATE_RNEXT_SAME bit that mi_update had just cleared.
As a result mi_rnext_same skipped rebuilding its reference key and compared subsequent keys against the now-overwritten lastkey2, hitting a spurious end-of-file and terminating the scan one row early. Fixed by removing the REMEMBER_POS/RESTORE_POS wrapper so the scan state maintained by mi_update is preserved.
#0 0x0000555557450e68 in mi_extra (info=0x7fffd4033538, function=HA_EXTRA_RESTORE_POS, extra_arg=0x0) at ../src/storage/myisam/mi_extra.c:203
|
#1 0x000055555742de19 in ha_myisam::extra (this=0x7fffd4030af8, operation=HA_EXTRA_RESTORE_POS) at ../src/storage/myisam/ha_myisam.cc:2166
|
#2 0x0000555556a1a068 in TABLE::delete_row<false> (this=0x7fffd40251b8, treat_versioned=true) at ../src/sql/sql_delete.cc:368
|
#3 0x0000555556a1a4fd in TABLE::delete_row (this=0x7fffd40251b8) at ../src/sql/table.h:2007
|
#4 0x0000555556a15570 in Sql_cmd_delete::delete_from_single_table (this=0x7fffd4017848, thd=0x7fffd4000d68) at ../src/sql/sql_delete.cc:919
|
#5 0x0000555556a1938b in Sql_cmd_delete::execute_inner (this=0x7fffd4017848, thd=0x7fffd4000d68) at ../src/sql/sql_delete.cc:1917
|
#6 0x0000555556b419d3 in Sql_cmd_dml::execute (this=0x7fffd4017848, thd=0x7fffd4000d68) at ../src/sql/sql_select.cc:34624
|
#7 0x0000555556a8133e in mysql_execute_command (thd=0x7fffd4000d68, is_called_from_prepared_stmt=false) at ../src/sql/sql_parse.cc:4467
|
#8 0x0000555556a79b2d in mysql_parse (thd=0x7fffd4000d68, rawbuf=0x7fffd4016910 "delete from t", length=13, parser_state=0x7ffff07a91e8) at ../src/sql/sql_parse.cc:7958
|
|
|
203 info->update= info->save_update | HA_STATE_WRITTEN;
|
#0 mi_rnext_same (info=0x7fffd4033538, buf=0x7fffd4031300 "\377\002") at ../src/storage/myisam/mi_rnext_same.c:64
|
#1 0x000055555742dbed in ha_myisam::index_next_same (this=0x7fffd4030af8, buf=0x7fffd4031300 "\377\002", key=0x7fffd4913488 "\377\377\377\377\017B?\245\001", length=7) at ../src/storage/myisam/ha_myisam.cc:2044
|
#2 0x000055555662d057 in handler::ha_index_next_same (this=0x7fffd4030af8, buf=0x7fffd4031300 "\377\002", key=0x7fffd4913488 "\377\377\377\377\017B?\245\001", keylen=7) at ../src/sql/handler.cc:4086
|
#3 0x0000555556636836 in handler::read_range_next (this=0x7fffd4030af8) at ../src/sql/handler.cc:7436
|
#4 0x0000555556d00dd5 in handler::multi_range_read_next (this=0x7fffd4030af8, range_info=0x7ffff07a69b8) at ../src/sql/multi_range_read.cc:570
|
#5 0x0000555556d01049 in Mrr_simple_index_reader::get_next (this=0x7fffd40311b8, range_info=0x7ffff07a69b8) at ../src/sql/multi_range_read.cc:635
|
#6 0x0000555556d03d21 in DsMrr_impl::dsmrr_next (this=0x7fffd4031068, range_info=0x7ffff07a69b8) at ../src/sql/multi_range_read.cc:1741
|
#7 0x000055555742f154 in ha_myisam::multi_range_read_next (this=0x7fffd4030af8, range_info=0x7ffff07a69b8) at ../src/storage/myisam/ha_myisam.cc:2644
|
#8 0x0000555556857c0d in QUICK_RANGE_SELECT::get_next (this=0x7fffd4913040) at ../src/sql/opt_range.cc:13319
|
#9 0x0000555556889c7d in rr_quick (info=0x7ffff07a6ed0) at ../src/sql/records.cc:398
|
#10 0x0000555556869a66 in READ_RECORD::read_record (this=0x7ffff07a6ed0) at ../src/sql/records.h:77
|
#11 0x0000555556a15327 in Sql_cmd_delete::delete_from_single_table (this=0x7fffd4017848, thd=0x7fffd4000d68) at ../src/sql/sql_delete.cc:885
|
#12 0x0000555556a1938b in Sql_cmd_delete::execute_inner (this=0x7fffd4017848, thd=0x7fffd4000d68) at ../src/sql/sql_delete.cc:1917
|
#13 0x0000555556b419d3 in Sql_cmd_dml::execute (this=0x7fffd4017848, thd=0x7fffd4000d68) at ../src/sql/sql_select.cc:34624
|
#14 0x0000555556a8133e in mysql_execute_command (thd=0x7fffd4000d68, is_called_from_prepared_stmt=false) at ../src/sql/sql_parse.cc:4467
|
#15 0x0000555556a79b2d in mysql_parse (thd=0x7fffd4000d68, rawbuf=0x7fffd4016910 "delete from t", length=13, parser_state=0x7ffff07a91e8) at ../src/sql/sql_parse.cc:7958
|
|
|
59 if (!(info->update & HA_STATE_RNEXT_SAME)) |
60 {
|
61 /* First rnext_same; Store old key */ |
62 memcpy(info->lastkey2,info->lastkey,info->last_rkey_length); |
63 }
|