summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-09-01 11:33:45 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-09-01 11:33:45 +0300
commit4e1fa7f63da580c1e0e4256bc4af3c02cdc51939 (patch)
tree6ac1589c98dbf15a465365f4f16a09da51ea8c48 /sql
parentff81faf670e083e1da4f3e7bce33fe9104410b2c (diff)
parent2f3968d98f8d90a9a9747e5b89c8f07efc6732e8 (diff)
downloadmariadb-git-4e1fa7f63da580c1e0e4256bc4af3c02cdc51939.tar.gz
Merge bb-10.2-ext into 10.3
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt44
-rw-r--r--sql/handler.cc48
-rw-r--r--sql/init.h2
-rw-r--r--sql/log.cc2
-rw-r--r--sql/mysqld.cc25
-rw-r--r--sql/mysqld.h2
-rw-r--r--sql/signal_handler.cc4
-rw-r--r--sql/sql_class.cc7
-rw-r--r--sql/sql_class.h7
-rw-r--r--sql/sql_parse.cc89
-rw-r--r--sql/sql_partition_admin.cc2
-rw-r--r--sql/sql_table.cc61
-rw-r--r--sql/sys_vars.cc12
-rw-r--r--sql/threadpool_common.cc22
-rw-r--r--sql/wsrep_applier.cc7
-rw-r--r--sql/wsrep_hton.cc1
-rw-r--r--sql/wsrep_mysqld.cc231
-rw-r--r--sql/wsrep_mysqld.h7
-rw-r--r--sql/wsrep_sst.cc9
-rw-r--r--sql/wsrep_utils.cc14
-rw-r--r--sql/wsrep_utils.h3
-rw-r--r--sql/wsrep_var.cc49
-rw-r--r--sql/wsrep_var.h4
23 files changed, 450 insertions, 202 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index b6cd663ae1e..9522d589945 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -232,23 +232,35 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
SET(_PLATFORM x64)
ENDIF()
+ # Create a cmake script to generate import and export libs
+ # from a .def file
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT "
+ IF ((mysqld_lib.def IS_NEWER_THAN mysqld_lib.lib) OR
+ (mysqld_lib.def IS_NEWER_THAN mysqld_lib.exp))
+ SET(ENV{VS_UNICODE_OUTPUT})
+ EXECUTE_PROCESS (
+ COMMAND \"${CMAKE_LINKER}\" /lib /NAME:mysqld.exe \"/DEF:${MYSQLD_DEF}\" /MACHINE:${_PLATFORM}
+ RESULT_VARIABLE ret)
+ IF(NOT ret EQUAL 0)
+ MESSAGE(FATAL_ERROR \"process failed ret=\${ret}\")
+ ENDIF()
+ ENDIF()
+ ")
+
+ CONFIGURE_FILE(
+ ${PROJECT_SOURCE_DIR}/cmake/configurable_file_content.in
+ make_mysqld_lib.cmake)
+
ADD_CUSTOM_COMMAND(
- OUTPUT ${MYSQLD_DEF}
+ OUTPUT ${MYSQLD_DEF} ${MYSQLD_LIB} ${MYSQLD_EXP}
COMMAND cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js
${_PLATFORM} /forLib ${LIB_LOCATIONS} > mysqld_lib.def.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different mysqld_lib.def.tmp mysqld_lib.def
- COMMAND ${CMAKE_COMMAND} -E remove mysqld_lib.def.tmp
+ COMMAND ${CMAKE_COMMAND} -P make_mysqld_lib.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${MYSQLD_CORELIBS}
)
- ADD_CUSTOM_COMMAND(
- OUTPUT ${MYSQLD_LIB}
- COMMAND lib
- ARGS /NAME:mysqld.exe "/DEF:${MYSQLD_DEF}" "/MACHINE:${_PLATFORM}"
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS ${MYSQLD_DEF}
- )
ADD_CUSTOM_TARGET(gen_mysqld_lib DEPENDS ${MYSQLD_LIB})
ADD_LIBRARY(mysqld_import_lib UNKNOWN IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB})
@@ -265,7 +277,10 @@ IF(APPLE)
ENDIF()
IF(NOT WITHOUT_DYNAMIC_PLUGINS)
- SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
+ IF(NOT MSVC)
+ SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
+ ENDIF()
+
GET_TARGET_PROPERTY(mysqld_link_flags mysqld LINK_FLAGS)
IF(NOT mysqld_link_flags)
SET(mysqld_link_flags)
@@ -279,7 +294,6 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS)
ENDIF()
ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS)
-SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
TARGET_LINK_LIBRARIES(mysqld sql)
# Provide plugins with minimal set of libraries
@@ -424,15 +438,15 @@ IF(WIN32 AND MYSQLD_EXECUTABLE)
ENDIF()
MAKE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR}/data)
ADD_CUSTOM_COMMAND(
- OUTPUT initdb.dep
- COMMAND ${CMAKE_COMMAND}
- ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep
+ COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -P ${CMAKE_CURRENT_BINARY_DIR}/create_initial_db.cmake
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data
DEPENDS mysqld
)
ADD_CUSTOM_TARGET(initial_database
ALL
- DEPENDS initdb.dep
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/initdb.dep
)
INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data DESTINATION .
COMPONENT DataFiles
diff --git a/sql/handler.cc b/sql/handler.cc
index dcaf08aa320..e5c15524e1d 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -73,6 +73,14 @@ KEY_CREATE_INFO default_key_create_info=
ulong total_ha= 0;
/* number of storage engines (from handlertons[]) that support 2pc */
ulong total_ha_2pc= 0;
+#ifndef DBUG_OFF
+/*
+ Number of non-mandatory 2pc handlertons whose initialization failed
+ to estimate total_ha_2pc value under supposition of the failures
+ have not occcured.
+*/
+ulong failed_ha_2pc= 0;
+#endif
/* size of savepoint storage area (see ha_init) */
ulong savepoint_alloc_size= 0;
@@ -652,6 +660,10 @@ err_deinit:
(void) plugin->plugin->deinit(NULL);
err:
+#ifndef DBUG_OFF
+ if (hton->prepare && hton->state == SHOW_OPTION_YES)
+ failed_ha_2pc++;
+#endif
my_free(hton);
err_no_hton_memory:
plugin->data= NULL;
@@ -1668,6 +1680,11 @@ int ha_rollback_trans(THD *thd, bool all)
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
+#ifdef WITH_WSREP
+ WSREP_WARN("handlerton rollback failed, thd %lu %lld conf %d SQL %s",
+ thd->thread_id, thd->query_id, thd->wsrep_conflict_state,
+ thd->query());
+#endif /* WITH_WSREP */
}
status_var_increment(thd->status_var.ha_rollback_count);
ha_info_next= ha_info->next();
@@ -1862,7 +1879,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
{
#ifndef DBUG_OFF
char buf[XIDDATASIZE*4+6]; // see xid_to_str
- sql_print_information("ignore xid %s", xid_to_str(buf, info->list+i));
+ DBUG_PRINT("info", ("ignore xid %s", xid_to_str(buf, info->list+i)));
#endif
xid_cache_insert(info->list+i, XA_PREPARED);
info->found_foreign_xids++;
@@ -1879,19 +1896,31 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
{
#ifndef DBUG_OFF
- char buf[XIDDATASIZE*4+6]; // see xid_to_str
- sql_print_information("commit xid %s", xid_to_str(buf, info->list+i));
+ int rc=
+#endif
+ hton->commit_by_xid(hton, info->list+i);
+#ifndef DBUG_OFF
+ if (rc == 0)
+ {
+ char buf[XIDDATASIZE*4+6]; // see xid_to_str
+ DBUG_PRINT("info", ("commit xid %s", xid_to_str(buf, info->list+i)));
+ }
#endif
- hton->commit_by_xid(hton, info->list+i);
}
else
{
#ifndef DBUG_OFF
- char buf[XIDDATASIZE*4+6]; // see xid_to_str
- sql_print_information("rollback xid %s",
- xid_to_str(buf, info->list+i));
+ int rc=
+#endif
+ hton->rollback_by_xid(hton, info->list+i);
+#ifndef DBUG_OFF
+ if (rc == 0)
+ {
+ char buf[XIDDATASIZE*4+6]; // see xid_to_str
+ DBUG_PRINT("info", ("rollback xid %s",
+ xid_to_str(buf, info->list+i)));
+ }
#endif
- hton->rollback_by_xid(hton, info->list+i);
}
}
if (got < info->len)
@@ -1913,7 +1942,8 @@ int ha_recover(HASH *commit_list)
/* commit_list and tc_heuristic_recover cannot be set both */
DBUG_ASSERT(info.commit_list==0 || tc_heuristic_recover==0);
/* if either is set, total_ha_2pc must be set too */
- DBUG_ASSERT(info.dry_run || total_ha_2pc>(ulong)opt_bin_log);
+ DBUG_ASSERT(info.dry_run ||
+ (failed_ha_2pc + total_ha_2pc) > (ulong)opt_bin_log);
if (total_ha_2pc <= (ulong)opt_bin_log)
DBUG_RETURN(0);
diff --git a/sql/init.h b/sql/init.h
index 11d74314f98..e8dec0c1e2e 100644
--- a/sql/init.h
+++ b/sql/init.h
@@ -17,6 +17,6 @@
#define INIT_INCLUDED
void unireg_init(ulong options);
-void unireg_end(void) __attribute__((noreturn));
+ATTRIBUTE_NORETURN void unireg_end(void);
#endif /* INIT_INCLUDED */
diff --git a/sql/log.cc b/sql/log.cc
index 1ae314708a4..948bd7844bd 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -9349,8 +9349,10 @@ int TC_LOG_BINLOG::open(const char *opt_name)
if (using_heuristic_recover())
{
+ mysql_mutex_lock(&LOCK_log);
/* generate a new binlog to mask a corrupted one */
open(opt_name, LOG_BIN, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE);
+ mysql_mutex_unlock(&LOCK_log);
cleanup();
return 1;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4dc7176e968..d3786cdd5f5 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1569,7 +1569,7 @@ static void close_server_sock();
static void clean_up_mutexes(void);
static void wait_for_signal_thread_to_end(void);
static void create_pid_file();
-static void mysqld_exit(int exit_code) __attribute__((noreturn));
+ATTRIBUTE_NORETURN static void mysqld_exit(int exit_code);
#endif
static void delete_pid_file(myf flags);
static void end_ssl();
@@ -9384,8 +9384,29 @@ mysqld_get_one_option(int optid, const struct my_option *opt, char *argument)
}
#ifdef WITH_WSREP
case OPT_WSREP_CAUSAL_READS:
- wsrep_causal_reads_update(&global_system_variables);
+ {
+ if (global_system_variables.wsrep_causal_reads)
+ {
+ WSREP_WARN("option --wsrep-causal-reads is deprecated");
+ if (!(global_system_variables.wsrep_sync_wait & WSREP_SYNC_WAIT_BEFORE_READ))
+ {
+ WSREP_WARN("--wsrep-causal-reads=ON takes precedence over --wsrep-sync-wait=%u. "
+ "WSREP_SYNC_WAIT_BEFORE_READ is on",
+ global_system_variables.wsrep_sync_wait);
+ global_system_variables.wsrep_sync_wait |= WSREP_SYNC_WAIT_BEFORE_READ;
+ }
+ }
+ else
+ {
+ if (global_system_variables.wsrep_sync_wait & WSREP_SYNC_WAIT_BEFORE_READ) {
+ WSREP_WARN("--wsrep-sync-wait=%u takes precedence over --wsrep-causal-reads=OFF. "
+ "WSREP_SYNC_WAIT_BEFORE_READ is on",
+ global_system_variables.wsrep_sync_wait);
+ global_system_variables.wsrep_causal_reads = 1;
+ }
+ }
break;
+ }
case OPT_WSREP_SYNC_WAIT:
global_system_variables.wsrep_causal_reads=
MY_TEST(global_system_variables.wsrep_sync_wait &
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 3c9fd536386..15208d4e2f5 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -715,7 +715,7 @@ enum enum_query_type
/* query_id */
extern query_id_t global_query_id;
-void unireg_end(void) __attribute__((noreturn));
+ATTRIBUTE_NORETURN void unireg_end(void);
/* increment query_id and return it. */
inline __attribute__((warn_unused_result)) query_id_t next_query_id()
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index 5cc8b958b0a..c99ad088e9f 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -204,6 +204,10 @@ extern "C" sig_handler handle_fatal_signal(int sig)
case KILL_SLAVE_SAME_ID:
kreason= "KILL_SLAVE_SAME_ID";
break;
+ case KILL_WAIT_TIMEOUT:
+ case KILL_WAIT_TIMEOUT_HARD:
+ kreason= "KILL_WAIT_TIMEOUT";
+ break;
}
my_safe_printf_stderr("%s", "\n"
"Trying to get some variables.\n"
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index f23dffb19c8..13db12b4f7e 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -891,6 +891,8 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
wsrep_info[sizeof(wsrep_info) - 1] = '\0'; /* make sure it is 0-terminated */
wsrep_sync_wait_gtid = WSREP_GTID_UNDEFINED;
wsrep_affected_rows = 0;
+ wsrep_replicate_GTID = false;
+ wsrep_skip_wsrep_GTID = false;
#endif
/* Call to init() below requires fully initialized Open_tables_state. */
reset_open_tables_state(this);
@@ -1336,6 +1338,8 @@ void THD::init(void)
wsrep_TOI_pre_query_len = 0;
wsrep_sync_wait_gtid = WSREP_GTID_UNDEFINED;
wsrep_affected_rows = 0;
+ wsrep_replicate_GTID = false;
+ wsrep_skip_wsrep_GTID = false;
#endif /* WITH_WSREP */
if (variables.sql_log_bin)
@@ -2054,6 +2058,9 @@ int THD::killed_errno()
DBUG_RETURN(ER_SERVER_SHUTDOWN);
case KILL_SLAVE_SAME_ID:
DBUG_RETURN(ER_SLAVE_SAME_ID);
+ case KILL_WAIT_TIMEOUT:
+ case KILL_WAIT_TIMEOUT_HARD:
+ DBUG_RETURN(ER_NET_READ_INTERRUPTED);
}
DBUG_RETURN(0); // Keep compiler happy
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 20989459c5f..1cbe70b2d5e 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -477,6 +477,11 @@ enum killed_state
KILL_SYSTEM_THREAD_HARD= 15,
KILL_SERVER= 16,
KILL_SERVER_HARD= 17,
+ /*
+ Used in threadpool to signal wait timeout.
+ */
+ KILL_WAIT_TIMEOUT= 18,
+ KILL_WAIT_TIMEOUT_HARD= 19
};
@@ -4472,6 +4477,8 @@ public:
bool wsrep_ignore_table;
wsrep_gtid_t wsrep_sync_wait_gtid;
ulong wsrep_affected_rows;
+ bool wsrep_replicate_GTID;
+ bool wsrep_skip_wsrep_GTID;
#endif /* WITH_WSREP */
/* Handling of timeouts for commands */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index deb2785e37c..2b43f700aca 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3655,6 +3655,7 @@ mysql_execute_command(THD *thd)
#endif
case SQLCOM_SHOW_STATUS:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
execute_show_status(thd, all_tables);
break;
}
@@ -3693,21 +3694,21 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_OPEN_TABLES:
case SQLCOM_SHOW_GENERIC:
+ case SQLCOM_SHOW_PLUGINS:
case SQLCOM_SHOW_FIELDS:
case SQLCOM_SHOW_KEYS:
- case SQLCOM_SELECT:
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd))
- goto error;
- /* fall through */
- case SQLCOM_SHOW_PLUGINS:
case SQLCOM_SHOW_VARIABLES:
case SQLCOM_SHOW_CHARSETS:
case SQLCOM_SHOW_COLLATIONS:
case SQLCOM_SHOW_STORAGE_ENGINES:
case SQLCOM_SHOW_PROFILE:
- {
+ case SQLCOM_SELECT:
+ {
#ifdef WITH_WSREP
- DBUG_ASSERT(thd->wsrep_exec_mode != REPL_RECV);
+ if (lex->sql_command == SQLCOM_SELECT)
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ)
+ else
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW)
#endif /* WITH_WSREP */
thd->status_var.last_query_cost= 0.0;
@@ -3836,6 +3837,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_RELAYLOG_EVENTS: /* fall through */
case SQLCOM_SHOW_BINLOG_EVENTS:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
if (check_global_access(thd, REPL_SLAVE_ACL))
goto error;
res = mysql_show_binlog_events(thd);
@@ -4415,6 +4417,7 @@ end_with_restore_list:
{
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
goto error;
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
res = show_binlogs(thd);
break;
}
@@ -4422,15 +4425,13 @@ end_with_restore_list:
#endif /* EMBEDDED_LIBRARY */
case SQLCOM_SHOW_CREATE:
{
- DBUG_ASSERT(first_table == all_tables && first_table != 0);
+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
#ifdef DONT_ALLOW_SHOW_COMMANDS
my_message(ER_NOT_ALLOWED_COMMAND, ER_THD(thd, ER_NOT_ALLOWED_COMMAND),
MYF(0)); /* purecov: inspected */
goto error;
#else
-
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd))
- goto error;
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
/*
Access check:
@@ -4493,8 +4494,7 @@ end_with_restore_list:
case SQLCOM_CHECKSUM:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd))
- goto error;
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ);
if (check_table_access(thd, SELECT_ACL, all_tables,
FALSE, UINT_MAX, FALSE))
@@ -4505,6 +4505,7 @@ end_with_restore_list:
}
case SQLCOM_UPDATE:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
ha_rows found= 0, updated= 0;
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (WSREP_CLIENT(thd) &&
@@ -4547,9 +4548,7 @@ end_with_restore_list:
/* if we switched from normal update, rights are checked */
if (up_result != 2)
{
- if (WSREP_CLIENT(thd) &&
- wsrep_sync_wait(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE))
- goto error;
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
if ((res= multi_update_precheck(thd, all_tables)))
break;
}
@@ -4619,10 +4618,6 @@ end_with_restore_list:
break;
}
case SQLCOM_REPLACE:
- {
- if (WSREP_CLIENT(thd) &&
- wsrep_sync_wait(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE))
- goto error;
#ifndef DBUG_OFF
if (mysql_bin_log.is_open())
{
@@ -4657,10 +4652,10 @@ end_with_restore_list:
DBUG_PRINT("debug", ("Just after generate_incident()"));
}
#endif
- }
/* fall through */
case SQLCOM_INSERT:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (WSREP_CLIENT(thd) &&
@@ -4719,6 +4714,7 @@ end_with_restore_list:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE);
select_result *sel_result;
bool explain= MY_TEST(lex->describe);
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -4842,6 +4838,7 @@ end_with_restore_list:
}
case SQLCOM_DELETE:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
select_result *sel_result=lex->result;
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (WSREP_CLIENT(thd) &&
@@ -4902,6 +4899,7 @@ end_with_restore_list:
}
case SQLCOM_DELETE_MULTI:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
multi_delete *result;
@@ -4983,19 +4981,6 @@ end_with_restore_list:
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
thd->variables.option_bits|= OPTION_KEEP_LOG;
}
- if (WSREP(thd))
- {
- for (TABLE_LIST *table= all_tables; table; table= table->next_global)
- {
- if (!lex->tmp_table() &&
- (!thd->is_current_stmt_binlog_format_row() ||
- !thd->find_temporary_table(table)))
- {
- WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
- break;
- }
- }
- }
/*
If we are a slave, we should add IF EXISTS if the query executed
on the master without an error. This will help a slave to
@@ -5005,6 +4990,20 @@ end_with_restore_list:
if (thd->slave_thread && !thd->slave_expected_error &&
slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
+
+ if (WSREP(thd))
+ {
+ for (TABLE_LIST *table= all_tables; table; table= table->next_global)
+ {
+ if (!lex->tmp_table() &&
+ (!thd->is_current_stmt_binlog_format_row() ||
+ !thd->find_temporary_table(table)))
+ {
+ WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
+ break;
+ }
+ }
+ }
/* DDL and binlog write order are protected by metadata locks. */
res= mysql_rm_table(thd, first_table, lex->if_exists(), lex->tmp_table(),
@@ -5249,9 +5248,7 @@ end_with_restore_list:
db_name.length= lex->name.length;
strmov(db_name_buff, lex->name.str);
-#ifdef WITH_WSREP
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd)) goto error;
-#endif /* WITH_WSREP */
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
if (check_db_name((LEX_STRING*) &db_name))
{
@@ -5306,9 +5303,7 @@ end_with_restore_list:
/* lex->unit.cleanup() is called outside, no need to call it here */
break;
case SQLCOM_SHOW_CREATE_EVENT:
-#ifdef WITH_WSREP
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd)) goto error;
-#endif /* WITH_WSREP */
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
res= Events::show_create_event(thd, &lex->spname->m_db,
&lex->spname->m_name);
break;
@@ -5692,6 +5687,7 @@ end_with_restore_list:
if (!grant_user)
goto error;
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
res = mysql_show_grants(thd, grant_user);
break;
}
@@ -6006,10 +6002,8 @@ end_with_restore_list:
case SQLCOM_SHOW_CREATE_PROC:
case SQLCOM_SHOW_CREATE_FUNC:
{
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
-#ifdef WITH_WSREP
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd)) goto error;
-#endif /* WITH_WSREP */
if (sph->sp_show_create_routine(thd, lex->spname))
goto error;
break;
@@ -6020,9 +6014,7 @@ end_with_restore_list:
#ifndef DBUG_OFF
sp_head *sp;
const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
-#ifdef WITH_WSREP
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd)) goto error;
-#endif /* WITH_WSREP */
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
if (sph->sp_cache_routine(thd, lex->spname, false, &sp))
goto error;
if (!sp || sp->show_routine_code(thd))
@@ -6044,9 +6036,7 @@ end_with_restore_list:
if (check_ident_length(&lex->spname->m_name))
goto error;
-#ifdef WITH_WSREP
- if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd)) goto error;
-#endif /* WITH_WSREP */
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
if (show_create_trigger(thd, lex->spname))
goto error; /* Error has been already logged. */
@@ -6507,6 +6497,7 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables)
if (!(res= check_table_access(thd, SELECT_ACL, all_tables, FALSE,
UINT_MAX, FALSE)))
res= execute_sqlcom_select(thd, all_tables);
+
/* Don't log SHOW STATUS commands to slow query log */
thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
SERVER_QUERY_NO_GOOD_INDEX_USED);
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index df37dd5ff42..c34769bf73f 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -778,7 +778,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
(!thd->is_current_stmt_binlog_format_row() ||
!thd->find_temporary_table(first_table)) &&
wsrep_to_isolation_begin(
- thd, first_table->db, first_table->table_name, NULL)
+ thd, first_table->db, first_table->table_name, NULL)
)
{
WSREP_WARN("ALTER TABLE TRUNCATE PARTITION isolation failure");
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 318378b4acc..ebf1052d115 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2091,6 +2091,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists,
DBUG_RETURN(TRUE);
my_ok(thd);
DBUG_RETURN(FALSE);
+
}
@@ -2137,7 +2138,6 @@ static uint32 comment_length(THD *thd, uint32 comment_pos,
return 0;
}
-
/**
Execute the drop of a normal or temporary table.
@@ -2573,6 +2573,9 @@ err:
/* Chop of the last comma */
built_non_trans_tmp_query.chop();
built_non_trans_tmp_query.append(" /* generated by server */");
+#ifdef WITH_WSREP
+ thd->wsrep_skip_wsrep_GTID = true;
+#endif /* WITH_WSREP */
error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
built_non_trans_tmp_query.ptr(),
built_non_trans_tmp_query.length(),
@@ -2585,6 +2588,9 @@ err:
/* Chop of the last comma */
built_trans_tmp_query.chop();
built_trans_tmp_query.append(" /* generated by server */");
+#ifdef WITH_WSREP
+ thd->wsrep_skip_wsrep_GTID = true;
+#endif /* WITH_WSREP */
error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
built_trans_tmp_query.ptr(),
built_trans_tmp_query.length(),
@@ -2599,6 +2605,9 @@ err:
built_query.append(" /* generated by server */");
int error_code = non_tmp_error ? thd->get_stmt_da()->sql_errno()
: 0;
+#ifdef WITH_WSREP
+ thd->wsrep_skip_wsrep_GTID = false;
+#endif /* WITH_WSREP */
error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
built_query.ptr(),
built_query.length(),
@@ -2647,6 +2656,9 @@ err:
}
end:
+#ifdef WITH_WSREP
+ thd->wsrep_skip_wsrep_GTID = false;
+#endif /* WITH_WSREP */
DBUG_RETURN(error);
}
@@ -7578,9 +7590,26 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
if (def->change.str && ! def->field)
{
- my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change.str,
- table->s->table_name.str);
- goto err;
+ /*
+ Check if there is modify for newly added field.
+ */
+ Create_field *find;
+ find_it.rewind();
+ while((find=find_it++))
+ {
+ if (!my_strcasecmp(system_charset_info,find->field_name.str,
+ def->field_name.str))
+ break;
+ }
+
+ if (find && !find->field)
+ find_it.remove();
+ else
+ {
+ my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change.str,
+ table->s->table_name.str);
+ goto err;
+ }
}
/*
Check that the DATE/DATETIME not null field we are going to add is
@@ -7648,6 +7677,30 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
find_it.after(def); // Put column after this
}
}
+ /*
+ Check if there is alter for newly added field.
+ */
+ alter_it.rewind();
+ Alter_column *alter;
+ while ((alter=alter_it++))
+ {
+ if (!my_strcasecmp(system_charset_info,def->field_name.str,
+ alter->name))
+ break;
+ }
+ if (alter)
+ {
+ if (def->real_field_type() == MYSQL_TYPE_BLOB)
+ {
+ my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
+ goto err;
+ }
+ if ((def->default_value= alter->default_value)) // Use new default
+ def->flags&= ~NO_DEFAULT_VALUE_FLAG;
+ else
+ def->flags|= NO_DEFAULT_VALUE_FLAG;
+ alter_it.remove();
+ }
}
if (alter_info->alter_list.elements)
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 6c5bc4baec6..a159fc87aa9 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -5058,7 +5058,7 @@ static Sys_var_ulong Sys_wsrep_slave_threads(
GLOBAL_VAR(wsrep_slave_threads), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(1, 512), DEFAULT(1), BLOCK_SIZE(1),
&PLock_wsrep_slave_threads, NOT_IN_BINLOG,
- ON_CHECK(wsrep_slave_threads_check),
+ ON_CHECK(NULL),
ON_UPDATE(wsrep_slave_threads_update));
static Sys_var_charptr Sys_wsrep_dbug_option(
@@ -5170,21 +5170,13 @@ static Sys_var_mybool Sys_wsrep_certify_nonPK(
GLOBAL_VAR(wsrep_certify_nonPK),
CMD_LINE(OPT_ARG), DEFAULT(TRUE));
-static bool fix_wsrep_causal_reads(sys_var *self, THD* thd, enum_var_type var_type)
-{
- if (var_type == OPT_GLOBAL)
- wsrep_causal_reads_update(&global_system_variables);
- else
- wsrep_causal_reads_update(&thd->variables);
- return false;
-}
static Sys_var_mybool Sys_wsrep_causal_reads(
"wsrep_causal_reads", "Setting this variable is equivalent "
"to setting wsrep_sync_wait READ flag",
SESSION_VAR(wsrep_causal_reads),
CMD_LINE(OPT_ARG, OPT_WSREP_CAUSAL_READS), DEFAULT(FALSE),
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
- ON_UPDATE(fix_wsrep_causal_reads),
+ ON_UPDATE(wsrep_causal_reads_update),
DEPRECATED("'@@wsrep_sync_wait=1'"));
static Sys_var_uint Sys_wsrep_sync_wait(
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index b6e7d0818a5..486a829c645 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -308,6 +308,24 @@ static void threadpool_remove_connection(THD *thd)
my_thread_end();
}
+
+/*
+ Ensure that proper error message is sent to client,
+ and "aborted" message appears in the log in case of
+ wait timeout.
+
+ See also timeout handling in net_serv.cc
+*/
+static void handle_wait_timeout(THD *thd)
+{
+ thd->get_stmt_da()->reset_diagnostics_area();
+ thd->reset_killed();
+ my_error(ER_NET_READ_INTERRUPTED, MYF(0));
+ thd->net.last_errno= ER_NET_READ_INTERRUPTED;
+ thd->net.error= 2;
+}
+
+
/**
Process a single client request or a single batch.
*/
@@ -323,6 +341,8 @@ static int threadpool_process_request(THD *thd)
or KILL command. Return error.
*/
retval= 1;
+ if(thd->killed == KILL_WAIT_TIMEOUT)
+ handle_wait_timeout(thd);
goto end;
}
@@ -458,7 +478,7 @@ void tp_timeout_handler(TP_connection *c)
return;
THD *thd=c->thd;
mysql_mutex_lock(&thd->LOCK_thd_data);
- thd->killed= KILL_CONNECTION;
+ thd->set_killed(KILL_WAIT_TIMEOUT);
c->priority= TP_PRIORITY_HIGH;
post_kill_notification(thd);
mysql_mutex_unlock(&thd->LOCK_thd_data);
diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc
index 93d4ebc495d..465d1f25b5b 100644
--- a/sql/wsrep_applier.cc
+++ b/sql/wsrep_applier.cc
@@ -218,12 +218,15 @@ wsrep_cb_status_t wsrep_apply_cb(void* const ctx,
{
THD* const thd((THD*)ctx);
+ assert(thd->wsrep_apply_toi == false);
+
// Allow tests to block the applier thread using the DBUG facilities.
DBUG_EXECUTE_IF("sync.wsrep_apply_cb",
{
const char act[]=
"now "
- "wait_for signal.wsrep_apply_cb";
+ "SIGNAL sync.wsrep_apply_cb_reached "
+ "WAIT_FOR signal.wsrep_apply_cb";
DBUG_ASSERT(!debug_sync_set_action(thd,
STRING_WITH_LEN(act)));
};);
@@ -383,7 +386,7 @@ wsrep_cb_status_t wsrep_commit_cb(void* const ctx,
mysql_mutex_unlock(&LOCK_wsrep_slave_threads);
}
- if (*exit == false && thd->wsrep_applier)
+ if (thd->wsrep_applier)
{
/* From trans_begin() */
thd->variables.option_bits|= OPTION_BEGIN;
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index 5eaa89a5be9..6c805d662ac 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -43,6 +43,7 @@ void wsrep_cleanup_transaction(THD *thd)
thd->wsrep_trx_meta.depends_on= WSREP_SEQNO_UNDEFINED;
thd->wsrep_exec_mode= LOCAL_STATE;
thd->wsrep_affected_rows= 0;
+ thd->wsrep_skip_wsrep_GTID= false;
return;
}
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index d0cd90e28c3..7caff913106 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -2,7 +2,7 @@
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 Foundation; version 2 of the License.
+ the Free Software Foundation; version 2 of the License.x1
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -17,6 +17,7 @@
#include <mysqld.h>
#include <sql_class.h>
#include <sql_parse.h>
+#include <sql_base.h> /* find_temporary_table() */
#include "slave.h"
#include "rpl_mi.h"
#include "sql_repl.h"
@@ -995,8 +996,6 @@ bool wsrep_must_sync_wait (THD* thd, uint mask)
{
return (thd->variables.wsrep_sync_wait & mask) &&
thd->variables.wsrep_on &&
- !(thd->variables.wsrep_dirty_reads &&
- !is_update_query(thd->lex->sql_command)) &&
!thd->in_active_multi_stmt_transaction() &&
thd->wsrep_conflict_state != REPLAYING &&
thd->wsrep_sync_wait_gtid.seqno == WSREP_SEQNO_UNDEFINED;
@@ -1125,83 +1124,70 @@ static bool wsrep_prepare_keys_for_isolation(THD* thd,
const TABLE_LIST* table_list,
wsrep_key_arr_t* ka)
{
- ka->keys= 0;
- ka->keys_len= 0;
+ ka->keys= 0;
+ ka->keys_len= 0;
- if (db || table)
+ if (db || table)
+ {
+ if (!(ka->keys= (wsrep_key_t*)my_malloc(sizeof(wsrep_key_t), MYF(0))))
+ {
+ WSREP_ERROR("Can't allocate memory for key_array");
+ goto err;
+ }
+ ka->keys_len= 1;
+ if (!(ka->keys[0].key_parts= (wsrep_buf_t*)
+ my_malloc(sizeof(wsrep_buf_t)*2, MYF(0))))
{
- TABLE_LIST tmp_table;
+ WSREP_ERROR("Can't allocate memory for key_parts");
+ goto err;
+ }
+ ka->keys[0].key_parts_num= 2;
+ if (!wsrep_prepare_key_for_isolation(
+ db, table,
+ (wsrep_buf_t*)ka->keys[0].key_parts,
+ &ka->keys[0].key_parts_num))
+ {
+ WSREP_ERROR("Preparing keys for isolation failed (1)");
+ goto err;
+ }
+ }
- memset(&tmp_table, 0, sizeof(tmp_table));
- tmp_table.table_name= (char*)table;
- tmp_table.db= (char*)db;
- tmp_table.mdl_request.init(MDL_key::GLOBAL, (db) ? db : "",
- (table) ? table : "",
- MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT);
+ for (const TABLE_LIST* table= table_list; table; table= table->next_global)
+ {
+ wsrep_key_t* tmp;
+ if (ka->keys)
+ tmp= (wsrep_key_t*)my_realloc(ka->keys,
+ (ka->keys_len + 1) * sizeof(wsrep_key_t),
+ MYF(0));
+ else
+ tmp= (wsrep_key_t*)my_malloc((ka->keys_len + 1) * sizeof(wsrep_key_t), MYF(0));
- if (!table || !thd->find_temporary_table(&tmp_table))
- {
- if (!(ka->keys= (wsrep_key_t*)my_malloc(sizeof(wsrep_key_t), MYF(0))))
- {
- WSREP_ERROR("Can't allocate memory for key_array");
- goto err;
- }
- ka->keys_len= 1;
- if (!(ka->keys[0].key_parts= (wsrep_buf_t*)
- my_malloc(sizeof(wsrep_buf_t)*2, MYF(0))))
- {
- WSREP_ERROR("Can't allocate memory for key_parts");
- goto err;
- }
- ka->keys[0].key_parts_num= 2;
- if (!wsrep_prepare_key_for_isolation(
- db, table,
- (wsrep_buf_t*)ka->keys[0].key_parts,
- &ka->keys[0].key_parts_num))
- {
- WSREP_ERROR("Preparing keys for isolation failed");
- goto err;
- }
- }
+ if (!tmp)
+ {
+ WSREP_ERROR("Can't allocate memory for key_array");
+ goto err;
}
-
- for (const TABLE_LIST* table= table_list; table; table= table->next_global)
+ ka->keys= tmp;
+ if (!(ka->keys[ka->keys_len].key_parts= (wsrep_buf_t*)
+ my_malloc(sizeof(wsrep_buf_t)*2, MYF(0))))
{
- if (!thd->find_temporary_table(table))
- {
- wsrep_key_t* tmp;
- tmp= (wsrep_key_t*)my_realloc(
- ka->keys, (ka->keys_len + 1) * sizeof(wsrep_key_t),
- MYF(MY_ALLOW_ZERO_PTR));
-
- if (!tmp)
- {
- WSREP_ERROR("Can't allocate memory for key_array");
- goto err;
- }
- ka->keys= tmp;
- if (!(ka->keys[ka->keys_len].key_parts= (wsrep_buf_t*)
- my_malloc(sizeof(wsrep_buf_t)*2, MYF(0))))
- {
- WSREP_ERROR("Can't allocate memory for key_parts");
- goto err;
- }
- ka->keys[ka->keys_len].key_parts_num= 2;
- ++ka->keys_len;
- if (!wsrep_prepare_key_for_isolation(
- table->db, table->table_name,
- (wsrep_buf_t*)ka->keys[ka->keys_len - 1].key_parts,
- &ka->keys[ka->keys_len - 1].key_parts_num))
- {
- WSREP_ERROR("Preparing keys for isolation failed");
- goto err;
- }
- }
+ WSREP_ERROR("Can't allocate memory for key_parts");
+ goto err;
}
- return true;
+ ka->keys[ka->keys_len].key_parts_num= 2;
+ ++ka->keys_len;
+ if (!wsrep_prepare_key_for_isolation(table->db, table->table_name,
+ (wsrep_buf_t*)ka->keys[ka->keys_len - 1].key_parts,
+ &ka->keys[ka->keys_len - 1].key_parts_num))
+ {
+ WSREP_ERROR("Preparing keys for isolation failed (2)");
+ goto err;
+ }
+ }
+ return 0;
err:
wsrep_keys_free(ka);
- return false;
+ return 1;
}
@@ -1411,6 +1397,84 @@ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len);
static int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
/*
+ Decide if statement should run in TOI.
+
+ Look if table or table_list contain temporary tables. If the
+ statement affects only temporary tables, statement should not run
+ in TOI. If the table list contains mix of regular and temporary tables
+ (DROP TABLE, OPTIMIZE, ANALYZE), statement should be run in TOI but
+ should be rewritten at later time for replication to contain only
+ non-temporary tables.
+ */
+static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
+ const TABLE_LIST *table_list)
+{
+ DBUG_ASSERT(!table || db);
+ DBUG_ASSERT(table_list || db);
+
+ LEX* lex= thd->lex;
+ SELECT_LEX* select_lex= &lex->select_lex;
+ TABLE_LIST* first_table= select_lex->table_list.first;
+
+ switch (lex->sql_command)
+ {
+ case SQLCOM_CREATE_TABLE:
+ DBUG_ASSERT(!table_list);
+ if (thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
+ {
+ return false;
+ }
+ return true;
+
+ case SQLCOM_CREATE_VIEW:
+
+ DBUG_ASSERT(!table_list);
+ DBUG_ASSERT(first_table); /* First table is view name */
+ /*
+ If any of the remaining tables refer to temporary table error
+ is returned to client, so TOI can be skipped
+ */
+ for (TABLE_LIST* it= first_table->next_global; it; it= it->next_global)
+ {
+ if (thd->find_temporary_table(it))
+ {
+ return false;
+ }
+ }
+ return true;
+
+ case SQLCOM_CREATE_TRIGGER:
+
+ DBUG_ASSERT(!table_list);
+ DBUG_ASSERT(first_table);
+
+ if (thd->find_temporary_table(first_table))
+ {
+ return false;
+ }
+ return true;
+
+ default:
+ if (table && !thd->find_temporary_table(db, table))
+ {
+ return true;
+ }
+
+ if (table_list)
+ {
+ for (TABLE_LIST* table= first_table; table; table= table->next_global)
+ {
+ if (!thd->find_temporary_table(table->db, table->table_name))
+ {
+ return true;
+ }
+ }
+ }
+ return !(table || table_list);
+ }
+}
+
+/*
returns:
0: statement was replicated as TOI
1: TOI replication was skipped
@@ -1425,6 +1489,12 @@ static int wsrep_TOI_begin(THD *thd, const char *db_, const char *table_,
int buf_err;
int rc= 0;
+ if (wsrep_can_run_in_toi(thd, db_, table_, table_list) == false)
+ {
+ WSREP_DEBUG("No TOI for %s", WSREP_QUERY(thd));
+ return 1;
+ }
+
WSREP_DEBUG("TO BEGIN: %lld, %d : %s", (long long)wsrep_thd_trx_seqno(thd),
thd->wsrep_exec_mode, thd->query() );
switch (thd->lex->sql_command)
@@ -1452,16 +1522,16 @@ static int wsrep_TOI_begin(THD *thd, const char *db_, const char *table_,
}
/* fallthrough */
default:
- buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(), &buf,
- &buf_len);
+ buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(),
+ &buf, &buf_len);
break;
}
wsrep_key_arr_t key_arr= {0, 0};
struct wsrep_buf buff = { buf, buf_len };
- if (!buf_err &&
- wsrep_prepare_keys_for_isolation(thd, db_, table_, table_list, &key_arr)&&
- key_arr.keys_len > 0 &&
+ if (!buf_err &&
+ !wsrep_prepare_keys_for_isolation(thd, db_, table_, table_list, &key_arr) &&
+ key_arr.keys_len > 0 &&
WSREP_OK == (ret = wsrep->to_execute_start(wsrep, thd->thread_id,
key_arr.keys, key_arr.keys_len,
&buff, 1,
@@ -1658,9 +1728,12 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE)
{
switch (thd->variables.wsrep_OSU_method) {
- case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, db_, table_,
- table_list); break;
- case WSREP_OSU_RSU: ret = wsrep_RSU_begin(thd, db_, table_); break;
+ case WSREP_OSU_TOI:
+ ret = wsrep_TOI_begin(thd, db_, table_, table_list);
+ break;
+ case WSREP_OSU_RSU:
+ ret = wsrep_RSU_begin(thd, db_, table_);
+ break;
default:
WSREP_ERROR("Unsupported OSU method: %lu",
thd->variables.wsrep_OSU_method);
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index fb46cda7019..e50f869a363 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -99,11 +99,12 @@ enum enum_wsrep_OSU_method {
enum enum_wsrep_sync_wait {
WSREP_SYNC_WAIT_NONE = 0x0,
- // show, select, begin
+ // select, begin
WSREP_SYNC_WAIT_BEFORE_READ = 0x1,
WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE = 0x2,
WSREP_SYNC_WAIT_BEFORE_INSERT_REPLACE = 0x4,
- WSREP_SYNC_WAIT_MAX = 0x7
+ WSREP_SYNC_WAIT_BEFORE_SHOW = 0x8,
+ WSREP_SYNC_WAIT_MAX = 0xF
};
// MySQL status variables
@@ -218,6 +219,8 @@ void wsrep_log(void (*fun)(const char *, ...), const char *format, ...);
#define WSREP_PROVIDER_EXISTS \
(wsrep_provider && strncasecmp(wsrep_provider, WSREP_NONE, FN_REFLEN))
+#define WSREP_QUERY(thd) (thd->query())
+
extern void wsrep_ready_wait();
class Ha_trx_info;
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 30564a51547..35bf1b251e7 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -745,7 +745,7 @@ ssize_t wsrep_sst_prepare (void** msg)
// Attempt 1: wsrep_sst_receive_address
if (wsrep_sst_receive_address &&
- strcmp (wsrep_sst_receive_address, WSREP_SST_ADDRESS_AUTO))
+ strcmp (wsrep_sst_receive_address, WSREP_SST_ADDRESS_AUTO))
{
addr_in= wsrep_sst_receive_address;
}
@@ -885,16 +885,13 @@ static int sst_donate_mysqldump (const char* addr,
{
char host[256];
wsp::Address address(addr);
-
if (!address.is_valid())
{
WSREP_ERROR("Could not parse SST address : %s", addr);
return 0;
}
-
memcpy(host, address.get_address(), address.get_address_len());
int port= address.get_port();
-
int const cmd_len= 4096;
wsp::string cmd_str(cmd_len);
@@ -911,7 +908,7 @@ static int sst_donate_mysqldump (const char* addr,
int ret= snprintf (cmd_str(), cmd_len,
"wsrep_sst_mysqldump "
- WSREP_SST_OPT_HOST" '%s' "
+ WSREP_SST_OPT_ADDR" '%s' "
WSREP_SST_OPT_PORT" '%d' "
WSREP_SST_OPT_LPORT" '%u' "
WSREP_SST_OPT_SOCKET" '%s' "
@@ -919,7 +916,7 @@ static int sst_donate_mysqldump (const char* addr,
WSREP_SST_OPT_GTID" '%s:%lld' "
WSREP_SST_OPT_GTID_DOMAIN_ID" '%d'"
"%s",
- host, port, mysqld_port, mysqld_unix_port,
+ addr, port, mysqld_port, mysqld_unix_port,
wsrep_defaults_file, uuid_str,
(long long)seqno, wsrep_gtid_domain_id,
bypass ? " " WSREP_SST_OPT_BYPASS : "");
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc
index bff4b10ad83..3c341e222b3 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -574,3 +574,17 @@ done:
return ret;
}
+/* returns the length of the host part of the address string */
+size_t wsrep_host_len(const char* const addr, size_t const addr_len)
+{
+ // check for IPv6 notation first
+ const char* const bracket= ('[' == addr[0] ? strchr(addr, ']') : NULL);
+
+ if (bracket) { // IPv6
+ return (bracket - addr + 1);
+ }
+ else { // host part ends at ':' or end of string
+ const char* const colon= strchr(addr, ':');
+ return (colon ? colon - addr : addr_len);
+ }
+}
diff --git a/sql/wsrep_utils.h b/sql/wsrep_utils.h
index e4f421930f4..277cea9dc31 100644
--- a/sql/wsrep_utils.h
+++ b/sql/wsrep_utils.h
@@ -22,6 +22,9 @@
unsigned int wsrep_check_ip (const char* const addr, bool *is_ipv6);
size_t wsrep_guess_ip (char* buf, size_t buf_len);
+/* returns the length of the host part of the address string */
+size_t wsrep_host_len(const char* addr, size_t addr_len);
+
namespace wsp {
class Address {
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index d7f55dbca60..8107ab12c6b 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -27,6 +27,8 @@
#include <cstdlib>
+static long wsrep_prev_slave_threads = wsrep_slave_threads;
+
int wsrep_init_vars()
{
wsrep_provider = my_strdup(WSREP_NONE, MYF(MY_WME));
@@ -49,12 +51,23 @@ bool wsrep_on_update (sys_var *self, THD* thd, enum_var_type var_type)
return false;
}
-bool wsrep_causal_reads_update (SV *sv)
+bool wsrep_causal_reads_update (sys_var *self, THD* thd, enum_var_type var_type)
{
- if (sv->wsrep_causal_reads) {
- sv->wsrep_sync_wait |= WSREP_SYNC_WAIT_BEFORE_READ;
+ // global setting should not affect session setting.
+ // if (var_type == OPT_GLOBAL) {
+ // thd->variables.wsrep_causal_reads = global_system_variables.wsrep_causal_reads;
+ // }
+ if (thd->variables.wsrep_causal_reads) {
+ thd->variables.wsrep_sync_wait |= WSREP_SYNC_WAIT_BEFORE_READ;
+ } else {
+ thd->variables.wsrep_sync_wait &= ~WSREP_SYNC_WAIT_BEFORE_READ;
+ }
+
+ // update global settings too.
+ if (global_system_variables.wsrep_causal_reads) {
+ global_system_variables.wsrep_sync_wait |= WSREP_SYNC_WAIT_BEFORE_READ;
} else {
- sv->wsrep_sync_wait &= ~WSREP_SYNC_WAIT_BEFORE_READ;
+ global_system_variables.wsrep_sync_wait &= ~WSREP_SYNC_WAIT_BEFORE_READ;
}
return false;
@@ -62,12 +75,17 @@ bool wsrep_causal_reads_update (SV *sv)
bool wsrep_sync_wait_update (sys_var* self, THD* thd, enum_var_type var_type)
{
- if (var_type == OPT_GLOBAL)
- global_system_variables.wsrep_causal_reads =
- MY_TEST(global_system_variables.wsrep_sync_wait & WSREP_SYNC_WAIT_BEFORE_READ);
- else
- thd->variables.wsrep_causal_reads =
- MY_TEST(thd->variables.wsrep_sync_wait & WSREP_SYNC_WAIT_BEFORE_READ);
+ // global setting should not affect session setting.
+ // if (var_type == OPT_GLOBAL) {
+ // thd->variables.wsrep_sync_wait = global_system_variables.wsrep_sync_wait;
+ // }
+ thd->variables.wsrep_causal_reads = thd->variables.wsrep_sync_wait &
+ WSREP_SYNC_WAIT_BEFORE_READ;
+
+ // update global settings too
+ global_system_variables.wsrep_causal_reads = global_system_variables.wsrep_sync_wait &
+ WSREP_SYNC_WAIT_BEFORE_READ;
+
return false;
}
@@ -528,18 +546,15 @@ void wsrep_node_address_init (const char* value)
wsrep_node_address = (value) ? my_strdup(value, MYF(0)) : NULL;
}
-bool wsrep_slave_threads_check (sys_var *self, THD* thd, set_var* var)
+static void wsrep_slave_count_change_update ()
{
- mysql_mutex_lock(&LOCK_wsrep_slave_threads);
- wsrep_slave_count_change += (var->save_result.ulonglong_value -
- wsrep_slave_threads);
- mysql_mutex_unlock(&LOCK_wsrep_slave_threads);
-
- return 0;
+ wsrep_slave_count_change += (wsrep_slave_threads - wsrep_prev_slave_threads);
+ wsrep_prev_slave_threads = wsrep_slave_threads;
}
bool wsrep_slave_threads_update (sys_var *self, THD* thd, enum_var_type type)
{
+ wsrep_slave_count_change_update();
if (wsrep_slave_count_change > 0)
{
wsrep_create_appliers(wsrep_slave_count_change);
diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h
index 1509fc7d589..dde59d1503f 100644
--- a/sql/wsrep_var.h
+++ b/sql/wsrep_var.h
@@ -41,9 +41,7 @@ int wsrep_init_vars();
#define DEFAULT_ARGS (THD* thd, enum_var_type var_type)
#define INIT_ARGS (const char* opt)
-struct system_variables;
-bool wsrep_causal_reads_update(struct system_variables *sv);
-
+extern bool wsrep_causal_reads_update UPDATE_ARGS;
extern bool wsrep_on_update UPDATE_ARGS;
extern bool wsrep_sync_wait_update UPDATE_ARGS;
extern bool wsrep_start_position_check CHECK_ARGS;