mirror of
https://github.com/MariaDB/server.git
synced 2026-05-09 16:44:29 +02:00
MDEV-21540 Initialization of already inited long unique index on reorganize partition
Handler for existing partition was already index-inited at the
beginning of copy_partitions().
In the case of REORGANIZE PARTITION we fill new partition by calling
its ha_write_row() (handler is storage engine of new partition). From
that we go through the below conditions:
if (this->inited == RND)
table->clone_handler_for_update();
handler *h= table->update_handler ? table->update_handler : table->file;
First, the above misses the meaning of this->inited check. Now it is
new partition and this handler is not inited. So, we assign
table->file which is ha_partition and is really not known to be inited
or not. It is supposed (this == table->file), otherwise we are
out of the logic for using update_handler. This patch adds DBUG_ASSERT
for that.
Second, we call check_duplicate_long_entries() for table->file and
that calls ha_partition::index_init() which calls index_init() for
each partition's handler. But the existing parititions' handlers was
already inited in copy_partitions() and we fail on assertion.
The fix implies that we don't need check_duplicate_long_entries()
per-partition as we've already done check_duplicate_long_entries() for
ha_partition. For REORGANIZE PARTITION that means existing row was
already checked at previous INSERT/UPDATE commands, so no need to
check it again (see NOTE in handler::ha_write_row()).
The fix also optimizes ha_update_row() so
check_duplicate_long_entries_update() is not called per-partition
considering it was already called for ha_partition. Besides,
per-partition duplicate check is not really usable.
This commit is contained in:
parent
f0107c90a0
commit
231feabd2b
3 changed files with 69 additions and 3 deletions
|
|
@ -6782,7 +6782,18 @@ int handler::ha_write_row(const uchar *buf)
|
|||
mark_trx_read_write();
|
||||
increment_statistics(&SSV::ha_write_count);
|
||||
|
||||
if (table->s->long_unique_table)
|
||||
/*
|
||||
NOTE: this != table->file is true in 3 cases:
|
||||
|
||||
1. under copy_partitions() (REORGANIZE PARTITION): that does not
|
||||
require long unique check as it does not introduce new rows or new index.
|
||||
2. under partition's ha_write_row() (INSERT): check_duplicate_long_entries()
|
||||
was already done by ha_partition::ha_write_row(), no need to check it
|
||||
again for each single partition.
|
||||
3. under ha_mroonga::wrapper_write_row()
|
||||
*/
|
||||
|
||||
if (table->s->long_unique_table && this == table->file)
|
||||
{
|
||||
if (this->inited == RND)
|
||||
table->clone_handler_for_update();
|
||||
|
|
@ -6830,8 +6841,17 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data)
|
|||
MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
|
||||
mark_trx_read_write();
|
||||
increment_statistics(&SSV::ha_update_count);
|
||||
if (table->s->long_unique_table &&
|
||||
(error= check_duplicate_long_entries_update(table, table->file, (uchar *)new_data)))
|
||||
|
||||
/*
|
||||
NOTE: this != table->file is true under partition's ha_update_row():
|
||||
check_duplicate_long_entries_update() was already done by
|
||||
ha_partition::ha_update_row(), no need to check it again for each single
|
||||
partition. Same applies to ha_mroonga wrapper.
|
||||
*/
|
||||
|
||||
if (table->s->long_unique_table && this == table->file &&
|
||||
(error= check_duplicate_long_entries_update(table, table->file,
|
||||
(uchar *)new_data)))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue