Commit 6f314eda authored by Marko Mäkelä's avatar Marko Mäkelä Committed by Vladislav Vaintroub

MDEV-14648 Restore fix for MySQL BUG#39053 - UNINSTALL PLUGIN does not allow...

MDEV-14648 Restore fix for MySQL BUG#39053 - UNINSTALL PLUGIN does not allow the storage engine to cleanup open connections

Also, allow the MariaDB 10.2 server to link InnoDB dynamically
against ha_innodb.so (which is what mysql-test-run.pl expects
to exist, instead of the default name ha_innobase.so).

wsrep_load_data_split(): Instead of referring to innodb_hton_ptr,
check the handlerton::db_type. This was recently broken by me in
MDEV-11415.

innodb_lock_schedule_algorithm: Define as a weak global symbol,
so that WITH_WSREP will not depend on InnoDB being linked statically.
I tested this manually. Notably, running a test that only does
	SET GLOBAL wsrep_on=1;
with a static or dynamic InnoDB and
	./mtr --mysqld=--loose-innodb-lock-schedule-algorithm=fcfs
will crash with SIGSEGV at shutdown. With the default VATS
combination the wsrep_on is properly refused for both the
static and dynamic InnoDB.

ha_close_connection(): Do invoke the method also for plugins
for which UNINSTALL PLUGIN was deferred due to open connections.
Thanks to @svoj for pointing this out.

thd_to_trx(): Return a pointer, not a reference to a pointer.

check_trx_exists(): Invoke thd_set_ha_data() for assigning a transaction.

log_write_checkpoint_info(): Remove an unused DEBUG_SYNC point
that would cause an assertion failure on shutdown after deferred
UNINSTALL PLUGIN.

This was tested as follows:

