Skip to content
Permalink
Browse files
MDEV-20618 Assertion failed in row_upd_sec_index_entry
Add a proper error handling of innobase_get_computed_value results in
row_upd_store_row/row_upd_store_v_row.

Also add an assertion in row_vers_build_clust_v_col to fail during row
purge.
Add one more assertion in row_sel_sec_rec_is_for_clust_rec for possible
future catches.
  • Loading branch information
FooBarrior committed Sep 1, 2020
1 parent a3d6609 commit 97db6c1
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 59 deletions.
@@ -747,4 +747,66 @@ ANALYZE TABLE t1, t2;
--eval $query
DROP TABLE t1, t2;

if($support_virtual_index)
{
--echo #
--echo # MDEV-20618 Assertion `btr_validate_index(index, 0, false)' failed
--echo # in row_upd_sec_index_entry
--echo #
CREATE TABLE t1 (A BIT(15), VA BIT(10) GENERATED ALWAYS AS (A),PK INT,
PRIMARY KEY (PK), UNIQUE KEY (VA));

INSERT IGNORE INTO t1 VALUES ( '\r1','a',1);
--error ER_DATA_TOO_LONG
REPLACE INTO t1 (PK) VALUES (1);

DROP TABLE t1;

--echo #
--echo # MDEV-17890 Record in index was not found on update, server crash in
--echo # row_upd_build_difference_binary or
--echo # Assertion `0' failed in row_upd_sec_index_entry
--echo #
CREATE TABLE t1 (
pk BIGINT AUTO_INCREMENT,
b BIT(15),
v BIT(10) AS (b) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(v)
);

INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101');
SELECT pk, b INTO OUTFILE 'load.data' FROM t1;
--error ER_DATA_TOO_LONG
LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);

--let $datadir= `SELECT @@datadir`
--remove_file $datadir/test/load.data
DROP TABLE t1;

--echo #
--echo # MDEV-17834 Server crashes in row_upd_build_difference_binary
--echo # on LOAD DATA into table with indexed virtual column
--echo #
CREATE TABLE t1 (
pk INT,
i TINYINT,
ts TIMESTAMP NULL,
vi TINYINT AS (i+1) PERSISTENT,
vts TIMESTAMP(5) AS (ts) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(vts)
);

INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);

--write_file $MYSQLTEST_VARDIR/tmp/load.data
1 4 2019-01-01 00:00:00
EOF
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error ER_WARN_DATA_OUT_OF_RANGE
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/load.data' REPLACE INTO TABLE t1 (pk,i,ts);

--remove_file $MYSQLTEST_VARDIR/tmp/load.data
DROP TABLE t1;
}
@@ -825,6 +825,56 @@ a1 a2 b
0 NULL 1
DROP TABLE t1, t2;
#
# MDEV-20618 Assertion `btr_validate_index(index, 0, false)' failed
# in row_upd_sec_index_entry
#
CREATE TABLE t1 (A BIT(15), VA BIT(10) GENERATED ALWAYS AS (A),PK INT,
PRIMARY KEY (PK), UNIQUE KEY (VA));
INSERT IGNORE INTO t1 VALUES ( '\r1','a',1);
Warnings:
Warning 1906 The value specified for generated column 'VA' in table 't1' has been ignored
Warning 1264 Out of range value for column 'VA' at row 1
REPLACE INTO t1 (PK) VALUES (1);
ERROR 22001: Data too long for column 'VA' at row 1
DROP TABLE t1;
#
# MDEV-17890 Record in index was not found on update, server crash in
# row_upd_build_difference_binary or
# Assertion `0' failed in row_upd_sec_index_entry
#
CREATE TABLE t1 (
pk BIGINT AUTO_INCREMENT,
b BIT(15),
v BIT(10) AS (b) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(v)
);
INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101');
Warnings:
Warning 1264 Out of range value for column 'v' at row 1
SELECT pk, b INTO OUTFILE 'load.data' FROM t1;
LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);
ERROR 22001: Data too long for column 'v' at row 1
DROP TABLE t1;
#
# MDEV-17834 Server crashes in row_upd_build_difference_binary
# on LOAD DATA into table with indexed virtual column
#
CREATE TABLE t1 (
pk INT,
i TINYINT,
ts TIMESTAMP NULL,
vi TINYINT AS (i+1) PERSISTENT,
vts TIMESTAMP(5) AS (ts) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(vts)
);
INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/load.data' REPLACE INTO TABLE t1 (pk,i,ts);
ERROR 22003: Out of range value for column 'vi' at row 1
DROP TABLE t1;
#
# BUG#21365158 WL8149:ASSERTION `!TABLE || (!TABLE->WRITE_SET
#
@@ -827,6 +827,56 @@ a1 a2 b
0 NULL 1
DROP TABLE t1, t2;
#
# MDEV-20618 Assertion `btr_validate_index(index, 0, false)' failed
# in row_upd_sec_index_entry
#
CREATE TABLE t1 (A BIT(15), VA BIT(10) GENERATED ALWAYS AS (A),PK INT,
PRIMARY KEY (PK), UNIQUE KEY (VA));
INSERT IGNORE INTO t1 VALUES ( '\r1','a',1);
Warnings:
Warning 1906 The value specified for generated column 'VA' in table 't1' has been ignored
Warning 1264 Out of range value for column 'VA' at row 1
REPLACE INTO t1 (PK) VALUES (1);
ERROR 22001: Data too long for column 'VA' at row 1
DROP TABLE t1;
#
# MDEV-17890 Record in index was not found on update, server crash in
# row_upd_build_difference_binary or
# Assertion `0' failed in row_upd_sec_index_entry
#
CREATE TABLE t1 (
pk BIGINT AUTO_INCREMENT,
b BIT(15),
v BIT(10) AS (b) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(v)
);
INSERT IGNORE INTO t1 (b) VALUES (b'101110001110100'),(b'011101');
Warnings:
Warning 1264 Out of range value for column 'v' at row 1
SELECT pk, b INTO OUTFILE 'load.data' FROM t1;
LOAD DATA INFILE 'load.data' REPLACE INTO TABLE t1 (pk, b);
ERROR 22001: Data too long for column 'v' at row 1
DROP TABLE t1;
#
# MDEV-17834 Server crashes in row_upd_build_difference_binary
# on LOAD DATA into table with indexed virtual column
#
CREATE TABLE t1 (
pk INT,
i TINYINT,
ts TIMESTAMP NULL,
vi TINYINT AS (i+1) PERSISTENT,
vts TIMESTAMP(5) AS (ts) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(vts)
);
INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/load.data' REPLACE INTO TABLE t1 (pk,i,ts);
ERROR 22003: Out of range value for column 'vi' at row 1
DROP TABLE t1;
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;
@@ -456,8 +456,7 @@ select pk, col_bit+0, vcol_bit+0 from t1;
pk col_bit+0 vcol_bit+0
99 10000 1023
REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
Warnings:
Warning 1264 Out of range value for column 'vcol_bit' at row 1
ERROR 22001: Data too long for column 'vcol_bit' at row 1
drop table t1;
#
# MDEV-17837 REPLACE on table with virtual_field can cause crash in set_ok_status()
@@ -476,8 +475,7 @@ INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
REPLACE INTO t1 (pk,i) VALUES (1,2);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
ERROR 22003: Out of range value for column 'vi' at row 1
DROP TABLE t1;
SET @sql_mode=@old_sql_mode;
#
@@ -431,6 +431,7 @@ replace INTO `t1` (`pk`,col_bit) VALUES (99,1000);
select pk, col_bit+0, vcol_bit+0 from t1;
replace INTO `t1` (`pk`,col_bit) VALUES (99,10000);
select pk, col_bit+0, vcol_bit+0 from t1;
--error ER_DATA_TOO_LONG
REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
drop table t1;

@@ -451,6 +452,7 @@ CREATE TABLE t1 (
INSERT INTO t1 (pk,i) VALUES (1,1);
TRUNCATE TABLE t1;
INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
--error ER_WARN_DATA_OUT_OF_RANGE
REPLACE INTO t1 (pk,i) VALUES (1,2);
DROP TABLE t1;
SET @sql_mode=@old_sql_mode;
@@ -1748,15 +1748,13 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
}
if (table->vfield)
{
my_bool abort_on_warning= thd->abort_on_warning;
/*
We have not yet called update_virtual_fields(VOL_UPDATE_FOR_READ)
in handler methods for the just read row in record[1].
*/
table->move_fields(table->field, table->record[1], table->record[0]);
thd->abort_on_warning= 0;
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE);
thd->abort_on_warning= abort_on_warning;
if (table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE))
goto err;
table->move_fields(table->field, table->record[0], table->record[1]);
}
if (info->handle_duplicates == DUP_UPDATE)
@@ -103,6 +103,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "srv0mon.h"
#include "srv0srv.h"
#include "srv0start.h"
#include "rem0rec.h"
#ifdef UNIV_DEBUG
#include "trx0purge.h"
#endif /* UNIV_DEBUG */
@@ -21881,6 +21882,13 @@ void innobase_free_row_for_vcol(VCOL_STORAGE *storage)
}


void innobase_report_computed_value_failed(dtuple_t *row)
{
ib::error() << "Compute virtual column values failed for "
<< rec_printer(row).str();
}


/** Get the computed value by supplying the base column values.
@param[in,out] row the data row
@param[in] col virtual column
@@ -22008,13 +22016,6 @@ innobase_get_computed_value(
dbug_tmp_restore_column_map(mysql_table->write_set, old_write_set);

if (ret != 0) {
// FIXME: Why this error message is macro-hidden?
#ifdef INNODB_VIRTUAL_DEBUG
ib::warn() << "Compute virtual column values failed ";
fputs("InnoDB: Cannot compute value for following record ",
stderr);
dtuple_print(stderr, row);
#endif /* INNODB_VIRTUAL_DEBUG */
DBUG_RETURN(NULL);
}

@@ -874,6 +874,12 @@ class ib_vcol_row
}
};

/** Report virtual value computation failure in ib::error
@param[in] row the data row
*/
ATTRIBUTE_COLD
void innobase_report_computed_value_failed(dtuple_t *row);

/** Get the computed value by supplying the base column values.
@param[in,out] row the data row
@param[in] col virtual column

0 comments on commit 97db6c1

Please sign in to comment.