From 6fde0073bfa8f572a02637816a389e56e430edf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Oct 2019 18:47:14 +0300 Subject: [PATCH 01/13] Rename log_make_checkpoint_at() to log_make_checkpoint() The function was always called with lsn=LSN_MAX. Remove that redundant parameter. Spotted by Thirunarayanan Balathandayuthapani. --- storage/innobase/buf/buf0dblwr.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/include/log0log.h | 8 +++----- storage/innobase/include/srv0srv.h | 4 ++-- storage/innobase/log/log0log.cc | 12 +++++------- storage/innobase/row/row0import.cc | 2 +- storage/innobase/row/row0trunc.cc | 2 +- storage/innobase/srv/srv0srv.cc | 4 ++-- storage/innobase/srv/srv0start.cc | 2 +- 9 files changed, 17 insertions(+), 21 deletions(-) diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 8410a753699..78a7c06a3f0 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -328,7 +328,7 @@ too_small: mtr_commit(&mtr); /* Flush the modified pages to disk and make a checkpoint */ - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5ff36aa9c24..3267983c89f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -19075,7 +19075,7 @@ checkpoint_now_set( + (log_sys->append_on_checkpoint != NULL ? log_sys->append_on_checkpoint->size() : 0) < log_sys->lsn) { - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); fil_flush_file_spaces(FIL_TYPE_LOG); } diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 8a6705359db..0fd983a1a10 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -210,15 +210,13 @@ log_buffer_sync_in_background( /** Make a checkpoint. Note that this function does not flush dirty blocks from the buffer pool: it only checks what is lsn of the oldest modification in the pool, and writes information about the lsn in -log files. Use log_make_checkpoint_at() to flush also the pool. +log files. Use log_make_checkpoint() to flush also the pool. @param[in] sync whether to wait for the write to complete @return true if success, false if a checkpoint write was already running */ bool log_checkpoint(bool sync); -/** Make a checkpoint at or after a specified LSN. -@param[in] lsn the log sequence number, or LSN_MAX -for the latest LSN */ -void log_make_checkpoint_at(lsn_t lsn); +/** Make a checkpoint */ +void log_make_checkpoint(); /****************************************************************//** Makes a checkpoint at the latest lsn and writes it to first page of each diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 591eec4b42c..0f1936eac70 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -656,11 +656,11 @@ do { \ #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint_at(). */ +everything after flush log_make_checkpoint(). */ extern PSI_stage_info srv_stage_alter_table_end; /** Performance schema stage event for monitoring ALTER TABLE progress -log_make_checkpoint_at(). */ +log_make_checkpoint(). */ extern PSI_stage_info srv_stage_alter_table_flush; /** Performance schema stage event for monitoring ALTER TABLE progress diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 682a79409f9..c3eaa05b680 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1553,7 +1553,7 @@ log_append_on_checkpoint( /** Make a checkpoint. Note that this function does not flush dirty blocks from the buffer pool: it only checks what is lsn of the oldest modification in the pool, and writes information about the lsn in -log files. Use log_make_checkpoint_at() to flush also the pool. +log files. Use log_make_checkpoint() to flush also the pool. @param[in] sync whether to wait for the write to complete @return true if success, false if a checkpoint write was already running */ bool log_checkpoint(bool sync) @@ -1667,14 +1667,12 @@ bool log_checkpoint(bool sync) return(true); } -/** Make a checkpoint at or after a specified LSN. -@param[in] lsn the log sequence number, or LSN_MAX -for the latest LSN */ -void log_make_checkpoint_at(lsn_t lsn) +/** Make a checkpoint */ +void log_make_checkpoint() { /* Preflush pages synchronously */ - while (!log_preflush_pool_modified_pages(lsn)) { + while (!log_preflush_pool_modified_pages(LSN_MAX)) { /* Flush as much as we can */ } @@ -2010,7 +2008,7 @@ wait_suspend_loop: if (!srv_read_only_mode) { service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "ensuring dirty buffer pool are written to log"); - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); log_mutex_enter(); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index abadeafba9c..6d0d77c9f5b 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -2090,7 +2090,7 @@ row_import_cleanup( DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE();); - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); return(err); } diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc index 9906ba11614..09573610e7c 100644 --- a/storage/innobase/row/row0trunc.cc +++ b/storage/innobase/row/row0trunc.cc @@ -2224,7 +2224,7 @@ truncate_t::fixup_tables_in_non_system_tablespace() if (err == DB_SUCCESS && s_tables.size() > 0) { - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); } for (ulint i = 0; i < s_tables.size(); ++i) { diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index a93a7cd71f8..bff26d05029 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -669,12 +669,12 @@ static const ulint SRV_MASTER_SLOT = 0; #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint_at(). */ +everything after flush log_make_checkpoint(). */ PSI_stage_info srv_stage_alter_table_end = {0, "alter table (end)", PSI_FLAG_STAGE_PROGRESS}; /** Performance schema stage event for monitoring ALTER TABLE progress -log_make_checkpoint_at(). */ +log_make_checkpoint(). */ PSI_stage_info srv_stage_alter_table_flush = {0, "alter table (flush)", PSI_FLAG_STAGE_PROGRESS}; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 46a2b7b7c09..75bdf17eab7 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -516,7 +516,7 @@ create_log_files( (log_sys->lsn - log_sys->last_checkpoint_lsn)); log_mutex_exit(); - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); return(DB_SUCCESS); } From 6684989801cd0e93be5646716bb3cffedd271ce6 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 30 May 2018 12:43:54 +0300 Subject: [PATCH 02/13] versioning test suite fixes Preparation for MDEV-16210: replace.test: key_type combinations: PK and UNIQUE. foreign.test: Preparation for key_type combinations. Other fixes: * Merged versioning.update2 into versioning.update; * Removed test2 database and done individual drop instead. --- .../federated/federatedx_versioning.result | 8 +-- .../federated/federatedx_versioning.test | 7 ++- mysql-test/suite/versioning/common.inc | 2 - mysql-test/suite/versioning/common_finish.inc | 3 -- .../suite/versioning/key_type.combinations | 3 ++ mysql-test/suite/versioning/key_type.inc | 14 +++++ mysql-test/suite/versioning/r/alter.result | 17 +++--- mysql-test/suite/versioning/r/create.result | 13 +++-- mysql-test/suite/versioning/r/delete.result | 1 + mysql-test/suite/versioning/r/foreign.result | 46 +++++++++------- mysql-test/suite/versioning/r/online.result | 4 +- .../suite/versioning/r/partition.result | 21 ++++---- .../versioning/r/partition_innodb.result | 1 + mysql-test/suite/versioning/r/replace.result | 10 ++-- mysql-test/suite/versioning/r/select.result | 10 ++-- mysql-test/suite/versioning/r/truncate.result | 2 +- mysql-test/suite/versioning/r/trx_id.result | 4 +- .../suite/versioning/r/update-big.result | 2 +- mysql-test/suite/versioning/r/update.result | 24 +++++++++ mysql-test/suite/versioning/r/update2.result | 21 -------- mysql-test/suite/versioning/r/view.result | 9 ++-- mysql-test/suite/versioning/t/alter.test | 5 +- mysql-test/suite/versioning/t/create.test | 3 +- mysql-test/suite/versioning/t/delete.test | 1 + .../suite/versioning/t/engines.combinations | 8 --- mysql-test/suite/versioning/t/foreign.test | 53 ++++++++++++------- mysql-test/suite/versioning/t/online.test | 4 +- mysql-test/suite/versioning/t/partition.test | 14 ++--- .../suite/versioning/t/partition_innodb.test | 2 + mysql-test/suite/versioning/t/replace.test | 17 ++++-- mysql-test/suite/versioning/t/trx_id.test | 5 +- mysql-test/suite/versioning/t/update-big.test | 2 +- mysql-test/suite/versioning/t/update.test | 30 +++++++++++ mysql-test/suite/versioning/t/update2.test | 31 ----------- mysql-test/suite/versioning/t/view.test | 9 ++-- 35 files changed, 223 insertions(+), 183 deletions(-) create mode 100644 mysql-test/suite/versioning/key_type.combinations create mode 100644 mysql-test/suite/versioning/key_type.inc delete mode 100644 mysql-test/suite/versioning/r/update2.result delete mode 100644 mysql-test/suite/versioning/t/engines.combinations delete mode 100644 mysql-test/suite/versioning/t/update2.test diff --git a/mysql-test/suite/federated/federatedx_versioning.result b/mysql-test/suite/federated/federatedx_versioning.result index 9a7b180a5ab..c708b5f7932 100644 --- a/mysql-test/suite/federated/federatedx_versioning.result +++ b/mysql-test/suite/federated/federatedx_versioning.result @@ -4,14 +4,14 @@ row_start SYS_TYPE as row start invisible, row_end SYS_TYPE as row end invisible, period for system_time (row_start, row_end)) with system versioning; -create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test2/t1'; +create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test/t1'; show create table tf; Table Create Table tf CREATE TABLE `tf` ( `x` int(11) DEFAULT NULL, `row_start` SYS_TYPE NOT NULL INVISIBLE DEFAULT 0, `row_end` SYS_TYPE NOT NULL INVISIBLE DEFAULT 0 -) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:MASTER_MYPORT/test2/t1' +) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:MASTER_MYPORT/test/t1' # INSERT insert into t1 values (1); select * from tf; @@ -57,7 +57,7 @@ row_start SYS_TYPE as row start invisible, row_end SYS_TYPE as row end invisible, period for system_time (row_start, row_end)) with system versioning; -create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test2/t2'; +create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test/t2'; insert t2f (id, y) values (1, 2); replace t2f (id, y) values (1, 3); select *, check_row(row_start, row_end) from t2 for system_time all @@ -96,3 +96,5 @@ order by y; id y check_row(row_start, row_end) 2 2 HISTORICAL ROW 2 22 CURRENT ROW +drop view vt1; +drop tables t1, t2, t2f, tf; diff --git a/mysql-test/suite/federated/federatedx_versioning.test b/mysql-test/suite/federated/federatedx_versioning.test index b003403b629..40d0bc5018a 100644 --- a/mysql-test/suite/federated/federatedx_versioning.test +++ b/mysql-test/suite/federated/federatedx_versioning.test @@ -11,7 +11,7 @@ eval create or replace table t1 ( period for system_time (row_start, row_end)) with system versioning; --replace_result $MASTER_MYPORT MASTER_MYPORT -eval create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test2/t1'; +eval create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t1'; --replace_result $MASTER_MYPORT MASTER_MYPORT $sys_datatype_expl SYS_TYPE "'0000-00-00 00:00:00.000000'" 0 show create table tf; --echo # INSERT @@ -45,7 +45,7 @@ eval create or replace table t2 ( period for system_time (row_start, row_end)) with system versioning; --replace_result $MASTER_MYPORT MASTER_MYPORT -eval create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test2/t2'; +eval create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t2'; insert t2f (id, y) values (1, 2); replace t2f (id, y) values (1, 3); select *, check_row(row_start, row_end) from t2 for system_time all @@ -72,4 +72,7 @@ order by x; select *, check_row(row_start, row_end) from t2 for system_time all order by y; +drop view vt1; +drop tables t1, t2, t2f, tf; + --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc index 39abccd7ecd..355b571e5a0 100644 --- a/mysql-test/suite/versioning/common.inc +++ b/mysql-test/suite/versioning/common.inc @@ -4,8 +4,6 @@ if (!$TEST_VERSIONING_SO) --skip needs test_versioning plugin } source include/have_innodb.inc; -create database test2 character set latin1; -use test2; set @@session.time_zone='+00:00'; select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry; diff --git a/mysql-test/suite/versioning/common_finish.inc b/mysql-test/suite/versioning/common_finish.inc index 90a305078c8..61641c6c5ce 100644 --- a/mysql-test/suite/versioning/common_finish.inc +++ b/mysql-test/suite/versioning/common_finish.inc @@ -5,7 +5,4 @@ drop procedure if exists verify_trt_dummy; drop function if exists current_row; drop function if exists check_row; --enable_warnings - -use test; -drop database test2; --enable_query_log diff --git a/mysql-test/suite/versioning/key_type.combinations b/mysql-test/suite/versioning/key_type.combinations new file mode 100644 index 00000000000..93c0ea8bc06 --- /dev/null +++ b/mysql-test/suite/versioning/key_type.combinations @@ -0,0 +1,3 @@ +[unique] +[pk] +[sec] diff --git a/mysql-test/suite/versioning/key_type.inc b/mysql-test/suite/versioning/key_type.inc new file mode 100644 index 00000000000..888a1d97098 --- /dev/null +++ b/mysql-test/suite/versioning/key_type.inc @@ -0,0 +1,14 @@ +--disable_query_log +if ($MTR_COMBINATION_UNIQUE) +{ + let $KEY_TYPE= unique; +} +if ($MTR_COMBINATION_PK) +{ + let $KEY_TYPE= primary key; +} +if ($MTR_COMBINATION_SEC) +{ + let $KEY_TYPE= key; +} +--enable_query_log diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index b5d44332955..a453617d3b3 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -18,13 +18,13 @@ t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING alter table t add column y int; -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. alter table t add primary key (a); -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. alter table t add unique key (a); -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. alter table t engine innodb; -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change to/from native system versioning engine is not supported. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change to/from native system versioning engine is not supported. alter table t drop system versioning; show create table t; Table Create Table @@ -527,7 +527,7 @@ create or replace table t (x int) with system versioning; ERROR HY000: System versioning tables in the `mysql` database are not suported alter table user add system versioning; ERROR HY000: System versioning tables in the `mysql` database are not suported -use test2; +use test; # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; alter table t1 modify s timestamp(6) as row start; @@ -537,10 +537,10 @@ create or replace table t (a int) with system versioning; insert into t values (0), (1); delete from t where a = 0; alter table t add check (a > 1); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test2`.`t` +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t` alter table t add check (a > 0); insert into t values (0); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test2`.`t` +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t` insert into t values (2); # # MDEV-18869 Assertion `!((field)->vcol_info && (field)->stored_in_db())' failed in innodb_col_no upon altering table with system versioning @@ -679,5 +679,4 @@ alter table t add column c int without system versioning, change column c c int, change column b b int without system versioning; -drop database test; -create database test; +drop table t; diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result index f9d13123db5..5189e55bc30 100644 --- a/mysql-test/suite/versioning/r/create.result +++ b/mysql-test/suite/versioning/r/create.result @@ -15,7 +15,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING select table_catalog,table_schema,table_name,table_type,version,table_rows,data_free,auto_increment,check_time,table_collation,checksum,create_options,table_comment from information_schema.tables where table_name='t1'; table_catalog def -table_schema test2 +table_schema test table_name t1 table_type SYSTEM VERSIONED version 10 @@ -29,7 +29,7 @@ create_options table_comment select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,character_maximum_length,character_octet_length,character_set_name,collation_name,column_key,extra,column_comment,is_generated,generation_expression from information_schema.columns where table_name='t1'; table_catalog def -table_schema test2 +table_schema test table_name t1 column_name x1 ordinal_position 1 @@ -44,7 +44,7 @@ column_comment is_generated NEVER generation_expression NULL table_catalog def -table_schema test2 +table_schema test table_name t1 column_name Sys_start ordinal_position 2 @@ -59,7 +59,7 @@ column_comment start is_generated ALWAYS generation_expression ROW START table_catalog def -table_schema test2 +table_schema test table_name t1 column_name Sys_end ordinal_position 3 @@ -235,7 +235,7 @@ tt1 CREATE TABLE `tt1` ( drop table tt1; create temporary table tt1 like t1; Warnings: -Warning 1105 System versioning is stripped from temporary `test2.tt1` +Warning 1105 System versioning is stripped from temporary `test.tt1` # Temporary is stripped from versioning show create table tt1; Table Create Table @@ -523,5 +523,4 @@ create or replace table t1 (x int without system versioning) with system versioning select 1 as x; ERROR HY000: Table `t1` must have at least one versioned column -drop database test; -create database test; +drop tables t0, t1, t2, t3; diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result index cfce8aa3069..77b7fc80286 100644 --- a/mysql-test/suite/versioning/r/delete.result +++ b/mysql-test/suite/versioning/r/delete.result @@ -115,3 +115,4 @@ select x from t1 for system_time all; x 2 1 +drop table t1; diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index 001577750ba..e5ffb6c5f0c 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -2,7 +2,8 @@ # Test RESTRICT # ################# create table parent( -id int unique key +id int, +KEY_TYPE (id) ) engine innodb; create table child( parent_id int, @@ -16,13 +17,13 @@ on update restrict insert into parent values(1); insert into child values(1); delete from parent where id = 1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) delete from child where parent_id = 1; delete from parent where id = 1; insert into parent values(1); insert into child values(1); update parent set id=id+1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) delete from child; update parent set id=id+1; select * from child for system_time all; @@ -35,7 +36,8 @@ drop table parent; # Test when clustered index is a foreign key # ############################################## create table parent( -id int(10) unsigned unique key +id int(10) unsigned, +KEY_TYPE (id) ) engine innodb; create table child( parent_id int(10) unsigned primary key, @@ -47,14 +49,15 @@ foreign key(parent_id) references parent(id) insert into parent values(1); insert into child values(1); delete from parent where id = 1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) drop table child; drop table parent; ################ # Test CASCADE # ################ create table parent( -id int unique key +id int, +KEY_TYPE (id) ) engine innodb; create table child( parent_id int, @@ -87,7 +90,8 @@ parent_id drop table child; drop table parent; create or replace table parent ( -id int primary key, +id int, +KEY_TYPE(id), sys_start SYS_DATATYPE as row start invisible, sys_end SYS_DATATYPE as row end invisible, period for system_time(sys_start, sys_end) @@ -110,7 +114,8 @@ x parent_id drop table child; drop table parent; create or replace table parent ( -id int primary key +id int, +KEY_TYPE(id) ) engine innodb; create or replace table child ( @@ -138,8 +143,9 @@ drop table parent; ################# # Test SET NULL # ################# -create or replace table parent( -id int unique key +create table parent( +id int, +KEY_TYPE (id) ) engine innodb; create or replace table child( parent_id int, @@ -183,7 +189,8 @@ drop table parent; # Parent table is foreign # ########################### create or replace table parent( -id int unique key, +id int, +KEY_TYPE (id), sys_start SYS_DATATYPE as row start invisible, sys_end SYS_DATATYPE as row end invisible, period for system_time(sys_start, sys_end) @@ -195,26 +202,27 @@ foreign key(parent_id) references parent(id) insert into parent values(1); insert into child values(1); delete from parent; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) update parent set id=2; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) delete from child; delete from parent; insert into child values(1); -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) insert into parent values(1); insert into child values(1); delete from parent; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) update parent set id=2; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) drop table child; drop table parent; ################### # crash on DELETE # ################### create or replace table a ( -cola int(10) primary key, +cola int(10), +KEY_TYPE (cola), v_cola int(10) as (cola mod 10) virtual, sys_start SYS_DATATYPE as row start invisible, sys_end SYS_DATATYPE as row end invisible, @@ -233,7 +241,7 @@ foreign key (v_cola) references a (v_cola); insert into a(cola) values (12); insert into b(cola, v_cola) values (10,2); delete from a; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`b`, CONSTRAINT `v_cola_fk` FOREIGN KEY (`v_cola`) REFERENCES `a` (`v_cola`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `v_cola_fk` FOREIGN KEY (`v_cola`) REFERENCES `a` (`v_cola`)) drop table b, a; ############################################### # CASCADE UPDATE foreign not system versioned # @@ -296,7 +304,7 @@ SET FOREIGN_KEY_CHECKS= OFF; INSERT IGNORE INTO t2 VALUES (1); SET FOREIGN_KEY_CHECKS= ON; UPDATE t2 SET f2= 2; -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test2`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)) DELETE FROM t2; DROP TABLE t2, t1; # diff --git a/mysql-test/suite/versioning/r/online.result b/mysql-test/suite/versioning/r/online.result index 2e5a165dd81..aabf2b98cbf 100644 --- a/mysql-test/suite/versioning/r/online.result +++ b/mysql-test/suite/versioning/r/online.result @@ -89,13 +89,13 @@ period for system_time(row_start, row_end) insert into t values (1, 1); select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id -where t.name='test2/t' and c.name='b'; +where t.name='test/t' and c.name='b'; prtype 50179 set @@system_versioning_alter_history=keep; select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id -where t.name='test2/t' and c.name='b'; +where t.name='test/t' and c.name='b'; prtype 50179 show create table t; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index b364dca5376..2163ebeb1a0 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -46,7 +46,7 @@ period for system_time(row_start, row_end)) engine=DEFAULT_ENGINE with system versioning partition by hash(i); alter table t1 engine=NON_DEFAULT_ENGINE; -ERROR HY000: Not allowed for system-versioned `test2`.`t1`. Change to/from native system versioning engine is not supported. +ERROR HY000: Not allowed for system-versioned `test`.`t1`. Change to/from native system versioning engine is not supported. ## CREATE TABLE create or replace table t1 (x int) partition by system_time ( @@ -254,11 +254,11 @@ x 6 insert into t1 values (7), (8); Warnings: -Warning 4114 Versioned table `test2`.`t1`: partition `p1` is full, add more HISTORY partitions +Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions ### warn about full partition delete from t1; Warnings: -Warning 4114 Versioned table `test2`.`t1`: partition `p1` is full, add more HISTORY partitions +Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions select * from t1 partition (p1) order by x; x 4 @@ -433,16 +433,16 @@ create or replace table t1 (i int) with system versioning partition by system_time interval 1 hour ( partition p0 history, partition pn current); set @ts=(select partition_description from information_schema.partitions -where table_schema='test2' and table_name='t1' and partition_name='p0'); +where table_schema='test' and table_name='t1' and partition_name='p0'); alter table t1 add column b int; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p0 1 SYSTEM_TIME 00:00:00.000000 pn 2 SYSTEM_TIME NULL Warnings: Warning 1292 Truncated incorrect time value: 'CURRENT' alter table t1 add partition (partition p1 history, partition p2 history); -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p0 1 SYSTEM_TIME 00:00:00.000000 p1 2 SYSTEM_TIME 01:00:00.000000 @@ -451,7 +451,7 @@ pn 4 SYSTEM_TIME NULL Warnings: Warning 1292 Truncated incorrect time value: 'CURRENT' alter table t1 drop partition p0; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p1 1 SYSTEM_TIME 01:00:00.000000 p2 2 SYSTEM_TIME 02:00:00.000000 @@ -460,7 +460,7 @@ Warnings: Warning 1292 Truncated incorrect time value: 'CURRENT' alter table t1 drop partition p2; ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p1 1 SYSTEM_TIME 01:00:00.000000 p2 2 SYSTEM_TIME 02:00:00.000000 @@ -556,7 +556,7 @@ insert into t1 values (0), (1), (2), (3); delete from t1 where x < 3; delete from t1; Warnings: -Warning 4114 Versioned table `test2`.`t1`: partition `p1` is full, add more HISTORY partitions +Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions unlock tables; # # MDEV-20336 Assertion bitmap_is_set(read_partitions) upon SELECT FOR UPDATE from versioned table @@ -564,4 +564,5 @@ unlock tables; create or replace table t1 (pk int primary key) with system versioning partition by system_time limit 100 (partition p1 history, partition pn current); execute immediate 'select * from t1 for update'; pk -drop table t1; +drop view v1; +drop tables t, t1, t2, t3, t4; diff --git a/mysql-test/suite/versioning/r/partition_innodb.result b/mysql-test/suite/versioning/r/partition_innodb.result index 5fd2d7b4dce..3c4adce099a 100644 --- a/mysql-test/suite/versioning/r/partition_innodb.result +++ b/mysql-test/suite/versioning/r/partition_innodb.result @@ -21,6 +21,7 @@ partition p0 history, partition pn current ); ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `#sql-temporary` +drop table t1; create or replace table t ( a int primary key, row_start bigint unsigned as row start invisible, diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result index e5dcf61678e..bda61f118b0 100644 --- a/mysql-test/suite/versioning/r/replace.result +++ b/mysql-test/suite/versioning/r/replace.result @@ -1,9 +1,10 @@ -create table t ( -id int primary key, +create or replace table t( +id int, +KEY_TYPE(id), x int, row_start SYS_DATATYPE as row start invisible, row_end SYS_DATATYPE as row end invisible, -period for system_time (row_start, row_end) +period for system_time(row_start, row_end) ) with system versioning; insert t values (1, 2); replace t values (1, 3); @@ -32,7 +33,8 @@ insert into t1 values (1,1); create or replace table t2 (c int); create or replace view v as select t1.* from t1 join t2; replace into v (a, b) select a, b from t1; -drop table t1; +drop view v; +drop tables t1, t2; CREATE TABLE t1 ( pk INT AUTO_INCREMENT, f INT, diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 40202edf4a6..c887e524e63 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -153,21 +153,21 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`x` AS `IJ2_x1`,`test2`.`t1`.`y` AS `y1`,`test2`.`t2`.`x` AS `x2`,`test2`.`t2`.`y` AS `y2` from `test2`.`t1` FOR SYSTEM_TIME ALL join `test2`.`t2` FOR SYSTEM_TIME ALL where `test2`.`t1`.`x` = `test2`.`t2`.`x` and `test2`.`t2`.`row_end` > @`t0` and `test2`.`t2`.`row_start` <= @`t0` and `test2`.`t1`.`row_end` > @`t0` and `test2`.`t1`.`row_start` <= @`t0` +Note 1003 select `test`.`t1`.`x` AS `IJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0` explain extended select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) for system_time as of timestamp @t0 as t; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`x` AS `LJ2_x1`,`test2`.`t1`.`y` AS `y1`,`test2`.`t2`.`x` AS `x2`,`test2`.`t2`.`y` AS `y2` from `test2`.`t1` FOR SYSTEM_TIME ALL left join `test2`.`t2` FOR SYSTEM_TIME ALL on(`test2`.`t2`.`x` = `test2`.`t1`.`x` and `test2`.`t2`.`row_end` > @`t0` and `test2`.`t2`.`row_start` <= @`t0`) where `test2`.`t1`.`row_end` > @`t0` and `test2`.`t1`.`row_start` <= @`t0` +Note 1003 select `test`.`t1`.`x` AS `LJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL left join `test`.`t2` FOR SYSTEM_TIME ALL on(`test`.`t2`.`x` = `test`.`t1`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`) where `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0` explain extended select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) for system_time as of timestamp @t0 as t; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`x` AS `RJ2_x1`,`test2`.`t1`.`y` AS `y1`,`test2`.`t2`.`x` AS `x2`,`test2`.`t2`.`y` AS `y2` from `test2`.`t2` FOR SYSTEM_TIME ALL left join `test2`.`t1` FOR SYSTEM_TIME ALL on(`test2`.`t1`.`x` = `test2`.`t2`.`x` and `test2`.`t1`.`row_end` > @`t0` and `test2`.`t1`.`row_start` <= @`t0`) where `test2`.`t2`.`row_end` > @`t0` and `test2`.`t2`.`row_start` <= @`t0` +Note 1003 select `test`.`t1`.`x` AS `RJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t2` FOR SYSTEM_TIME ALL left join `test`.`t1` FOR SYSTEM_TIME ALL on(`test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`) where `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0` select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) for system_time as of timestamp @t0 as t; IJ2_x1 y1 x2 y2 @@ -294,7 +294,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`a` AS `a`,`test2`.`t2`.`a` AS `a` from `test2`.`t1` FOR SYSTEM_TIME ALL left join (`test2`.`t1` FOR SYSTEM_TIME ALL `t2` left join `test2`.`t1` FOR SYSTEM_TIME ALL `t3` on(`test2`.`t3`.`a` = `test2`.`t2`.`a` and `test2`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test2`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test2`.`t1`.`a` > 1) where `test2`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` FOR SYSTEM_TIME ALL left join (`test`.`t1` FOR SYSTEM_TIME ALL `t2` left join `test`.`t1` FOR SYSTEM_TIME ALL `t3` on(`test`.`t3`.`a` = `test`.`t2`.`a` and `test`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test`.`t1`.`a` > 1) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; a a 2 1 @@ -511,7 +511,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`f1` AS `f1` from `test2`.`t1` FOR SYSTEM_TIME ALL join `test2`.`t2` left join (`test2`.`t3` left join `test2`.`t4` FOR SYSTEM_TIME ALL on(`test2`.`t4`.`f4` = `test2`.`t2`.`f2` and `test2`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test2`.`t3`.`f3` = `test2`.`t2`.`f2`) where `test2`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' +Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` left join (`test`.`t3` left join `test`.`t4` FOR SYSTEM_TIME ALL on(`test`.`t4`.`f4` = `test`.`t2`.`f2` and `test`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t3`.`f3` = `test`.`t2`.`f2`) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' drop view v1; drop table t1, t2, t3, t4; # diff --git a/mysql-test/suite/versioning/r/truncate.result b/mysql-test/suite/versioning/r/truncate.result index 9d016a2bcd7..93f240272c1 100644 --- a/mysql-test/suite/versioning/r/truncate.result +++ b/mysql-test/suite/versioning/r/truncate.result @@ -93,7 +93,7 @@ drop view v; create or replace table t (i int); create or replace view v as select * from t; drop table v; -ERROR 42S02: 'test2.v' is a view +ERROR 42S02: 'test.v' is a view lock table v write; delete history from v before system_time now(6); ERROR 42S02: 'v' is a view diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result index 98543caadbc..413272f55f9 100644 --- a/mysql-test/suite/versioning/r/trx_id.result +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -181,9 +181,7 @@ select row_start from t1 into @trx_id; select trt_begin_ts(@trx_id) <= @ts1 as BEGIN_TS_GOOD; BEGIN_TS_GOOD 1 -drop database test; -create database test; -use test; +drop table t1; # # MDEV-16100 FOR SYSTEM_TIME erroneously resolves string user variables as transaction IDs # diff --git a/mysql-test/suite/versioning/r/update-big.result b/mysql-test/suite/versioning/r/update-big.result index 5accf0a0b56..89297fe5d89 100644 --- a/mysql-test/suite/versioning/r/update-big.result +++ b/mysql-test/suite/versioning/r/update-big.result @@ -12,7 +12,7 @@ insert into t1 select * from t1; insert into t1 select * from t1; insert into t1 select * from t1; insert into t1 select * from t1; -connect con1,localhost,root,,test2; +connect con1,localhost,root,,test; alter table t1 add system versioning; connection default; update t1 set a= 7 where a = 3; diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index 334d8d8899b..af263a63fae 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -241,3 +241,27 @@ B2 salary 1 2500 drop table t1; drop table t2; +### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row) +create or replace table t1 (a int primary key, b int) +with system versioning engine myisam; +insert into t1 (a) values (1); +replace t1 values (1,2),(1,3),(2,4); +# +# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE +# +create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) +engine=innodb with system versioning; +insert into t1 (pk) values (1); +connect con1,localhost,root,,test; +start transaction; +select * from t1 for update; +pk a b +1 NULL NULL +connection default; +update t1 set b = 'foo'; +connection con1; +update t1 set a = 'bar'; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +disconnect con1; +connection default; +drop table t1; diff --git a/mysql-test/suite/versioning/r/update2.result b/mysql-test/suite/versioning/r/update2.result deleted file mode 100644 index 73e6c5b393d..00000000000 --- a/mysql-test/suite/versioning/r/update2.result +++ /dev/null @@ -1,21 +0,0 @@ -### Issue #365, bug 7 (duplicate of historical row) -create or replace table t1 (a int primary key, b int) -with system versioning engine myisam; -insert into t1 (a) values (1); -replace t1 values (1,2),(1,3),(2,4); -create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) -engine=innodb with system versioning; -insert into t1 (pk) values (1); -connect con1,localhost,root,,test; -start transaction; -select * from t1 for update; -pk a b -1 NULL NULL -connection default; -update t1 set b = 'foo'; -connection con1; -update t1 set a = 'bar'; -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction -disconnect con1; -connection default; -drop table t1; diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result index e897f0e17d9..850eba32c0d 100644 --- a/mysql-test/suite/versioning/r/view.result +++ b/mysql-test/suite/versioning/r/view.result @@ -118,9 +118,8 @@ execute stmt; a execute stmt; a -drop database test2; -create database test2; -use test2; +drop view v1; +drop tables t1, t2; # # MDEV-15146 SQLError[4122]: View is not system versioned # @@ -148,5 +147,5 @@ create or replace view v1 as select * from t1 for system_time as of date_sub(now show create view v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` FOR SYSTEM_TIME AS OF current_timestamp() - interval 6 second latin1 latin1_swedish_ci -drop view v1; -drop table t1; +drop view v1, vt1, vt12; +drop tables t1, t3; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 735bde0614d..c8275a5d3f4 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -453,7 +453,7 @@ use mysql; create or replace table t (x int) with system versioning; --error ER_VERS_DB_NOT_SUPPORTED alter table user add system versioning; -use test2; +use test; --echo # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; @@ -574,5 +574,4 @@ alter table t change column c c int, change column b b int without system versioning; -drop database test; -create database test; +drop table t; diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test index b8caf6b7097..fc4120ef2aa 100644 --- a/mysql-test/suite/versioning/t/create.test +++ b/mysql-test/suite/versioning/t/create.test @@ -405,5 +405,4 @@ create or replace table t1 (x int without system versioning) with system versioning select 1 as x; -drop database test; -create database test; +drop tables t0, t1, t2, t3; diff --git a/mysql-test/suite/versioning/t/delete.test b/mysql-test/suite/versioning/t/delete.test index 01c8ba438ab..b9045898bb0 100644 --- a/mysql-test/suite/versioning/t/delete.test +++ b/mysql-test/suite/versioning/t/delete.test @@ -81,5 +81,6 @@ insert into t1 values (1); update t1 set x= 2; delete from t1; select x from t1 for system_time all; +drop table t1; --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/engines.combinations b/mysql-test/suite/versioning/t/engines.combinations deleted file mode 100644 index 561c5656929..00000000000 --- a/mysql-test/suite/versioning/t/engines.combinations +++ /dev/null @@ -1,8 +0,0 @@ -[timestamp] -default-storage-engine=innodb - -[trx_id] -default-storage-engine=innodb - -[myisam] -default-storage-engine=myisam diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index 1f4b3404618..d60172f99bc 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -1,11 +1,15 @@ --source suite/versioning/common.inc +let $KEY_TYPE= primary key; + --echo ################# --echo # Test RESTRICT # --echo ################# -create table parent( - id int unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -42,8 +46,10 @@ drop table parent; --echo # Test when clustered index is a foreign key # --echo ############################################## -create table parent( - id int(10) unsigned unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int(10) unsigned, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -68,8 +74,10 @@ drop table parent; --echo # Test CASCADE # --echo ################ -create table parent( - id int unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -99,9 +107,10 @@ select * from child for system_time all; drop table child; drop table parent; ---replace_result $sys_datatype_expl SYS_DATATYPE +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE eval create or replace table parent ( - id int primary key, + id int, + $KEY_TYPE(id), sys_start $sys_datatype_expl as row start invisible, sys_end $sys_datatype_expl as row end invisible, period for system_time(sys_start, sys_end) @@ -126,8 +135,10 @@ select * from child; drop table child; drop table parent; -create or replace table parent ( - id int primary key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create or replace table parent ( + id int, + $KEY_TYPE(id) ) engine innodb; @@ -158,8 +169,10 @@ drop table parent; --echo # Test SET NULL # --echo ################# -create or replace table parent( - id int unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -196,9 +209,10 @@ drop table parent; --echo # Parent table is foreign # --echo ########################### ---replace_result $sys_datatype_expl SYS_DATATYPE +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE eval create or replace table parent( - id int unique key, + id int, + $KEY_TYPE (id), sys_start $sys_datatype_expl as row start invisible, sys_end $sys_datatype_expl as row end invisible, period for system_time(sys_start, sys_end) @@ -236,9 +250,10 @@ drop table parent; --echo # crash on DELETE # --echo ################### ---replace_result $sys_datatype_expl SYS_DATATYPE +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE eval create or replace table a ( - cola int(10) primary key, + cola int(10), + $KEY_TYPE (cola), v_cola int(10) as (cola mod 10) virtual, sys_start $sys_datatype_expl as row start invisible, sys_end $sys_datatype_expl as row end invisible, @@ -406,8 +421,8 @@ REPLACE INTO t2 SELECT * FROM t2; # Cleanup DROP TABLE t1, t2; --let $datadir= `select @@datadir` ---remove_file $datadir/test2/t1.data ---remove_file $datadir/test2/t1.data.2 ---remove_file $datadir/test2/t2.data +--remove_file $datadir/test/t1.data +--remove_file $datadir/test/t1.data.2 +--remove_file $datadir/test/t2.data --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/online.test b/mysql-test/suite/versioning/t/online.test index c02df3d3044..cff3193407b 100644 --- a/mysql-test/suite/versioning/t/online.test +++ b/mysql-test/suite/versioning/t/online.test @@ -107,7 +107,7 @@ insert into t values (1, 1); select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id - where t.name='test2/t' and c.name='b'; + where t.name='test/t' and c.name='b'; set @@system_versioning_alter_history=keep; @@ -125,7 +125,7 @@ set debug_dbug= default; select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id - where t.name='test2/t' and c.name='b'; + where t.name='test/t' and c.name='b'; --replace_result $sys_datatype_expl SYS_DATATYPE show create table t; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index a9dff811d40..eca322d9ef4 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -402,17 +402,17 @@ partition by system_time interval 1 hour ( partition p0 history, partition pn current); set @ts=(select partition_description from information_schema.partitions - where table_schema='test2' and table_name='t1' and partition_name='p0'); + where table_schema='test' and table_name='t1' and partition_name='p0'); alter table t1 add column b int; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; alter table t1 add partition (partition p1 history, partition p2 history); -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; alter table t1 drop partition p0; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; --error ER_VERS_DROP_PARTITION_INTERVAL alter table t1 drop partition p2; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; --echo # --echo # MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW @@ -513,6 +513,8 @@ unlock tables; --echo # create or replace table t1 (pk int primary key) with system versioning partition by system_time limit 100 (partition p1 history, partition pn current); execute immediate 'select * from t1 for update'; -drop table t1; + +drop view v1; +drop tables t, t1, t2, t3, t4; --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/partition_innodb.test b/mysql-test/suite/versioning/t/partition_innodb.test index 36adb6345b0..aaaf7001644 100644 --- a/mysql-test/suite/versioning/t/partition_innodb.test +++ b/mysql-test/suite/versioning/t/partition_innodb.test @@ -29,6 +29,8 @@ alter table t1 partition by system_time ( partition pn current ); +drop table t1; + --error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED create or replace table t ( a int primary key, diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test index 22d32ff3795..392c0ffcf35 100644 --- a/mysql-test/suite/versioning/t/replace.test +++ b/mysql-test/suite/versioning/t/replace.test @@ -1,13 +1,19 @@ +--source suite/versioning/key_type.inc +if ($MTR_COMBINATION_SEC) +{ + --skip pk or unique only +} --source suite/versioning/common.inc --source suite/versioning/engines.inc ---replace_result $sys_datatype_expl SYS_DATATYPE -eval create table t ( - id int primary key, +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE +eval create or replace table t( + id int, + $KEY_TYPE(id), x int, row_start $sys_datatype_expl as row start invisible, row_end $sys_datatype_expl as row end invisible, - period for system_time (row_start, row_end) + period for system_time(row_start, row_end) ) with system versioning; insert t values (1, 2); @@ -35,7 +41,8 @@ insert into t1 values (1,1); create or replace table t2 (c int); create or replace view v as select t1.* from t1 join t2; replace into v (a, b) select a, b from t1; -drop table t1; +drop view v; +drop tables t1, t2; --replace_result $sys_datatype_expl SYS_DATATYPE eval CREATE TABLE t1 ( diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test index 943d9182a8a..617c46a9332 100644 --- a/mysql-test/suite/versioning/t/trx_id.test +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -173,10 +173,7 @@ commit; select row_start from t1 into @trx_id; select trt_begin_ts(@trx_id) <= @ts1 as BEGIN_TS_GOOD; -drop database test; -create database test; -use test; - +drop table t1; --echo # --echo # MDEV-16100 FOR SYSTEM_TIME erroneously resolves string user variables as transaction IDs diff --git a/mysql-test/suite/versioning/t/update-big.test b/mysql-test/suite/versioning/t/update-big.test index f5a72b22454..175bfc79a48 100644 --- a/mysql-test/suite/versioning/t/update-big.test +++ b/mysql-test/suite/versioning/t/update-big.test @@ -17,7 +17,7 @@ insert into t1 select * from t1; insert into t1 select * from t1; insert into t1 select * from t1; ---connect (con1,localhost,root,,test2) +--connect (con1,localhost,root,,test) alter table t1 add system versioning; --connection default diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index 95c844c88a2..a9550564a15 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -147,4 +147,34 @@ select @tmp2 = sys_trx_start as B2, salary from t2; drop table t1; drop table t2; +--echo ### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row) +create or replace table t1 (a int primary key, b int) +with system versioning engine myisam; +insert into t1 (a) values (1); + +replace t1 values (1,2),(1,3),(2,4); + +--echo # +--echo # MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE +--echo # + +create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) + engine=innodb with system versioning; + +insert into t1 (pk) values (1); +connect (con1,localhost,root,,test); +start transaction; +select * from t1 for update; +connection default; +send update t1 set b = 'foo'; +connection con1; +let $wait_condition= select count(*) from information_schema.innodb_lock_waits; +source include/wait_condition.inc; +error ER_LOCK_DEADLOCK; +update t1 set a = 'bar'; +disconnect con1; +connection default; +reap; +drop table t1; + source suite/versioning/common_finish.inc; diff --git a/mysql-test/suite/versioning/t/update2.test b/mysql-test/suite/versioning/t/update2.test deleted file mode 100644 index 87ca3746b12..00000000000 --- a/mysql-test/suite/versioning/t/update2.test +++ /dev/null @@ -1,31 +0,0 @@ -source include/have_innodb.inc; - -echo ### Issue #365, bug 7 (duplicate of historical row); -create or replace table t1 (a int primary key, b int) -with system versioning engine myisam; -insert into t1 (a) values (1); - -replace t1 values (1,2),(1,3),(2,4); - -# -# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE -# - -create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) - engine=innodb with system versioning; - -insert into t1 (pk) values (1); -connect (con1,localhost,root,,test); -start transaction; -select * from t1 for update; -connection default; -send update t1 set b = 'foo'; -connection con1; -let $wait_condition= select count(*) from information_schema.innodb_lock_waits; -source include/wait_condition.inc; -error ER_LOCK_DEADLOCK; -update t1 set a = 'bar'; -disconnect con1; -connection default; -reap; -drop table t1; diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test index d824f1c52c0..5a03a50f1d3 100644 --- a/mysql-test/suite/versioning/t/view.test +++ b/mysql-test/suite/versioning/t/view.test @@ -98,9 +98,8 @@ create or replace table t2 (b int) with system versioning; prepare stmt from 'select a from v1 inner join t2 group by a order by a'; execute stmt; execute stmt; -drop database test2; -create database test2; -use test2; +drop view v1; +drop tables t1, t2; --echo # --echo # MDEV-15146 SQLError[4122]: View is not system versioned @@ -122,7 +121,7 @@ select * from t1 for system_time as of now() - interval 6 second; create or replace view v1 as select * from t1 for system_time as of date_sub(now(), interval 6 second); show create view v1; -drop view v1; -drop table t1; +drop view v1, vt1, vt12; +drop tables t1, t3; --source suite/versioning/common_finish.inc From 75ba5c815d0272b35a28225d495a4a03fe63d29f Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 30 May 2018 13:19:03 +0300 Subject: [PATCH 03/13] MDEV-16210 FK constraints on versioned tables use historical rows, which may cause constraint violation Constraint check is done on secondary index update. F.ex. DELETE does row_upd_sec_index_entry() and checks constraints in row_upd_check_references_constraints(). UPDATE is optimized for the case when order is not changed (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) and doesn't do row_upd_sec_index_entry(), so it doesn't check constraints. Since for versioned DELETE we do UPDATE actually, but expect behaviour of DELETE in terms of constraints, we should deny this optimization to get constraints checked. Fix wrong referenced table check when versioned DELETE inserts history in parent table. Set check_ref to false in this case. Removed unused dup_chk_only argument for row_ins_sec_index_entry() and added check_ref argument. MDEV-18057 fix was superseded by this fix and reverted. foreign.test: All key_type combinations: pk, unique, sec(ondary). --- mysql-test/suite/versioning/r/foreign.result | 19 +++++++++------- mysql-test/suite/versioning/t/foreign.test | 23 ++++++++++---------- storage/innobase/include/row0ins.h | 5 ++++- storage/innobase/row/row0ins.cc | 17 ++++++++++----- storage/innobase/row/row0upd.cc | 11 ++++++---- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index e5ffb6c5f0c..6a9746b62e2 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -298,15 +298,18 @@ select count(*) from subchild; count(*) 0 drop table subchild, child, parent; -CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=InnoDB; -CREATE TABLE t2 (f2 INT, FOREIGN KEY (f2) REFERENCES t1 (f1)) ENGINE=InnoDB WITH SYSTEM VERSIONING; -SET FOREIGN_KEY_CHECKS= OFF; -INSERT IGNORE INTO t2 VALUES (1); -SET FOREIGN_KEY_CHECKS= ON; -UPDATE t2 SET f2= 2; +# +# MDEV-18057 Assertion `(node->state == 5) || (node->state == 6)' failed in row_upd_sec_step upon DELETE after UPDATE failed due to FK violation +# +create or replace table t1 (f1 int, key(f1)) engine=innodb; +create or replace table t2 (f2 int, foreign key (f2) references t1 (f1)) engine=innodb with system versioning; +set foreign_key_checks= off; +insert ignore into t2 values (1); +set foreign_key_checks= on; +update t2 set f2= 2; ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)) -DELETE FROM t2; -DROP TABLE t2, t1; +delete from t2; +drop table t2, t1; # # MDEV-18879 Corrupted record inserted by FOREIGN KEY operation # diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index d60172f99bc..9f015630e0a 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -1,7 +1,6 @@ +--source suite/versioning/key_type.inc --source suite/versioning/common.inc -let $KEY_TYPE= primary key; - --echo ################# --echo # Test RESTRICT # --echo ################# @@ -331,19 +330,21 @@ select count(*) from subchild; drop table subchild, child, parent; +--echo # +--echo # MDEV-18057 Assertion `(node->state == 5) || (node->state == 6)' failed in row_upd_sec_step upon DELETE after UPDATE failed due to FK violation +--echo # +create or replace table t1 (f1 int, key(f1)) engine=innodb; +create or replace table t2 (f2 int, foreign key (f2) references t1 (f1)) engine=innodb with system versioning; -CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=InnoDB; -CREATE TABLE t2 (f2 INT, FOREIGN KEY (f2) REFERENCES t1 (f1)) ENGINE=InnoDB WITH SYSTEM VERSIONING; +set foreign_key_checks= off; +insert ignore into t2 values (1); -SET FOREIGN_KEY_CHECKS= OFF; -INSERT IGNORE INTO t2 VALUES (1); - -SET FOREIGN_KEY_CHECKS= ON; +set foreign_key_checks= on; --error ER_NO_REFERENCED_ROW_2 -UPDATE t2 SET f2= 2; -DELETE FROM t2; +update t2 set f2= 2; +delete from t2; -DROP TABLE t2, t1; +drop table t2, t1; --echo # --echo # MDEV-18879 Corrupted record inserted by FOREIGN KEY operation diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index ddc3db8c694..87a72d88eb6 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -145,7 +145,10 @@ row_ins_sec_index_entry( /*====================*/ dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ - que_thr_t* thr) /*!< in: query thread */ + que_thr_t* thr, /*!< in: query thread */ + bool check_ref) /*!< in: TRUE if we want to check that + the referenced table is ok, FALSE if we + want to check the foreign key table */ MY_ATTRIBUTE((warn_unused_result)); /***********************************************************//** Inserts a row to a table. This is a high-level function used in diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 62115beddc0..88deacbc823 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1988,7 +1988,10 @@ row_ins_check_foreign_constraints( dict_index_t* index, /*!< in: index */ bool pk, /*!< in: index->is_primary() */ dtuple_t* entry, /*!< in: index entry for index */ - que_thr_t* thr) /*!< in: query thread */ + que_thr_t* thr, /*!< in: query thread */ + bool check_ref = true) /*!< in: TRUE if we want to check that + the referenced table is ok, FALSE if we + want to check the foreign key table */ { dict_foreign_t* foreign; dberr_t err; @@ -2037,7 +2040,7 @@ row_ins_check_foreign_constraints( table from being dropped while the check is running. */ err = row_ins_check_foreign_constraint( - TRUE, foreign, table, entry, thr); + check_ref, foreign, table, entry, thr); if (referenced_table) { foreign->foreign_table->dec_fk_checks(); @@ -3267,7 +3270,10 @@ row_ins_sec_index_entry( /*====================*/ dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ - que_thr_t* thr) /*!< in: query thread */ + que_thr_t* thr, /*!< in: query thread */ + bool check_ref) /*!< in: true if we want to check that + the referenced table is ok, false if we + want to check the foreign key table */ { dberr_t err; mem_heap_t* offsets_heap; @@ -3280,7 +3286,8 @@ row_ins_sec_index_entry( if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints(index->table, index, - false, entry, thr); + false, entry, thr, + check_ref); if (err != DB_SUCCESS) { return(err); @@ -3355,7 +3362,7 @@ row_ins_index_entry( if (index->is_primary()) { return row_ins_clust_index_entry(index, entry, thr, 0); } else { - return row_ins_sec_index_entry(index, entry, thr); + return(row_ins_sec_index_entry(index, entry, thr, true)); } } diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index d081c5c2122..64021b48ee2 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2529,7 +2529,8 @@ row_upd_sec_index_entry( ut_a(entry); /* Insert new index entry */ - err = row_ins_sec_index_entry(index, entry, thr); + err = row_ins_sec_index_entry(index, entry, thr, + node->is_delete != VERSIONED_DELETE); func_exit: mem_heap_free(heap); @@ -3191,9 +3192,8 @@ row_upd_clust_step( row_upd_eval_new_vals(node->update); } - if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { + if (!node->is_delete && node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { - node->index = NULL; err = row_upd_clust_rec( flags, node, index, offsets, &heap, thr, &mtr); goto exit_func; @@ -3237,7 +3237,10 @@ row_upd_clust_step( goto exit_func; } - node->state = UPD_NODE_UPDATE_SOME_SEC; + ut_ad(node->is_delete != PLAIN_DELETE); + node->state = node->is_delete ? + UPD_NODE_UPDATE_ALL_SEC : + UPD_NODE_UPDATE_SOME_SEC; } node->index = dict_table_get_next_index(index); From 647a38818a44012c22128e0e1cad96739aa8a5c2 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 23 May 2018 22:15:04 +0300 Subject: [PATCH 04/13] MDEV-16130 wrong error message adding AS ROW START to versioned table --- mysql-test/suite/versioning/r/alter.result | 8 ++++++-- mysql-test/suite/versioning/t/alter.test | 9 +++++++-- sql/handler.cc | 6 ++++-- sql/sql_table.cc | 6 ------ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index a453617d3b3..532412e3574 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -80,13 +80,17 @@ t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 alter table t add column trx_start timestamp(6) as row start; -ERROR HY000: Table `t` is not system-versioned +ERROR HY000: Duplicate ROW START column `trx_start` alter table t add system versioning; show create table t; Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add column trx_start timestamp(6) as row start; +ERROR HY000: Duplicate ROW START column `trx_start` +alter table t modify a int as row start; +ERROR HY000: Duplicate ROW START column `a` alter table t add column b int; show create table t; Table Create Table @@ -531,7 +535,7 @@ use test; # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; alter table t1 modify s timestamp(6) as row start; -ERROR HY000: Can not change system versioning field `s` +ERROR HY000: Duplicate ROW START column `s` # ignore CHECK for historical rows create or replace table t (a int) with system versioning; insert into t values (0), (1); diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index c8275a5d3f4..ff33f2cf95b 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -68,12 +68,17 @@ select row_start from t; alter table t drop system versioning; show create table t; ---error ER_VERS_NOT_VERSIONED +--error ER_VERS_DUPLICATE_ROW_START_END alter table t add column trx_start timestamp(6) as row start; alter table t add system versioning; show create table t; +--error ER_VERS_DUPLICATE_ROW_START_END +alter table t add column trx_start timestamp(6) as row start; +--error ER_VERS_DUPLICATE_ROW_START_END +alter table t modify a int as row start; + alter table t add column b int; show create table t; @@ -457,7 +462,7 @@ use test; --echo # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; ---error ER_VERS_ALTER_SYSTEM_FIELD +--error ER_VERS_DUPLICATE_ROW_START_END alter table t1 modify s timestamp(6) as row start; --echo # ignore CHECK for historical rows diff --git a/sql/handler.cc b/sql/handler.cc index 587ec633245..1494060e24d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7301,13 +7301,15 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, return false; } + if (!(alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING)) { List_iterator_fast it(alter_info->create_list); while (Create_field *f= it++) { - if (f->change.length && f->flags & VERS_SYSTEM_FIELD) + if (f->flags & VERS_SYSTEM_FIELD) { - my_error(ER_VERS_ALTER_SYSTEM_FIELD, MYF(0), f->field_name.str); + my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0), + f->flags & VERS_SYS_START_FLAG ? "START" : "END", f->field_name.str); return true; } } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b4cf6f61f60..c2c26222a82 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8159,12 +8159,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, alter_ctx->datetime_field= def; alter_ctx->error_if_not_empty= TRUE; } - if (def->flags & VERS_SYSTEM_FIELD && - !(alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING)) - { - my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->s->table_name.str); - goto err; - } if (!def->after.str) new_create_list.push_back(def, thd->mem_root); else From a92f3146d22cb3b290228c0e66eb1ea6c7b7c373 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sat, 11 May 2019 17:27:23 +0300 Subject: [PATCH 05/13] MDEV-19406 Assertion on updating view of join with versioned table TABLE::mark_columns_needed_for_update(): use_all_columns() assigns pointer of all_set into read_set and write_set, but this is not good since all_set is changed later by TABLE::mark_columns_used_by_index_no_reset(). Do column_bitmaps_signal() whenever we change read_set/write_set. --- mysql-test/suite/versioning/r/update.result | 11 +++++++ mysql-test/suite/versioning/t/update.test | 15 ++++++++++ sql/log_event.cc | 2 ++ sql/sql_insert.cc | 1 + sql/table.cc | 32 ++++++++++++++------- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index af263a63fae..eaa8549b38a 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -265,3 +265,14 @@ ERROR 40001: Deadlock found when trying to get lock; try restarting transaction disconnect con1; connection default; drop table t1; +# +# MDEV-19406 Assertion on updating view of join with versioned table +# +create or replace table t1 (pk int primary key, a date, b int, index(b)) engine=innodb with system versioning; +create or replace table t2 (c int); +create or replace view v as select * from t1 join t2; +insert into t1 (pk) values (1); +update t1 set a= '2012-12-12'; +update v set a= '2000-01-01' order by b limit 1; +drop view v; +drop table t1, t2; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index a9550564a15..e41c7d15995 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -177,4 +177,19 @@ connection default; reap; drop table t1; +--echo # +--echo # MDEV-19406 Assertion on updating view of join with versioned table +--echo # +--disable_warnings +create or replace table t1 (pk int primary key, a date, b int, index(b)) engine=innodb with system versioning; +create or replace table t2 (c int); +create or replace view v as select * from t1 join t2; + +insert into t1 (pk) values (1); +update t1 set a= '2012-12-12'; +update v set a= '2000-01-01' order by b limit 1; # point of failure +drop view v; +drop table t1, t2; +--enable_warnings + source suite/versioning/common_finish.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index dc7203fc94f..78111e86f20 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -13450,6 +13450,7 @@ Rows_log_event::write_row(rpl_group_info *rgi, { ulong sec_part; bitmap_set_bit(table->read_set, table->vers_start_field()->field_index); + table->file->column_bitmaps_signal(); // Check whether a row came from unversioned table and fix vers fields. if (table->vers_start_field()->get_timestamp(&sec_part) == 0 && sec_part == 0) table->vers_update_fields(); @@ -14010,6 +14011,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi) table->vers_end_field()->set_max(); m_vers_from_plain= true; } + table->file->column_bitmaps_signal(); } DBUG_PRINT("info",("looking for the following record")); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7913ea2b2ec..dc8ee19b1e1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1945,6 +1945,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (table->versioned(VERS_TRX_ID)) { bitmap_set_bit(table->write_set, table->vers_start_field()->field_index); + table->file->column_bitmaps_signal(); table->vers_start_field()->store(0, false); } if (unlikely(error= table->file->ha_update_row(table->record[1], diff --git a/sql/table.cc b/sql/table.cc index e2b2a5ec273..34523767eb4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6510,15 +6510,16 @@ void TABLE::mark_columns_needed_for_delete() } } - if (need_signal) - file->column_bitmaps_signal(); - if (s->versioned) { bitmap_set_bit(read_set, s->vers_start_field()->field_index); bitmap_set_bit(read_set, s->vers_end_field()->field_index); bitmap_set_bit(write_set, s->vers_end_field()->field_index); + need_signal= true; } + + if (need_signal) + file->column_bitmaps_signal(); } @@ -6531,7 +6532,7 @@ void TABLE::mark_columns_needed_for_delete() updated columns to be read. If this is no the case, we do like in the delete case and mark - if neeed, either the primary key column or all columns to be read. + if needed, either the primary key column or all columns to be read. (see mark_columns_needed_for_delete() for details) If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will @@ -6595,14 +6596,18 @@ void TABLE::mark_columns_needed_for_update() need_signal= true; } } - /* - For System Versioning we have to read all columns since we will store - a copy of previous row with modified Sys_end column back to a table. - */ if (s->versioned) { - // We will copy old columns to a new row. - use_all_columns(); + /* + For System Versioning we have to read all columns since we store + a copy of previous row with modified row_end back to a table. + + Without write_set versioning.rpl,row is unstable until MDEV-16370 is + applied. + */ + bitmap_union(read_set, &s->all_set); + bitmap_union(write_set, &s->all_set); + need_signal= true; } if (check_constraints) { @@ -7991,7 +7996,10 @@ void TABLE::vers_update_fields() if (versioned(VERS_TIMESTAMP)) { if (!vers_write) + { + file->column_bitmaps_signal(); return; + } if (vers_start_field()->store_timestamp(in_use->query_start(), in_use->query_start_sec_part())) DBUG_ASSERT(0); @@ -7999,11 +8007,15 @@ void TABLE::vers_update_fields() else { if (!vers_write) + { + file->column_bitmaps_signal(); return; + } } vers_end_field()->set_max(); bitmap_set_bit(read_set, vers_end_field()->field_index); + file->column_bitmaps_signal(); } From c9cba59749e1b5a39a9e3a0a5b8bd762507245f9 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 8 Oct 2018 20:38:58 +0300 Subject: [PATCH 06/13] MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD While `handler::next_insert_id` is restored on duplicate key errors `part_share->next_auto_inc_val` is not restored which causes discrepancy. --- mysql-test/main/auto_increment_ranges.inc | 20 +++++++++++++++++++ .../main/auto_increment_ranges_innodb.result | 11 ++++++++++ .../main/auto_increment_ranges_myisam.result | 11 ++++++++++ sql/ha_partition.h | 15 ++++++++++++++ sql/handler.h | 16 ++++++++++++++- sql/sql_insert.cc | 8 ++++---- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/auto_increment_ranges.inc b/mysql-test/main/auto_increment_ranges.inc index dc60f07a700..d94e446a0f5 100644 --- a/mysql-test/main/auto_increment_ranges.inc +++ b/mysql-test/main/auto_increment_ranges.inc @@ -238,3 +238,23 @@ delete from t1 where a=32767; --error HA_ERR_AUTOINC_ERANGE insert into t1 values(NULL); drop table t1; + +--echo # +--echo # MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD +--echo # +--source include/have_partition.inc +let $mysqld_datadir= `select @@datadir`; +--write_file $mysqld_datadir/test/load.data +1 1 +0 2 +3 3 +4 1 +0 1 +6 6 +EOF +create or replace table t1 (pk int auto_increment, x int, primary key(pk), unique key(x)) +with system versioning partition by system_time interval 2 day +(partition p1 history, partition pn current); +load data infile 'load.data' ignore into table t1; +--remove_file $mysqld_datadir/test/load.data +drop table t1; diff --git a/mysql-test/main/auto_increment_ranges_innodb.result b/mysql-test/main/auto_increment_ranges_innodb.result index 0471a5a33ba..61eccc6f944 100644 --- a/mysql-test/main/auto_increment_ranges_innodb.result +++ b/mysql-test/main/auto_increment_ranges_innodb.result @@ -264,6 +264,17 @@ delete from t1 where a=32767; insert into t1 values(NULL); ERROR 22003: Out of range value for column 'a' at row 1 drop table t1; +# +# MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD +# +create or replace table t1 (pk int auto_increment, x int, primary key(pk), unique key(x)) +with system versioning partition by system_time interval 2 day +(partition p1 history, partition pn current); +load data infile 'load.data' ignore into table t1; +Warnings: +Warning 1062 Duplicate entry '1' for key 'x' +Warning 1062 Duplicate entry '1' for key 'x' +drop table t1; create table t1 (pk int auto_increment primary key, f varchar(20)); insert t1 (f) values ('a'), ('b'), ('c'), ('d'); select null, f into outfile 'load.data' from t1 limit 1; diff --git a/mysql-test/main/auto_increment_ranges_myisam.result b/mysql-test/main/auto_increment_ranges_myisam.result index e849e980083..a300518adeb 100644 --- a/mysql-test/main/auto_increment_ranges_myisam.result +++ b/mysql-test/main/auto_increment_ranges_myisam.result @@ -270,3 +270,14 @@ delete from t1 where a=32767; insert into t1 values(NULL); ERROR 22003: Out of range value for column 'a' at row 1 drop table t1; +# +# MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD +# +create or replace table t1 (pk int auto_increment, x int, primary key(pk), unique key(x)) +with system versioning partition by system_time interval 2 day +(partition p1 history, partition pn current); +load data infile 'load.data' ignore into table t1; +Warnings: +Warning 1062 Duplicate entry '1' for key 'x' +Warning 1062 Duplicate entry '1' for key 'x' +drop table t1; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index d795502600f..0c945e5b317 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -92,6 +92,7 @@ public: bool auto_inc_initialized; mysql_mutex_t auto_inc_mutex; /**< protecting auto_inc val */ ulonglong next_auto_inc_val; /**< first non reserved value */ + ulonglong prev_auto_inc_val; /**< stored next_auto_inc_val */ /** Hash of partition names. Initialized in the first ha_partition::open() for the table_share. After that it is read-only, i.e. no locking required. @@ -103,6 +104,7 @@ public: Partition_share() : auto_inc_initialized(false), next_auto_inc_val(0), + prev_auto_inc_val(0), partition_name_hash_initialized(false), partition_names(NULL) { @@ -371,6 +373,19 @@ private: MY_BITMAP m_locked_partitions; /** Stores shared auto_increment etc. */ Partition_share *part_share; + /** Store and restore next_auto_inc_val over duplicate key errors. */ + virtual void store_auto_increment() + { + DBUG_ASSERT(part_share); + part_share->prev_auto_inc_val= part_share->next_auto_inc_val; + handler::store_auto_increment(); + } + virtual void restore_auto_increment() + { + DBUG_ASSERT(part_share); + part_share->next_auto_inc_val= part_share->prev_auto_inc_val; + handler::restore_auto_increment(); + } /** Temporary storage for new partitions Handler_shares during ALTER */ List m_new_partitions_share_refs; /** Sorted array of partition ids in descending order of number of rows. */ diff --git a/sql/handler.h b/sql/handler.h index 8a5c16dc4a7..fcaec4d5030 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3008,6 +3008,10 @@ private: */ Handler_share **ha_share; + /** Stores next_insert_id for handling duplicate key errors. */ + ulonglong m_prev_insert_id; + + public: handler(handlerton *ht_arg, TABLE_SHARE *share_arg) :table_share(share_arg), table(0), @@ -3030,7 +3034,7 @@ public: auto_inc_intervals_count(0), m_psi(NULL), set_top_table_fields(FALSE), top_table(0), top_table_field(0), top_table_fields(0), - m_lock_type(F_UNLCK), ha_share(NULL) + m_lock_type(F_UNLCK), ha_share(NULL), m_prev_insert_id(0) { DBUG_PRINT("info", ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d", @@ -3700,6 +3704,16 @@ public: insert_id_for_cur_row; } + /** Store and restore next_insert_id over duplicate key errors. */ + virtual void store_auto_increment() + { + m_prev_insert_id= next_insert_id; + } + virtual void restore_auto_increment() + { + restore_auto_increment(m_prev_insert_id); + } + virtual void update_create_info(HA_CREATE_INFO *create_info) {} int check_old_types(); virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index dc8ee19b1e1..59cc88f9db3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1691,7 +1691,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) int error, trg_error= 0; char *key=0; MY_BITMAP *save_read_set, *save_write_set; - ulonglong prev_insert_id= table->file->next_insert_id; + table->file->store_auto_increment(); ulonglong insert_id_for_cur_row= 0; ulonglong prev_insert_id_for_cur_row= 0; DBUG_ENTER("write_record"); @@ -1844,7 +1844,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (res == VIEW_CHECK_ERROR) goto before_trg_err; - table->file->restore_auto_increment(prev_insert_id); + table->file->restore_auto_increment(); info->touched++; if (different_records) { @@ -2038,7 +2038,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (!(thd->variables.old_behavior & OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) table->file->print_error(error, MYF(ME_JUST_WARNING)); - table->file->restore_auto_increment(prev_insert_id); + table->file->restore_auto_increment(); goto ok_or_after_trg_err; } @@ -2061,7 +2061,7 @@ err: table->file->print_error(error,MYF(0)); before_trg_err: - table->file->restore_auto_increment(prev_insert_id); + table->file->restore_auto_increment(); if (key) my_safe_afree(key, table->s->max_unique_length); table->column_bitmaps_set(save_read_set, save_write_set); From 726b1998fc9a97a8b2e58fe56668d570c4a01891 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 10 Oct 2019 10:25:32 +0300 Subject: [PATCH 07/13] Fixed feedback_plugin_load to work with staticly loaded plugin --- mysql-test/suite/plugins/t/feedback_plugin_load.test | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/plugins/t/feedback_plugin_load.test b/mysql-test/suite/plugins/t/feedback_plugin_load.test index 1f9f837308b..c0546cef0f9 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_load.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_load.test @@ -1,4 +1,8 @@ -if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'feedback' and plugin_status='active' and @@feedback_url <> ""`) +if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'feedback' and plugin_status='active'`) +{ + --skip Feedback plugin is not active +} +if (`select @@feedback_url = ""`) { --skip Feedback plugin is not active } From cb3f856ecdcaa2f63f51762f36226869ff08738f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 10 Oct 2019 10:36:11 +0300 Subject: [PATCH 08/13] Fix compiler error when using -Wconversion. /mariadb/10.3/wsrep/wsrep_gtid.c:45:26: error: conversion from 'long int' to 'unsigned int' may change value [-Werror=conversion] 45 | offset = endptr - str; --- wsrep/wsrep_gtid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsrep/wsrep_gtid.c b/wsrep/wsrep_gtid.c index bf5cab06585..fc87275f4ff 100644 --- a/wsrep/wsrep_gtid.c +++ b/wsrep/wsrep_gtid.c @@ -42,7 +42,7 @@ wsrep_gtid_scan(const char* str, size_t str_len, wsrep_gtid_t* gtid) gtid->seqno = strtoll(str + offset, &endptr, 0); if (errno == 0) { - offset = endptr - str; + offset = (unsigned int)(endptr - str); return offset; } } From 3c78d1b640f545025235bf52a0bde987817c3685 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 10 Oct 2019 11:08:31 +0300 Subject: [PATCH 09/13] Fix Mroonga compilation Fixed warnings: -Woverloaded-virtual, -Winconsistent-missing-override Caused by c9cba59749e1b5a39a9e3a0a5b8bd762507245f9 --- sql/handler.h | 2 +- storage/mroonga/ha_mroonga.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/handler.h b/sql/handler.h index fcaec4d5030..345e0bc1f00 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3688,7 +3688,7 @@ public: DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id)); next_insert_id= id; } - void restore_auto_increment(ulonglong prev_insert_id) + virtual void restore_auto_increment(ulonglong prev_insert_id) { /* Insertion of a row failed, re-use the lastly generated auto_increment diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index 7347af25bdc..f2fb2bfe8e7 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -571,7 +571,7 @@ public: void set_next_insert_id(ulonglong id); void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong *first_value, ulonglong *nb_reserved_values) mrn_override; - void restore_auto_increment(ulonglong prev_insert_id); + void restore_auto_increment(ulonglong prev_insert_id) mrn_override; void release_auto_increment() mrn_override; int check_for_upgrade(HA_CHECK_OPT *check_opt) mrn_override; #ifdef MRN_HANDLER_HAVE_RESET_AUTO_INCREMENT From 545c5452063ec9fc8a2f770512002f6c67c96770 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 10 Oct 2019 13:35:32 +0300 Subject: [PATCH 10/13] Fix compilation 2 (GCC 9) Fixed warning: -Woverloaded-virtual for GCC 9 (Clang treats it differently) Caused by c9cba59749e1b5a39a9e3a0a5b8bd762507245f9 --- sql/ha_partition.h | 5 +++++ storage/mroonga/ha_mroonga.hpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 0c945e5b317..d48947822b9 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -373,6 +373,11 @@ private: MY_BITMAP m_locked_partitions; /** Stores shared auto_increment etc. */ Partition_share *part_share; + /** Fix spurious -Werror=overloaded-virtual in GCC 9 */ + virtual void restore_auto_increment(ulonglong prev_insert_id) + { + handler::restore_auto_increment(prev_insert_id); + } /** Store and restore next_auto_inc_val over duplicate key errors. */ virtual void store_auto_increment() { diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index f2fb2bfe8e7..e1dbb63178e 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -571,6 +571,11 @@ public: void set_next_insert_id(ulonglong id); void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong *first_value, ulonglong *nb_reserved_values) mrn_override; + /** Fix spurious -Werror=overloaded-virtual in GCC 9 */ + void restore_auto_increment() mrn_override + { + handler::restore_auto_increment(); + } void restore_auto_increment(ulonglong prev_insert_id) mrn_override; void release_auto_increment() mrn_override; int check_for_upgrade(HA_CHECK_OPT *check_opt) mrn_override; From 6d7a8269532f4989b1515f259120e91019a74dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Oct 2019 20:29:30 +0300 Subject: [PATCH 11/13] MDEV-20788: Bogus assertion failure for PAGE_FREE list In MDEV-11369 (instant ADD COLUMN) in MariaDB Server 10.3, we introduced the hidden metadata record that must be the first record in the clustered index if and only if index->is_instant() holds. To catch MDEV-19783, in commit ed0793e096a17955c5a03844b248bcf8303dd335 and commit 99dc40d6ac2234fa4c990665cc1914c1925cd641 we added some assertions to find cases where the metadata record is missing while it should not be, or a record exists when it should not. Those assertions were invalid when traversing the PAGE_FREE list. That list can contain anything; we must only be able to determine the successor and the size of each garbage record in it. page_validate(), page_simple_validate_old(), page_simple_validate_new(): Do not invoke page_rec_get_next_const() for traversing the PAGE_FREE list, but instead use a lower-level accessor that does not attempt to validate the REC_INFO_MIN_REC_FLAG. page_copy_rec_list_end_no_locks(), page_copy_rec_list_start(), page_delete_rec_list_start(): Add assertions. btr_page_get_split_rec_to_left(): Remove a redundant return value, and make the output parameter the return value. btr_page_get_split_rec_to_right(), btr_page_split_and_insert(): Clean up. --- storage/innobase/btr/btr0btr.cc | 208 +++++++++++------------------ storage/innobase/btr/btr0cur.cc | 2 +- storage/innobase/include/btr0btr.h | 40 +++--- storage/innobase/page/page0page.cc | 73 +++++++--- 4 files changed, 148 insertions(+), 175 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 473e4248656..212b6489f29 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2030,104 +2030,78 @@ btr_root_raise_and_insert( } } -/*************************************************************//** -Decides if the page should be split at the convergence point of inserts +/** Decide if the page should be split at the convergence point of inserts converging to the left. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_left( -/*===========================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec) /*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple to be inserted should - be first */ +@param[in] cursor insert position +@return the first record to be moved to the right half page +@retval NULL if no split is recommended */ +rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor) { - page_t* page; - rec_t* insert_point; - rec_t* infimum; - - page = btr_cur_get_page(cursor); - insert_point = btr_cur_get_rec(cursor); + rec_t* split_rec = btr_cur_get_rec(cursor); + const page_t* page = page_align(split_rec); if (page_header_get_ptr(page, PAGE_LAST_INSERT) - == page_rec_get_next(insert_point)) { - - infimum = page_get_infimum_rec(page); - - /* If the convergence is in the middle of a page, include also - the record immediately before the new insert to the upper - page. Otherwise, we could repeatedly move from page to page - lots of records smaller than the convergence point. */ - - if (infimum != insert_point - && page_rec_get_next(infimum) != insert_point) { - - *split_rec = insert_point; - } else { - *split_rec = page_rec_get_next(insert_point); - } - - return(TRUE); + != page_rec_get_next(split_rec)) { + return NULL; } - return(FALSE); + const rec_t* infimum = page_get_infimum_rec(page); + + /* If the convergence is in the middle of a page, include also + the record immediately before the new insert to the upper + page. Otherwise, we could repeatedly move from page to page + lots of records smaller than the convergence point. */ + + if (split_rec == infimum + || split_rec == page_rec_get_next_const(infimum)) { + split_rec = page_rec_get_next(split_rec); + } + + return split_rec; } -/*************************************************************//** -Decides if the page should be split at the convergence point of inserts +/** Decide if the page should be split at the convergence point of inserts converging to the right. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_right( -/*============================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec) /*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple to be inserted should - be first */ +@param[in] cursor insert position +@param[out] split_rec if split recommended, the first record + on the right half page, or + NULL if the to-be-inserted record + should be first +@return whether split is recommended */ +bool +btr_page_get_split_rec_to_right(const btr_cur_t* cursor, rec_t** split_rec) { - page_t* page; - rec_t* insert_point; - - page = btr_cur_get_page(cursor); - insert_point = btr_cur_get_rec(cursor); + rec_t* insert_point = btr_cur_get_rec(cursor); + const page_t* page = page_align(insert_point); /* We use eager heuristics: if the new insert would be right after the previous insert on the same page, we assume that there is a pattern of sequential inserts here. */ - if (page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point) { - - rec_t* next_rec; - - next_rec = page_rec_get_next(insert_point); - - if (page_rec_is_supremum(next_rec)) { -split_at_new: - /* Split at the new record to insert */ - *split_rec = NULL; - } else { - rec_t* next_next_rec = page_rec_get_next(next_rec); - if (page_rec_is_supremum(next_next_rec)) { - - goto split_at_new; - } - - /* If there are >= 2 user records up from the insert - point, split all but 1 off. We want to keep one because - then sequential inserts can use the adaptive hash - index, as they can do the necessary checks of the right - search position just by looking at the records on this - page. */ - - *split_rec = next_next_rec; - } - - return(TRUE); + if (page_header_get_ptr(page, PAGE_LAST_INSERT) != insert_point) { + return false; } - return(FALSE); + insert_point = page_rec_get_next(insert_point); + + if (page_rec_is_supremum(insert_point)) { + insert_point = NULL; + } else { + insert_point = page_rec_get_next(insert_point); + if (page_rec_is_supremum(insert_point)) { + insert_point = NULL; + } + + /* If there are >= 2 user records up from the insert + point, split all but 1 off. We want to keep one because + then sequential inserts can use the adaptive hash + index, as they can do the necessary checks of the right + search position just by looking at the records on this + page. */ + } + + *split_rec = insert_point; + return true; } /*************************************************************//** @@ -2782,30 +2756,20 @@ btr_page_split_and_insert( buf_block_t* block; page_t* page; page_zip_des_t* page_zip; - ulint page_no; - byte direction; - ulint hint_page_no; buf_block_t* new_block; page_t* new_page; page_zip_des_t* new_page_zip; rec_t* split_rec; buf_block_t* left_block; buf_block_t* right_block; - buf_block_t* insert_block; page_cur_t* page_cursor; rec_t* first_rec; byte* buf = 0; /* remove warning */ rec_t* move_limit; - ibool insert_will_fit; - ibool insert_left; ulint n_iterations = 0; - rec_t* rec; ulint n_uniq; - dict_index_t* index; - index = btr_cur_get_index(cursor); - - if (dict_index_is_spatial(index)) { + if (dict_index_is_spatial(cursor->index)) { /* Split rtree page and update parent */ return(rtr_page_split_and_insert(flags, cursor, offsets, heap, tuple, n_ext, mtr)); @@ -2837,23 +2801,19 @@ func_start: ut_ad(!page_is_empty(page)); /* try to insert to the next page if possible before split */ - rec = btr_insert_into_right_sibling( - flags, cursor, offsets, *heap, tuple, n_ext, mtr); - - if (rec != NULL) { + if (rec_t* rec = btr_insert_into_right_sibling( + flags, cursor, offsets, *heap, tuple, n_ext, mtr)) { return(rec); } - page_no = block->page.id.page_no(); - /* 1. Decide the split record; split_rec == NULL means that the tuple to be inserted should be the first record on the upper half-page */ - insert_left = FALSE; + bool insert_left = false; + ulint hint_page_no = block->page.id.page_no() + 1; + byte direction = FSP_UP; - if (tuple != NULL && n_iterations > 0) { - direction = FSP_UP; - hint_page_no = page_no + 1; + if (tuple && n_iterations > 0) { split_rec = btr_page_get_split_rec(cursor, tuple, n_ext); if (split_rec == NULL) { @@ -2861,17 +2821,10 @@ func_start: cursor, tuple, offsets, n_uniq, heap); } } else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) { - direction = FSP_UP; - hint_page_no = page_no + 1; - - } else if (btr_page_get_split_rec_to_left(cursor, &split_rec)) { + } else if ((split_rec = btr_page_get_split_rec_to_left(cursor))) { direction = FSP_DOWN; - hint_page_no = page_no - 1; - ut_ad(split_rec); + hint_page_no -= 2; } else { - direction = FSP_UP; - hint_page_no = page_no + 1; - /* If there is only one record in the index page, we can't split the node in the middle by default. We need to determine whether the new record will be inserted @@ -2896,7 +2849,7 @@ func_start: new_block = btr_page_alloc(cursor->index, hint_page_no, direction, btr_page_get_level(page, mtr), mtr, mtr); - if (new_block == NULL && os_has_said_disk_full) { + if (!new_block) { return(NULL); } @@ -2921,12 +2874,8 @@ func_start: *offsets = rec_get_offsets(split_rec, cursor->index, *offsets, page_is_leaf(page), n_uniq, heap); - if (tuple != NULL) { - insert_left = cmp_dtuple_rec( - tuple, split_rec, *offsets) < 0; - } else { - insert_left = 1; - } + insert_left = !tuple + || cmp_dtuple_rec(tuple, split_rec, *offsets) < 0; if (!insert_left && new_page_zip && n_iterations > 0) { /* If a compressed page has already been split, @@ -2961,10 +2910,10 @@ insert_empty: on the appropriate half-page, we may release the tree x-latch. We can then move the records after releasing the tree latch, thus reducing the tree latch contention. */ + bool insert_will_fit; if (tuple == NULL) { - insert_will_fit = 1; - } - else if (split_rec) { + insert_will_fit = true; + } else if (split_rec) { insert_will_fit = !new_page_zip && btr_page_insert_fits(cursor, split_rec, offsets, tuple, n_ext, heap); @@ -3069,8 +3018,6 @@ insert_empty: new_block, block, move_limit); } - ut_ad(!dict_index_is_spatial(index)); - btr_search_move_or_delete_hash_entries( new_block, block, cursor->index); @@ -3102,18 +3049,15 @@ insert_empty: /* 6. The split and the tree modification is now completed. Decide the page where the tuple should be inserted */ + rec_t* rec; + buf_block_t* const insert_block = insert_left + ? left_block : right_block; - if (tuple == NULL) { + if (UNIV_UNLIKELY(!tuple)) { rec = NULL; goto func_exit; } - if (insert_left) { - insert_block = left_block; - } else { - insert_block = right_block; - } - /* 7. Reposition the cursor for insert and try insertion */ page_cursor = btr_cur_get_page_cur(cursor); @@ -3190,9 +3134,7 @@ func_exit: ut_ad(page_validate(buf_block_get_frame(left_block), cursor->index)); ut_ad(page_validate(buf_block_get_frame(right_block), cursor->index)); - if (tuple == NULL) { - ut_ad(rec == NULL); - } + ut_ad(tuple || !rec); ut_ad(!rec || rec_offs_validate(rec, cursor->index, *offsets)); return(rec); } diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 3060865bc8e..788b34bca62 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -3138,7 +3138,7 @@ fail_err: && page_get_n_recs(page) >= 2 && dict_index_get_space_reserve() + rec_size > max_size && (btr_page_get_split_rec_to_right(cursor, &dummy) - || btr_page_get_split_rec_to_left(cursor, &dummy))) { + || btr_page_get_split_rec_to_left(cursor))) { goto fail; } diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index 604890ed03c..ded01e53bad 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -445,30 +445,22 @@ btr_page_reorganize( dict_index_t* index, /*!< in: the index tree of the page */ mtr_t* mtr) /*!< in/out: mini-transaction */ MY_ATTRIBUTE((nonnull)); -/*************************************************************//** -Decides if the page should be split at the convergence point of -inserts converging to left. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_left( -/*===========================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec)/*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple should be first */ - MY_ATTRIBUTE((warn_unused_result)); -/*************************************************************//** -Decides if the page should be split at the convergence point of -inserts converging to right. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_right( -/*============================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec)/*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple should be first */ - MY_ATTRIBUTE((warn_unused_result)); +/** Decide if the page should be split at the convergence point of inserts +converging to the left. +@param[in] cursor insert position +@return the first record to be moved to the right half page +@retval NULL if no split is recommended */ +rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor); +/** Decide if the page should be split at the convergence point of inserts +converging to the right. +@param[in] cursor insert position +@param[out] split_rec if split recommended, the first record + on the right half page, or + NULL if the to-be-inserted record + should be first +@return whether split is recommended */ +bool +btr_page_get_split_rec_to_right(const btr_cur_t* cursor, rec_t** split_rec); /*************************************************************//** Splits an index page to halves and inserts the tuple. It is assumed diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index bda4693648b..e316c8b1568 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -604,20 +604,20 @@ page_copy_rec_list_end_no_locks( /* Copy records from the original page to the new page */ while (!page_cur_is_after_last(&cur1)) { - rec_t* cur1_rec = page_cur_get_rec(&cur1); rec_t* ins_rec; - offsets = rec_get_offsets(cur1_rec, index, offsets, is_leaf, + offsets = rec_get_offsets(cur1.rec, index, offsets, is_leaf, ULINT_UNDEFINED, &heap); ins_rec = page_cur_insert_rec_low(cur2, index, - cur1_rec, offsets, mtr); + cur1.rec, offsets, mtr); if (UNIV_UNLIKELY(!ins_rec)) { ib::fatal() << "Rec offset " << page_offset(rec) - << ", cur1 offset " - << page_offset(page_cur_get_rec(&cur1)) + << ", cur1 offset " << page_offset(cur1.rec) << ", cur2 offset " << page_offset(cur2); } page_cur_move_to_next(&cur1); + ut_ad(!(rec_get_info_bits(cur1.rec, page_is_comp(new_page)) + & REC_INFO_MIN_REC_FLAG)); cur2 = ins_rec; } @@ -803,6 +803,8 @@ page_copy_rec_list_start( dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ { + ut_ad(page_align(rec) == block->frame); + page_t* new_page = buf_block_get_frame(new_block); page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block); page_cur_t cur1; @@ -820,7 +822,6 @@ page_copy_rec_list_start( predefined infimum record. */ if (page_rec_is_infimum(rec)) { - return(ret); } @@ -854,17 +855,18 @@ page_copy_rec_list_start( rec_move, max_to_move, &num_moved, mtr); } else { - while (page_cur_get_rec(&cur1) != rec) { - rec_t* cur1_rec = page_cur_get_rec(&cur1); - offsets = rec_get_offsets(cur1_rec, index, offsets, + offsets = rec_get_offsets(cur1.rec, index, offsets, is_leaf, ULINT_UNDEFINED, &heap); cur2 = page_cur_insert_rec_low(cur2, index, - cur1_rec, offsets, mtr); + cur1.rec, offsets, mtr); ut_a(cur2); page_cur_move_to_next(&cur1); + ut_ad(!(rec_get_info_bits(cur1.rec, + page_is_comp(new_page)) + & REC_INFO_MIN_REC_FLAG)); } } @@ -1254,6 +1256,7 @@ page_delete_rec_list_start( rec_offs_init(offsets_); + ut_ad(page_align(rec) == block->frame); ut_ad((ibool) !!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); #ifdef UNIV_ZIP_DEBUG @@ -2163,7 +2166,17 @@ page_simple_validate_old( goto func_exit; } - rec = page_rec_get_next_const(rec); + ulint offs = rec_get_next_offs(rec, FALSE); + if (!offs) { + break; + } + if (UNIV_UNLIKELY(offs < PAGE_OLD_INFIMUM + || offs >= srv_page_size)) { + ib::error() << "Page free list is corrupted " << count; + goto func_exit; + } + + rec = page + offs; } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { @@ -2355,7 +2368,17 @@ page_simple_validate_new( goto func_exit; } - rec = page_rec_get_next_const(rec); + const ulint offs = rec_get_next_offs(rec, TRUE); + if (!offs) { + break; + } + if (UNIV_UNLIKELY(offs < PAGE_OLD_INFIMUM + || offs >= srv_page_size)) { + ib::error() << "Page free list is corrupted " << count; + goto func_exit; + } + + rec = page + offs; } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { @@ -2668,16 +2691,32 @@ n_owned_zero: page_is_leaf(page), ULINT_UNDEFINED, &heap); if (UNIV_UNLIKELY(!page_rec_validate(rec, offsets))) { + ret = FALSE; +next_free: + const ulint offs = rec_get_next_offs( + rec, page_is_comp(page)); + if (!offs) { + break; + } + if (UNIV_UNLIKELY(offs < PAGE_OLD_INFIMUM + || offs >= srv_page_size)) { + ib::error() << "Page free list is corrupted"; + ret = FALSE; + break; + } - goto func_exit; + rec = page + offs; + continue; } count++; offs = page_offset(rec_get_start(rec, offsets)); i = rec_offs_size(offsets); - if (UNIV_UNLIKELY(offs + i >= UNIV_PAGE_SIZE)) { - ib::error() << "Record offset out of bounds"; - goto func_exit; + if (UNIV_UNLIKELY(offs + i >= srv_page_size)) { + ib::error() << "Free record offset out of bounds: " + << offs << '+' << i; + ret = FALSE; + goto next_free; } while (i--) { @@ -2691,7 +2730,7 @@ n_owned_zero: buf[offs + i] = 1; } - rec = page_rec_get_next_const(rec); + goto next_free; } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { From 01f45becd1b71433e240959228e35266f271bba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Oct 2019 20:40:26 +0300 Subject: [PATCH 12/13] MDEV-19783: Add more assertions btr_page_get_split_rec_to_left(): Assert that in the leftmost leaf page, the metadata record exists if and only if index->is_instant(). page_validate(): Correct the wording of a message. rec_init_offsets(): Assert that whenever a record is in "instant ALTER" format, index->is_instant() must hold. --- storage/innobase/btr/btr0btr.cc | 10 +++++++++- storage/innobase/page/page0page.cc | 5 +++-- storage/innobase/rem/rem0rec.cc | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 6fb56acce14..18f34d382e6 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2062,6 +2062,14 @@ rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor) return NULL; } + /* The metadata record must be present in the leftmost leaf page + of the clustered index, if and only if index->is_instant(). */ + ut_ad(!page_is_leaf(page) || page_has_prev(page) + || cursor->index->is_instant() + == rec_is_metadata(page_rec_get_next_const( + page_get_infimum_rec(page)), + cursor->index)); + const rec_t* infimum = page_get_infimum_rec(page); /* If the convergence is in the middle of a page, include also @@ -2783,7 +2791,7 @@ btr_page_split_and_insert( ulint n_iterations = 0; ulint n_uniq; - if (dict_index_is_spatial(cursor->index)) { + if (cursor->index->is_spatial()) { /* Split rtree page and update parent */ return(rtr_page_split_and_insert(flags, cursor, offsets, heap, tuple, n_ext, mtr)); diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index d72d13f6d09..77bdbf8bf2c 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -839,7 +839,8 @@ page_copy_rec_list_start( const bool is_leaf = page_rec_is_leaf(rec); /* Copy records from the original page to the new page */ - if (dict_index_is_spatial(index)) { + if (index->is_spatial()) { + ut_ad(!index->is_instant()); ulint max_to_move = page_get_n_recs( buf_block_get_frame(block)); heap = mem_heap_create(256); @@ -2535,7 +2536,7 @@ wrong_page_type: & REC_INFO_MIN_REC_FLAG)) { if (page_has_prev(page)) { ib::error() << "REC_INFO_MIN_REC_FLAG " - "is set in on non-left page"; + "is set on non-left page"; ret = false; } else if (!page_is_leaf(page)) { /* leftmost node pointer page */ diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 11e4bff217f..8803e691498 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -600,6 +600,7 @@ rec_init_offsets( break; case REC_STATUS_COLUMNS_ADDED: ut_ad(leaf); + ut_ad(index->is_instant()); rec_init_offsets_comp_ordinary(rec, index, offsets, index->n_core_fields, NULL, @@ -741,6 +742,8 @@ resolved: } if (i < rec_offs_n_fields(offsets)) { + ut_ad(index->is_instant()); + offs = (rec_offs_base(offsets)[i] & REC_OFFS_MASK) | REC_OFFS_DEFAULT; From 4cdb72f2372b27e1fbbc573812240c1e29128c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Oct 2019 21:21:24 +0300 Subject: [PATCH 13/13] MDEV-19783: Relax an assertion btr_page_get_split_rec_to_left(): Assert that in the leftmost leaf page, if the metadata record exists, index->is_instant() must hold. The assertion of commit 01f45becd1b71433e240959228e35266f271bba1 could fail during innobase_instant_try(). --- storage/innobase/btr/btr0btr.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 18f34d382e6..ce736af2c11 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2063,12 +2063,18 @@ rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor) } /* The metadata record must be present in the leftmost leaf page - of the clustered index, if and only if index->is_instant(). */ + of the clustered index, if and only if index->is_instant(). + However, during innobase_instant_try(), index->is_instant() + would already hold when row_ins_clust_index_entry_low() + is being invoked to insert the the metadata record. + So, we can only assert that when the metadata record exists, + index->is_instant() must hold. */ ut_ad(!page_is_leaf(page) || page_has_prev(page) || cursor->index->is_instant() - == rec_is_metadata(page_rec_get_next_const( - page_get_infimum_rec(page)), - cursor->index)); + || !(rec_get_info_bits(page_rec_get_next_const( + page_get_infimum_rec(page)), + dict_table_is_comp(cursor->index->table)) + & REC_INFO_MIN_REC_FLAG)); const rec_t* infimum = page_get_infimum_rec(page);