cmake -DWITH_WSREP=1 -DPLUGIN_INNOBASE:STRING=DYNAMIC \
-DWITH_MARIABACKUP:BOOL=OFF ...
make
cd mysql-test
./mtr innodb.innodb_uninstall
parent 54e66eef
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2009, 2016, MariaDB
Copyright (c) 2009, 2018, 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
......@@ -793,7 +793,9 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
*/
void ha_close_connection(THD* thd)
{
plugin_foreach(thd, closecon_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0);
plugin_foreach_with_mask(thd, closecon_handlerton,
MYSQL_STORAGE_ENGINE_PLUGIN,
PLUGIN_IS_DELETED|PLUGIN_IS_READY, 0);
}
static my_bool kill_handlerton(THD *thd, plugin_ref plugin,
......
......@@ -104,23 +104,25 @@ the transaction after every 10,000 inserted rows. */
static bool wsrep_load_data_split(THD *thd, const TABLE *table,
const COPY_INFO &info)
{
extern struct handlerton* innodb_hton_ptr;
DBUG_ENTER("wsrep_load_data_split");
if (wsrep_load_data_splitting && wsrep_on(thd)
&& info.records && !(info.records % 10000)
&& thd->transaction.stmt.ha_list
&& thd->transaction.stmt.ha_list->ht() == binlog_hton
&& thd->transaction.stmt.ha_list->next()
&& thd->transaction.stmt.ha_list->next()->ht() == innodb_hton_ptr
&& !thd->transaction.stmt.ha_list->next()->next())
if (!wsrep_load_data_splitting || !wsrep_on(thd)
|| !info.records || (info.records % 10000)
|| !thd->transaction.stmt.ha_list
|| thd->transaction.stmt.ha_list->ht() != binlog_hton
|| !thd->transaction.stmt.ha_list->next()
|| thd->transaction.stmt.ha_list->next()->next())
DBUG_RETURN(false);
if (handlerton* hton= thd->transaction.stmt.ha_list->next()->ht())
{
if (hton->db_type != DB_TYPE_INNODB)
DBUG_RETURN(false);
WSREP_DEBUG("intermediate transaction commit in LOAD DATA");
if (wsrep_run_wsrep_commit(thd, true) != WSREP_TRX_OK) DBUG_RETURN(true);
if (binlog_hton->commit(binlog_hton, thd, true)) DBUG_RETURN(true);
wsrep_post_commit(thd, true);
innodb_hton_ptr->commit(innodb_hton_ptr, thd, true);
hton->commit(hton, thd, true);
table->file->extra(HA_EXTRA_FAKE_START_STMT);
}
......
......@@ -42,7 +42,10 @@ int wsrep_init_vars()
return 0;
}
extern ulong innodb_lock_schedule_algorithm;
/* This is intentionally declared as a weak global symbol, so that
linking will succeed even if the server is built with a dynamically
linked InnoDB. */
ulong innodb_lock_schedule_algorithm __attribute__((weak));
bool wsrep_on_update (sys_var *self, THD* thd, enum_var_type var_type)
{
......
......@@ -151,6 +151,7 @@ SET(INNOBASE_SOURCES
ut/ut0timer.cc)
MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
MODULE_OUTPUT_NAME ha_innodb
DEFAULT RECOMPILE_FOR_EMBEDDED
LINK_LIBRARIES
${ZLIB_LIBRARY}
......
......@@ -154,12 +154,9 @@ innodb_check_deprecated(void);
#ifdef WITH_WSREP
#include "dict0priv.h"
#include "../storage/innobase/include/ut0byte.h"
#include "ut0byte.h"
#include <mysql/service_md5.h>
class binlog_trx_data;
extern handlerton *binlog_hton;
extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log;
static inline wsrep_ws_handle_t*
......@@ -1961,14 +1958,11 @@ thd_innodb_tmpdir(
}
/** Obtain the InnoDB transaction of a MySQL thread.
@param[in,out] thd MySQL thread handler.
@param[in,out] thd thread handle
@return reference to transaction pointer */
MY_ATTRIBUTE((warn_unused_result))
trx_t*&
thd_to_trx(
THD* thd)
static trx_t* thd_to_trx(THD* thd)
{
return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
return *reinterpret_cast<trx_t**>(thd_ha_data(thd, innodb_hton_ptr));
}
#ifdef WITH_WSREP
......@@ -2877,20 +2871,19 @@ check_trx_exists(
/*=============*/
THD* thd) /*!< in: user thread handle */
{
trx_t*& trx = thd_to_trx(thd);
if (trx == NULL) {
if (trx_t* trx = thd_to_trx(thd)) {
ut_a(trx->magic_n == TRX_MAGIC_N);
innobase_trx_init(thd, trx);
return trx;
} else {
trx = innobase_trx_allocate(thd);
/* User trx can be forced to rollback,
so we unset the disable flag. */
ut_ad(trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE);
trx->in_innodb &= TRX_FORCE_ROLLBACK_MASK;
} else {
ut_a(trx->magic_n == TRX_MAGIC_N);
innobase_trx_init(thd, trx);
thd_set_ha_data(thd, innodb_hton_ptr, trx);
return trx;
}
return(trx);
}
/*************************************************************************
......@@ -2900,8 +2893,7 @@ innobase_get_trx()
{
THD *thd=current_thd;
if (likely(thd != 0)) {
trx_t*& trx = thd_to_trx(thd);
return(trx);
return thd_to_trx(thd);
} else {
return(NULL);
}
......
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2013, 2018, 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
......@@ -911,11 +911,6 @@ innodb_base_col_setup_for_stored(
create_table_info_t::normalize_table_name_low(norm_name, name, FALSE)
#endif /* _WIN32 */
/** Obtain the InnoDB transaction of a MySQL thread.
@param[in,out] thd MySQL thread handler.
@return reference to transaction pointer */
trx_t*& thd_to_trx(THD* thd);
/** Converts an InnoDB error code to a MySQL error code.
Also tells to MySQL about a possible transaction rollback inside InnoDB caused
by a lock wait timeout or a deadlock.
......
......@@ -54,7 +54,7 @@ Created 5/7/1996 Heikki Tuuri
#endif /* WITH_WSREP */
/** Lock scheduling algorithm */
ulong innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
ulong innodb_lock_schedule_algorithm;
/** The value of innodb_deadlock_detect */
my_bool innobase_deadlock_detect;
......
......@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Google Inc.
Copyright (c) 2014, 2017, MariaDB Corporation.
Copyright (c) 2014, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
......@@ -1584,8 +1584,6 @@ log_write_checkpoint_info(bool sync, lsn_t end_lsn)
rw_lock_s_lock(&log_sys->checkpoint_lock);
rw_lock_s_unlock(&log_sys->checkpoint_lock);
DEBUG_SYNC_C("checkpoint_completed");
DBUG_EXECUTE_IF(
"crash_after_checkpoint",
DBUG_SUICIDE(););
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment