From f080863501972af381877c6c2335b8dcf3e87830 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 3 Mar 2021 15:37:03 +0530 Subject: [PATCH 1/3] MDEV-20648 InnoDB: Failing assertion: !(*node)->being_extended, innodb.log_data_file_size failed in buildbot, assertion `!space->is_stopping()' InnoDB should check whether the tablespace is being deleted while extending the tablespace. --- storage/innobase/fil/fil0fil.cc | 40 +++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index c71dbeff421..5adbd4df69e 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1038,15 +1038,14 @@ fil_space_extend_must_retry( } -/*******************************************************************//** -Reserves the fil_system mutex and tries to make sure we can open at least one +/** Reserves the fil_system mutex and tries to make sure we can open at least one file while holding it. This should be called before calling -fil_node_prepare_for_io(), because that function may need to open a file. */ +fil_node_prepare_for_io(), because that function may need to open a file. +@param[in] space_id tablespace id +@return whether the tablespace is usable for io */ static -void -fil_mutex_enter_and_prepare_for_io( -/*===============================*/ - ulint space_id) /*!< in: space id */ +bool +fil_mutex_enter_and_prepare_for_io(ulint space_id) { for (ulint count = 0;;) { mutex_enter(&fil_system->mutex); @@ -1059,7 +1058,7 @@ fil_mutex_enter_and_prepare_for_io( fil_space_t* space = fil_space_get_by_id(space_id); if (space == NULL) { - break; + return false; } fil_node_t* node = UT_LIST_GET_LAST(space->chain); @@ -1074,6 +1073,10 @@ fil_mutex_enter_and_prepare_for_io( the insert buffer. The insert buffer is in tablespace 0, and we cannot end up waiting in this function. */ + } else if (space->is_stopping() && !space->is_being_truncated) { + /* If the tablespace is being deleted then InnoDB + shouldn't prepare the tablespace for i/o */ + return false; } else if (!node || node->is_open()) { /* If the file is already open, no need to do anything; if the space does not exist, we handle the @@ -1144,6 +1147,8 @@ fil_mutex_enter_and_prepare_for_io( break; } + + return true; } /** Try to extend a tablespace if it is smaller than the specified size. @@ -1160,7 +1165,10 @@ fil_space_extend( bool success; do { - fil_mutex_enter_and_prepare_for_io(space->id); + if (!fil_mutex_enter_and_prepare_for_io(space->id)) { + success = false; + break; + } } while (fil_space_extend_must_retry( space, UT_LIST_GET_LAST(space->chain), size, &success)); @@ -1537,7 +1545,9 @@ fil_space_t* fil_system_t::read_page0(ulint id) /* It is possible that the tablespace is dropped while we are not holding the mutex. */ - fil_mutex_enter_and_prepare_for_io(id); + if (!fil_mutex_enter_and_prepare_for_io(id)) { + return NULL; + } fil_space_t* space = fil_space_get_by_id(id); @@ -1610,14 +1620,16 @@ fil_space_get_first_path( ut_ad(fil_system); ut_a(id); - fil_mutex_enter_and_prepare_for_io(id); + if (!fil_mutex_enter_and_prepare_for_io(id)) { +fail_exit: + mutex_exit(&fil_system->mutex); + return(NULL); + } space = fil_space_get_space(id); if (space == NULL) { - mutex_exit(&fil_system->mutex); - - return(NULL); + goto fail_exit; } ut_ad(mutex_own(&fil_system->mutex)); From b044898b97729c36dd22e1133e47c92ed7c42e04 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 1 Mar 2021 21:16:13 +0530 Subject: [PATCH 2/3] MDEV-24748 extern column check missing in btr_index_rec_validate() In btr_index_rec_validate(), externally stored column check is missing while matching the length of the field with the length of the field data stored in record. Fetch the length of the externally stored part and compare it with the fixed field length. --- mysql-test/suite/innodb/r/innodb.result | 17 +++++++++++++++++ mysql-test/suite/innodb/t/innodb.test | 18 ++++++++++++++++++ storage/innobase/btr/btr0btr.cc | 12 ++++++++++++ 3 files changed, 47 insertions(+) diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index ace226781c0..326aed06901 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -3373,3 +3373,20 @@ c1 c2 9 3 DROP TABLE t1; DROP TABLE t2; +# +# MDEV-24748 Extern field check missing +# in btr_index_rec_validate() +# +CREATE TABLE t1 (pk INT, c1 char(255), +c2 char(255), c3 char(255), c4 char(255), +c5 char(255), c6 char(255), c7 char(255), +c8 char(255), primary key (pk) +) CHARACTER SET utf32 ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'), +(2, 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'); +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +ALTER TABLE t1 FORCE; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index 7aa146d7d99..d494f40bcb6 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -2628,3 +2628,21 @@ SELECT * FROM t2; DROP TABLE t1; DROP TABLE t2; + +--echo # +--echo # MDEV-24748 Extern field check missing +--echo # in btr_index_rec_validate() +--echo # +CREATE TABLE t1 (pk INT, c1 char(255), +c2 char(255), c3 char(255), c4 char(255), +c5 char(255), c6 char(255), c7 char(255), +c8 char(255), primary key (pk) +) CHARACTER SET utf32 ENGINE=InnoDB; + +INSERT INTO t1 VALUES + (1, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'), + (2, 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'); +CHECK TABLE t1; +ALTER TABLE t1 FORCE; +# Cleanup +DROP TABLE t1; diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 511ac66d58c..f7fe4413086 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -4519,6 +4519,18 @@ btr_index_rec_validate( rec_get_nth_field_offs(offsets, i, &len); + if (rec_offs_nth_extern(offsets, i)) { + + const byte* data = rec_get_nth_field( + rec, offsets, i, &len); + len -= BTR_EXTERN_FIELD_REF_SIZE; + ulint extern_len = mach_read_from_4( + data + len + BTR_EXTERN_LEN + 4); + if (fixed_size == extern_len) { + continue; + } + } + /* Note that if fixed_size != 0, it equals the length of a fixed-size column in the clustered index. We should adjust it here. From 5da6ffe22772897a55b1293f0f054b299e4bf539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Tue, 2 Mar 2021 15:37:12 +0200 Subject: [PATCH 3/3] MDEV-25032: Window functions without column references get removed from ORDER BY row_number() over () window function can be used without any column in the OVER clause. Additionally, the item doesn't reference any tables, as it's not effectively referencing any table. Rather it is specifically built based on the end temporary table used for window function computation. This caused remove_const function to wrongly drop it from the ORDER list. Effectively, we shouldn't be dropping any window function from the ORDER clause, so adjust remove_const to account for that. Reviewed by: Sergei Petrunia sergey@mariadb.com --- mysql-test/r/win.result | 26 +++++++++++++++++++ .../encryption/r/tempfiles_encrypted.result | 26 +++++++++++++++++++ mysql-test/t/win.test | 20 ++++++++++++++ sql/sql_select.cc | 1 + 4 files changed, 73 insertions(+) diff --git a/mysql-test/r/win.result b/mysql-test/r/win.result index 3023a86eaad..dd74c5c77fd 100644 --- a/mysql-test/r/win.result +++ b/mysql-test/r/win.result @@ -3866,5 +3866,31 @@ NULL DROP VIEW v1; DROP TABLE t1,t2; # +# MDEV-25032 Window functions without column references get removed from ORDER BY +# +create table t1 (id int, score double); +insert into t1 values +(1, 5), +(1, 6), +(1, 6), +(1, 6), +(1, 7), +(1, 8.1), +(1, 9), +(1, 10); +select id, row_number() over () rn +from t1 +order by rn desc; +id rn +1 8 +1 7 +1 6 +1 5 +1 4 +1 3 +1 2 +1 1 +drop table t1; +# # End of 10.2 tests # diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index 1856c30a36b..27eedc45028 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -3872,6 +3872,32 @@ NULL DROP VIEW v1; DROP TABLE t1,t2; # +# MDEV-25032 Window functions without column references get removed from ORDER BY +# +create table t1 (id int, score double); +insert into t1 values +(1, 5), +(1, 6), +(1, 6), +(1, 6), +(1, 7), +(1, 8.1), +(1, 9), +(1, 10); +select id, row_number() over () rn +from t1 +order by rn desc; +id rn +1 8 +1 7 +1 6 +1 5 +1 4 +1 3 +1 2 +1 1 +drop table t1; +# # End of 10.2 tests # # diff --git a/mysql-test/t/win.test b/mysql-test/t/win.test index c7e3dac598b..57214ab0165 100644 --- a/mysql-test/t/win.test +++ b/mysql-test/t/win.test @@ -2522,6 +2522,26 @@ SELECT NTH_VALUE(i1, i1) OVER (PARTITION BY i1) FROM v1; DROP VIEW v1; DROP TABLE t1,t2; +--echo # +--echo # MDEV-25032 Window functions without column references get removed from ORDER BY +--echo # + +create table t1 (id int, score double); +insert into t1 values +(1, 5), +(1, 6), +(1, 6), +(1, 6), +(1, 7), +(1, 8.1), +(1, 9), +(1, 10); +select id, row_number() over () rn +from t1 +order by rn desc; + +drop table t1; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f30ce088bc4..7bfbf719017 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12671,6 +12671,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, { table_map order_tables=order->item[0]->used_tables(); if (order->item[0]->with_sum_func || + order->item[0]->with_window_func || /* If the outer table of an outer join is const (either by itself or after applying WHERE condition), grouping on a field from such a