Commit a1e5a284 authored by Alexey Yurchenko's avatar Alexey Yurchenko Committed by Julius Goryavsky

MDEV-31809 Automatic SST user account management

Implement automatic creation of temporary accounts for SST and pass
account credentials to SST script via socket as opposed to environment
variables. Delete the user after the SST script returns,

Respect wsrep_sst_auth set by the adminitrator in case some additional
privilege grants are needed for particular SST method.

mysqldump SST requires significant change to make use of the new
automatic user generation facility. For now just make it compatible
by ignoring automatically generated user and rely only on wsrep_sst_auth
setting on the joiner node to keep backward compatibility.

Adapt mysqldump SST to automatic SST user generation changes:
 - disable special treatment for mysqldump SST on donor
 - make mysqldump SST script compatible with the new SST script
   interface.

Differentiate user privileges for different SST methods:
 - grant minimum required privileges for clone and xtrabackup SST
   accounts
 - grant all privileges to custom SST accounts as it is not known what
   is needed.
 - disable SST account generation for rsync SST since it is not needed.

MTR tests:
 - add MTR tests for clone and xtrabackup SSTs without wsrep_sst_auth,
 - add MTR test for testing masking of wsrep_sst_auth.
 - don't attmept to restore original wsrep_sst_auth in MTR tests as it
   is always masked.
Signed-off-by: default avatarJulius Goryavsky <julius.goryavsky@mariadb.com>
parent 1aa1a7cf
...@@ -49,7 +49,7 @@ WSREP_SLAVE_FK_CHECKS ON ...@@ -49,7 +49,7 @@ WSREP_SLAVE_FK_CHECKS ON
WSREP_SLAVE_THREADS 1 WSREP_SLAVE_THREADS 1
WSREP_SLAVE_UK_CHECKS OFF WSREP_SLAVE_UK_CHECKS OFF
WSREP_SR_STORE table WSREP_SR_STORE table
WSREP_SST_AUTH WSREP_SST_AUTH ********
WSREP_SST_DONOR WSREP_SST_DONOR
WSREP_SST_DONOR_REJECTS_QUERIES OFF WSREP_SST_DONOR_REJECTS_QUERIES OFF
WSREP_SST_METHOD rsync WSREP_SST_METHOD rsync
......
--- r/galera_sst_mariabackup.result
+++ r/galera_sst_mariabackup.reject
@@ -516,5 +516,189 @@
1
DROP TABLE t1;
COMMIT;
+Performing State Transfer on a server that has been killed and restarted
+while a DDL was in progress on it
+connection node_1;
+CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 VALUES (1,'node1_committed_before');
+INSERT INTO t1 VALUES (2,'node1_committed_before');
+INSERT INTO t1 VALUES (3,'node1_committed_before');
+INSERT INTO t1 VALUES (4,'node1_committed_before');
+INSERT INTO t1 VALUES (5,'node1_committed_before');
+connection node_2;
+START TRANSACTION;
+INSERT INTO t1 VALUES (6,'node2_committed_before');
+INSERT INTO t1 VALUES (7,'node2_committed_before');
+INSERT INTO t1 VALUES (8,'node2_committed_before');
+INSERT INTO t1 VALUES (9,'node2_committed_before');
+INSERT INTO t1 VALUES (10,'node2_committed_before');
+COMMIT;
+SET GLOBAL debug_dbug = 'd,sync.alter_opened_table';
+connection node_1;
+ALTER TABLE t1 ADD COLUMN f2 INTEGER;
+connection node_2;
+SET wsrep_sync_wait = 0;
+Killing server ...
+connection node_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (id,f1) VALUES (11,'node1_committed_during');
+INSERT INTO t1 (id,f1) VALUES (12,'node1_committed_during');
+INSERT INTO t1 (id,f1) VALUES (13,'node1_committed_during');
+INSERT INTO t1 (id,f1) VALUES (14,'node1_committed_during');
+INSERT INTO t1 (id,f1) VALUES (15,'node1_committed_during');
+COMMIT;
+START TRANSACTION;
+INSERT INTO t1 (id,f1) VALUES (16,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (17,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (18,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (19,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (20,'node1_to_be_committed_after');
+connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (id,f1) VALUES (21,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (22,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (23,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (24,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (25,'node1_to_be_rollbacked_after');
+connection node_2;
+Performing --wsrep-recover ...
+connection node_2;
+Starting server ...
+Using --wsrep-start-position when starting mysqld ...
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (id,f1) VALUES (26,'node2_committed_after');
+INSERT INTO t1 (id,f1) VALUES (27,'node2_committed_after');
+INSERT INTO t1 (id,f1) VALUES (28,'node2_committed_after');
+INSERT INTO t1 (id,f1) VALUES (29,'node2_committed_after');
+INSERT INTO t1 (id,f1) VALUES (30,'node2_committed_after');
+COMMIT;
+connection node_1;
+INSERT INTO t1 (id,f1) VALUES (31,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (32,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (33,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (34,'node1_to_be_committed_after');
+INSERT INTO t1 (id,f1) VALUES (35,'node1_to_be_committed_after');
+COMMIT;
+SET AUTOCOMMIT=OFF;
+START TRANSACTION;
+INSERT INTO t1 (id,f1) VALUES (36,'node1_committed_after');
+INSERT INTO t1 (id,f1) VALUES (37,'node1_committed_after');
+INSERT INTO t1 (id,f1) VALUES (38,'node1_committed_after');
+INSERT INTO t1 (id,f1) VALUES (39,'node1_committed_after');
+INSERT INTO t1 (id,f1) VALUES (40,'node1_committed_after');
+COMMIT;
+connection node_1a_galera_st_kill_slave_ddl;
+INSERT INTO t1 (id,f1) VALUES (41,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (42,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (43,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (44,'node1_to_be_rollbacked_after');
+INSERT INTO t1 (id,f1) VALUES (45,'node1_to_be_rollbacked_after');
+ROLLBACK;
+SET AUTOCOMMIT=ON;
+SET SESSION wsrep_sync_wait=15;
+SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
+EXPECT_3
+3
+SELECT COUNT(*) AS EXPECT_35 FROM t1;
+EXPECT_35
+35
+SELECT * FROM t1;
+id f1 f2
+1 node1_committed_before NULL
+2 node1_committed_before NULL
+3 node1_committed_before NULL
+4 node1_committed_before NULL
+5 node1_committed_before NULL
+6 node2_committed_before NULL
+7 node2_committed_before NULL
+8 node2_committed_before NULL
+9 node2_committed_before NULL
+10 node2_committed_before NULL
+11 node1_committed_during NULL
+12 node1_committed_during NULL
+13 node1_committed_during NULL
+14 node1_committed_during NULL
+15 node1_committed_during NULL
+16 node1_to_be_committed_after NULL
+17 node1_to_be_committed_after NULL
+18 node1_to_be_committed_after NULL
+19 node1_to_be_committed_after NULL
+20 node1_to_be_committed_after NULL
+26 node2_committed_after NULL
+27 node2_committed_after NULL
+28 node2_committed_after NULL
+29 node2_committed_after NULL
+30 node2_committed_after NULL
+31 node1_to_be_committed_after NULL
+32 node1_to_be_committed_after NULL
+33 node1_to_be_committed_after NULL
+34 node1_to_be_committed_after NULL
+35 node1_to_be_committed_after NULL
+36 node1_committed_after NULL
+37 node1_committed_after NULL
+38 node1_committed_after NULL
+39 node1_committed_after NULL
+40 node1_committed_after NULL
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+COMMIT;
+connection node_1;
+SET AUTOCOMMIT=ON;
+SET SESSION wsrep_sync_wait=15;
+SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1';
+EXPECT_3
+3
+SELECT COUNT(*) AS EXPECT_35 FROM t1;
+EXPECT_35
+35
+SELECT * FROM t1;
+id f1 f2
+1 node1_committed_before NULL
+2 node1_committed_before NULL
+3 node1_committed_before NULL
+4 node1_committed_before NULL
+5 node1_committed_before NULL
+6 node2_committed_before NULL
+7 node2_committed_before NULL
+8 node2_committed_before NULL
+9 node2_committed_before NULL
+10 node2_committed_before NULL
+11 node1_committed_during NULL
+12 node1_committed_during NULL
+13 node1_committed_during NULL
+14 node1_committed_during NULL
+15 node1_committed_during NULL
+16 node1_to_be_committed_after NULL
+17 node1_to_be_committed_after NULL
+18 node1_to_be_committed_after NULL
+19 node1_to_be_committed_after NULL
+20 node1_to_be_committed_after NULL
+26 node2_committed_after NULL
+27 node2_committed_after NULL
+28 node2_committed_after NULL
+29 node2_committed_after NULL
+30 node2_committed_after NULL
+31 node1_to_be_committed_after NULL
+32 node1_to_be_committed_after NULL
+33 node1_to_be_committed_after NULL
+34 node1_to_be_committed_after NULL
+35 node1_to_be_committed_after NULL
+36 node1_committed_after NULL
+37 node1_committed_after NULL
+38 node1_committed_after NULL
+39 node1_committed_after NULL
+40 node1_committed_after NULL
+SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
+COUNT(*) = 0
+1
+DROP TABLE t1;
+COMMIT;
+SET GLOBAL debug_dbug = $debug_orig;
disconnect node_2;
disconnect node_1;
!include ../galera_2nodes.cnf
[mysqld]
wsrep_sst_method=mariabackup
wsrep_debug=1
[mysqld.1]
wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true'
[mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
[sst]
transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=mbstream
--source include/big_test.inc
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_mariabackup.inc
# Save original auto_increment_offset values.
--let $node_1=node_1
--let $node_2=node_2
--source include/auto_increment_offset_save.inc
--source suite/galera/include/galera_st_shutdown_slave.inc
--source suite/galera/include/galera_st_clean_slave.inc
--source suite/galera/include/galera_st_kill_slave.inc
--source suite/galera/include/galera_st_kill_slave_ddl.inc
# Restore original auto_increment_offset values.
--source include/auto_increment_offset_restore.inc
--source include/galera_end.inc
...@@ -20,7 +20,6 @@ call mtr.add_suppression("Failed to load slave replication state from table mysq ...@@ -20,7 +20,6 @@ call mtr.add_suppression("Failed to load slave replication state from table mysq
CREATE USER 'sst'; CREATE USER 'sst';
GRANT ALL PRIVILEGES ON *.* TO 'sst'; GRANT ALL PRIVILEGES ON *.* TO 'sst';
--let $wsrep_sst_auth_orig = `SELECT @@wsrep_sst_auth`
SET GLOBAL wsrep_sst_auth = 'sst:'; SET GLOBAL wsrep_sst_auth = 'sst:';
--connection node_2 --connection node_2
......
# #
# wsrep_sst_auth # wsrep_sst_auth
# #
# save the initial value
SET @wsrep_sst_auth_global_saved = @@global.wsrep_sst_auth;
# default # default
SELECT @@global.wsrep_sst_auth; SELECT @@global.wsrep_sst_auth;
@@global.wsrep_sst_auth @@global.wsrep_sst_auth
...@@ -47,6 +45,4 @@ NULL ...@@ -47,6 +45,4 @@ NULL
SET @@global.wsrep_sst_auth=user:pass; SET @@global.wsrep_sst_auth=user:pass;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':pass' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ':pass' at line 1
# restore the initial value
SET @@global.wsrep_sst_auth = @wsrep_sst_auth_global_saved;
# End of test # End of test
...@@ -4,9 +4,6 @@ ...@@ -4,9 +4,6 @@
--echo # wsrep_sst_auth --echo # wsrep_sst_auth
--echo # --echo #
--echo # save the initial value
SET @wsrep_sst_auth_global_saved = @@global.wsrep_sst_auth;
--echo # default --echo # default
SELECT @@global.wsrep_sst_auth; SELECT @@global.wsrep_sst_auth;
...@@ -39,7 +36,4 @@ SELECT @@global.wsrep_sst_auth; ...@@ -39,7 +36,4 @@ SELECT @@global.wsrep_sst_auth;
SET @@global.wsrep_sst_auth=user:pass; SET @@global.wsrep_sst_auth=user:pass;
--echo --echo
--echo # restore the initial value
SET @@global.wsrep_sst_auth = @wsrep_sst_auth_global_saved;
--echo # End of test --echo # End of test
...@@ -1057,19 +1057,55 @@ if ! wsrep_auth_not_set; then ...@@ -1057,19 +1057,55 @@ if ! wsrep_auth_not_set; then
fi fi
fi fi
readonly WSREP_SST_OPT_USER WSREP_SST_OPT_REMOTE_USER=
readonly WSREP_SST_OPT_PSWD WSREP_SST_OPT_REMOTE_PSWD=
readonly WSREP_SST_OPT_AUTH
if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]; then if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]; then
# Split auth string at the last ':' # Split auth string at the last ':'
readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}" readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}"
readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}" readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}"
else
readonly WSREP_SST_OPT_REMOTE_USER=
readonly WSREP_SST_OPT_REMOTE_PSWD=
fi fi
# Reads incoming data from STDIN and sets the variables
#
# Globals:
# WSREP_SST_OPT_USER (sets this variable)
# WSREP_SST_OPT_PSWD (sets this variable)
#
# Parameters:
# None
#
read_variables_from_stdin()
{
while read line; do
key=${line%%=*}
value=${line#*=}
case "$key" in
'sst_user')
WSREP_SST_OPT_USER="$value"
;;
'sst_password')
WSREP_SST_OPT_PSWD="$value"
;;
'sst_remote_user')
WSREP_SST_OPT_REMOTE_USER="$value"
;;
'sst_remote_password')
WSREP_SST_OPT_REMOTE_PSWD="$value"
;;
*)
wsrep_log_warning "Unrecognized input: $line"
esac
done
return 0
}
[ "$WSREP_SST_OPT_ROLE" = "donor" ] && read_variables_from_stdin || :
readonly WSREP_SST_OPT_USER
readonly WSREP_SST_OPT_PSWD
readonly WSREP_SST_OPT_AUTH
readonly WSREP_SST_OPT_REMOTE_USER
readonly WSREP_SST_OPT_REMOTE_PSWD
readonly WSREP_SST_OPT_REMOTE_AUTH readonly WSREP_SST_OPT_REMOTE_AUTH
if [ -n "$WSREP_SST_OPT_DATA" ]; then if [ -n "$WSREP_SST_OPT_DATA" ]; then
......
...@@ -62,13 +62,21 @@ fi ...@@ -62,13 +62,21 @@ fi
# whereas (at least on Linux) unprivileged user can't see process environment # whereas (at least on Linux) unprivileged user can't see process environment
# that he does not own. So while it may be not secure in the NSA sense of the # that he does not own. So while it may be not secure in the NSA sense of the
# word, it is arguably more secure than passing password on the command line. # word, it is arguably more secure than passing password on the command line.
if [ -n "$WSREP_SST_OPT_PSWD" ]; then if [ -n "$WSREP_SST_OPT_REMOTE_PSWD" ]; then
export MYSQL_PWD="$WSREP_SST_OPT_PSWD" export MYSQL_PWD="$WSREP_SST_OPT_REMOTE_PSWD"
elif [ $usrst -eq 1 ]; then elif [ $usrst -eq 1 ]; then
# Empty password, used for testing, debugging etc. # Empty password, used for testing, debugging etc.
unset MYSQL_PWD unset MYSQL_PWD
fi fi
# The above also means that both donor and joiner must have the same
# wsrep_sst_auth configuration and and different (and thus automatically
# generated) authentication credentials can't be used for this type of SST
# In this case the SST will fail if joiner does not provide correct
# authentication.
[ -n "$WSREP_SST_OPT_REMOTE_USER" ] && REMOTE_AUTH="-u$WSREP_SST_OPT_REMOTE_USER" || REMOTE_AUTH=
[ -n "$REMOTE_AUTH" ] && AUTH="$REMOTE_AUTH" || AUTH=
STOP_WSREP='SET wsrep_on=OFF;' STOP_WSREP='SET wsrep_on=OFF;'
# mysqldump cannot restore CSV tables, fix this issue # mysqldump cannot restore CSV tables, fix this issue
...@@ -91,6 +99,7 @@ PREPARE stmt FROM @stmt; ...@@ -91,6 +99,7 @@ PREPARE stmt FROM @stmt;
EXECUTE stmt; EXECUTE stmt;
DROP PREPARE stmt;" DROP PREPARE stmt;"
STATE="$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID"
SET_START_POSITION="SET GLOBAL wsrep_start_position='$WSREP_SST_OPT_GTID';" SET_START_POSITION="SET GLOBAL wsrep_start_position='$WSREP_SST_OPT_GTID';"
SET_WSREP_GTID_DOMAIN_ID="" SET_WSREP_GTID_DOMAIN_ID=""
...@@ -104,7 +113,7 @@ if [ -n "$WSREP_SST_OPT_GTID_DOMAIN_ID" ]; then ...@@ -104,7 +113,7 @@ if [ -n "$WSREP_SST_OPT_GTID_DOMAIN_ID" ]; then
fi fi
MYSQL="$MYSQL_CLIENT$WSREP_SST_OPT_CONF_UNQUOTED "\ MYSQL="$MYSQL_CLIENT$WSREP_SST_OPT_CONF_UNQUOTED "\
"$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\ "$REMOTE_AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\
"-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10"
# Check if binary logging is enabled on the joiner node. # Check if binary logging is enabled on the joiner node.
...@@ -169,5 +178,7 @@ else ...@@ -169,5 +178,7 @@ else
echo "$SET_START_POSITION" | $MYSQL || exit $? echo "$SET_START_POSITION" | $MYSQL || exit $?
fi fi
echo "done $STATE"
wsrep_log_info "$WSREP_METHOD $WSREP_TRANSFER_TYPE completed on $WSREP_SST_OPT_ROLE" wsrep_log_info "$WSREP_METHOD $WSREP_TRANSFER_TYPE completed on $WSREP_SST_OPT_ROLE"
exit 0 exit 0
...@@ -1819,7 +1819,6 @@ static void close_connections(void) ...@@ -1819,7 +1819,6 @@ static void close_connections(void)
{ {
wsrep_deinit(true); wsrep_deinit(true);
} }
wsrep_sst_auth_free();
#endif #endif
/* All threads has now been aborted */ /* All threads has now been aborted */
DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)",
......
...@@ -6212,7 +6212,7 @@ static Sys_var_charptr Sys_wsrep_sst_receive_address( ...@@ -6212,7 +6212,7 @@ static Sys_var_charptr Sys_wsrep_sst_receive_address(
static Sys_var_charptr Sys_wsrep_sst_auth( static Sys_var_charptr Sys_wsrep_sst_auth(
"wsrep_sst_auth", "Authentication for SST connection", "wsrep_sst_auth", "Authentication for SST connection",
PREALLOCATED GLOBAL_VAR(wsrep_sst_auth), CMD_LINE(REQUIRED_ARG), PREALLOCATED GLOBAL_VAR(wsrep_sst_auth), CMD_LINE(REQUIRED_ARG),
DEFAULT(NULL), NO_MUTEX_GUARD, DEFAULT(WSREP_SST_AUTH_DEFAULT), NO_MUTEX_GUARD,
NOT_IN_BINLOG, NOT_IN_BINLOG,
ON_CHECK(wsrep_sst_auth_check), ON_CHECK(wsrep_sst_auth_check),
ON_UPDATE(wsrep_sst_auth_update)); ON_UPDATE(wsrep_sst_auth_update));
......
...@@ -97,6 +97,9 @@ int wsrep_check_opts() ...@@ -97,6 +97,9 @@ int wsrep_check_opts()
return 1; return 1;
} }
} }
wsrep_sst_auth_set(wsrep_sst_auth);
return 0; return 0;
} }
...@@ -849,6 +849,12 @@ void wsrep_init_globals() ...@@ -849,6 +849,12 @@ void wsrep_init_globals()
} }
} }
wsrep_init_schema(); wsrep_init_schema();
{
/* apparently this thread has already called my_thread_init(),
* so we skip it, hence 'false' for initialization. */
wsp::thd thd(false, true);
wsrep_sst_cleanup_user(thd.ptr);
}
if (WSREP_ON) if (WSREP_ON)
{ {
Wsrep_server_state::instance().initialized(); Wsrep_server_state::instance().initialized();
...@@ -868,7 +874,6 @@ int wsrep_init() ...@@ -868,7 +874,6 @@ int wsrep_init()
assert(wsrep_provider); assert(wsrep_provider);
wsrep_init_position(); wsrep_init_position();
wsrep_sst_auth_init();
if (!*wsrep_provider || if (!*wsrep_provider ||
!strcasecmp(wsrep_provider, WSREP_NONE)) !strcasecmp(wsrep_provider, WSREP_NONE))
...@@ -1060,11 +1065,6 @@ void wsrep_deinit(bool free_options) ...@@ -1060,11 +1065,6 @@ void wsrep_deinit(bool free_options)
wsrep_provider_capabilities= NULL; wsrep_provider_capabilities= NULL;
free(p); free(p);
} }
if (free_options)
{
wsrep_sst_auth_free();
}
} }
/* Destroy wsrep thread LOCKs and CONDs */ /* Destroy wsrep thread LOCKs and CONDs */
......
This diff is collapsed.
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
#define WSREP_SST_XTRABACKUPV2 "xtrabackupv2" #define WSREP_SST_XTRABACKUPV2 "xtrabackupv2"
#define WSREP_SST_DEFAULT WSREP_SST_RSYNC #define WSREP_SST_DEFAULT WSREP_SST_RSYNC
#define WSREP_SST_ADDRESS_AUTO "AUTO" #define WSREP_SST_ADDRESS_AUTO "AUTO"
#define WSREP_SST_AUTH_MASK "********" #define WSREP_SST_AUTH_DEFAULT NULL
/* system variables */ /* system variables */
extern const char* wsrep_sst_method; extern const char* wsrep_sst_method;
...@@ -71,7 +71,7 @@ extern void wsrep_sst_grab(); ...@@ -71,7 +71,7 @@ extern void wsrep_sst_grab();
extern bool wsrep_sst_wait(); extern bool wsrep_sst_wait();
/*! Signals wsrep that initialization is complete, writesets can be applied */ /*! Signals wsrep that initialization is complete, writesets can be applied */
extern bool wsrep_sst_continue(); extern bool wsrep_sst_continue();
extern void wsrep_sst_auth_init(); extern bool wsrep_sst_auth_set(const char* value);
extern void wsrep_sst_auth_free(); extern void wsrep_sst_auth_free();
extern void wsrep_SE_init_grab(); /*! grab init critical section */ extern void wsrep_SE_init_grab(); /*! grab init critical section */
...@@ -98,6 +98,12 @@ int wsrep_sst_donate(const std::string& request, ...@@ -98,6 +98,12 @@ int wsrep_sst_donate(const std::string& request,
const wsrep::gtid& gtid, const wsrep::gtid& gtid,
bool bypass); bool bypass);
/**
Cleanup stale SST users from the database records
@param thd wsp::thd object (wraps initialized THD* pointer)
*/
void wsrep_sst_cleanup_user(THD* thd);
#else #else
#define wsrep_SE_initialized() do { } while(0) #define wsrep_SE_initialized() do { } while(0)
#define wsrep_SE_init_grab() do { } while(0) #define wsrep_SE_init_grab() do { } while(0)
......
...@@ -404,11 +404,13 @@ process::process (const char* cmd, const char* type, char** env) ...@@ -404,11 +404,13 @@ process::process (const char* cmd, const char* type, char** env)
if (read_from_child) if (read_from_child)
{ {
setup_parent_pipe_end(READ, read_pipe, READ_END, "r"); setup_parent_pipe_end(READ, read_pipe, READ_END, "r");
assert(from());
} }
if (write_to_child) if (write_to_child)
{ {
setup_parent_pipe_end(WRITE, write_pipe, WRITE_END, "w"); setup_parent_pipe_end(WRITE, write_pipe, WRITE_END, "w");
assert(to());
} }
cleanup_fact: cleanup_fact:
...@@ -532,6 +534,40 @@ thd::~thd () ...@@ -532,6 +534,40 @@ thd::~thd ()
} }
} }
mysql::mysql() :
mysql_(mysql_init(NULL))
{
int err = 0;
if (mysql_real_connect_local(mysql_) == NULL) {
err = mysql_errno(mysql_);
WSREP_ERROR("mysql::mysql() mysql_real_connect() failed: %d (%s)",
err, mysql_error(mysql_));
}
}
mysql::~mysql()
{
mysql_close(mysql_);
}
int
mysql::disable_replication()
{
int err = execute("SET SESSION sql_log_bin = OFF;");
if (err) {
WSREP_ERROR("sst_user::user() disabling log_bin failed: %d (%s)",
err, errstr());
}
else {
err = execute("SET SESSION wsrep_on = OFF;");
if (err) {
WSREP_ERROR("sst_user::user() disabling wsrep replication failed: %d (%s)",
err, errstr());
}
}
return err;
}
} // namespace wsp } // namespace wsp
/* Returns INADDR_NONE, INADDR_ANY, INADDR_LOOPBACK or something else */ /* Returns INADDR_NONE, INADDR_ANY, INADDR_LOOPBACK or something else */
......
...@@ -340,6 +340,28 @@ class thd ...@@ -340,6 +340,28 @@ class thd
THD* const ptr; THD* const ptr;
}; };
/* local server connection */
class mysql
{
MYSQL* mysql_;
public:
mysql();
~mysql();
int execute(const std::string& query) {
if (mysql_real_query(mysql_, query.c_str(), query.length())) {
return mysql_errno(mysql_);
}
return 0;
}
int errnum() {
return (mysql_errno(mysql_));
}
const char* errstr() {
return mysql_error(mysql_);
}
int disable_replication();
};
class string class string
{ {
public: public:
......
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