summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/mariadb-galera-server-10.0.mysql.init12
-rw-r--r--mysql-test/suite/galera/r/galera_read_only.result10
-rw-r--r--mysql-test/suite/galera/t/galera_read_only.test18
-rw-r--r--mysys/my_alloc.c5
-rw-r--r--sql/mysqld.cc71
-rw-r--r--sql/sql_parse.cc20
-rw-r--r--sql/wsrep_mysqld.cc8
-rw-r--r--sql/wsrep_mysqld.h1
-rw-r--r--support-files/mysql.server.sh8
9 files changed, 119 insertions, 34 deletions
diff --git a/debian/mariadb-galera-server-10.0.mysql.init b/debian/mariadb-galera-server-10.0.mysql.init
index 46911aa57a1..a59013f8047 100644
--- a/debian/mariadb-galera-server-10.0.mysql.init
+++ b/debian/mariadb-galera-server-10.0.mysql.init
@@ -17,6 +17,9 @@ set -e
set -u
${DEBIAN_SCRIPT_DEBUG:+ set -v -x}
+# Prevent Debian's init scripts from calling systemctl
+_SYSTEMCTL_SKIP_REDIRECT=true
+
test -x /usr/sbin/mysqld || exit 0
. /lib/lsb/init-functions
@@ -179,8 +182,15 @@ case "${1:-''}" in
fi
;;
+ 'bootstrap')
+ # Bootstrap the cluster, start the first node
+ # that initiates the cluster
+ log_daemon_msg "Bootstrapping the cluster" "mysqld"
+ $SELF start "${@:2}" --wsrep-new-cluster
+ ;;
+
*)
- echo "Usage: $SELF start|stop|restart|reload|force-reload|status"
+ echo "Usage: $SELF start|stop|restart|reload|force-reload|status|bootstrap"
exit 1
;;
esac
diff --git a/mysql-test/suite/galera/r/galera_read_only.result b/mysql-test/suite/galera/r/galera_read_only.result
index d2af3867fe7..82736c5f4ba 100644
--- a/mysql-test/suite/galera/r/galera_read_only.result
+++ b/mysql-test/suite/galera/r/galera_read_only.result
@@ -4,5 +4,15 @@ INSERT INTO t1 VALUES (1);
SELECT COUNT(*) = 1 FROM t1;
COUNT(*) = 1
1
+CREATE USER foo@localhost;
+# Open connection to node 2 using 'foo' user.
+
+# Connect with foo_node_2
+INSERT INTO t1 VALUES (2);
+ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement
+SELECT COUNT(*) = 1 FROM t1;
+COUNT(*) = 1
+1
SET GLOBAL read_only=FALSE;
DROP TABLE t1;
+DROP USER foo@localhost;
diff --git a/mysql-test/suite/galera/t/galera_read_only.test b/mysql-test/suite/galera/t/galera_read_only.test
index 828f35d2ba3..c0fa4af07e0 100644
--- a/mysql-test/suite/galera/t/galera_read_only.test
+++ b/mysql-test/suite/galera/t/galera_read_only.test
@@ -17,7 +17,23 @@ INSERT INTO t1 VALUES (1);
--connection node_2
SELECT COUNT(*) = 1 FROM t1;
-SET GLOBAL read_only=FALSE;
+CREATE USER foo@localhost;
+
+--echo # Open connection to node 2 using 'foo' user.
+--let $port_2= \$NODE_MYPORT_2
+--connect(foo_node_2,127.0.0.1,foo,,test,$port_2,)
+--echo
+--echo # Connect with foo_node_2
+--connection foo_node_2
+--error ER_OPTION_PREVENTS_STATEMENT
+INSERT INTO t1 VALUES (2);
+
+--connection node_2
+SELECT COUNT(*) = 1 FROM t1;
+
+# Cleanup
+SET GLOBAL read_only=FALSE;
DROP TABLE t1;
+DROP USER foo@localhost;
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index fc30185eb5a..f0ebad9cf30 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -104,6 +104,7 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
size_t pre_alloc_size __attribute__((unused)))
{
+ DBUG_ENTER("reset_root_defaults");
DBUG_ASSERT(alloc_root_inited(mem_root));
mem_root->block_size= (((block_size - ALLOC_ROOT_MIN_BLOCK_SIZE) & ~1) |
@@ -126,7 +127,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
{
/* We found a suitable block, no need to do anything else */
mem_root->pre_alloc= mem;
- return;
+ DBUG_VOID_RETURN;
}
if (mem->left + ALIGN_SIZE(sizeof(USED_MEM)) == mem->size)
{
@@ -156,6 +157,8 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
else
#endif
mem_root->pre_alloc= 0;
+
+ DBUG_VOID_RETURN;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 9154b84cfe8..f75f5440279 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5104,6 +5104,39 @@ static int init_server_components()
}
plugins_are_initialized= TRUE; /* Don't separate from init function */
+#ifdef WITH_WSREP
+ /* Wait for wsrep threads to get created. */
+ if (wsrep_creating_startup_threads == 1) {
+ mysql_mutex_lock(&LOCK_thread_count);
+ while (wsrep_running_threads < 2)
+ {
+ mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
+ }
+
+ /* Now is the time to initialize threads for queries. */
+ THD *tmp;
+ I_List_iterator<THD> it(threads);
+ while ((tmp= it++))
+ {
+ if (tmp->wsrep_applier == true)
+ {
+ /*
+ Set THR_THD to temporally point to this THD to register all the
+ variables that allocates memory for this THD.
+ */
+ THD *current_thd_saved= current_thd;
+ set_current_thd(tmp);
+
+ tmp->init_for_queries();
+
+ /* Restore current_thd. */
+ set_current_thd(current_thd_saved);
+ }
+ }
+ mysql_mutex_unlock(&LOCK_thread_count);
+ }
+#endif
+
/* we do want to exit if there are any other unknown options */
if (remaining_argc > 1)
{
@@ -5340,16 +5373,11 @@ pthread_handler_t start_wsrep_THD(void *arg)
THD *thd;
wsrep_thd_processor_fun processor= (wsrep_thd_processor_fun)arg;
- if (my_thread_init())
+ if (my_thread_init() || (!(thd= new THD(true))))
{
- WSREP_ERROR("Could not initialize thread");
- return(NULL);
+ goto error;
}
- if (!(thd= new THD(true)))
- {
- return(NULL);
- }
mysql_mutex_lock(&LOCK_thread_count);
thd->thread_id=thread_id++;
@@ -5374,13 +5402,13 @@ pthread_handler_t start_wsrep_THD(void *arg)
mysql_thread_set_psi_id(thd->thread_id);
thd->thr_create_utime= microsecond_interval_timer();
+
if (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0))
{
close_connection(thd, ER_OUT_OF_RESOURCES);
statistic_increment(aborted_connects,&LOCK_status);
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
-
- return(NULL);
+ goto error;
}
// </5.1.17>
@@ -5403,8 +5431,7 @@ pthread_handler_t start_wsrep_THD(void *arg)
statistic_increment(aborted_connects,&LOCK_status);
MYSQL_CALLBACK(thread_scheduler, end_thread, (thd, 0));
delete thd;
-
- return(NULL);
+ goto error;
}
thd->system_thread= SYSTEM_THREAD_SLAVE_SQL;
@@ -5414,12 +5441,21 @@ pthread_handler_t start_wsrep_THD(void *arg)
//thd->version= refresh_version;
thd->proc_info= 0;
thd->set_command(COM_SLEEP);
- thd->set_time();
- thd->init_for_queries();
+
+ if (wsrep_creating_startup_threads == 0)
+ {
+ thd->init_for_queries();
+ }
mysql_mutex_lock(&LOCK_thread_count);
wsrep_running_threads++;
mysql_cond_broadcast(&COND_thread_count);
+
+ if (wsrep_running_threads > 2)
+ {
+ wsrep_creating_startup_threads= 0;
+ }
+
mysql_mutex_unlock(&LOCK_thread_count);
processor(thd);
@@ -5457,6 +5493,15 @@ pthread_handler_t start_wsrep_THD(void *arg)
mysql_mutex_unlock(&LOCK_thread_count);
}
return(NULL);
+
+error:
+ WSREP_ERROR("Failed to create/initialize system thread");
+
+ /* Abort if its the first applier/rollbacker thread. */
+ if (wsrep_creating_startup_threads < 2)
+ unireg_abort(1);
+ else
+ return NULL;
}
/**/
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index af35a2a3b55..ca7b236eb04 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1199,22 +1199,6 @@ static my_bool deny_updates_if_read_only_option(THD *thd,
}
#ifdef WITH_WSREP
-static my_bool wsrep_read_only_option(THD *thd, TABLE_LIST *all_tables)
-{
- int opt_readonly_saved = opt_readonly;
- ulong flag_saved = (ulong)(thd->security_ctx->master_access & SUPER_ACL);
-
- opt_readonly = 0;
- thd->security_ctx->master_access &= ~SUPER_ACL;
-
- my_bool ret = !deny_updates_if_read_only_option(thd, all_tables);
-
- opt_readonly = opt_readonly_saved;
- thd->security_ctx->master_access |= flag_saved;
-
- return ret;
-}
-
static void wsrep_copy_query(THD *thd)
{
thd->wsrep_retry_command = thd->get_command();
@@ -1228,6 +1212,7 @@ static void wsrep_copy_query(THD *thd)
thd->wsrep_retry_query[thd->wsrep_retry_query_len] = '\0';
}
#endif /* WITH_WSREP */
+
/**
Perform one connection-level (COM_XXXX) command.
@@ -6989,8 +6974,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
bool is_autocommit=
!thd->in_multi_stmt_transaction_mode() &&
thd->wsrep_conflict_state == NO_CONFLICT &&
- !thd->wsrep_applier &&
- wsrep_read_only_option(thd, thd->lex->query_tables);
+ !thd->wsrep_applier;
do
{
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 20ba2d7a51a..b05214682e6 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -71,6 +71,13 @@ my_bool wsrep_restart_slave_activated = 0; // node has dropped, and slave
// restart will be needed
my_bool wsrep_slave_UK_checks = 0; // slave thread does UK checks
my_bool wsrep_slave_FK_checks = 0; // slave thread does FK checks
+
+/*
+ Set during the creation of first wsrep applier and rollback threads.
+ Since these threads are critical, abort if the thread creation fails.
+*/
+my_bool wsrep_creating_startup_threads = 0;
+
/*
* End configuration options
*/
@@ -671,6 +678,7 @@ void wsrep_init_startup (bool first)
if (!wsrep_start_replication()) unireg_abort(1);
+ wsrep_creating_startup_threads= 1;
wsrep_create_rollbacker();
wsrep_create_appliers(1);
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 414284f45fd..4e0d2f4128f 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -107,6 +107,7 @@ extern my_bool wsrep_restart_slave_activated;
extern my_bool wsrep_slave_FK_checks;
extern my_bool wsrep_slave_UK_checks;
extern bool wsrep_new_cluster; // bootstrap the cluster ?
+extern my_bool wsrep_creating_startup_threads;
enum enum_wsrep_OSU_method {
WSREP_OSU_TOI,
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
index 104ad436843..76a0622589e 100644
--- a/support-files/mysql.server.sh
+++ b/support-files/mysql.server.sh
@@ -24,6 +24,14 @@
# Short-Description: start and stop MySQL
# Description: MySQL is a very fast and reliable SQL database engine.
### END INIT INFO
+
+# Prevent OpenSUSE's init scripts from calling systemd, so that
+# both 'bootstrap' and 'start' are handled entirely within this
+# script
+SYSTEMD_NO_WRAP=1
+
+# Prevent Debian's init scripts from calling systemctl
+_SYSTEMCTL_SKIP_REDIRECT=true
# If you install MySQL on some other places than @prefix@, then you
# have to do one of the following things for this script to work: