Skip to content

Commit f18dcfc

Browse files
author
Alexey Botchkov
committed
MDEV-20498 Assertion `table_share->tmp_table != NO_TMP_TABLE || m_lock_type == 1' failed upon REBUILD PARTITION.
Reorganise checks if it inserts rows from old partition into new that wasn't opened for reading. So rows that don't belong there will produce an error.
1 parent ef3c577 commit f18dcfc

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

mysql-test/main/partition.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2906,5 +2906,18 @@ Table Op Msg_type Msg_text
29062906
test.t1 check status OK
29072907
DROP TABLE t1;
29082908
#
2909+
# MDEV-20498 Assertion `table_share->tmp_table != NO_TMP_TABLE || m_lock_type == 1' failed upon REBUILD PARTITION.
2910+
# ALTER TABLE REBUILD PARTITION crashed on misplaced rows.
2911+
#
2912+
CREATE TABLE mdev20498 (a INT) ENGINE=myisam PARTITION BY LIST (a)
2913+
(PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1));
2914+
INSERT INTO mdev20498 values (0), (0), (1), (1);
2915+
FLUSH TABLES;
2916+
CALL mtr.add_suppression("corrupted: row in wrong partition:");
2917+
ALTER TABLE mdev20498 REBUILD PARTITION p0;
2918+
ERROR HY000: Found a row in wrong partition (0 != 1) a:1
2919+
ALTER TABLE mdev20498 REBUILD PARTITION p0, p1;
2920+
DROP TABLE mdev20498;
2921+
#
29092922
# End of 10.6 tests
29102923
#

mysql-test/main/partition.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3115,6 +3115,32 @@ ALTER TABLE t1 DROP a, ADD a INT NOT NULL DEFAULT 0;
31153115
CHECK TABLE t1;
31163116
DROP TABLE t1;
31173117

3118+
--echo #
3119+
--echo # MDEV-20498 Assertion `table_share->tmp_table != NO_TMP_TABLE || m_lock_type == 1' failed upon REBUILD PARTITION.
3120+
--echo # ALTER TABLE REBUILD PARTITION crashed on misplaced rows.
3121+
--echo #
3122+
3123+
CREATE TABLE mdev20498 (a INT) ENGINE=myisam PARTITION BY LIST (a)
3124+
(PARTITION p0 VALUES IN (0), PARTITION p1 VALUES IN (1));
3125+
INSERT INTO mdev20498 values (0), (0), (1), (1);
3126+
FLUSH TABLES;
3127+
3128+
let $datadir=`select @@datadir`;
3129+
CALL mtr.add_suppression("corrupted: row in wrong partition:");
3130+
3131+
move_file $datadir/test/mdev20498#P#p0.MYD $datadir/test//tmp.MYD;
3132+
move_file $datadir/test/mdev20498#P#p1.MYD $datadir/test/mdev20498#P#p0.MYD;
3133+
move_file $datadir/test/tmp.MYD $datadir/test/mdev20498#P#p1.MYD;
3134+
3135+
move_file $datadir/test/mdev20498#P#p0.MYI $datadir/test/tmp.MYI;
3136+
move_file $datadir/test/mdev20498#P#p1.MYI $datadir/test/mdev20498#P#p0.MYI;
3137+
move_file $datadir/test/tmp.MYI $datadir/test/mdev20498#P#p1.MYI;
3138+
3139+
--error ER_ROW_IN_WRONG_PARTITION
3140+
ALTER TABLE mdev20498 REBUILD PARTITION p0;
3141+
ALTER TABLE mdev20498 REBUILD PARTITION p0, p1;
3142+
DROP TABLE mdev20498;
3143+
31183144
--echo #
31193145
--echo # End of 10.6 tests
31203146
--echo #

sql/ha_partition.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,13 @@ int ha_partition::copy_partitions(ulonglong * const copied,
22272227
}
22282228
else
22292229
{
2230+
if (m_new_file[new_part]->m_lock_type != F_WRLCK)
2231+
{
2232+
m_last_part= reorg_part;
2233+
m_err_rec= table->record[0];
2234+
result= HA_ERR_ROW_IN_WRONG_PARTITION;
2235+
goto error;
2236+
}
22302237
/* Copy record to new handler */
22312238
(*copied)++;
22322239
DBUG_ASSERT(!m_new_file[new_part]->row_logging);
@@ -10326,11 +10333,12 @@ void ha_partition::print_error(int error, myf errflag)
1032610333
}
1032710334
else if (error == HA_ERR_ROW_IN_WRONG_PARTITION)
1032810335
{
10329-
/* Should only happen on DELETE or UPDATE! */
10336+
/* Should only happen on DELETE, UPDATE or REBUILD PARTITION! */
1033010337
DBUG_ASSERT(thd_sql_command(thd) == SQLCOM_DELETE ||
1033110338
thd_sql_command(thd) == SQLCOM_DELETE_MULTI ||
1033210339
thd_sql_command(thd) == SQLCOM_UPDATE ||
10333-
thd_sql_command(thd) == SQLCOM_UPDATE_MULTI);
10340+
thd_sql_command(thd) == SQLCOM_UPDATE_MULTI ||
10341+
thd_sql_command(thd) == SQLCOM_ALTER_TABLE);
1033410342
DBUG_ASSERT(m_err_rec);
1033510343
if (m_err_rec)
1033610344
{

0 commit comments

Comments
 (0)