diff --git a/router/tests/component/test_bootstrap.cc b/router/tests/component/test_bootstrap.cc index ed09865d8916..3c20eb116301 100644 --- a/router/tests/component/test_bootstrap.cc +++ b/router/tests/component/test_bootstrap.cc @@ -687,8 +687,8 @@ TEST_F(RouterBootstrapTest, BootstrapFailWhenServerResponseExceedsReadTimeout) { "-d", bootstrap_dir.name(), "--connect-timeout=1", "--read-timeout=1"}; bootstrap_failover(mock_servers, router_options, EXIT_FAILURE, - {"Error: Error executing MySQL query: Lost connection to " - "MySQL server during query \\(2013\\)"}); + {"Error: Error executing MySQL query: Read timeout is " + "reached \\(2066\\)"}); } class RouterAccountHostTest : public CommonBootstrapTest {}; diff --git a/sql/mdl.cc b/sql/mdl.cc index de9e3e10af8c..ce9c93590583 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1468,7 +1468,8 @@ MDL_context::MDL_context() m_force_dml_deadlock_weight(false), m_waiting_for(NULL), m_pins(NULL), - m_rand_state(UINT_MAX32) { + m_rand_state(UINT_MAX32), + m_ignore_owner_thd(false) { mysql_prlock_init(key_MDL_context_LOCK_waiting_for, &m_LOCK_waiting_for); } @@ -3350,7 +3351,8 @@ void MDL_lock::object_lock_notify_conflicting_locks(MDL_context *ctx, if (conflicting_ticket->get_ctx() != ctx && (conflicting_ticket->get_type() == MDL_SHARED || conflicting_ticket->get_type() == MDL_SHARED_HIGH_PRIO) && - conflicting_ticket->get_ctx()->get_owner()->get_thd() != nullptr) { + (conflicting_ticket->get_ctx()->get_owner()->get_thd() != nullptr || + ctx->get_ignore_owner_thd())) { MDL_context *conflicting_ctx = conflicting_ticket->get_ctx(); /* @@ -3524,16 +3526,18 @@ bool MDL_context::acquire_lock_nsec(MDL_request *mdl_request, */ enum_mdl_type kill_conflicting_locks_lower_than = MDL_INTENTION_EXCLUSIVE; bool kill_conflicting_connections_after_timeout_and_retry = false; - if ((thd->variables.high_priority_ddl || - (thd->slave_thread && slave_high_priority_ddl)) && - ticket->get_type() >= MDL_SHARED_NO_WRITE) { - kill_conflicting_connections_after_timeout_and_retry = true; - /* Use MDL_SHARED_NO_WRITE to kill "lock tables read" connection */ - kill_conflicting_locks_lower_than = MDL_SHARED_NO_WRITE; - } - if (thd->variables.kill_conflicting_connections) { - kill_conflicting_connections_after_timeout_and_retry = true; - kill_conflicting_locks_lower_than = MDL_TYPE_END; + if (thd != nullptr) { + if ((thd->variables.high_priority_ddl || + (thd->slave_thread && slave_high_priority_ddl)) && + ticket->get_type() >= MDL_SHARED_NO_WRITE) { + kill_conflicting_connections_after_timeout_and_retry = true; + /* Use MDL_SHARED_NO_WRITE to kill "lock tables read" connection */ + kill_conflicting_locks_lower_than = MDL_SHARED_NO_WRITE; + } + if (thd->variables.kill_conflicting_connections) { + kill_conflicting_connections_after_timeout_and_retry = true; + kill_conflicting_locks_lower_than = MDL_TYPE_END; + } } /* do not set status on timeout if we are going to retry */ bool set_status_on_timeout = diff --git a/sql/mdl.h b/sql/mdl.h index 930af28c590d..8a1349982ca8 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -1657,6 +1657,14 @@ class MDL_context { */ uint m_rand_state; + /** + MDL_lock::object_lock_notify_conflicting_locks() checks THD of + conflicting lock on nullptr value and doesn't call the virtual + method MDL_context_owner::notify_shared_lock() in case condition + satisfied. This field allows unit tests to work with THD set to nullptr. + */ + bool m_ignore_owner_thd; + private: MDL_ticket *find_ticket(MDL_request *mdl_req, enum_mdl_duration *duration); void release_locks_stored_before(enum_mdl_duration duration, @@ -1698,6 +1706,10 @@ class MDL_context { } void lock_deadlock_victim() { mysql_prlock_rdlock(&m_LOCK_waiting_for); } void unlock_deadlock_victim() { mysql_prlock_unlock(&m_LOCK_waiting_for); } + void set_ignore_owner_thd(bool ignore_owner_thd) { + m_ignore_owner_thd = ignore_owner_thd; + } + bool get_ignore_owner_thd() { return m_ignore_owner_thd; } private: MDL_context(const MDL_context &rhs); /* not implemented */ diff --git a/unittest/gunit/mdl-t.cc b/unittest/gunit/mdl-t.cc index f6e1bf4341b8..db3f10ac9949 100644 --- a/unittest/gunit/mdl-t.cc +++ b/unittest/gunit/mdl-t.cc @@ -112,6 +112,7 @@ class MDLTest : public ::testing::Test, public Test_MDL_context_owner { max_write_lock_count = ULONG_MAX; mdl_init(); m_mdl_context.init(this); + m_mdl_context.set_ignore_owner_thd(true); EXPECT_FALSE(m_mdl_context.has_locks()); m_charset = system_charset_info; system_charset_info = &my_charset_utf8_bin; @@ -2181,6 +2182,7 @@ TEST_F(MDLTest, NotifyScenarios) { /* Acquire S lock which will be granted using "fast path". */ mdl_thread1.enable_release_on_notify(); mdl_thread1.start(); + mdl_thread1.get_mdl_context().set_ignore_owner_thd(true); first_shared_grabbed.wait_for_notification(); /* @@ -2195,6 +2197,7 @@ TEST_F(MDLTest, NotifyScenarios) { should be successfully granted after that. */ mdl_thread2.start(); + mdl_thread2.get_mdl_context().set_ignore_owner_thd(true); first_shared_released.wait_for_notification(); first_exclusive_grabbed.wait_for_notification(); @@ -2222,6 +2225,7 @@ TEST_F(MDLTest, NotifyScenarios) { mdl_thread3.enable_release_on_notify(); /* Acquire S lock which will be granted using "fast path". */ mdl_thread3.start(); + mdl_thread3.get_mdl_context().set_ignore_owner_thd(true); second_shared_grabbed.wait_for_notification(); /* @@ -2230,6 +2234,7 @@ TEST_F(MDLTest, NotifyScenarios) { should be successfully granted after that. */ mdl_thread4.start(); + mdl_thread4.get_mdl_context().set_ignore_owner_thd(true); second_shared_released.wait_for_notification(); second_exclusive_grabbed.wait_for_notification(); diff --git a/unittest/gunit/mysys_pathfuncs-t.cc b/unittest/gunit/mysys_pathfuncs-t.cc index c473ab9724b9..4511a9271706 100644 --- a/unittest/gunit/mysys_pathfuncs-t.cc +++ b/unittest/gunit/mysys_pathfuncs-t.cc @@ -152,7 +152,7 @@ TEST(Mysys, CreateTempFile) { File fileno = create_temp_file(dst, "/tmp", prefix, 42, UNLINK_FILE, 0); EXPECT_GE(fileno, 0); my_close(fileno, 0); - EXPECT_THAT(dst, MatchesRegex("/tmp/[a]+fd=[0-9]+")); + EXPECT_THAT(dst, MatchesRegex("/tmp/[a]+[a-z0-9=]+")); aset(dst, 0xaa); char *env_tmpdir = getenv("TMPDIR"); diff --git a/unittest/gunit/parsertest.h b/unittest/gunit/parsertest.h index 0b677dc8e71b..215e47bdbcfd 100644 --- a/unittest/gunit/parsertest.h +++ b/unittest/gunit/parsertest.h @@ -75,7 +75,7 @@ class ParserTest : public ::testing::Test { static_cast(my_malloc(PSI_NOT_INSTRUMENTED, 3, MYF(0))); sprintf(db, "db"); LEX_CSTRING db_lex_cstr = {db, strlen(db)}; - thd()->reset_db(db_lex_cstr); + thd()->reset_db(db_lex_cstr, /* lock_held_skip_metadata */ true); } lex_start(thd()); diff --git a/unittest/gunit/test_mdl_context_owner.h b/unittest/gunit/test_mdl_context_owner.h index 415516472f24..6319d2fe74ae 100644 --- a/unittest/gunit/test_mdl_context_owner.h +++ b/unittest/gunit/test_mdl_context_owner.h @@ -37,15 +37,7 @@ class Test_MDL_context_owner : public MDL_context_owner { virtual int is_killed() const final { return 0; } virtual bool is_connected() { return true; } - virtual THD *get_thd() { - /* - MDL_lock::object_lock_notify_conflicting_locks() checks THD of - conflicting lock on nullptr value and doesn't call the virtual - method MDL_context_owner::notify_shared_lock() in case condition - satisfied. To workaround it return the value 1 casted to THD*. - */ - return (THD *)1; - } + virtual THD *get_thd() { return nullptr; } virtual bool notify_hton_pre_acquire_exclusive(const MDL_key *, bool *) { return false;