From fda5846704ec9218b78ed5ed06f58b7391369a1a Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 8 Nov 2022 15:49:52 +0000 Subject: MDEV-29397 CONNECT engine: Fix note turning into error (#2325) * MDEV-29397 Fix note turning into error ODBC Rewind triggered an error with no SQL, but this is sometimes a valid condition (as can be seen with other classes). Setting this to a 0 return stops errors firing when they shouldn't. Also fixes ASAN hits from in MDEV-29687 tabext.cpp. --- storage/connect/mysql-test/connect/r/odbc_postgresql.result | 9 +++++++++ storage/connect/mysql-test/connect/t/odbc_postgresql.test | 9 +++++++++ storage/connect/odbconn.cpp | 2 +- storage/connect/tabext.cpp | 4 ++-- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/storage/connect/mysql-test/connect/r/odbc_postgresql.result b/storage/connect/mysql-test/connect/r/odbc_postgresql.result index 6bd8d75a601..9ecb66307e6 100644 --- a/storage/connect/mysql-test/connect/r/odbc_postgresql.result +++ b/storage/connect/mysql-test/connect/r/odbc_postgresql.result @@ -319,3 +319,12 @@ SELECT * from pg_in_maria; my space column My value DROP TABLE pg_in_maria; +# +# MDEV-29397 UPDATE with WHERE on part of two-part primary key causes +# info to turn into error. +# +CREATE TABLE t1 (a VARCHAR(6), b VARCHAR(6), PRIMARY KEY(a, b)) ENGINE=CONNECT TABNAME='schema1.t3' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr'; +UPDATE t1 SET a='10' WHERE a='20'; +Warnings: +Note 1105 schema1.t3: 0 affected rows +DROP TABLE t1; diff --git a/storage/connect/mysql-test/connect/t/odbc_postgresql.test b/storage/connect/mysql-test/connect/t/odbc_postgresql.test index ec98453d630..187bec55b38 100644 --- a/storage/connect/mysql-test/connect/t/odbc_postgresql.test +++ b/storage/connect/mysql-test/connect/t/odbc_postgresql.test @@ -223,3 +223,12 @@ DROP TABLE t1; CREATE TABLE pg_in_maria ENGINE=CONNECT TABNAME='schema1.space_in_column_name' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' quoted=1; SELECT * from pg_in_maria; DROP TABLE pg_in_maria; + +--echo # +--echo # MDEV-29397 UPDATE with WHERE on part of two-part primary key causes +--echo # info to turn into error. +--echo # +CREATE TABLE t1 (a VARCHAR(6), b VARCHAR(6), PRIMARY KEY(a, b)) ENGINE=CONNECT TABNAME='schema1.t3' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr'; +UPDATE t1 SET a='10' WHERE a='20'; +DROP TABLE t1; + diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 33c2b0aaf70..e83f1b5f04c 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -2582,7 +2582,7 @@ int ODBConn::Rewind(char *sql, ODBCCOL *tocols) int rc, rbuf = -1; if (!m_hstmt) - rbuf = -1; + rbuf = 0; else if (m_Full) rbuf = m_Rows; // No need to "rewind" else if (m_Scrollable) { diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp index 95725dfc44b..d1b94c81c11 100644 --- a/storage/connect/tabext.cpp +++ b/storage/connect/tabext.cpp @@ -473,7 +473,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) my_len= res - buf + 1; my_schema_table= (char *) malloc(my_len); memcpy(my_schema_table, buf, my_len - 1); - my_schema_table[my_len] = 0; + my_schema_table[my_len - 1] = 0; Query->Append(Quote); Query->Append(my_schema_table); Query->Append(Quote); @@ -481,7 +481,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) Query->Append("."); // Parse table my_len= strlen(buf) - my_len + 1; - my_schema_table= (char *) malloc(my_len); + my_schema_table= (char *) malloc(my_len + 1); memcpy(my_schema_table, ++res, my_len); my_schema_table[my_len] = 0; Query->Append(Quote); -- cgit v1.2.1 From 6b91792a087a4c356584a6f1fa8e7d9809a1d58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Nov 2022 09:23:18 +0200 Subject: MDEV-29883 Deadlock between InnoDB statistics update and BLOB insert This is a backport of commit 8b6a308e463f937eb8d2498b04967a222c83af90 from MariaDB Server 10.6.11. No attempt to reproduce the hang in earlier an earlier version of MariaDB Server than 10.6 was made. In each caller of fseg_n_reserved_pages() except ibuf_init_at_db_start() which is a special case for ibuf.index at database startup, we must hold an index latch that prevents concurrent allocation or freeing of index pages. Any operation that allocates or free pages that belong to an index tree must first acquire an index latch in non-shared mode, and while holding that, acquire an index root page latch in non-shared mode. btr_get_size(), btr_get_size_and_reserved(): Assert that a strong enough index latch is being held. dict_stats_update_transient_for_index(), dict_stats_analyze_index(): Acquire a strong enough index latch. These operations had followed the same order of acquiring latches in every InnoDB version since the very beginning (commit c533308a158795f91247e9fe3c7304fa5e7d2b3c). The hang was introduced in commit 2e814d4702d71a04388386a9f591d14a35980bfe which imported mysql/mysql-server@ac74632293bea967b352d1b472abedeeaa921b98 which failed to strengthen the locking requirements of the function btr_get_size(). --- storage/innobase/btr/btr0btr.cc | 4 ++-- storage/innobase/dict/dict0defrag_bg.cc | 4 ++-- storage/innobase/dict/dict0stats.cc | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index f041e35e501..6b575885f81 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -603,7 +603,7 @@ btr_get_size( ut_ad(srv_read_only_mode || mtr_memo_contains(mtr, dict_index_get_lock(index), - MTR_MEMO_S_LOCK)); + MTR_MEMO_SX_LOCK)); if (index->page == FIL_NULL || dict_index_is_online_ddl(index) @@ -657,7 +657,7 @@ btr_get_size_and_reserved( ulint dummy; ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), - MTR_MEMO_S_LOCK)); + MTR_MEMO_SX_LOCK)); ut_a(flag == BTR_N_LEAF_PAGES || flag == BTR_TOTAL_SIZE); diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 7c6f5d75b5d..9cc23a89c1b 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -282,7 +282,7 @@ dict_stats_save_defrag_stats( ulint n_leaf_pages; ulint n_leaf_reserved; mtr.start(); - mtr_s_lock_index(index, &mtr); + mtr_sx_lock_index(index, &mtr); n_leaf_reserved = btr_get_size_and_reserved(index, BTR_N_LEAF_PAGES, &n_leaf_pages, &mtr); mtr.commit(); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index e36e2184e2d..b74edee5669 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2009, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2021, MariaDB Corporation. +Copyright (c) 2015, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -852,7 +852,7 @@ dict_stats_update_transient_for_index( ulint size; mtr.start(); - mtr_s_lock_index(index, &mtr); + mtr_sx_lock_index(index, &mtr); size = btr_get_size(index, BTR_TOTAL_SIZE, &mtr); if (size != ULINT_UNDEFINED) { @@ -1945,7 +1945,7 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) DEBUG_PRINTF(" %s(index=%s)\n", __func__, index->name()); mtr.start(); - mtr_s_lock_index(index, &mtr); + mtr_sx_lock_index(index, &mtr); size = btr_get_size(index, BTR_TOTAL_SIZE, &mtr); if (size != ULINT_UNDEFINED) { -- cgit v1.2.1