summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/wsrep.cmake2
-rw-r--r--sql/mysqld.cc9
-rw-r--r--sql/sys_vars.cc4
-rw-r--r--sql/wsrep_mysqld.cc41
-rw-r--r--sql/wsrep_mysqld.h4
-rw-r--r--sql/wsrep_var.cc6
-rw-r--r--storage/innobase/handler/ha_innodb.cc11
-rw-r--r--storage/innobase/rem/rem0rec.c5
-rw-r--r--storage/innobase/row/row0upd.c179
9 files changed, 202 insertions, 59 deletions
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake
index c1dc5a54958..69a8c19ab1d 100644
--- a/cmake/wsrep.cmake
+++ b/cmake/wsrep.cmake
@@ -17,7 +17,7 @@
# so WSREP_VERSION is produced regardless
# Set the patch version
-SET(WSREP_PATCH_VERSION "7a")
+SET(WSREP_PATCH_VERSION "7.1")
# Obtain patch revision number
SET(WSREP_PATCH_REVNO $ENV{WSREP_REV})
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 7d413fe737a..47082f6bb18 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2363,6 +2363,9 @@ static my_socket activate_tcp_port(uint port)
socket_errno);
unireg_abort(1);
}
+#if defined(WITH_WSREP) && defined(HAVE_FCNTL)
+ (void) fcntl(ip_sock, F_SETFD, FD_CLOEXEC);
+#endif /* WITH_WSREP */
DBUG_RETURN(ip_sock);
}
@@ -2484,6 +2487,9 @@ static void network_init(void)
if (listen(unix_sock,(int) back_log) < 0)
sql_print_warning("listen() on Unix socket failed with error %d",
socket_errno);
+#if defined(WITH_WSREP) && defined(HAVE_FCNTL)
+ (void) fcntl(unix_sock, F_SETFD, FD_CLOEXEC);
+#endif /* WITH_WSREP */
}
#endif
DBUG_PRINT("info",("server started"));
@@ -6366,6 +6372,9 @@ void handle_connections_sockets()
sleep(1); // Give other threads some time
continue;
}
+#if defined(WITH_WSREP) && defined(HAVE_FCNTL)
+ (void) fcntl(new_sock, F_SETFD, FD_CLOEXEC);
+#endif /* WITH_WSREP */
#ifdef HAVE_LIBWRAP
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index e3df253f873..81ad091cca6 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -3677,9 +3677,7 @@ static Sys_var_charptr Sys_wsrep_node_incoming_address(
"wsrep_node_incoming_address", "Client connection address",
GLOBAL_VAR(wsrep_node_incoming_address),CMD_LINE(REQUIRED_ARG),
IN_FS_CHARSET, DEFAULT(wsrep_node_incoming_address),
- NO_MUTEX_GUARD, NOT_IN_BINLOG,
- ON_CHECK(wsrep_node_name_check),
- ON_UPDATE(wsrep_node_name_update));
+ NO_MUTEX_GUARD, NOT_IN_BINLOG);
static Sys_var_ulong Sys_wsrep_slave_threads(
"wsrep_slave_threads", "Number of slave appliers to launch",
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 62397c58a6e..9e1c84b897e 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -30,9 +30,6 @@ my_bool wsrep_emulate_bin_log = FALSE; // activating parts of binlog interface
*/
const char* wsrep_data_home_dir = NULL;
-
-#define WSREP_NODE_INCOMING_AUTO "AUTO"
-const char* wsrep_node_incoming_address = WSREP_NODE_INCOMING_AUTO;
const char* wsrep_dbug_option = "";
long wsrep_slave_threads = 1; // # of slave action appliers wanted
@@ -463,9 +460,9 @@ int wsrep_init()
wsrep_data_home_dir = mysql_real_data_home;
char node_addr[512]= { 0, };
+ size_t const node_addr_max= sizeof(node_addr) - 1;
if (!wsrep_node_address || !strcmp(wsrep_node_address, ""))
{
- size_t const node_addr_max= sizeof(node_addr);
size_t const ret= guess_ip(node_addr, node_addr_max);
if (!(ret > 0 && ret < node_addr_max))
{
@@ -476,11 +473,11 @@ int wsrep_init()
}
else
{
- strncpy(node_addr, wsrep_node_address, sizeof(node_addr) - 1);
+ strncpy(node_addr, wsrep_node_address, node_addr_max);
}
- static char inc_addr[512]= { 0, };
-
+ char inc_addr[512]= { 0, };
+ size_t const inc_addr_max= sizeof (inc_addr);
if ((!wsrep_node_incoming_address ||
!strcmp (wsrep_node_incoming_address, WSREP_NODE_INCOMING_AUTO)))
{
@@ -490,7 +487,6 @@ int wsrep_init()
const char* const colon= strrchr(node_addr, ':');
if (strchr(node_addr, ':') == colon) // 1 or 0 ':'
{
- size_t const inc_addr_max= sizeof (inc_addr);
size_t const ip_len= colon ? colon - node_addr : node_addr_len;
if (ip_len + 7 /* :55555\0 */ < inc_addr_max)
{
@@ -512,22 +508,41 @@ int wsrep_init()
}
}
- // this is to display detected address on SHOW VARIABLES...
- wsrep_node_incoming_address = inc_addr;
-
- if (!strlen(wsrep_node_incoming_address))
+ if (!strlen(inc_addr))
{
WSREP_WARN("Guessing address for incoming client connections failed. "
"Try setting wsrep_node_incoming_address explicitly.");
}
}
+ else if (!strchr(wsrep_node_incoming_address, ':')) // no port included
+ {
+ if ((int)inc_addr_max <=
+ snprintf(inc_addr, inc_addr_max, "%s:%u",
+ wsrep_node_incoming_address,(int)mysqld_port))
+ {
+ WSREP_WARN("Guessing address for incoming client connections: "
+ "address too long.");
+ inc_addr[0]= '\0';
+ }
+ }
+ else
+ {
+ size_t const need = strlen (wsrep_node_incoming_address);
+ if (need >= inc_addr_max) {
+ WSREP_WARN("wsrep_node_incoming_address too long: %zu", need);
+ inc_addr[0]= '\0';
+ }
+ else {
+ memcpy (inc_addr, wsrep_node_incoming_address, need);
+ }
+ }
struct wsrep_init_args wsrep_args;
wsrep_args.data_dir = wsrep_data_home_dir;
wsrep_args.node_name = (wsrep_node_name) ? wsrep_node_name : "";
wsrep_args.node_address = node_addr;
- wsrep_args.node_incoming = wsrep_node_incoming_address;
+ wsrep_args.node_incoming = inc_addr;
wsrep_args.options = (wsrep_provider_options) ?
wsrep_provider_options : "";
wsrep_args.proto_ver = wsrep_max_protocol_version;
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index e9cd227efcf..0709a2c1f34 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -114,7 +114,9 @@ extern const char* wsrep_provider_vendor;
extern int wsrep_show_status(THD *thd, SHOW_VAR *var, char *buff);
extern void wsrep_free_status(THD *thd);
-#define WSREP_SST_ADDRESS_AUTO "AUTO"
+#define WSREP_SST_ADDRESS_AUTO "AUTO"
+#define WSREP_NODE_INCOMING_AUTO "AUTO"
+
// MySQL variables funcs
#define CHECK_ARGS (sys_var *self, THD* thd, set_var *var)
diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc
index 36d73369c7d..c79c0a6a19f 100644
--- a/sql/wsrep_var.cc
+++ b/sql/wsrep_var.cc
@@ -31,8 +31,8 @@ const char* wsrep_provider_options = 0;
const char* wsrep_cluster_address = 0;
const char* wsrep_cluster_name = 0;
const char* wsrep_node_name = 0;
-static char node_address[256] = { 0, };
-const char* wsrep_node_address = node_address; // ???
+const char* wsrep_node_address = 0;
+const char* wsrep_node_incoming_address = 0;
const char* wsrep_start_position = 0;
ulong wsrep_OSU_method_options;
static int wsrep_thread_change = 0;
@@ -44,6 +44,8 @@ int wsrep_init_vars()
wsrep_cluster_address = my_strdup("", MYF(MY_WME));
wsrep_cluster_name = my_strdup(WSREP_CLUSTER_NAME, MYF(MY_WME));
wsrep_node_name = my_strdup("", MYF(MY_WME));
+ wsrep_node_address = my_strdup("", MYF(MY_WME));
+ wsrep_node_incoming_address= my_strdup(WSREP_NODE_INCOMING_AUTO, MYF(MY_WME));
wsrep_start_position = my_strdup(WSREP_START_POSITION_ZERO, MYF(MY_WME));
global_system_variables.binlog_format=BINLOG_FORMAT_ROW;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 42150429078..f0f889cad86 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4978,6 +4978,7 @@ wsrep_store_key_val_for_row(
/* Pad the unused space with spaces. */
+#ifdef REMOVED
if (true_len < key_len) {
ulint pad_len = key_len - true_len;
ut_a(!(pad_len % cs->mbminlen));
@@ -4986,6 +4987,7 @@ wsrep_store_key_val_for_row(
0x20 /* space */);
buff += pad_len;
}
+#endif /* REMOVED */
}
}
@@ -7281,6 +7283,15 @@ ha_innobase::wsrep_append_keys(
DBUG_ENTER("wsrep_append_keys");
trx_t *trx = thd_to_trx(thd);
+ if (table_share && table_share->tmp_table != NO_TMP_TABLE) {
+ WSREP_DEBUG("skipping tmp table DML: THD: %lu tmp: %d SQL: %s",
+ wsrep_thd_thread_id(thd),
+ table_share->tmp_table,
+ (wsrep_thd_query(thd)) ?
+ wsrep_thd_query(thd) : "void");
+ DBUG_RETURN(0);
+ }
+
/* if no PK, calculate hash of full row, to be the key value */
if (prebuilt->clust_index_was_generated && wsrep_certify_nonPK) {
uchar digest[16];
diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c
index d921889aaef..0e8f606c311 100644
--- a/storage/innobase/rem/rem0rec.c
+++ b/storage/innobase/rem/rem0rec.c
@@ -1865,7 +1865,8 @@ wsrep_rec_get_foreign_key(
}
case DATA_VARCHAR:
case DATA_VARMYSQL:
- case DATA_BINARY:
+ case DATA_CHAR:
+ case DATA_MYSQL:
/* Copy the actual data */
ut_memcpy(buf, data, len);
wsrep_innobase_mysql_sort(
@@ -1876,7 +1877,7 @@ wsrep_rec_get_foreign_key(
buf, len);
break;
case DATA_BLOB:
- case DATA_MYSQL:
+ case DATA_BINARY:
memcpy(buf, data, len);
break;
default:
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index 8469d688c5c..c5c51d8283d 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -51,6 +51,9 @@ Created 12/27/1996 Heikki Tuuri
#include "pars0sym.h"
#include "eval0eval.h"
#include "buf0lru.h"
+#ifdef WITH_WSREP
+extern my_bool wsrep_debug;
+#endif
/* What kind of latch and lock can we assume when the control comes to
@@ -178,36 +181,6 @@ ulint wsrep_append_foreign_key(trx_t *trx,
ibool referenced,
ibool shared);
-static
-void
-wsrep_append_fk_reference(
-/*=================================*/
- upd_node_t* node, /*!< in: row update node */
- dict_table_t* table, /*!< in: table in question */
- dict_index_t* index, /*!< in: index of the cursor */
- que_thr_t* thr, /*!< in: query thread */
- const rec_t* rec
-) {
- dict_foreign_t *foreign = UT_LIST_GET_FIRST(table->foreign_list);
-
- while (foreign) {
- if (foreign->foreign_index == index
- && node->is_delete)
- {
- if (DB_SUCCESS != wsrep_append_foreign_key(
- thr_get_trx(thr),
- foreign,
- rec,
- index,
- TRUE, TRUE)
- ) {
- fprintf(stderr,
- "WSREP: FK key append failed\n");
- }
- }
- foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
- }
-}
#endif /* WITH_WSREP */
/*********************************************************************//**
@@ -332,6 +305,122 @@ func_exit:
return(err);
}
+#ifdef WITH_WSREP
+static
+ulint
+wsrep_row_upd_check_foreign_constraints(
+/*=================================*/
+ upd_node_t* node, /*!< in: row update node */
+ btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
+ cursor position is lost in this function! */
+ dict_table_t* table, /*!< in: table in question */
+ dict_index_t* index, /*!< in: index of the cursor */
+ ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
+{
+ dict_foreign_t* foreign;
+ mem_heap_t* heap;
+ dtuple_t* entry;
+ trx_t* trx;
+ const rec_t* rec;
+ ulint n_ext;
+ ulint err;
+ ibool got_s_lock = FALSE;
+
+ if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) {
+
+ return(DB_SUCCESS);
+ }
+
+ trx = thr_get_trx(thr);
+
+ rec = btr_pcur_get_rec(pcur);
+ ut_ad(rec_offs_validate(rec, index, offsets));
+
+ heap = mem_heap_create(500);
+
+ entry = row_rec_to_index_entry(ROW_COPY_DATA, rec, index, offsets,
+ &n_ext, heap);
+
+ mtr_commit(mtr);
+
+ mtr_start(mtr);
+
+ if (trx->dict_operation_lock_mode == 0) {
+ got_s_lock = TRUE;
+
+ row_mysql_freeze_data_dictionary(trx);
+ }
+
+ foreign = UT_LIST_GET_FIRST(table->foreign_list);
+
+ while (foreign) {
+ /* Note that we may have an update which updates the index
+ record, but does NOT update the first fields which are
+ referenced in a foreign key constraint. Then the update does
+ NOT break the constraint. */
+
+ if (foreign->foreign_index == index
+ && (node->is_delete
+ || row_upd_changes_first_fields_binary(
+ entry, index, node->update,
+ foreign->n_fields))) {
+
+ if (foreign->referenced_table == NULL) {
+ dict_table_get(foreign->referenced_table_name_lookup,
+ FALSE);
+ }
+
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)++;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ /* NOTE that if the thread ends up waiting for a lock
+ we will release dict_operation_lock temporarily!
+ But the counter on the table protects 'foreign' from
+ being dropped while the check is running. */
+
+ err = row_ins_check_foreign_constraint(
+ TRUE, foreign, table, entry, thr);
+
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ ut_a(foreign->referenced_table
+ ->n_foreign_key_checks_running > 0);
+
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)--;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ if (err != DB_SUCCESS) {
+
+ goto func_exit;
+ }
+ }
+
+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
+ }
+
+ err = DB_SUCCESS;
+func_exit:
+ if (got_s_lock) {
+ row_mysql_unfreeze_data_dictionary(trx);
+ }
+
+ mem_heap_free(heap);
+
+ return(err);
+}
+#endif /* WITH_WSREP */
/*********************************************************************//**
Creates an update node for a query graph.
@@ -1687,8 +1776,18 @@ row_upd_sec_index_entry(
}
#ifdef WITH_WSREP
if (err == DB_SUCCESS && !referenced) {
- wsrep_append_fk_reference(node, index->table,
- index, thr, rec);
+ ulint* offsets =
+ rec_get_offsets(
+ rec, index, NULL, ULINT_UNDEFINED,
+ &heap);
+ uint werr = wsrep_row_upd_check_foreign_constraints(
+ node, &pcur, index->table,
+ index, offsets, thr, &mtr);
+
+ if (wsrep_debug && werr != DB_SUCCESS)
+ fprintf (stderr,
+ "WSREP: FK check fail: %u",
+ werr);
}
#endif /* WITH_WSREP */
}
@@ -1934,8 +2033,12 @@ err_exit:
}
#ifdef WITH_WSREP
if (!referenced) {
- wsrep_append_fk_reference(node, index->table,
- index, thr, rec);
+ uint werr = wsrep_row_upd_check_foreign_constraints(
+ node, pcur, table, index, offsets, thr, mtr);
+ if (wsrep_debug && werr != DB_SUCCESS)
+ fprintf (stderr,
+ "WSREP: FK check fail: %u",
+ werr);
}
#endif /* WITH_WSREP */
}
@@ -2173,13 +2276,15 @@ row_upd_del_mark_clust_rec(
if (err == DB_SUCCESS && referenced) {
/* NOTE that the following call loses the position of pcur ! */
- err = row_upd_check_references_constraints(
+ err = wsrep_row_upd_check_foreign_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
}
#ifdef WITH_WSREP
if (err == DB_SUCCESS && !referenced) {
- wsrep_append_fk_reference(node, index->table,
- index, thr, rec);
+ uint werr = row_upd_check_references_constraints(
+ node, pcur, index->table, index, offsets, thr, mtr);
+ if (wsrep_debug && werr != DB_SUCCESS)
+ fprintf (stderr, "WSREP: FK check fail: %u", werr);
}
#endif /* WITH_WSREP */