summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS22
-rw-r--r--client/mysqladmin.cc98
-rw-r--r--client/mysqlbinlog.cc2
-rw-r--r--debian/mariadb-server-10.1.mysql-server.logrotate3
-rw-r--r--extra/yassl/src/ssl.cpp1
-rw-r--r--include/my_global.h7
-rw-r--r--man/mysqladmin.112
-rwxr-xr-xmysql-test/mysql-test-run.pl5
-rw-r--r--mysql-test/r/alter_table.result21
-rw-r--r--mysql-test/r/contributors.result14
-rw-r--r--mysql-test/r/sp.result38
-rw-r--r--mysql-test/suite/innodb/r/alter_key_block_size-11757.result47
-rw-r--r--mysql-test/suite/innodb/t/alter_key_block_size-11757.test23
-rw-r--r--mysql-test/suite/perfschema/include/pfs_no_running_event_scheduler.inc10
-rw-r--r--mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc10
-rw-r--r--mysql-test/suite/perfschema/t/threads_mysql.test18
-rw-r--r--mysql-test/t/alter_table.test11
-rw-r--r--mysql-test/t/sp.test40
-rw-r--r--mysql-test/valgrind.supp9
-rw-r--r--mysys/hash.c12
-rw-r--r--mysys/mf_iocache.c5
-rw-r--r--sql/contributors.h14
-rw-r--r--sql/event_scheduler.cc40
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item_func.cc8
-rw-r--r--sql/log.cc42
-rw-r--r--sql/log_event.cc17
-rw-r--r--sql/log_event_old.cc4
-rw-r--r--sql/mysql_install_db.cc4
-rw-r--r--sql/mysqld.cc101
-rw-r--r--sql/mysqld.h6
-rw-r--r--sql/nt_servc.cc2
-rw-r--r--sql/nt_servc.h2
-rw-r--r--sql/rpl_mi.cc412
-rw-r--r--sql/rpl_mi.h19
-rw-r--r--sql/rpl_parallel.cc126
-rw-r--r--sql/rpl_parallel.h1
-rw-r--r--sql/rpl_rli.cc15
-rw-r--r--sql/rpl_rli.h2
-rw-r--r--sql/slave.cc137
-rw-r--r--sql/slave.h3
-rw-r--r--sql/sql_alter.h35
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_class.cc6
-rw-r--r--sql/sql_parse.cc66
-rw-r--r--sql/sql_reload.cc56
-rw-r--r--sql/sql_repl.cc78
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/sys_vars.cc127
-rw-r--r--storage/connect/ha_connect.cc6
-rw-r--r--storage/connect/ioapi.c21
-rw-r--r--storage/connect/zip.c14
-rw-r--r--storage/innobase/fil/fil0fil.cc7
-rw-r--r--storage/innobase/log/log0log.cc12
-rw-r--r--storage/innobase/os/os0file.cc7
-rw-r--r--storage/mroonga/vendor/groonga/lib/CMakeLists.txt12
-rw-r--r--storage/myisam/ha_myisam.cc68
-rw-r--r--storage/myisam/ha_myisam.h2
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.result2
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.test2
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.result2
-rw-r--r--storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.test2
-rw-r--r--storage/xtradb/fil/fil0fil.cc7
-rw-r--r--storage/xtradb/log/log0log.cc12
-rw-r--r--storage/xtradb/os/os0file.cc7
-rw-r--r--support-files/mysql-log-rotate.sh3
-rw-r--r--support-files/rpm/server-postin.sh5
68 files changed, 1283 insertions, 648 deletions
diff --git a/CREDITS b/CREDITS
index 35ab4d48a8f..d352232ad2e 100644
--- a/CREDITS
+++ b/CREDITS
@@ -3,16 +3,18 @@ organization registered in the USA.
The current main sponsors of the MariaDB Foundation are:
-Booking.com http://www.booking.com (2013 - 2016)
-Development Bank of Singapore http://dbs.com (2016)
-MariaDB Corporation https://www.mariadb.com (2013 - 2016)
-Visma http://visma.com (2015 - 2016)
-Acronis http://acronis.com (2016)
-Nexedi https://www.nexedi.com (2016)
-Automattic https://automattic.com (2014 - 2016)
-Tencent Game DBA http://tencentdba.com/about (2016)
-Verkkokauppa.com https://www.verkkokauppa.com (2015 - 2016)
-Virtuozzo https://virtuozzo.com (2016)
+Alibaba Cloud https://intl.aliyun.com (2017)
+Booking.com https://www.booking.com (2013 - 2017)
+Development Bank of Singapore https://dbs.com (2016 - 2017)
+MariaDB Corporation https://www.mariadb.com (2013 - 2017)
+Visma https://visma.com (2015 - 2017)
+Acronis http://acronis.com (2016 - 2017)
+Nexedi https://www.nexedi.com (2016 - 2017)
+Automattic https://automattic.com (2014 - 2017)
+Tencent Game DBA http://tencentdba.com/about (2016 - 2017)
+Tencent TDSQL http://tdsql.org/ (2016 - 2017)
+Verkkokauppa.com https://www.verkkokauppa.com (2015 - 2017)
+Virtuozzo https://virtuozzo.com (2016 - 2017)
For a full list of sponsors, see
https://mariadb.org/about/supporters/
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 9642903ae79..d090fe20a01 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -38,8 +38,8 @@ char ex_var_names[MAX_MYSQL_VAR][FN_REFLEN];
ulonglong last_values[MAX_MYSQL_VAR];
static int interval=0;
static my_bool option_force=0,interrupted=0,new_line=0,
- opt_compress=0, opt_relative=0, opt_verbose=0, opt_vertical=0,
- tty_password= 0, opt_nobeep;
+ opt_compress= 0, opt_local= 0, opt_relative= 0, opt_verbose= 0,
+ opt_vertical= 0, tty_password= 0, opt_nobeep;
static my_bool debug_info_flag= 0, debug_check_flag= 0;
static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations;
static uint opt_count_iterations= 0, my_end_arg;
@@ -102,9 +102,12 @@ enum commands {
ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS,
ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE,
ADMIN_START_ALL_SLAVES, ADMIN_STOP_ALL_SLAVES,
- ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_SLOW_LOG,
+ ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_BINARY_LOG,
+ ADMIN_FLUSH_ENGINE_LOG, ADMIN_FLUSH_ERROR_LOG, ADMIN_FLUSH_GENERAL_LOG,
+ ADMIN_FLUSH_RELAY_LOG, ADMIN_FLUSH_SLOW_LOG,
ADMIN_FLUSH_TABLE_STATISTICS, ADMIN_FLUSH_INDEX_STATISTICS,
ADMIN_FLUSH_USER_STATISTICS, ADMIN_FLUSH_CLIENT_STATISTICS,
+ ADMIN_FLUSH_USER_RESOURCES,
ADMIN_FLUSH_ALL_STATUS, ADMIN_FLUSH_ALL_STATISTICS
};
static const char *command_names[]= {
@@ -116,9 +119,10 @@ static const char *command_names[]= {
"ping", "extended-status", "flush-status",
"flush-privileges", "start-slave", "stop-slave",
"start-all-slaves", "stop-all-slaves",
- "flush-threads", "old-password", "flush-slow-log",
+ "flush-threads", "old-password", "flush-binary-log", "flush-engine-log",
+ "flush-error-log", "flush-general-log", "flush-relay-log", "flush-slow-log",
"flush-table-statistics", "flush-index-statistics",
- "flush-user-statistics", "flush-client-statistics",
+ "flush-user-statistics", "flush-client-statistics", "flush-user-resources",
"flush-all-status", "flush-all-statistics",
NullS
};
@@ -160,6 +164,9 @@ static struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", &host, &host, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"local", 'l', "Local command, don't write to binlog.",
+ &opt_local, &opt_local, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ 0, 0, 0},
{"no-beep", 'b', "Turn off beep on error.", &opt_nobeep,
&opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"password", 'p',
@@ -617,6 +624,18 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
*/
struct my_rnd_struct rand_st;
+ char buff[FN_REFLEN + 20];
+
+ if (opt_local)
+ {
+ sprintf(buff, "set local sql_log_bin=0");
+ if (mysql_query(mysql, buff))
+ {
+ my_printf_error(0, "SET LOCAL SQL_LOG_BIN=0 failed; error: '%-.200s'",
+ error_flags, mysql_error(mysql));
+ return -1;
+ }
+ }
for (; argc > 0 ; argv++,argc--)
{
@@ -624,7 +643,6 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
switch ((command= find_type(argv[0],&command_typelib,FIND_TYPE_BASIC))) {
case ADMIN_CREATE:
{
- char buff[FN_REFLEN+20];
if (argc < 2)
{
my_printf_error(0, "Too few arguments to create", error_flags);
@@ -899,6 +917,56 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
break;
}
+ case ADMIN_FLUSH_BINARY_LOG:
+ {
+ if (mysql_query(mysql, "flush binary logs"))
+ {
+ my_printf_error(0, "flush failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ break;
+ }
+ case ADMIN_FLUSH_ENGINE_LOG:
+ {
+ if (mysql_query(mysql,"flush engine logs"))
+ {
+ my_printf_error(0, "flush failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ break;
+ }
+ case ADMIN_FLUSH_ERROR_LOG:
+ {
+ if (mysql_query(mysql, "flush error logs"))
+ {
+ my_printf_error(0, "flush failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ break;
+ }
+ case ADMIN_FLUSH_GENERAL_LOG:
+ {
+ if (mysql_query(mysql, "flush general logs"))
+ {
+ my_printf_error(0, "flush failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ break;
+ }
+ case ADMIN_FLUSH_RELAY_LOG:
+ {
+ if (mysql_query(mysql, "flush relay logs"))
+ {
+ my_printf_error(0, "flush failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ break;
+ }
case ADMIN_FLUSH_SLOW_LOG:
{
if (mysql_query(mysql,"flush slow logs"))
@@ -969,6 +1037,16 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
}
break;
}
+ case ADMIN_FLUSH_USER_RESOURCES:
+ {
+ if (mysql_query(mysql, "flush user_resources"))
+ {
+ my_printf_error(0, "flush failed; error: '%s'", error_flags,
+ mysql_error(mysql));
+ return -1;
+ }
+ break;
+ }
case ADMIN_FLUSH_CLIENT_STATISTICS:
{
if (mysql_query(mysql,"flush client_statistics"))
@@ -1292,12 +1370,18 @@ static void usage(void)
flush-index-statistics Flush index statistics\n\
flush-logs Flush all logs\n\
flush-privileges Reload grant tables (same as reload)\n\
+ flush-binary-log Flush binary log\n\
+ flush-engine-log Flush engine log(s)\n\
+ flush-error-log Flush error log\n\
+ flush-general-log Flush general log\n\
+ flush-relay-log Flush relay log\n\
flush-slow-log Flush slow query log\n\
- flush-status Clear status variables\n\
+ flush-status Clear status variables\n\
flush-table-statistics Clear table statistics\n\
flush-tables Flush all tables\n\
flush-threads Flush the thread cache\n\
flush-user-statistics Flush user statistics\n\
+ flush-user-resources Flush user resources\n\
kill id,id,... Kill mysql threads");
#if MYSQL_VERSION_ID >= 32200
puts("\
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index e27a4a8e4e3..4699503d5bc 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -110,7 +110,7 @@ static const char* sock= 0;
static char *opt_plugindir= 0, *opt_default_auth= 0;
#ifdef HAVE_SMEM
-static char *shared_memory_base_name= 0;
+static const char *shared_memory_base_name= 0;
#endif
static char* user = 0;
static char* pass = 0;
diff --git a/debian/mariadb-server-10.1.mysql-server.logrotate b/debian/mariadb-server-10.1.mysql-server.logrotate
index a19e9ec46a2..dbe2a7e7dfe 100644
--- a/debian/mariadb-server-10.1.mysql-server.logrotate
+++ b/debian/mariadb-server-10.1.mysql-server.logrotate
@@ -14,7 +14,8 @@
if [ -f `my_print_defaults --mysqld | grep -oP "pid-file=\K[^$]+"` ]; then
# If this fails, check debian.conf!
- mysqladmin --defaults-file=/etc/mysql/debian.cnf flush-logs
+ mysqladmin --defaults-file=/etc/mysql/debian.cnf --local flush-error-log \
+ flush-engine-log flush-general-log flush-slow-log
fi
endscript
}
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 7f4b0fd095f..28927c41c5c 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -774,7 +774,6 @@ int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
const char* path)
{
int ret = SSL_FAILURE;
- const int HALF_PATH = 128;
if (file) ret = read_file(ctx, file, SSL_FILETYPE_PEM, CA);
diff --git a/include/my_global.h b/include/my_global.h
index bca03bfc4d6..b958a8d9e28 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -1076,10 +1076,9 @@ typedef ulong myf; /* Type of MyFlags in my_funcs */
static inline char *dlerror(void)
{
static char win_errormsg[2048];
- if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
- 0, GetLastError(), 0, win_errormsg, 2048, NULL))
- return win_errormsg;
- return "";
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, GetLastError(), 0, win_errormsg, 2048, NULL);
+ return win_errormsg;
}
#define HAVE_DLOPEN 1
#define HAVE_DLERROR 1
diff --git a/man/mysqladmin.1 b/man/mysqladmin.1
index 14e34ed2f84..d974f569f1a 100644
--- a/man/mysqladmin.1
+++ b/man/mysqladmin.1
@@ -816,6 +816,18 @@ Connect to the MariaDB server on the given host\&.
.sp -1
.IP \(bu 2.3
.\}
+.\" mysqladmin: local option
+.\" local option: mysqladmin
+\fB\-\-local\fR,
+\fB\-l\fR
+.sp
+Suppress the SQL command(s) from being written to the binary log by enabled sql_log_bin=0 for the session\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
.\" mysqladmin: no-beep option
.\" no-beep option: mysqladmin
\fB\-\-no\-beep\fR,
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 5bc984ed496..57fdb10e9d7 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1170,7 +1170,7 @@ sub command_line_setup {
# Directories
'tmpdir=s' => \$opt_tmpdir,
'vardir=s' => \$opt_vardir,
- 'mem:s' => \$opt_mem,
+ 'mem' => \$opt_mem,
'clean-vardir' => \$opt_clean_vardir,
'client-bindir=s' => \$path_client_bindir,
'client-libdir=s' => \$path_client_libdir,
@@ -1433,9 +1433,6 @@ sub command_line_setup {
# Use $ENV{'MTR_MEM'} as first location to look (if defined)
unshift(@tmpfs_locations, $ENV{'MTR_MEM'}) if defined $ENV{'MTR_MEM'};
- # however if the opt_mem was given a value, use this first
- unshift(@tmpfs_locations, $opt_mem) if $opt_mem ne '';
-
foreach my $fs (@tmpfs_locations)
{
if ( -d $fs && ! -l $fs )
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index d203c3d99bd..35d9e97a380 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -2101,6 +2101,27 @@ Note 1061 Duplicate key name 'id1'
DROP TABLE t2;
DROP TABLE t1;
#
+# MDEV-6390 CONVERT TO CHARACTER SET utf8 doesn't change DEFAULT CHARSET.
+#
+CREATE TABLE t1 (id int(11) NOT NULL, a int(11) NOT NULL, b int(11))
+ENGINE=InnoDB DEFAULT CHARSET=latin1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `a` int(11) NOT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 CONVERT TO CHARACTER SET utf8;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `a` int(11) NOT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=utf8
+DROP TABLE t1;
+#
# Start of 10.1 tests
#
#
diff --git a/mysql-test/r/contributors.result b/mysql-test/r/contributors.result
index f3f5e227d3a..4a26d0f19dd 100644
--- a/mysql-test/r/contributors.result
+++ b/mysql-test/r/contributors.result
@@ -1,15 +1,17 @@
SHOW CONTRIBUTORS;
Name Location Comment
-Booking.com http://www.booking.com Founding member, Platinum Sponsor of the MariaDB Foundation
+Booking.com https://www.booking.com Founding member, Platinum Sponsor of the MariaDB Foundation
+Alibaba Cloud https://intl.aliyun.com Platinum Sponsor of the MariaDB Foundation
MariaDB Corporation https://mariadb.com Founding member, Gold Sponsor of the MariaDB Foundation
-Visma http://visma.com Gold Sponsor of the MariaDB Foundation
-DBS http://dbs.com Gold Sponsor of the MariaDB Foundation
+Visma https://visma.com Gold Sponsor of the MariaDB Foundation
+DBS https://dbs.com Gold Sponsor of the MariaDB Foundation
Nexedi https://www.nexedi.com Silver Sponsor of the MariaDB Foundation
Acronis http://www.acronis.com Silver Sponsor of the MariaDB Foundation
Auttomattic https://automattic.com Bronze Sponsor of the MariaDB Foundation
-Verkkokauppa.com https://virtuozzo.com Bronze Sponsor of the MariaDB Foundation
-Virtuozzo https://virtuozzo.com/ Bronze Sponsor of the MariaDB Foundation
-Tencent Game DBA http://tencentdba.com/about/ Bronze Sponsor of the MariaDB Foundation
+Verkkokauppa.com https://www.verkkokauppa.com Bronze Sponsor of the MariaDB Foundation
+Virtuozzo https://virtuozzo.com Bronze Sponsor of the MariaDB Foundation
+Tencent Game DBA http://tencentdba.com/about Bronze Sponsor of the MariaDB Foundation
+Tencent TDSQL http://tdsql.org Bronze Sponsor of the MariaDB Foundation
Google USA Sponsoring encryption, parallel replication and GTID
Facebook USA Sponsoring non-blocking API, LIMIT ROWS EXAMINED etc
Ronald Bradford Brisbane, Australia EFF contribution for UC2006 Auction
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 4142fc0b796..d9b5dfd5a1f 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -7955,6 +7955,44 @@ set global table_open_cache= @tmp_toc;
set global table_definition_cache= @tmp_tdc;
drop procedure p1;
drop table t1,t2,t3,t4,t5,t6;
+#
+# MDEV-11935: Queries in stored procedures with and
+# EXISTS(SELECT * FROM VIEW) crashes and closes hte conneciton.
+#
+CREATE TABLE ANY_TABLE (
+ENTITY_UID BIGINT NOT NULL
+);
+CREATE TABLE SECURITY_PATH(
+origid BIGINT UNSIGNED NOT NULL,
+destid BIGINT UNSIGNED NOT NULL,
+KEY (destid)
+);
+CREATE VIEW ENTITY_ACCESS (
+ENTITY_UID,
+OWNER_UID
+) AS
+SELECT SP1.origid,
+SP2.destid
+FROM SECURITY_PATH SP1
+JOIN SECURITY_PATH SP2 ON SP1.destid = SP2.origid
+;
+CREATE PROCEDURE SP_EXAMPLE_SELECT ()
+BEGIN
+SELECT *
+FROM ANY_TABLE AT1
+WHERE EXISTS ( SELECT *
+FROM ENTITY_ACCESS EA
+WHERE AT1.ENTITY_UID = EA.ENTITY_UID
+AND EA.OWNER_UID IS NULL );
+END
+//
+CALL SP_EXAMPLE_SELECT ();
+ENTITY_UID
+CALL SP_EXAMPLE_SELECT ();
+ENTITY_UID
+drop procedure SP_EXAMPLE_SELECT;
+drop view ENTITY_ACCESS;
+drop table ANY_TABLE, SECURITY_PATH;
# End of 10.0 test
CREATE FUNCTION f(f1 VARCHAR(64) COLLATE latin1_german2_ci)
RETURNS VARCHAR(64)
diff --git a/mysql-test/suite/innodb/r/alter_key_block_size-11757.result b/mysql-test/suite/innodb/r/alter_key_block_size-11757.result
new file mode 100644
index 00000000000..400a3d0df3c
--- /dev/null
+++ b/mysql-test/suite/innodb/r/alter_key_block_size-11757.result
@@ -0,0 +1,47 @@
+set global innodb_file_format=barracuda;
+create table t1 (
+id1 bigint(20) not null,
+id2 bigint(20) not null,
+primary key (id1),
+unique key id2 (id2)
+) engine=innodb row_format=compressed key_block_size=8;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id1` bigint(20) NOT NULL,
+ `id2` bigint(20) NOT NULL,
+ PRIMARY KEY (`id1`),
+ UNIQUE KEY `id2` (`id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8
+alter table t1 row_format=dynamic;
+Warnings:
+Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=8 unless ROW_FORMAT=COMPRESSED.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id1` bigint(20) NOT NULL,
+ `id2` bigint(20) NOT NULL,
+ PRIMARY KEY (`id1`),
+ UNIQUE KEY `id2` (`id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=8
+alter table t1 key_block_size=0;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id1` bigint(20) NOT NULL,
+ `id2` bigint(20) NOT NULL,
+ PRIMARY KEY (`id1`) KEY_BLOCK_SIZE=8,
+ UNIQUE KEY `id2` (`id2`) KEY_BLOCK_SIZE=8
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+alter table t1 drop primary key, add primary key (id1),
+drop key id2, add unique (id2);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id1` bigint(20) NOT NULL,
+ `id2` bigint(20) NOT NULL,
+ PRIMARY KEY (`id1`),
+ UNIQUE KEY `id2` (`id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+drop table t1;
+set global innodb_file_format=default;
diff --git a/mysql-test/suite/innodb/t/alter_key_block_size-11757.test b/mysql-test/suite/innodb/t/alter_key_block_size-11757.test
new file mode 100644
index 00000000000..50a909870ba
--- /dev/null
+++ b/mysql-test/suite/innodb/t/alter_key_block_size-11757.test
@@ -0,0 +1,23 @@
+#
+# MDEV-11757 KEY_BLOCK_SIZE strangeness when UNCOMPRESSing COMPRESSed InnoDB tables
+#
+source include/have_innodb.inc;
+set global innodb_file_format=barracuda;
+
+create table t1 (
+ id1 bigint(20) not null,
+ id2 bigint(20) not null,
+ primary key (id1),
+ unique key id2 (id2)
+) engine=innodb row_format=compressed key_block_size=8;
+show create table t1;
+alter table t1 row_format=dynamic;
+show create table t1;
+alter table t1 key_block_size=0;
+show create table t1;
+alter table t1 drop primary key, add primary key (id1),
+ drop key id2, add unique (id2);
+show create table t1;
+drop table t1;
+
+set global innodb_file_format=default;
diff --git a/mysql-test/suite/perfschema/include/pfs_no_running_event_scheduler.inc b/mysql-test/suite/perfschema/include/pfs_no_running_event_scheduler.inc
new file mode 100644
index 00000000000..eff3d7df854
--- /dev/null
+++ b/mysql-test/suite/perfschema/include/pfs_no_running_event_scheduler.inc
@@ -0,0 +1,10 @@
+# threads are removed from:
+# - information_schema.processlist
+# - performance_schema.threads
+# at different times, so we may have to wait a little more
+# for the event_scheduler to shutdown
+#
+let $wait_condition=
+ SELECT COUNT(*) = 0 FROM performance_schema.threads
+ WHERE name like 'thread/sql/event%';
+--source include/wait_condition.inc
diff --git a/mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc b/mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc
new file mode 100644
index 00000000000..219a41051fb
--- /dev/null
+++ b/mysql-test/suite/perfschema/include/pfs_running_event_scheduler.inc
@@ -0,0 +1,10 @@
+# threads are removed from:
+# - information_schema.processlist
+# - performance_schema.threads
+# at different times, so we may have to wait a little more
+# for the event_scheduler to shutdown
+#
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM performance_schema.threads
+ WHERE name like 'thread/sql/event%';
+--source include/wait_condition.inc
diff --git a/mysql-test/suite/perfschema/t/threads_mysql.test b/mysql-test/suite/perfschema/t/threads_mysql.test
index 8576c8767d6..c33f421863e 100644
--- a/mysql-test/suite/perfschema/t/threads_mysql.test
+++ b/mysql-test/suite/perfschema/t/threads_mysql.test
@@ -9,22 +9,10 @@
# Ensure that the event scheduler (started via threads_mysql-master.opt)
# is really running.
---source include/running_event_scheduler.inc
+--source include/pfs_running_event_scheduler.inc
SET GLOBAL event_scheduler = OFF;
---source include/no_running_event_scheduler.inc
-
-# threads are removed from:
-# - information_schema.processlist
-# - performance_schema.threads
-# at different times, so we may have to wait a little more
-# for the event_scheduler to shutdown
-#
-let $wait_timeout= 1;
-let $wait_condition=
- SELECT COUNT(*) = 0 FROM performance_schema.threads
- WHERE name like 'thread/sql/event%';
---source include/wait_condition.inc
+--source include/pfs_no_running_event_scheduler.inc
--vertical_results
@@ -59,7 +47,7 @@ WHERE name LIKE 'thread/sql%';
SET GLOBAL event_scheduler = ON;
---source include/running_event_scheduler.inc
+--source include/pfs_running_event_scheduler.inc
# Show entries belonging to the just started event scheduler
SELECT name, type, processlist_user, processlist_host, processlist_db,
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 5a38abab1e5..32116cdaf55 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1757,6 +1757,17 @@ DROP TABLE t2;
DROP TABLE t1;
--echo #
+--echo # MDEV-6390 CONVERT TO CHARACTER SET utf8 doesn't change DEFAULT CHARSET.
+--echo #
+
+CREATE TABLE t1 (id int(11) NOT NULL, a int(11) NOT NULL, b int(11))
+ ENGINE=InnoDB DEFAULT CHARSET=latin1;
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 CONVERT TO CHARACTER SET utf8;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo #
--echo # Start of 10.1 tests
--echo #
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 3034f34d763..6eba2522089 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -9418,6 +9418,46 @@ drop procedure p1;
drop table t1,t2,t3,t4,t5,t6;
+--echo #
+--echo # MDEV-11935: Queries in stored procedures with and
+--echo # EXISTS(SELECT * FROM VIEW) crashes and closes hte conneciton.
+--echo #
+
+CREATE TABLE ANY_TABLE (
+ ENTITY_UID BIGINT NOT NULL
+);
+CREATE TABLE SECURITY_PATH(
+origid BIGINT UNSIGNED NOT NULL,
+destid BIGINT UNSIGNED NOT NULL,
+KEY (destid)
+);
+CREATE VIEW ENTITY_ACCESS (
+ENTITY_UID,
+OWNER_UID
+) AS
+SELECT SP1.origid,
+ SP2.destid
+FROM SECURITY_PATH SP1
+JOIN SECURITY_PATH SP2 ON SP1.destid = SP2.origid
+;
+--delimiter //
+CREATE PROCEDURE SP_EXAMPLE_SELECT ()
+BEGIN
+ SELECT *
+ FROM ANY_TABLE AT1
+ WHERE EXISTS ( SELECT *
+ FROM ENTITY_ACCESS EA
+ WHERE AT1.ENTITY_UID = EA.ENTITY_UID
+ AND EA.OWNER_UID IS NULL );
+END
+//
+--delimiter ;
+CALL SP_EXAMPLE_SELECT ();
+CALL SP_EXAMPLE_SELECT ();
+
+drop procedure SP_EXAMPLE_SELECT;
+drop view ENTITY_ACCESS;
+drop table ANY_TABLE, SECURITY_PATH;
--echo # End of 10.0 test
DELIMITER |;
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index c9ec5613dda..db44e49482a 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -1074,6 +1074,15 @@
fun:SSL_library_init
}
+{
+ OpenSSL still reachable.
+ Memcheck:Leak
+ fun:*alloc
+ fun:CRYPTO_malloc
+ fun:sk_new
+ fun:SSL_COMP_get_compression_methods
+ fun:SSL_library_init
+}
{
OpenSSL still reachable.
diff --git a/mysys/hash.c b/mysys/hash.c
index dc03ea9a4dc..d59e63bddc4 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -114,14 +114,19 @@ my_hash_init2(HASH *hash, uint growth_size, CHARSET_INFO *charset,
static inline void my_hash_free_elements(HASH *hash)
{
+ uint records= hash->records;
+ /*
+ Set records to 0 early to guard against anyone looking at the structure
+ during the free process
+ */
+ hash->records= 0;
if (hash->free)
{
HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
- HASH_LINK *end= data + hash->records;
+ HASH_LINK *end= data + records;
while (data < end)
(*hash->free)((data++)->data);
}
- hash->records=0;
}
@@ -518,6 +523,9 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
The record with the same record ptr is removed.
If there is a free-function it's called if record was found.
+ hash->free() is guarantee to be called only after the row has been
+ deleted from the hash and the hash can be reused by other threads.
+
@return
@retval 0 ok
@retval 1 Record not found
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 4afe74da077..510278c8a4d 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1876,6 +1876,7 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
It's currently safe to call this if one has called init_io_cache()
on the 'info' object, even if init_io_cache() failed.
This function is also safe to call twice with the same handle.
+ Note that info->file is not reset as the caller may still use ut for my_close()
RETURN
0 ok
@@ -1905,10 +1906,12 @@ int end_io_cache(IO_CACHE *info)
if (info->type == SEQ_READ_APPEND)
{
/* Destroy allocated mutex */
- info->type= TYPE_NOT_SET;
mysql_mutex_destroy(&info->append_buffer_lock);
}
info->share= 0;
+ info->type= TYPE_NOT_SET; /* Ensure that flush_io_cache() does nothing */
+ info->write_end= 0; /* Ensure that my_b_write() fails */
+ info->write_function= 0; /* my_b_write will crash if used */
DBUG_RETURN(error);
} /* end_io_cache */
diff --git a/sql/contributors.h b/sql/contributors.h
index 0359ec54022..3a771e2b493 100644
--- a/sql/contributors.h
+++ b/sql/contributors.h
@@ -37,16 +37,18 @@ struct show_table_contributors_st {
struct show_table_contributors_st show_table_contributors[]= {
/* MariaDB foundation sponsors, in contribution, size , time order */
- {"Booking.com", "http://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
+ {"Booking.com", "https://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
+ {"Alibaba Cloud", "https://intl.aliyun.com", "Platinum Sponsor of the MariaDB Foundation"},
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Gold Sponsor of the MariaDB Foundation"},
- {"Visma", "http://visma.com", "Gold Sponsor of the MariaDB Foundation"},
- {"DBS", "http://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
+ {"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
+ {"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
{"Nexedi", "https://www.nexedi.com", "Silver Sponsor of the MariaDB Foundation"},
{"Acronis", "http://www.acronis.com", "Silver Sponsor of the MariaDB Foundation"},
{"Auttomattic", "https://automattic.com", "Bronze Sponsor of the MariaDB Foundation"},
- {"Verkkokauppa.com", "https://virtuozzo.com", "Bronze Sponsor of the MariaDB Foundation"},
- {"Virtuozzo", "https://virtuozzo.com/", "Bronze Sponsor of the MariaDB Foundation"},
- {"Tencent Game DBA", "http://tencentdba.com/about/", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Verkkokauppa.com", "https://www.verkkokauppa.com", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Virtuozzo", "https://virtuozzo.com", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Tencent Game DBA", "http://tencentdba.com/about", "Bronze Sponsor of the MariaDB Foundation"},
+ {"Tencent TDSQL", "http://tdsql.org", "Bronze Sponsor of the MariaDB Foundation"},
/* Sponsors of important features */
{"Google", "USA", "Sponsoring encryption, parallel replication and GTID"},
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 95c5f6d9047..e02b618a80a 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -133,12 +133,6 @@ post_init_event_thread(THD *thd)
thd->cleanup();
return TRUE;
}
-
- thread_safe_increment32(&thread_count);
- mysql_mutex_lock(&LOCK_thread_count);
- threads.append(thd);
- mysql_mutex_unlock(&LOCK_thread_count);
- inc_thread_running();
return FALSE;
}
@@ -157,7 +151,13 @@ deinit_event_thread(THD *thd)
thd->proc_info= "Clearing";
DBUG_PRINT("exit", ("Event thread finishing"));
- delete_running_thd(thd);
+ mysql_mutex_lock(&LOCK_thread_count);
+ thd->unlink();
+ mysql_mutex_unlock(&LOCK_thread_count);
+
+ delete thd;
+ thread_safe_decrement32(&thread_count);
+ signal_thd_deleted();
}
@@ -191,8 +191,10 @@ pre_init_event_thread(THD* thd)
thd->net.read_timeout= slave_net_timeout;
thd->variables.option_bits|= OPTION_AUTO_IS_NULL;
thd->client_capabilities|= CLIENT_MULTI_RESULTS;
+ thread_safe_increment32(&thread_count);
mysql_mutex_lock(&LOCK_thread_count);
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
+ threads.append(thd);
mysql_mutex_unlock(&LOCK_thread_count);
/*
@@ -240,13 +242,8 @@ event_scheduler_thread(void *arg)
my_free(arg);
if (!res)
scheduler->run(thd);
- else
- {
- thd->proc_info= "Clearing";
- net_end(&thd->net);
- delete thd;
- }
+ deinit_event_thread(thd);
DBUG_LEAVE; // Against gcc warnings
my_thread_end();
return 0;
@@ -310,6 +307,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
DBUG_ENTER("Event_worker_thread::run");
DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd));
+ inc_thread_running();
if (res)
goto end;
@@ -338,6 +336,7 @@ end:
event->name.str));
delete event;
+ dec_thread_running();
deinit_event_thread(thd);
DBUG_VOID_RETURN;
@@ -442,13 +441,9 @@ Event_scheduler::start(int *err_no)
" Can not create thread for event scheduler (errno=%d)",
*err_no);
- new_thd->proc_info= "Clearing";
- DBUG_ASSERT(new_thd->net.buff != 0);
- net_end(&new_thd->net);
-
state= INITIALIZED;
scheduler_thd= NULL;
- delete new_thd;
+ deinit_event_thread(new_thd);
delete scheduler_param_value;
ret= true;
@@ -515,7 +510,6 @@ Event_scheduler::run(THD *thd)
}
LOCK_DATA();
- deinit_event_thread(thd);
scheduler_thd= NULL;
state= INITIALIZED;
DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers"));
@@ -575,10 +569,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
sql_print_error("Event_scheduler::execute_top: Can not create event worker"
" thread (errno=%d). Stopping event scheduler", res);
- new_thd->proc_info= "Clearing";
- DBUG_ASSERT(new_thd->net.buff != 0);
- net_end(&new_thd->net);
-
+ deinit_event_thread(new_thd);
goto error;
}
@@ -590,9 +581,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name)
error:
DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res));
- if (new_thd)
- delete new_thd;
-
delete event_name;
DBUG_RETURN(TRUE);
}
diff --git a/sql/handler.cc b/sql/handler.cc
index cca77eece48..7ac8dd63e9e 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4200,7 +4200,7 @@ enum_alter_inplace_result
handler::check_if_supported_inplace_alter(TABLE *altered_table,
Alter_inplace_info *ha_alter_info)
{
- DBUG_ENTER("check_if_supported_alter");
+ DBUG_ENTER("handler::check_if_supported_inplace_alter");
HA_CREATE_INFO *create_info= ha_alter_info->create_info;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 623ff1128f3..ee3fd2f6026 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3932,12 +3932,7 @@ longlong Item_master_pos_wait::val_int()
else
connection_name= thd->variables.default_master_connection;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index) // master_info_index is set to NULL on shutdown.
- mi= master_info_index->get_master_info(&connection_name,
- Sql_condition::WARN_LEVEL_WARN);
- mysql_mutex_unlock(&LOCK_active_mi);
- if (!mi)
+ if (!(mi= get_master_info(&connection_name, Sql_condition::WARN_LEVEL_WARN)))
goto err;
if ((event_count = mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2)
@@ -3945,6 +3940,7 @@ longlong Item_master_pos_wait::val_int()
null_value = 1;
event_count=0;
}
+ mi->release();
#endif
return event_count;
diff --git a/sql/log.cc b/sql/log.cc
index 5a4f883b0ac..4a1e9f26c4c 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2789,16 +2789,16 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name,
void MYSQL_QUERY_LOG::reopen_file()
{
char *save_name;
-
DBUG_ENTER("MYSQL_LOG::reopen_file");
+
+ mysql_mutex_lock(&LOCK_log);
if (!is_open())
{
DBUG_PRINT("info",("log is closed"));
+ mysql_mutex_unlock(&LOCK_log);
DBUG_VOID_RETURN;
}
- mysql_mutex_lock(&LOCK_log);
-
save_name= name;
name= 0; // Don't free name
close(LOG_CLOSE_TO_BE_OPENED);
@@ -2957,13 +2957,6 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
DBUG_ENTER("MYSQL_QUERY_LOG::write");
mysql_mutex_lock(&LOCK_log);
-
- if (!is_open())
- {
- mysql_mutex_unlock(&LOCK_log);
- DBUG_RETURN(0);
- }
-
if (is_open())
{ // Safety agains reopen
int tmp_errno= 0;
@@ -3207,7 +3200,9 @@ void MYSQL_BIN_LOG::cleanup()
}
inited= 0;
+ mysql_mutex_lock(&LOCK_log);
close(LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
+ mysql_mutex_unlock(&LOCK_log);
delete description_event_for_queue;
delete description_event_for_exec;
@@ -3374,6 +3369,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
DBUG_ENTER("MYSQL_BIN_LOG::open");
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
+ mysql_mutex_assert_owner(&LOCK_log);
+
if (!is_relay_log)
{
if (!binlog_state_recover_done)
@@ -4329,7 +4326,7 @@ void MYSQL_BIN_LOG::wait_for_last_checkpoint_event()
int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
{
- int error;
+ int error, errcode;
char *to_purge_if_included= NULL;
inuse_relaylog *ir;
ulonglong log_space_reclaimed= 0;
@@ -4397,7 +4394,8 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
}
/* Store where we are in the new file for the execution thread */
- flush_relay_log_info(rli);
+ if (flush_relay_log_info(rli))
+ error= LOG_INFO_IO;
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
@@ -4413,10 +4411,10 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
* Need to update the log pos because purge logs has been called
* after fetching initially the log pos at the begining of the method.
*/
- if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
+ if ((errcode= find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
{
sql_print_error("next log error: %d offset: %llu log: %s included: %d",
- error, rli->linfo.index_file_offset,
+ errcode, rli->linfo.index_file_offset,
rli->group_relay_log_name, included);
goto err;
}
@@ -5040,19 +5038,19 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
File UNINIT_VAR(old_file);
DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
+ if (need_lock)
+ mysql_mutex_lock(&LOCK_log);
+ mysql_mutex_assert_owner(&LOCK_log);
+
if (!is_open())
{
DBUG_PRINT("info",("log is closed"));
+ mysql_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
}
- if (need_lock)
- mysql_mutex_lock(&LOCK_log);
mysql_mutex_lock(&LOCK_index);
- mysql_mutex_assert_owner(&LOCK_log);
- mysql_mutex_assert_owner(&LOCK_index);
-
/* Reuse old name if not binlog and not update log */
new_name_ptr= name;
@@ -5189,9 +5187,9 @@ end:
new_name_ptr, errno);
}
+ mysql_mutex_unlock(&LOCK_index);
if (need_lock)
mysql_mutex_unlock(&LOCK_log);
- mysql_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
}
@@ -8133,9 +8131,11 @@ int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos(THD* thd,
void MYSQL_BIN_LOG::close(uint exiting)
{ // One can't set log_type here!
bool failed_to_save_state= false;
-
DBUG_ENTER("MYSQL_BIN_LOG::close");
DBUG_PRINT("enter",("exiting: %d", (int) exiting));
+
+ mysql_mutex_assert_owner(&LOCK_log);
+
if (log_state == LOG_OPENED)
{
#ifdef HAVE_REPLICATION
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 21b5de2725e..13a271d98da 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -6405,9 +6405,11 @@ bool Rotate_log_event::write()
@retval
0 ok
+ 1 error
*/
int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
{
+ int error= 0;
Relay_log_info *rli= rgi->rli;
DBUG_ENTER("Rotate_log_event::do_update_pos");
@@ -6456,7 +6458,7 @@ int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
(ulong) rli->group_master_log_pos));
mysql_mutex_unlock(&rli->data_lock);
rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
- flush_relay_log_info(rli);
+ error= flush_relay_log_info(rli);
/*
Reset thd->variables.option_bits and sql_mode etc, because this could
@@ -6474,8 +6476,7 @@ int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
else
rgi->inc_event_relay_log_pos();
-
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
@@ -8235,6 +8236,7 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
int Stop_log_event::do_update_pos(rpl_group_info *rgi)
{
+ int error= 0;
Relay_log_info *rli= rgi->rli;
DBUG_ENTER("Stop_log_event::do_update_pos");
/*
@@ -8250,9 +8252,10 @@ int Stop_log_event::do_update_pos(rpl_group_info *rgi)
{
rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
rli->inc_group_relay_log_pos(0, rgi);
- flush_relay_log_info(rli);
+ if (flush_relay_log_info(rli))
+ error= 1;
}
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
#endif /* !MYSQL_CLIENT */
@@ -10298,8 +10301,8 @@ int
Rows_log_event::do_update_pos(rpl_group_info *rgi)
{
Relay_log_info *rli= rgi->rli;
- DBUG_ENTER("Rows_log_event::do_update_pos");
int error= 0;
+ DBUG_ENTER("Rows_log_event::do_update_pos");
DBUG_PRINT("info", ("flags: %s",
get_flags(STMT_END_F) ? "STMT_END_F " : ""));
@@ -10311,7 +10314,7 @@ Rows_log_event::do_update_pos(rpl_group_info *rgi)
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
- rli->stmt_done(log_pos, thd, rgi);
+ error= rli->stmt_done(log_pos, thd, rgi);
/*
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 0502f20d2b1..59f704d8474 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1746,8 +1746,8 @@ int
Old_rows_log_event::do_update_pos(rpl_group_info *rgi)
{
Relay_log_info *rli= rgi->rli;
- DBUG_ENTER("Old_rows_log_event::do_update_pos");
int error= 0;
+ DBUG_ENTER("Old_rows_log_event::do_update_pos");
DBUG_PRINT("info", ("flags: %s",
get_flags(STMT_END_F) ? "STMT_END_F " : ""));
@@ -1759,7 +1759,7 @@ Old_rows_log_event::do_update_pos(rpl_group_info *rgi)
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
- rli->stmt_done(log_pos, thd, rgi);
+ error= rli->stmt_done(log_pos, thd, rgi);
/*
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc
index c23a20ebac9..de799874a8f 100644
--- a/sql/mysql_install_db.cc
+++ b/sql/mysql_install_db.cc
@@ -386,8 +386,8 @@ static int register_service()
CloseServiceHandle(sc_manager);
die("CreateService failed (%u)", GetLastError());
}
-
- SERVICE_DESCRIPTION sd= { "MariaDB database server" };
+ char description[] = "MariaDB database server";
+ SERVICE_DESCRIPTION sd= { description };
ChangeServiceConfig2(sc_service, SERVICE_CONFIG_DESCRIPTION, &sd);
CloseServiceHandle(sc_service);
CloseServiceHandle(sc_manager);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 5ff56daf7c2..90607882aa4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -714,12 +714,15 @@ mysql_mutex_t
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt,
LOCK_global_system_variables,
- LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
+ LOCK_user_conn, LOCK_slave_list,
LOCK_connection_count, LOCK_error_messages, LOCK_slave_background;
mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
LOCK_global_table_stats, LOCK_global_index_stats;
+/* This protects against changes in master_info_index */
+mysql_mutex_t LOCK_active_mi;
+
/**
The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables
@@ -877,7 +880,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_system_variables_hash, key_LOCK_thd_data,
key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log,
key_master_info_data_lock, key_master_info_run_lock,
- key_master_info_sleep_lock,
+ key_master_info_sleep_lock, key_master_info_start_stop_lock,
key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
key_rpl_group_info_sleep_lock,
key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
@@ -949,6 +952,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL},
{ &key_LOG_LOCK_log, "LOG::LOCK_log", 0},
{ &key_master_info_data_lock, "Master_info::data_lock", 0},
+ { &key_master_info_start_stop_lock, "Master_info::start_stop_lock", 0},
{ &key_master_info_run_lock, "Master_info::run_lock", 0},
{ &key_master_info_sleep_lock, "Master_info::sleep_lock", 0},
{ &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0},
@@ -1434,7 +1438,7 @@ ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
Query_cache query_cache;
#endif
#ifdef HAVE_SMEM
-char *shared_memory_base_name= default_shared_memory_base_name;
+const char *shared_memory_base_name= default_shared_memory_base_name;
my_bool opt_enable_shared_memory;
HANDLE smem_event_connect_request= 0;
#endif
@@ -1675,7 +1679,7 @@ static void close_connections(void)
mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
Events::deinit();
- end_slave();
+ slave_prepare_for_shutdown();
/*
Give threads time to die.
@@ -1752,6 +1756,7 @@ static void close_connections(void)
DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
mysql_mutex_unlock(&LOCK_thread_count);
}
+ end_slave();
/* All threads has now been aborted */
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
mysql_mutex_lock(&LOCK_thread_count);
@@ -2769,22 +2774,6 @@ void dec_connection_count(THD *thd)
/*
- Delete THD and decrement thread counters, including thread_running
-*/
-
-void delete_running_thd(THD *thd)
-{
- mysql_mutex_lock(&LOCK_thread_count);
- thd->unlink();
- mysql_mutex_unlock(&LOCK_thread_count);
-
- delete thd;
- dec_thread_running();
- thread_safe_decrement32(&thread_count);
- signal_thd_deleted();
-}
-
-/*
Send a signal to unblock close_conneciton() if there is no more
threads running with a THD attached
@@ -5294,15 +5283,13 @@ static int init_server_components()
if (opt_bin_log)
{
- /**
- * mutex lock is not needed here.
- * but to be able to have mysql_mutex_assert_owner() in code,
- * we do it anyway */
- mysql_mutex_lock(mysql_bin_log.get_log_lock());
- int r= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0,
+ int error;
+ mysql_mutex_t *log_lock= mysql_bin_log.get_log_lock();
+ mysql_mutex_lock(log_lock);
+ error= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0,
WRITE_CACHE, max_binlog_size, 0, TRUE);
- mysql_mutex_unlock(mysql_bin_log.get_log_lock());
- if (r)
+ mysql_mutex_unlock(log_lock);
+ if (error)
unireg_abort(1);
}
@@ -7652,17 +7639,14 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff,
var->type= SHOW_MY_BOOL;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE)))
{
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_NOTE);
- if (mi)
- tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING &&
- mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN);
+ tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING &&
+ mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
if (mi)
*((my_bool *)buff)= tmp;
else
@@ -7694,14 +7678,9 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff)
{
var->type= SHOW_LONGLONG;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
- *((longlong *)buff)= master_info_index->any_slave_sql_running();
- else
- *((longlong *)buff)= 0;
+ *((longlong *)buff)= any_slave_sql_running();
- mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
@@ -7709,23 +7688,17 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff)
static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff,
enum enum_var_type scope)
{
- Master_info *mi= NULL;
- longlong UNINIT_VAR(tmp);
+ Master_info *mi;
var->type= SHOW_LONGLONG;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE)))
{
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_NOTE);
- if (mi)
- tmp= mi->received_heartbeats;
+ *((longlong *)buff)= mi->received_heartbeats;
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
- if (mi)
- *((longlong *)buff)= tmp;
else
var->type= SHOW_UNDEF;
return 0;
@@ -7735,23 +7708,17 @@ static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff,
static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff,
enum enum_var_type scope)
{
- Master_info *mi= NULL;
- float UNINIT_VAR(tmp);
+ Master_info *mi;
var->type= SHOW_CHAR;
var->value= buff;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE)))
{
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_NOTE);
- if (mi)
- tmp= mi->heartbeat_period;
+ sprintf(buff, "%.3f", mi->heartbeat_period);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
- if (mi)
- sprintf(buff, "%.3f", tmp);
else
var->type= SHOW_UNDEF;
return 0;
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 52a4da77367..0e21b0f020a 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -83,7 +83,6 @@ void kill_mysql(void);
void close_connection(THD *thd, uint sql_errno= 0);
void handle_connection_in_main_thread(THD *thd);
void create_thread_to_handle_connection(THD *thd);
-void delete_running_thd(THD *thd);
void signal_thd_deleted();
void unlink_thd(THD *thd);
bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
@@ -139,7 +138,8 @@ extern my_bool sp_automatic_privileges, opt_noacl;
extern ulong use_stat_tables;
extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;
-extern char *shared_memory_base_name, *mysqld_unix_port;
+extern const char *shared_memory_base_name;
+extern char *mysqld_unix_port;
extern my_bool opt_enable_shared_memory;
extern ulong opt_replicate_events_marked_for_skip;
extern char *default_tz_name;
@@ -293,7 +293,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
key_LOCK_thd_data,
key_LOCK_user_conn, key_LOG_LOCK_log,
key_master_info_data_lock, key_master_info_run_lock,
- key_master_info_sleep_lock,
+ key_master_info_sleep_lock, key_master_info_start_stop_lock,
key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
key_rpl_group_info_sleep_lock,
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
index d6a8eac7ed5..e05e43a0a59 100644
--- a/sql/nt_servc.cc
+++ b/sql/nt_servc.cc
@@ -508,7 +508,7 @@ BOOL NTService::IsService(LPCSTR ServiceName)
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
-BOOL NTService::got_service_option(char **argv, char *service_option)
+BOOL NTService::got_service_option(char **argv, const char *service_option)
{
char *option;
for (option= argv[1]; *option; option++)
diff --git a/sql/nt_servc.h b/sql/nt_servc.h
index 949499d8d7f..6781fe0ddfa 100644
--- a/sql/nt_servc.h
+++ b/sql/nt_servc.h
@@ -61,7 +61,7 @@ class NTService
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
BOOL Remove(LPCSTR szInternName);
BOOL IsService(LPCSTR ServiceName);
- BOOL got_service_option(char **argv, char *service_option);
+ BOOL got_service_option(char **argv, const char *service_option);
BOOL is_super_user();
/*
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index 6048d26998b..3e73d80ef48 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -40,7 +40,9 @@ Master_info::Master_info(LEX_STRING *connection_name_arg,
sync_counter(0), heartbeat_period(0), received_heartbeats(0),
master_id(0), prev_master_id(0),
using_gtid(USE_GTID_NO), events_queued_since_last_gtid(0),
- gtid_reconnect_event_skip_count(0), gtid_event_seen(false)
+ gtid_reconnect_event_skip_count(0), gtid_event_seen(false),
+ in_start_all_slaves(0), in_stop_all_slaves(0),
+ users(0), killed(0)
{
host[0] = 0; user[0] = 0; password[0] = 0;
ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
@@ -81,6 +83,8 @@ Master_info::Master_info(LEX_STRING *connection_name_arg,
bzero((char*) &file, sizeof(file));
mysql_mutex_init(key_master_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_master_info_start_stop_lock, &start_stop_lock,
+ MY_MUTEX_INIT_SLOW);
mysql_mutex_setflags(&run_lock, MYF_NO_DEADLOCK_DETECTION);
mysql_mutex_setflags(&data_lock, MYF_NO_DEADLOCK_DETECTION);
mysql_mutex_init(key_master_info_sleep_lock, &sleep_lock, MY_MUTEX_INIT_FAST);
@@ -90,8 +94,27 @@ Master_info::Master_info(LEX_STRING *connection_name_arg,
mysql_cond_init(key_master_info_sleep_cond, &sleep_cond, NULL);
}
+
+/**
+ Wait until no one is using Master_info
+*/
+
+void Master_info::wait_until_free()
+{
+ mysql_mutex_lock(&sleep_lock);
+ killed= 1;
+ while (users)
+ mysql_cond_wait(&sleep_cond, &sleep_lock);
+ mysql_mutex_unlock(&sleep_lock);
+}
+
+/**
+ Delete master_info
+*/
+
Master_info::~Master_info()
{
+ wait_until_free();
#ifdef WITH_WSREP
/*
Do not free "wsrep" rpl_filter. It will eventually be freed by
@@ -106,6 +129,7 @@ Master_info::~Master_info()
mysql_mutex_destroy(&run_lock);
mysql_mutex_destroy(&data_lock);
mysql_mutex_destroy(&sleep_lock);
+ mysql_mutex_destroy(&start_stop_lock);
mysql_cond_destroy(&data_cond);
mysql_cond_destroy(&start_cond);
mysql_cond_destroy(&stop_cond);
@@ -841,12 +865,28 @@ uchar *get_key_master_info(Master_info *mi, size_t *length,
return (uchar*) mi->cmp_connection_name.str;
}
+/*
+ Delete a master info
+
+ Called from my_hash_delete(&master_info_hash)
+ Stops associated slave threads and frees master_info
+*/
+
void free_key_master_info(Master_info *mi)
{
DBUG_ENTER("free_key_master_info");
+ mysql_mutex_unlock(&LOCK_active_mi);
+
+ /* Ensure that we are not in reset_slave while this is done */
+ mi->lock_slave_threads();
terminate_slave_threads(mi,SLAVE_FORCE_ALL);
+ /* We use 2 here instead of 1 just to make it easier when debugging */
+ mi->killed= 2;
end_master_info(mi);
+ mi->unlock_slave_threads();
delete mi;
+
+ mysql_mutex_lock(&LOCK_active_mi);
DBUG_VOID_RETURN;
}
@@ -1002,9 +1042,28 @@ Master_info_index::Master_info_index()
index_file.file= -1;
}
+
+/**
+ Free all connection threads
+
+ This is done during early stages of shutdown
+ to give connection threads and slave threads time
+ to die before ~Master_info_index is called
+*/
+
+void Master_info_index::free_connections()
+{
+ mysql_mutex_assert_owner(&LOCK_active_mi);
+ my_hash_reset(&master_info_hash);
+}
+
+
+/**
+ Free all connection threads and free structures
+*/
+
Master_info_index::~Master_info_index()
{
- /* This will close connection for all objects in the cache */
my_hash_free(&master_info_hash);
end_io_cache(&index_file);
if (index_file.file >= 0)
@@ -1027,7 +1086,6 @@ bool Master_info_index::init_all_master_info()
File index_file_nr;
DBUG_ENTER("init_all_master_info");
- mysql_mutex_assert_owner(&LOCK_active_mi);
DBUG_ASSERT(master_info_index);
if ((index_file_nr= my_open(index_file_name,
@@ -1075,7 +1133,6 @@ bool Master_info_index::init_all_master_info()
DBUG_RETURN(1);
}
- lock_slave_threads(mi);
init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
create_logfile_name_with_suffix(buf_master_info_file,
@@ -1090,6 +1147,7 @@ bool Master_info_index::init_all_master_info()
sql_print_information("Reading Master_info: '%s' Relay_info:'%s'",
buf_master_info_file, buf_relay_log_info_file);
+ mi->lock_slave_threads();
if (init_master_info(mi, buf_master_info_file, buf_relay_log_info_file,
0, thread_mask))
{
@@ -1103,15 +1161,16 @@ bool Master_info_index::init_all_master_info()
if (master_info_index->add_master_info(mi, FALSE))
DBUG_RETURN(1);
succ_num++;
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
}
else
{
/* Master_info already in HASH */
sql_print_error(ER_THD_OR_DEFAULT(current_thd,
ER_CONNECTION_ALREADY_EXISTS),
+ (int) connection_name.length, connection_name.str,
(int) connection_name.length, connection_name.str);
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
delete mi;
}
continue;
@@ -1128,8 +1187,9 @@ bool Master_info_index::init_all_master_info()
/* Master_info was already registered */
sql_print_error(ER_THD_OR_DEFAULT(current_thd,
ER_CONNECTION_ALREADY_EXISTS),
+ (int) connection_name.length, connection_name.str,
(int) connection_name.length, connection_name.str);
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
delete mi;
continue;
}
@@ -1138,7 +1198,6 @@ bool Master_info_index::init_all_master_info()
if (master_info_index->add_master_info(mi, FALSE))
DBUG_RETURN(1);
succ_num++;
- unlock_slave_threads(mi);
if (!opt_skip_slave_start)
{
@@ -1160,6 +1219,7 @@ bool Master_info_index::init_all_master_info()
(int) connection_name.length,
connection_name.str);
}
+ mi->unlock_slave_threads();
}
}
@@ -1211,6 +1271,71 @@ bool Master_info_index::write_master_name_to_index_file(LEX_STRING *name,
/**
+ Get Master_info for a connection and lock the object from deletion
+
+ @param
+ connection_name Connection name
+ warning WARN_LEVEL_NOTE -> Don't print anything
+ WARN_LEVEL_WARN -> Issue warning if not exists
+ WARN_LEVEL_ERROR-> Issue error if not exists
+*/
+
+Master_info *get_master_info(const LEX_STRING *connection_name,
+ Sql_condition::enum_warning_level warning)
+{
+ Master_info *mi;
+ DBUG_ENTER("get_master_info");
+
+ /* Protect against inserts into hash */
+ mysql_mutex_lock(&LOCK_active_mi);
+ /*
+ The following can only be true during shutdown when slave has been killed
+ but some other threads are still trying to access slave statistics.
+ */
+ if (unlikely(!master_info_index))
+ {
+ if (warning != Sql_condition::WARN_LEVEL_NOTE)
+ my_error(WARN_NO_MASTER_INFO,
+ MYF(warning == Sql_condition::WARN_LEVEL_WARN ?
+ ME_JUST_WARNING : 0),
+ (int) connection_name->length, connection_name->str);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(0);
+ }
+ if ((mi= master_info_index->get_master_info(connection_name, warning)))
+ {
+ /*
+ We have to use sleep_lock here. If we would use LOCK_active_mi
+ then we would take locks in wrong order in Master_info::release()
+ */
+ mysql_mutex_lock(&mi->sleep_lock);
+ mi->users++;
+ DBUG_PRINT("info",("users: %d", mi->users));
+ mysql_mutex_unlock(&mi->sleep_lock);
+ }
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(mi);
+}
+
+
+/**
+ Release master info.
+ Signals ~Master_info that it's now safe to delete it
+*/
+
+void Master_info::release()
+{
+ mysql_mutex_lock(&sleep_lock);
+ if (!--users && killed)
+ {
+ /* Signal ~Master_info that it's ok to now free it */
+ mysql_cond_signal(&sleep_cond);
+ }
+ mysql_mutex_unlock(&sleep_lock);
+}
+
+
+/**
Get Master_info for a connection
@param
@@ -1232,8 +1357,6 @@ Master_info_index::get_master_info(const LEX_STRING *connection_name,
("connection_name: '%.*s'", (int) connection_name->length,
connection_name->str));
- mysql_mutex_assert_owner(&LOCK_active_mi);
-
/* Make name lower case for comparison */
res= strmake(buff, connection_name->str, connection_name->length);
my_casedn_str(system_charset_info, buff);
@@ -1299,7 +1422,12 @@ bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg,
/* Add a Master_info class to Hash Table */
bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file)
{
- if (!my_hash_insert(&master_info_hash, (uchar*) mi))
+ /*
+ We have to protect against shutdown to ensure we are not calling
+ my_hash_insert() while my_hash_free() is in progress
+ */
+ if (unlikely(shutdown_in_progress) ||
+ !my_hash_insert(&master_info_hash, (uchar*) mi))
{
if (global_system_variables.log_warnings > 1)
sql_print_information("Added new Master_info '%.*s' to hash table",
@@ -1325,105 +1453,131 @@ bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file)
atomic
*/
-bool Master_info_index::remove_master_info(LEX_STRING *name)
+bool Master_info_index::remove_master_info(Master_info *mi)
{
- Master_info* mi;
DBUG_ENTER("remove_master_info");
+ mysql_mutex_assert_owner(&LOCK_active_mi);
- if ((mi= get_master_info(name, Sql_condition::WARN_LEVEL_WARN)))
+ // Delete Master_info and rewrite others to file
+ if (!my_hash_delete(&master_info_hash, (uchar*) mi))
{
- // Delete Master_info and rewrite others to file
- if (!my_hash_delete(&master_info_hash, (uchar*) mi))
+ File index_file_nr;
+
+ // Close IO_CACHE and FILE handler fisrt
+ end_io_cache(&index_file);
+ my_close(index_file.file, MYF(MY_WME));
+
+ // Reopen File and truncate it
+ if ((index_file_nr= my_open(index_file_name,
+ O_RDWR | O_CREAT | O_TRUNC | O_BINARY ,
+ MYF(MY_WME))) < 0 ||
+ init_io_cache(&index_file, index_file_nr,
+ IO_SIZE, WRITE_CACHE,
+ my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
+ 0, MYF(MY_WME | MY_WAIT_IF_FULL)))
{
- File index_file_nr;
-
- // Close IO_CACHE and FILE handler fisrt
- end_io_cache(&index_file);
- my_close(index_file.file, MYF(MY_WME));
-
- // Reopen File and truncate it
- if ((index_file_nr= my_open(index_file_name,
- O_RDWR | O_CREAT | O_TRUNC | O_BINARY ,
- MYF(MY_WME))) < 0 ||
- init_io_cache(&index_file, index_file_nr,
- IO_SIZE, WRITE_CACHE,
- my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
- 0, MYF(MY_WME | MY_WAIT_IF_FULL)))
- {
- int error= my_errno;
- if (index_file_nr >= 0)
- my_close(index_file_nr,MYF(0));
-
- sql_print_error("Create of Master Info Index file '%s' failed with "
- "error: %M",
- index_file_name, error);
- DBUG_RETURN(TRUE);
- }
+ int error= my_errno;
+ if (index_file_nr >= 0)
+ my_close(index_file_nr,MYF(0));
- // Rewrite Master_info.index
- for (uint i= 0; i< master_info_hash.records; ++i)
- {
- Master_info *tmp_mi;
- tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i);
- write_master_name_to_index_file(&tmp_mi->connection_name, 0);
- }
- my_sync(index_file_nr, MYF(MY_WME));
+ sql_print_error("Create of Master Info Index file '%s' failed with "
+ "error: %M",
+ index_file_name, error);
+ DBUG_RETURN(TRUE);
+ }
+
+ // Rewrite Master_info.index
+ for (uint i= 0; i< master_info_hash.records; ++i)
+ {
+ Master_info *tmp_mi;
+ tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i);
+ write_master_name_to_index_file(&tmp_mi->connection_name, 0);
}
+ if (my_sync(index_file_nr, MYF(MY_WME)))
+ DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
}
/**
- Master_info_index::give_error_if_slave_running()
+ give_error_if_slave_running()
+
+ @param
+ already_locked 0 if we need to lock, 1 if we have LOCK_active_mi_locked
@return
TRUE If some slave is running. An error is printed
FALSE No slave is running
*/
-bool Master_info_index::give_error_if_slave_running()
+bool give_error_if_slave_running(bool already_locked)
{
+ bool ret= 0;
DBUG_ENTER("give_error_if_slave_running");
- mysql_mutex_assert_owner(&LOCK_active_mi);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ if (!already_locked)
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (!master_info_index)
{
- Master_info *mi;
- mi= (Master_info *) my_hash_element(&master_info_hash, i);
- if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN)
+ my_error(ER_SERVER_SHUTDOWN, MYF(0));
+ ret= 1;
+ }
+ else
+ {
+ HASH *hash= &master_info_index->master_info_hash;
+ for (uint i= 0; i< hash->records; ++i)
{
- my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length,
- mi->connection_name.str);
- DBUG_RETURN(TRUE);
+ Master_info *mi;
+ mi= (Master_info *) my_hash_element(hash, i);
+ if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN)
+ {
+ my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length,
+ mi->connection_name.str);
+ ret= 1;
+ break;
+ }
}
}
- DBUG_RETURN(FALSE);
+ if (!already_locked)
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(ret);
}
/**
- Master_info_index::any_slave_sql_running()
-
- The LOCK_active_mi must be held while calling this function.
+ any_slave_sql_running()
@return
0 No Slave SQL thread is running
# Number of slave SQL thread running
+
+ Note that during shutdown we return 1. This is needed to ensure we
+ don't try to resize thread pool during shutdown as during shutdown
+ master_info_hash may be freeing the hash and during that time
+ hash entries can't be accessed.
*/
-uint Master_info_index::any_slave_sql_running()
+uint any_slave_sql_running()
{
uint count= 0;
+ HASH *hash;
DBUG_ENTER("any_slave_sql_running");
- mysql_mutex_assert_owner(&LOCK_active_mi);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (unlikely(shutdown_in_progress || !master_info_index))
{
- Master_info *mi= (Master_info *)my_hash_element(&master_info_hash, i);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(1);
+ }
+ hash= &master_info_index->master_info_hash;
+ for (uint i= 0; i< hash->records; ++i)
+ {
+ Master_info *mi= (Master_info *)my_hash_element(hash, i);
if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN)
count++;
}
+ mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(count);
}
@@ -1436,15 +1590,25 @@ uint Master_info_index::any_slave_sql_running()
@return
TRUE Error
FALSE Everything ok.
+
+ This code is written so that we don't keep LOCK_active_mi active
+ while we are starting a slave.
*/
bool Master_info_index::start_all_slaves(THD *thd)
{
bool result= FALSE;
- DBUG_ENTER("warn_if_slave_running");
+ DBUG_ENTER("start_all_slaves");
mysql_mutex_assert_owner(&LOCK_active_mi);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ for (uint i= 0; i< master_info_hash.records; i++)
+ {
+ Master_info *mi;
+ mi= (Master_info *) my_hash_element(&master_info_hash, i);
+ mi->in_start_all_slaves= 0;
+ }
+
+ for (uint i= 0; i< master_info_hash.records; )
{
int error;
Master_info *mi;
@@ -1454,25 +1618,40 @@ bool Master_info_index::start_all_slaves(THD *thd)
Try to start all slaves that are configured (host is defined)
and are not already running
*/
- if ((mi->slave_running == MYSQL_SLAVE_NOT_RUN ||
- !mi->rli.slave_running) && *mi->host)
+ if (!((mi->slave_running == MYSQL_SLAVE_NOT_RUN ||
+ !mi->rli.slave_running) && *mi->host) ||
+ mi->in_start_all_slaves)
{
- if ((error= start_slave(thd, mi, 1)))
- {
- my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
- "START",
- (int) mi->connection_name.length,
- mi->connection_name.str);
- result= 1;
- if (error < 0) // fatal error
- break;
- }
- else if (thd)
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED),
- (int) mi->connection_name.length,
- mi->connection_name.str);
+ i++;
+ continue;
}
+ mi->in_start_all_slaves= 1;
+
+ mysql_mutex_lock(&mi->sleep_lock);
+ mi->users++; // Mark used
+ mysql_mutex_unlock(&mi->sleep_lock);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ error= start_slave(thd, mi, 1);
+ mi->release();
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (error)
+ {
+ my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
+ "START",
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ result= 1;
+ if (error < 0) // fatal error
+ break;
+ }
+ else if (thd)
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_SLAVE_STARTED, ER_THD(thd, ER_SLAVE_STARTED),
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ /* Restart from first element as master_info_hash may have changed */
+ i= 0;
+ continue;
}
DBUG_RETURN(result);
}
@@ -1488,39 +1667,64 @@ bool Master_info_index::start_all_slaves(THD *thd)
@return
TRUE Error
FALSE Everything ok.
+
+ This code is written so that we don't keep LOCK_active_mi active
+ while we are stopping a slave.
*/
bool Master_info_index::stop_all_slaves(THD *thd)
{
bool result= FALSE;
- DBUG_ENTER("warn_if_slave_running");
+ DBUG_ENTER("stop_all_slaves");
mysql_mutex_assert_owner(&LOCK_active_mi);
DBUG_ASSERT(thd);
- for (uint i= 0; i< master_info_hash.records; ++i)
+ for (uint i= 0; i< master_info_hash.records; i++)
+ {
+ Master_info *mi;
+ mi= (Master_info *) my_hash_element(&master_info_hash, i);
+ mi->in_stop_all_slaves= 0;
+ }
+
+ for (uint i= 0; i< master_info_hash.records ;)
{
int error;
Master_info *mi;
mi= (Master_info *) my_hash_element(&master_info_hash, i);
- if ((mi->slave_running != MYSQL_SLAVE_NOT_RUN ||
- mi->rli.slave_running))
+ if (!(mi->slave_running != MYSQL_SLAVE_NOT_RUN ||
+ mi->rli.slave_running) ||
+ mi->in_stop_all_slaves)
{
- if ((error= stop_slave(thd, mi, 1)))
- {
- my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
- "STOP",
- (int) mi->connection_name.length,
- mi->connection_name.str);
- result= 1;
- if (error < 0) // Fatal error
- break;
- }
- else
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_SLAVE_STOPPED, ER_THD(thd, ER_SLAVE_STOPPED),
- (int) mi->connection_name.length,
- mi->connection_name.str);
+ i++;
+ continue;
}
+ mi->in_stop_all_slaves= 1; // Protection for loops
+
+ mysql_mutex_lock(&mi->sleep_lock);
+ mi->users++; // Mark used
+ mysql_mutex_unlock(&mi->sleep_lock);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ error= stop_slave(thd, mi, 1);
+ mi->release();
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (error)
+ {
+ my_error(ER_CANT_START_STOP_SLAVE, MYF(0),
+ "STOP",
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ result= 1;
+ if (error < 0) // Fatal error
+ break;
+ }
+ else
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_SLAVE_STOPPED, ER_THD(thd, ER_SLAVE_STOPPED),
+ (int) mi->connection_name.length,
+ mi->connection_name.str);
+ /* Restart from first element as master_info_hash may have changed */
+ i= 0;
+ continue;
}
DBUG_RETURN(result);
}
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 9365c065ea9..31c0f280ac1 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -187,6 +187,10 @@ class Master_info : public Slave_reporting_capability
return opt_slave_parallel_threads > 0 &&
parallel_mode > SLAVE_PARALLEL_NONE;
}
+ void release();
+ void wait_until_free();
+ void lock_slave_threads();
+ void unlock_slave_threads();
/* the variables below are needed because we can change masters on the fly */
char master_log_name[FN_REFLEN+6]; /* Room for multi-*/
@@ -205,7 +209,7 @@ class Master_info : public Slave_reporting_capability
File fd; // we keep the file open, so we need to remember the file pointer
IO_CACHE file;
- mysql_mutex_t data_lock, run_lock, sleep_lock;
+ mysql_mutex_t data_lock, run_lock, sleep_lock, start_stop_lock;
mysql_cond_t data_cond, start_cond, stop_cond, sleep_cond;
THD *io_thd;
MYSQL* mysql;
@@ -297,6 +301,9 @@ class Master_info : public Slave_reporting_capability
uint64 gtid_reconnect_event_skip_count;
/* gtid_event_seen is false until we receive first GTID event from master. */
bool gtid_event_seen;
+ bool in_start_all_slaves, in_stop_all_slaves;
+ uint users; /* Active user for object */
+ uint killed;
/* domain-id based filter */
Domain_id_filter domain_id_filter;
@@ -341,13 +348,12 @@ public:
bool check_duplicate_master_info(LEX_STRING *connection_name,
const char *host, uint port);
bool add_master_info(Master_info *mi, bool write_to_file);
- bool remove_master_info(LEX_STRING *connection_name);
+ bool remove_master_info(Master_info *mi);
Master_info *get_master_info(const LEX_STRING *connection_name,
Sql_condition::enum_warning_level warning);
- bool give_error_if_slave_running();
- uint any_slave_sql_running();
bool start_all_slaves(THD *thd);
bool stop_all_slaves(THD *thd);
+ void free_connections();
};
@@ -360,6 +366,8 @@ public:
};
+Master_info *get_master_info(const LEX_STRING *connection_name,
+ Sql_condition::enum_warning_level warning);
bool check_master_connection_name(LEX_STRING *name);
void create_logfile_name_with_suffix(char *res_file_name, size_t length,
const char *info_file,
@@ -369,5 +377,8 @@ void create_logfile_name_with_suffix(char *res_file_name, size_t length,
uchar *get_key_master_info(Master_info *mi, size_t *length,
my_bool not_used __attribute__((unused)));
void free_key_master_info(Master_info *mi);
+uint any_slave_sql_running();
+bool give_error_if_slave_running(bool already_lock);
+
#endif /* HAVE_REPLICATION */
#endif /* RPL_MI_H */
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 1959f6bc4bb..a814628e72c 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -1313,39 +1313,16 @@ handle_rpl_parallel_thread(void *arg)
*/
rpt->batch_free();
- for (;;)
+ if ((events= rpt->event_queue) != NULL)
{
- if ((events= rpt->event_queue) != NULL)
- {
- /*
- Take next group of events from the replication pool.
- This is faster than having to wakeup the pool manager thread to give
- us a new event.
- */
- rpt->dequeue1(events);
- mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
- goto more_events;
- }
- if (!rpt->pause_for_ftwrl ||
- (in_event_group && !group_rgi->parallel_entry->force_abort))
- break;
/*
- We are currently in the delicate process of pausing parallel
- replication while FLUSH TABLES WITH READ LOCK is starting. We must
- not de-allocate the thread (setting rpt->current_owner= NULL) until
- rpl_unpause_after_ftwrl() has woken us up.
+ Take next group of events from the replication pool.
+ This is faster than having to wakeup the pool manager thread to give
+ us a new event.
*/
- mysql_mutex_lock(&rpt->current_entry->LOCK_parallel_entry);
+ rpt->dequeue1(events);
mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
- if (rpt->pause_for_ftwrl)
- mysql_cond_wait(&rpt->current_entry->COND_parallel_entry,
- &rpt->current_entry->LOCK_parallel_entry);
- mysql_mutex_unlock(&rpt->current_entry->LOCK_parallel_entry);
- mysql_mutex_lock(&rpt->LOCK_rpl_thread);
- /*
- Now loop to check again for more events available, since we released
- and re-aquired the LOCK_rpl_thread mutex.
- */
+ goto more_events;
}
rpt->inuse_relaylog_refcount_update();
@@ -1372,11 +1349,36 @@ handle_rpl_parallel_thread(void *arg)
}
if (!in_event_group)
{
+ /* If we are in a FLUSH TABLES FOR READ LOCK, wait for it */
+ while (rpt->current_entry && rpt->pause_for_ftwrl)
+ {
+ /*
+ We are currently in the delicate process of pausing parallel
+ replication while FLUSH TABLES WITH READ LOCK is starting. We must
+ not de-allocate the thread (setting rpt->current_owner= NULL) until
+ rpl_unpause_after_ftwrl() has woken us up.
+ */
+ rpl_parallel_entry *e= rpt->current_entry;
+ /*
+ Ensure that we will unblock rpl_pause_for_ftrwl()
+ e->pause_sub_id may be LONGLONG_MAX if rpt->current_entry has changed
+ */
+ DBUG_ASSERT(e->pause_sub_id == (uint64)ULONGLONG_MAX ||
+ e->last_committed_sub_id >= e->pause_sub_id);
+ mysql_mutex_lock(&e->LOCK_parallel_entry);
+ mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
+ if (rpt->pause_for_ftwrl)
+ mysql_cond_wait(&e->COND_parallel_entry, &e->LOCK_parallel_entry);
+ mysql_mutex_unlock(&e->LOCK_parallel_entry);
+ mysql_mutex_lock(&rpt->LOCK_rpl_thread);
+ }
+
rpt->current_owner= NULL;
/* Tell wait_for_done() that we are done, if it is waiting. */
if (likely(rpt->current_entry) &&
unlikely(rpt->current_entry->force_abort))
mysql_cond_broadcast(&rpt->COND_rpl_thread_stop);
+
rpt->current_entry= NULL;
if (!rpt->stop)
rpt->pool->release_thread(rpt);
@@ -1416,10 +1418,24 @@ dealloc_gco(group_commit_orderer *gco)
my_free(gco);
}
+/**
+ Change thread count for global parallel worker threads
+
+ @param pool parallel thread pool
+ @param new_count Number of threads to be in pool. 0 in shutdown
+ @param force Force thread count to new_count even if slave
+ threads are running
+
+ By default we don't resize pool of there are running threads.
+ However during shutdown we will always do it.
+ This is needed as any_slave_sql_running() returns 1 during shutdown
+ as we don't want to access master_info while
+ Master_info_index::free_connections are running.
+*/
static int
rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool,
- uint32 new_count)
+ uint32 new_count, bool force)
{
uint32 i;
rpl_parallel_thread **old_list= NULL;
@@ -1431,6 +1447,28 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool,
if ((res= pool_mark_busy(pool, current_thd)))
return res;
+ /* Protect against parallel pool resizes */
+ if (pool->count == new_count)
+ {
+ pool_mark_not_busy(pool);
+ return 0;
+ }
+
+ /*
+ If we are about to delete pool, do an extra check that there are no new
+ slave threads running since we marked pool busy
+ */
+ if (!new_count && !force)
+ {
+ if (any_slave_sql_running())
+ {
+ DBUG_PRINT("warning",
+ ("SQL threads running while trying to reset parallel pool"));
+ pool_mark_not_busy(pool);
+ return 0; // Ok to not resize pool
+ }
+ }
+
/*
Allocate the new list of threads up-front.
That way, if we fail half-way, we only need to free whatever we managed
@@ -1444,7 +1482,7 @@ rpl_parallel_change_thread_count(rpl_parallel_thread_pool *pool,
{
my_error(ER_OUTOFMEMORY, MYF(0), (int(new_count*sizeof(*new_list) +
new_count*sizeof(*rpt_array))));
- goto err;;
+ goto err;
}
for (i= 0; i < new_count; ++i)
@@ -1569,12 +1607,26 @@ err:
return 1;
}
+/*
+ Deactivate the parallel replication thread pool, if there are now no more
+ SQL threads running.
+*/
+
+int rpl_parallel_resize_pool_if_no_slaves(void)
+{
+ /* master_info_index is set to NULL on shutdown */
+ if (opt_slave_parallel_threads > 0 && !any_slave_sql_running())
+ return rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
+ return 0;
+}
+
int
rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool)
{
if (!pool->count)
- return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads);
+ return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads,
+ 0);
return 0;
}
@@ -1582,7 +1634,7 @@ rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool)
int
rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool)
{
- return rpl_parallel_change_thread_count(pool, 0);
+ return rpl_parallel_change_thread_count(pool, 0, 0);
}
@@ -1860,7 +1912,7 @@ rpl_parallel_thread_pool::destroy()
{
if (!inited)
return;
- rpl_parallel_change_thread_count(this, 0);
+ rpl_parallel_change_thread_count(this, 0, 1);
mysql_mutex_destroy(&LOCK_rpl_thread_pool);
mysql_cond_destroy(&COND_rpl_thread_pool);
inited= false;
@@ -1879,6 +1931,7 @@ rpl_parallel_thread_pool::get_thread(rpl_parallel_thread **owner,
{
rpl_parallel_thread *rpt;
+ DBUG_ASSERT(count > 0);
mysql_mutex_lock(&LOCK_rpl_thread_pool);
while (unlikely(busy) || !(rpt= free_list))
mysql_cond_wait(&COND_rpl_thread_pool, &LOCK_rpl_thread_pool);
@@ -2107,6 +2160,11 @@ rpl_parallel::find(uint32 domain_id)
return e;
}
+/**
+ Wait until all sql worker threads has stopped processing
+
+ This is called when sql thread has been killed/stopped
+*/
void
rpl_parallel::wait_for_done(THD *thd, Relay_log_info *rli)
diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h
index c6f77b0144c..a0faeae815c 100644
--- a/sql/rpl_parallel.h
+++ b/sql/rpl_parallel.h
@@ -365,6 +365,7 @@ struct rpl_parallel {
extern struct rpl_parallel_thread_pool global_rpl_thread_pool;
+extern int rpl_parallel_resize_pool_if_no_slaves(void);
extern int rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool);
extern int rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool);
extern bool process_gtid_for_restart_pos(Relay_log_info *rli, rpl_gtid *gtid);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 03f0f4fdf53..1b969fb4257 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -208,6 +208,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
Master_info* mi= rli->mi;
char buf_relay_logname[FN_REFLEN], buf_relaylog_index_name_buff[FN_REFLEN];
char *buf_relaylog_index_name= opt_relaylog_index_name;
+ mysql_mutex_t *log_lock;
create_logfile_name_with_suffix(buf_relay_logname,
sizeof(buf_relay_logname),
@@ -227,14 +228,18 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
*/
+ log_lock= rli->relay_log.get_log_lock();
+ mysql_mutex_lock(log_lock);
if (rli->relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) ||
rli->relay_log.open(ln, LOG_BIN, 0, 0, SEQ_READ_APPEND,
mi->rli.max_relay_log_size, 1, TRUE))
{
+ mysql_mutex_unlock(log_lock);
mysql_mutex_unlock(&rli->data_lock);
sql_print_error("Failed when trying to open logs for '%s' in init_relay_log_info(). Error: %M", ln, my_errno);
DBUG_RETURN(1);
}
+ mysql_mutex_unlock(log_lock);
}
/* if file does not exist */
@@ -424,7 +429,7 @@ Failed to open the existing relay log info file '%s' (errno %d)",
}
rli->inited= 1;
mysql_mutex_unlock(&rli->data_lock);
- DBUG_RETURN(error);
+ DBUG_RETURN(0);
err:
sql_print_error("%s", msg);
@@ -1289,9 +1294,10 @@ bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
}
-void Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
+bool Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
rpl_group_info *rgi)
{
+ int error= 0;
DBUG_ENTER("Relay_log_info::stmt_done");
DBUG_ASSERT(rgi->rli == this);
@@ -1343,10 +1349,11 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
}
DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE(););
if (mi->using_gtid == Master_info::USE_GTID_NO)
- flush_relay_log_info(this);
+ if (flush_relay_log_info(this))
+ error= 1;
DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE(););
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(error);
}
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 96c3e7c3fac..b9fc2127440 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -416,7 +416,7 @@ public:
relay log info and used to produce information for <code>SHOW
SLAVE STATUS</code>.
*/
- void stmt_done(my_off_t event_log_pos, THD *thd, rpl_group_info *rgi);
+ bool stmt_done(my_off_t event_log_pos, THD *thd, rpl_group_info *rgi);
int alloc_inuse_relaylog(const char *name);
void free_inuse_relaylog(inuse_relaylog *ir);
void reset_inuse_relaylog();
diff --git a/sql/slave.cc b/sql/slave.cc
index 717d37a7907..47bdf5eb3e8 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -232,16 +232,14 @@ void init_thread_mask(int* mask,Master_info* mi,bool inverse)
/*
- lock_slave_threads()
+ lock_slave_threads() against other threads doing STOP, START or RESET SLAVE
+
*/
-void lock_slave_threads(Master_info* mi)
+void Master_info::lock_slave_threads()
{
DBUG_ENTER("lock_slave_threads");
-
- //TODO: see if we can do this without dual mutex
- mysql_mutex_lock(&mi->run_lock);
- mysql_mutex_lock(&mi->rli.run_lock);
+ mysql_mutex_lock(&start_stop_lock);
DBUG_VOID_RETURN;
}
@@ -250,13 +248,10 @@ void lock_slave_threads(Master_info* mi)
unlock_slave_threads()
*/
-void unlock_slave_threads(Master_info* mi)
+void Master_info::unlock_slave_threads()
{
DBUG_ENTER("unlock_slave_threads");
-
- //TODO: see if we can do this without dual mutex
- mysql_mutex_unlock(&mi->rli.run_lock);
- mysql_mutex_unlock(&mi->run_lock);
+ mysql_mutex_unlock(&start_stop_lock);
DBUG_VOID_RETURN;
}
@@ -472,7 +467,6 @@ int init_slave()
accepted. However bootstrap may conflict with us if it does START SLAVE.
So it's safer to take the lock.
*/
- mysql_mutex_lock(&LOCK_active_mi);
if (pthread_key_create(&RPL_MASTER_INFO, NULL))
goto err;
@@ -481,7 +475,6 @@ int init_slave()
if (!master_info_index || master_info_index->init_all_master_info())
{
sql_print_error("Failed to initialize multi master structures");
- mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(1);
}
if (!(active_mi= new Master_info(&default_master_connection_name,
@@ -540,7 +533,6 @@ int init_slave()
}
end:
- mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(error);
err:
@@ -713,6 +705,7 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
if (!mi->inited)
DBUG_RETURN(0); /* successfully do nothing */
int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
+ int retval= 0;
mysql_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
mysql_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
@@ -732,24 +725,19 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
skip_lock)) &&
!force_all)
DBUG_RETURN(error);
+ retval= error;
mysql_mutex_lock(log_lock);
DBUG_PRINT("info",("Flushing relay-log info file."));
if (current_thd)
THD_STAGE_INFO(current_thd, stage_flushing_relay_log_info_file);
- if (flush_relay_log_info(&mi->rli))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
-
- if (my_sync(mi->rli.info_fd, MYF(MY_WME)))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
+ if (flush_relay_log_info(&mi->rli) ||
+ my_sync(mi->rli.info_fd, MYF(MY_WME)))
+ retval= ER_ERROR_DURING_FLUSH_LOGS;
mysql_mutex_unlock(log_lock);
}
- if (opt_slave_parallel_threads > 0 &&
- master_info_index &&// master_info_index is set to NULL on server shutdown
- !master_info_index->any_slave_sql_running())
- rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
{
DBUG_PRINT("info",("Terminating IO thread"));
@@ -760,25 +748,26 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
skip_lock)) &&
!force_all)
DBUG_RETURN(error);
+ if (!retval)
+ retval= error;
mysql_mutex_lock(log_lock);
DBUG_PRINT("info",("Flushing relay log and master info file."));
if (current_thd)
THD_STAGE_INFO(current_thd, stage_flushing_relay_log_and_master_info_repository);
- if (flush_master_info(mi, TRUE, FALSE))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
-
+ if (likely(mi->fd >= 0))
+ {
+ if (flush_master_info(mi, TRUE, FALSE) || my_sync(mi->fd, MYF(MY_WME)))
+ retval= ER_ERROR_DURING_FLUSH_LOGS;
+ }
if (mi->rli.relay_log.is_open() &&
my_sync(mi->rli.relay_log.get_log_file()->file, MYF(MY_WME)))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
-
- if (my_sync(mi->fd, MYF(MY_WME)))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
+ retval= ER_ERROR_DURING_FLUSH_LOGS;
mysql_mutex_unlock(log_lock);
}
- DBUG_RETURN(0);
+ DBUG_RETURN(retval);
}
@@ -941,6 +930,15 @@ int start_slave_thread(
mysql_mutex_unlock(start_lock);
DBUG_RETURN(ER_SLAVE_THREAD);
}
+
+ /*
+ In the following loop we can't check for thd->killed as we have to
+ wait until THD structures for the slave thread are created
+ before we can return.
+ This should be ok as there is no major work done in the slave
+ threads before they signal that we can stop waiting.
+ */
+
if (start_cond && cond_lock) // caller has cond_lock
{
THD* thd = current_thd;
@@ -958,16 +956,9 @@ int start_slave_thread(
registered, we could otherwise go waiting though thd->killed is
set.
*/
- if (!thd->killed)
- mysql_cond_wait(start_cond, cond_lock);
+ mysql_cond_wait(start_cond, cond_lock);
thd->EXIT_COND(& saved_stage);
mysql_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
- if (thd->killed)
- {
- if (start_lock)
- mysql_mutex_unlock(start_lock);
- DBUG_RETURN(thd->killed_errno());
- }
}
}
if (start_lock)
@@ -1056,10 +1047,7 @@ int start_slave_threads(THD *thd,
mi);
if (!error && (thread_mask & SLAVE_SQL))
{
- if (opt_slave_parallel_threads > 0)
- error= rpl_parallel_activate_pool(&global_rpl_thread_pool);
- if (!error)
- error= start_slave_thread(
+ error= start_slave_thread(
#ifdef HAVE_PSI_INTERFACE
key_thread_slave_sql,
#endif
@@ -1075,10 +1063,18 @@ int start_slave_threads(THD *thd,
/*
- Release slave threads at time of executing shutdown.
+ Kill slaves preparing for shutdown
+*/
- SYNOPSIS
- end_slave()
+void slave_prepare_for_shutdown()
+{
+ mysql_mutex_lock(&LOCK_active_mi);
+ master_info_index->free_connections();
+ mysql_mutex_unlock(&LOCK_active_mi);
+}
+
+/*
+ Release slave threads at time of executing shutdown.
*/
void end_slave()
@@ -1096,7 +1092,10 @@ void end_slave()
startup parameter to the server was wrong.
*/
mysql_mutex_lock(&LOCK_active_mi);
- /* This will call terminate_slave_threads() on all connections */
+ /*
+ master_info_index should not have any threads anymore as they where
+ killed as part of slave_prepare_for_shutdown()
+ */
delete master_info_index;
master_info_index= 0;
active_mi= 0;
@@ -2867,7 +2866,9 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full,
mysql_mutex_lock(&mi->data_lock);
mysql_mutex_lock(&mi->rli.data_lock);
+ /* err_lock is to protect mi->last_error() */
mysql_mutex_lock(&mi->err_lock);
+ /* err_lock is to protect mi->rli.last_error() */
mysql_mutex_lock(&mi->rli.err_lock);
protocol->store(mi->host, &my_charset_bin);
protocol->store(mi->user, &my_charset_bin);
@@ -4715,6 +4716,16 @@ pthread_handler_t handle_slave_sql(void *arg)
rli->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
pthread_detach_this_thread();
+
+ if (opt_slave_parallel_threads > 0 &&
+ rpl_parallel_activate_pool(&global_rpl_thread_pool))
+ {
+ mysql_cond_broadcast(&rli->start_cond);
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL,
+ "Failed during parallel slave pool activation");
+ goto err_during_init;
+ }
+
if (init_slave_thread(thd, mi, SLAVE_THD_SQL))
{
/*
@@ -5016,8 +5027,15 @@ pthread_handler_t handle_slave_sql(void *arg)
if (rli->mi->using_gtid != Master_info::USE_GTID_NO)
{
ulong domain_count;
+ my_bool save_log_all_errors= thd->log_all_errors;
+ /*
+ We don't need to check return value for flush_relay_log_info()
+ as any errors should be logged to stderr
+ */
+ thd->log_all_errors= 1;
flush_relay_log_info(rli);
+ thd->log_all_errors= save_log_all_errors;
if (mi->using_parallel())
{
/*
@@ -5126,17 +5144,7 @@ err_during_init:
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
mysql_mutex_unlock(&rli->run_lock); // tell the world we are done
- /*
- Deactivate the parallel replication thread pool, if there are now no more
- SQL threads running. Do this here, when we have released all locks, but
- while our THD (and current_thd) is still valid.
- */
- mysql_mutex_lock(&LOCK_active_mi);
- if (opt_slave_parallel_threads > 0 &&
- master_info_index &&// master_info_index is set to NULL on server shutdown
- !master_info_index->any_slave_sql_running())
- rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
- mysql_mutex_unlock(&LOCK_active_mi);
+ rpl_parallel_resize_pool_if_no_slaves();
mysql_mutex_lock(&LOCK_thread_count);
thd->unlink();
@@ -6295,6 +6303,7 @@ err:
void end_relay_log_info(Relay_log_info* rli)
{
+ mysql_mutex_t *log_lock;
DBUG_ENTER("end_relay_log_info");
if (!rli->inited)
@@ -6312,8 +6321,11 @@ void end_relay_log_info(Relay_log_info* rli)
rli->cur_log_fd = -1;
}
rli->inited = 0;
+ log_lock= rli->relay_log.get_log_lock();
+ mysql_mutex_lock(log_lock);
rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
+ mysql_mutex_unlock(log_lock);
/*
Delete the slave's temporary tables from memory.
In the future there will be other actions than this, to ensure persistance
@@ -6464,7 +6476,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
suppress_warnings= 0;
mi->report(ERROR_LEVEL, last_errno, NULL,
"error %s to master '%s@%s:%d'"
- " - retry-time: %d retries: %lu message: %s",
+ " - retry-time: %d maximum-retries: %lu message: %s",
(reconnect ? "reconnecting" : "connecting"),
mi->user, mi->host, mi->port,
mi->connect_retry, master_retry_count,
@@ -7026,9 +7038,12 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
}
rli->event_relay_log_pos = BIN_LOG_HEADER_SIZE;
strmake_buf(rli->event_relay_log_name,rli->linfo.log_file_name);
- flush_relay_log_info(rli);
+ if (flush_relay_log_info(rli))
+ {
+ errmsg= "error flushing relay log";
+ goto err;
+ }
}
-
/*
Now we want to open this next log. To know if it's a hot log (the one
being written by the I/O thread now) or a cold log, we can use
diff --git a/sql/slave.h b/sql/slave.h
index a78ae4cff6f..58c8106614d 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -220,13 +220,12 @@ bool rpl_master_erroneous_autoinc(THD* thd);
const char *print_slave_db_safe(const char *db);
void skip_load_data_infile(NET* net);
+void slave_prepare_for_shutdown();
void end_slave(); /* release slave threads */
void close_active_mi(); /* clean up slave threads data */
void clear_until_condition(Relay_log_info* rli);
void clear_slave_error(Relay_log_info* rli);
void end_relay_log_info(Relay_log_info* rli);
-void lock_slave_threads(Master_info* mi);
-void unlock_slave_threads(Master_info* mi);
void init_thread_mask(int* mask,Master_info* mi,bool inverse);
Format_description_log_event *
read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos,
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index 526442e83e2..7114694124b 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -70,59 +70,56 @@ public:
// Set for DISABLE KEYS | ENABLE KEYS
static const uint ALTER_KEYS_ONOFF = 1L << 9;
- // Set for CONVERT TO CHARACTER SET
- static const uint ALTER_CONVERT = 1L << 10;
-
// Set for FORCE
// Set for ENGINE(same engine)
// Set by mysql_recreate_table()
- static const uint ALTER_RECREATE = 1L << 11;
+ static const uint ALTER_RECREATE = 1L << 10;
// Set for ADD PARTITION
- static const uint ALTER_ADD_PARTITION = 1L << 12;
+ static const uint ALTER_ADD_PARTITION = 1L << 11;
// Set for DROP PARTITION
- static const uint ALTER_DROP_PARTITION = 1L << 13;
+ static const uint ALTER_DROP_PARTITION = 1L << 12;
// Set for COALESCE PARTITION
- static const uint ALTER_COALESCE_PARTITION = 1L << 14;
+ static const uint ALTER_COALESCE_PARTITION = 1L << 13;
// Set for REORGANIZE PARTITION ... INTO
- static const uint ALTER_REORGANIZE_PARTITION = 1L << 15;
+ static const uint ALTER_REORGANIZE_PARTITION = 1L << 14;
// Set for partition_options
- static const uint ALTER_PARTITION = 1L << 16;
+ static const uint ALTER_PARTITION = 1L << 15;
// Set for LOAD INDEX INTO CACHE ... PARTITION
// Set for CACHE INDEX ... PARTITION
- static const uint ALTER_ADMIN_PARTITION = 1L << 17;
+ static const uint ALTER_ADMIN_PARTITION = 1L << 16;
// Set for REORGANIZE PARTITION
- static const uint ALTER_TABLE_REORG = 1L << 18;
+ static const uint ALTER_TABLE_REORG = 1L << 17;
// Set for REBUILD PARTITION
- static const uint ALTER_REBUILD_PARTITION = 1L << 19;
+ static const uint ALTER_REBUILD_PARTITION = 1L << 18;
// Set for partitioning operations specifying ALL keyword
- static const uint ALTER_ALL_PARTITION = 1L << 20;
+ static const uint ALTER_ALL_PARTITION = 1L << 19;
// Set for REMOVE PARTITIONING
- static const uint ALTER_REMOVE_PARTITIONING = 1L << 21;
+ static const uint ALTER_REMOVE_PARTITIONING = 1L << 20;
// Set for ADD FOREIGN KEY
- static const uint ADD_FOREIGN_KEY = 1L << 22;
+ static const uint ADD_FOREIGN_KEY = 1L << 21;
// Set for DROP FOREIGN KEY
- static const uint DROP_FOREIGN_KEY = 1L << 23;
+ static const uint DROP_FOREIGN_KEY = 1L << 22;
// Set for EXCHANGE PARITION
- static const uint ALTER_EXCHANGE_PARTITION = 1L << 24;
+ static const uint ALTER_EXCHANGE_PARTITION = 1L << 23;
// Set by Sql_cmd_alter_table_truncate_partition::execute()
- static const uint ALTER_TRUNCATE_PARTITION = 1L << 25;
+ static const uint ALTER_TRUNCATE_PARTITION = 1L << 24;
// Set for ADD [COLUMN] FIRST | AFTER
- static const uint ALTER_COLUMN_ORDER = 1L << 26;
+ static const uint ALTER_COLUMN_ORDER = 1L << 25;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 860a2c52ab5..9c56b7d8f22 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -6674,7 +6674,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
if (!table_ref->belong_to_view &&
!table_ref->belong_to_derived)
{
- SELECT_LEX *current_sel= thd->lex->current_select;
+ SELECT_LEX *current_sel= item->context->select_lex;
SELECT_LEX *last_select= table_ref->select_lex;
bool all_merged= TRUE;
for (SELECT_LEX *sl= current_sel; sl && sl!=last_select;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7585e49390f..fb58519b816 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -7066,7 +7066,13 @@ wait_for_commit::reinit()
So in this case, do a re-init of the mutex. In release builds, we want to
avoid the overhead of a re-init though.
+
+ To ensure that no one is locking the mutex, we take a lock of it first.
+ For full explanation, see wait_for_commit::~wait_for_commit()
*/
+ mysql_mutex_lock(&LOCK_wait_commit);
+ mysql_mutex_unlock(&LOCK_wait_commit);
+
mysql_mutex_destroy(&LOCK_wait_commit);
mysql_mutex_init(key_LOCK_wait_commit, &LOCK_wait_commit, MY_MUTEX_INIT_FAST);
#endif
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index dadb03abfff..45815fe7a02 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2446,7 +2446,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp)
int
mysql_execute_command(THD *thd)
{
- int res= FALSE;
+ int res= 0;
int up_result= 0;
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
@@ -3119,10 +3119,17 @@ mysql_execute_command(THD *thd)
if (check_global_access(thd, SUPER_ACL))
goto error;
+ /*
+ In this code it's ok to use LOCK_active_mi as we are adding new things
+ into master_info_index
+ */
mysql_mutex_lock(&LOCK_active_mi);
-
if (!master_info_index)
+ {
+ mysql_mutex_unlock(&LOCK_active_mi);
+ my_error(ER_SERVER_SHUTDOWN, MYF(0));
goto error;
+ }
mi= master_info_index->get_master_info(&lex_mi->connection_name,
Sql_condition::WARN_LEVEL_NOTE);
@@ -3151,7 +3158,7 @@ mysql_execute_command(THD *thd)
If new master was not added, we still need to free mi.
*/
if (master_info_added)
- master_info_index->remove_master_info(&lex_mi->connection_name);
+ master_info_index->remove_master_info(mi);
else
delete mi;
}
@@ -3169,22 +3176,24 @@ mysql_execute_command(THD *thd)
/* Accept one of two privileges */
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
goto error;
- mysql_mutex_lock(&LOCK_active_mi);
if (lex->verbose)
+ {
+ mysql_mutex_lock(&LOCK_active_mi);
res= show_all_master_info(thd);
+ mysql_mutex_unlock(&LOCK_active_mi);
+ }
else
{
LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
Master_info *mi;
- mi= master_info_index->get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR);
- if (mi != NULL)
+ if ((mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
res= show_master_info(thd, mi, 0);
+ mi->release();
}
}
- mysql_mutex_unlock(&LOCK_active_mi);
break;
}
case SQLCOM_SHOW_MASTER_STAT:
@@ -3528,22 +3537,23 @@ end_with_restore_list:
load_error= rpl_load_gtid_slave_state(thd);
- mysql_mutex_lock(&LOCK_active_mi);
-
- if ((mi= (master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
+ /*
+ We don't need to ensure that only one user is using master_info
+ as start_slave is protected against simultaneous usage
+ */
+ if ((mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
if (load_error)
{
/*
- We cannot start a slave using GTID if we cannot load the GTID position
- from the mysql.gtid_slave_pos table. But we can allow non-GTID
- replication (useful eg. during upgrade).
+ We cannot start a slave using GTID if we cannot load the
+ GTID position from the mysql.gtid_slave_pos table. But we
+ can allow non-GTID replication (useful eg. during upgrade).
*/
if (mi->using_gtid != Master_info::USE_GTID_NO)
{
- mysql_mutex_unlock(&LOCK_active_mi);
+ mi->release();
break;
}
else
@@ -3551,8 +3561,8 @@ end_with_restore_list:
}
if (!start_slave(thd, mi, 1 /* net report*/))
my_ok(thd);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
break;
}
case SQLCOM_SLAVE_STOP:
@@ -3582,13 +3592,17 @@ end_with_restore_list:
}
lex_mi= &thd->lex->mi;
- mysql_mutex_lock(&LOCK_active_mi);
- if ((mi= (master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
- if (!stop_slave(thd, mi, 1/* net report*/))
+ if ((mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
+ {
+ if (stop_slave(thd, mi, 1/* net report*/))
+ res= 1;
+ mi->release();
+ if (rpl_parallel_resize_pool_if_no_slaves())
+ res= 1;
+ if (!res)
my_ok(thd);
- mysql_mutex_unlock(&LOCK_active_mi);
+ }
break;
}
case SQLCOM_SLAVE_ALL_START:
@@ -4900,11 +4914,13 @@ end_with_restore_list:
reload_acl_and_cache binlog interactions failed
*/
res= 1;
- }
+ }
if (!res)
my_ok(thd);
}
+ else
+ res= 1; // reload_acl_and_cache failed
#ifdef HAVE_REPLICATION
if (lex->type & REFRESH_READ_LOCK)
rpl_unpause_after_ftwrl(thd);
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index e361ed8b6e6..995c4c0a838 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -181,24 +181,20 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
slave is not likely to have the same connection names.
*/
tmp_write_to_binlog= 0;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if (!(mi= (get_master_info(&connection_name,
+ Sql_condition::WARN_LEVEL_ERROR))))
{
- if (!(mi= (master_info_index->
- get_master_info(&connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
- {
- result= 1;
- }
- else
- {
- mysql_mutex_lock(&mi->data_lock);
- if (rotate_relay_log(mi))
- *write_to_binlog= -1;
- mysql_mutex_unlock(&mi->data_lock);
- }
+ result= 1;
+ }
+ else
+ {
+ mysql_mutex_lock(&mi->data_lock);
+ if (rotate_relay_log(mi))
+ *write_to_binlog= -1;
+ mysql_mutex_unlock(&mi->data_lock);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
#endif
}
#ifdef HAVE_QUERY_CACHE
@@ -375,27 +371,33 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
Master_info *mi;
tmp_write_to_binlog= 0;
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index)
+
+ if (!(mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
- if (!(mi= (master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR))))
- {
- result= 1;
- }
- else if (reset_slave(thd, mi))
+ result= 1;
+ }
+ else
+ {
+ /* The following will fail if slave is running */
+ if (reset_slave(thd, mi))
{
+ mi->release();
/* NOTE: my_error() has been already called by reset_slave(). */
result= 1;
}
else if (mi->connection_name.length && thd->lex->reset_slave_info.all)
{
/* If not default connection and 'all' is used */
- master_info_index->remove_master_info(&mi->connection_name);
+ mi->release();
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (master_info_index->remove_master_info(mi))
+ result= 1;
+ mysql_mutex_unlock(&LOCK_active_mi);
}
+ else
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
}
#endif
if (options & REFRESH_USER_RESOURCES)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 0dd4c59ce56..6fedda95959 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -3041,7 +3041,16 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
relay_log_info_file, 0,
&mi->cmp_connection_name);
- lock_slave_threads(mi); // this allows us to cleanly read slave_running
+ mi->lock_slave_threads();
+ if (mi->killed)
+ {
+ /* connection was deleted while we waited for lock_slave_threads */
+ mi->unlock_slave_threads();
+ my_error(WARN_NO_MASTER_INFO, mi->connection_name.length,
+ mi->connection_name.str);
+ DBUG_RETURN(-1);
+ }
+
// Get a mask of _stopped_ threads
init_thread_mask(&thread_mask,mi,1 /* inverse */);
@@ -3176,7 +3185,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
if (!slave_errno)
slave_errno = start_slave_threads(thd,
- 0 /*no mutex */,
+ 1,
1 /* wait for start */,
mi,
master_info_file_tmp,
@@ -3192,7 +3201,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
}
err:
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
thd_proc_info(thd, 0);
if (slave_errno)
@@ -3233,8 +3242,12 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
DBUG_RETURN(-1);
THD_STAGE_INFO(thd, stage_killing_slave);
int thread_mask;
- lock_slave_threads(mi);
- // Get a mask of _running_ threads
+ mi->lock_slave_threads();
+ /*
+ Get a mask of _running_ threads.
+ We don't have to test for mi->killed as the thread_mask will take care
+ of checking if threads exists
+ */
init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
/*
Below we will stop all running threads.
@@ -3247,8 +3260,7 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
if (thread_mask)
{
- slave_errno= terminate_slave_threads(mi,thread_mask,
- 1 /*skip lock */);
+ slave_errno= terminate_slave_threads(mi,thread_mask, 0 /* get lock */);
}
else
{
@@ -3257,7 +3269,8 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_NOT_RUNNING,
ER_THD(thd, ER_SLAVE_WAS_NOT_RUNNING));
}
- unlock_slave_threads(mi);
+
+ mi->unlock_slave_threads();
if (slave_errno)
{
@@ -3292,11 +3305,20 @@ int reset_slave(THD *thd, Master_info* mi)
char relay_log_info_file_tmp[FN_REFLEN];
DBUG_ENTER("reset_slave");
- lock_slave_threads(mi);
+ mi->lock_slave_threads();
+ if (mi->killed)
+ {
+ /* connection was deleted while we waited for lock_slave_threads */
+ mi->unlock_slave_threads();
+ my_error(WARN_NO_MASTER_INFO, mi->connection_name.length,
+ mi->connection_name.str);
+ DBUG_RETURN(-1);
+ }
+
init_thread_mask(&thread_mask,mi,0 /* not inverse */);
if (thread_mask) // We refuse if any slave thread is running
{
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length,
mi->connection_name.str);
DBUG_RETURN(ER_SLAVE_MUST_STOP);
@@ -3359,7 +3381,7 @@ int reset_slave(THD *thd, Master_info* mi)
RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi));
err:
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
if (error)
my_error(sql_errno, MYF(0), errmsg);
DBUG_RETURN(error);
@@ -3474,8 +3496,8 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
DBUG_ENTER("change_master");
- mysql_mutex_assert_owner(&LOCK_active_mi);
DBUG_ASSERT(master_info_index);
+ mysql_mutex_assert_owner(&LOCK_active_mi);
*master_info_added= false;
/*
@@ -3495,7 +3517,16 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
lex_mi->port))
DBUG_RETURN(TRUE);
- lock_slave_threads(mi);
+ mi->lock_slave_threads();
+ if (mi->killed)
+ {
+ /* connection was deleted while we waited for lock_slave_threads */
+ mi->unlock_slave_threads();
+ my_error(WARN_NO_MASTER_INFO, mi->connection_name.length,
+ mi->connection_name.str);
+ DBUG_RETURN(TRUE);
+ }
+
init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
if (thread_mask) // We refuse if any slave thread is running
{
@@ -3816,12 +3847,13 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
in-memory value at restart (thus causing errors, as the old relay log does
not exist anymore).
*/
- flush_relay_log_info(&mi->rli);
+ if (flush_relay_log_info(&mi->rli))
+ ret= 1;
mysql_cond_broadcast(&mi->data_cond);
mysql_mutex_unlock(&mi->rli.data_lock);
err:
- unlock_slave_threads(mi);
+ mi->unlock_slave_threads();
if (ret == FALSE)
my_ok(thd);
DBUG_RETURN(ret);
@@ -3901,13 +3933,9 @@ bool mysql_show_binlog_events(THD* thd)
{
if (!lex_mi->connection_name.str)
lex_mi->connection_name= thd->variables.default_master_connection;
- mysql_mutex_lock(&LOCK_active_mi);
- if (!master_info_index ||
- !(mi= master_info_index->
- get_master_info(&lex_mi->connection_name,
- Sql_condition::WARN_LEVEL_ERROR)))
+ if (!(mi= get_master_info(&lex_mi->connection_name,
+ Sql_condition::WARN_LEVEL_ERROR)))
{
- mysql_mutex_unlock(&LOCK_active_mi);
DBUG_RETURN(TRUE);
}
binary_log= &(mi->rli.relay_log);
@@ -3926,7 +3954,7 @@ bool mysql_show_binlog_events(THD* thd)
if (mi)
{
/* We can unlock the mutex as we have a lock on the file */
- mysql_mutex_unlock(&LOCK_active_mi);
+ mi->release();
mi= 0;
}
@@ -3948,6 +3976,7 @@ bool mysql_show_binlog_events(THD* thd)
goto err;
}
+ /* These locks is here to enable syncronization with log_in_use() */
mysql_mutex_lock(&LOCK_thread_count);
thd->current_linfo = &linfo;
mysql_mutex_unlock(&LOCK_thread_count);
@@ -4061,7 +4090,7 @@ bool mysql_show_binlog_events(THD* thd)
mysql_mutex_unlock(log_lock);
}
else if (mi)
- mysql_mutex_unlock(&LOCK_active_mi);
+ mi->release();
// Check that linfo is still on the function scope.
DEBUG_SYNC(thd, "after_show_binlog_events");
@@ -4082,8 +4111,9 @@ err:
else
my_eof(thd);
+ /* These locks is here to enable syncronization with log_in_use() */
mysql_mutex_lock(&LOCK_thread_count);
- thd->current_linfo = 0;
+ thd->current_linfo= 0;
mysql_mutex_unlock(&LOCK_thread_count);
thd->variables.max_allowed_packet= old_max_allowed_packet;
DBUG_RETURN(ret);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index ebbec8c4c83..27d1b96886c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6450,6 +6450,9 @@ static bool fill_alter_inplace_info(THD *thd,
new_key->user_defined_key_parts))
goto index_changed;
+ if (table_key->block_size != new_key->block_size)
+ goto index_changed;
+
if (engine_options_differ(table_key->option_struct, new_key->option_struct,
table->file->ht->index_options))
goto index_changed;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 09dda0809de..efbc896b94a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -7533,7 +7533,7 @@ alter_list_item:
$5->name, $4->csname));
if (Lex->create_info.add_alter_list_item_convert_to_charset($5))
MYSQL_YYABORT;
- Lex->alter_info.flags|= Alter_info::ALTER_CONVERT;
+ Lex->alter_info.flags|= Alter_info::ALTER_OPTIONS;
}
| create_table_options_space_separated
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 02dad1d1ca7..1a6bb9a4e54 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1586,7 +1586,6 @@ bool
Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
{
String str, *res;
- bool running;
DBUG_ASSERT(var->type == OPT_GLOBAL);
@@ -1597,11 +1596,7 @@ Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
return true;
}
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
+ if (give_error_if_slave_running(0))
return true;
if (!(res= var->value->val_str(&str)))
return true;
@@ -1639,7 +1634,7 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var)
mysql_mutex_unlock(&LOCK_global_system_variables);
mysql_mutex_lock(&LOCK_active_mi);
- if (!master_info_index || master_info_index->give_error_if_slave_running())
+ if (give_error_if_slave_running(1))
err= true;
else
err= rpl_gtid_pos_update(thd, var->save_result.string_value.str,
@@ -1825,16 +1820,7 @@ Sys_var_last_gtid::session_value_ptr(THD *thd, const LEX_STRING *base)
static bool
check_slave_parallel_threads(sys_var *self, THD *thd, set_var *var)
{
- bool running;
-
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
- return true;
-
- return false;
+ return give_error_if_slave_running(0);
}
static bool
@@ -1843,10 +1829,7 @@ fix_slave_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
bool err;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- err= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
+ err= give_error_if_slave_running(0);
mysql_mutex_lock(&LOCK_global_system_variables);
return err;
@@ -1869,16 +1852,7 @@ static Sys_var_ulong Sys_slave_parallel_threads(
static bool
check_slave_domain_parallel_threads(sys_var *self, THD *thd, set_var *var)
{
- bool running;
-
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
- return true;
-
- return false;
+ return give_error_if_slave_running(0);
}
static bool
@@ -1887,13 +1861,10 @@ fix_slave_domain_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
bool running;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
+ running= give_error_if_slave_running(0);
mysql_mutex_lock(&LOCK_global_system_variables);
- return running ? true : false;
+ return running;
}
@@ -2036,16 +2007,7 @@ static Sys_var_bit Sys_skip_parallel_replication(
static bool
check_gtid_ignore_duplicates(sys_var *self, THD *thd, set_var *var)
{
- bool running;
-
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
- if (running)
- return true;
-
- return false;
+ return give_error_if_slave_running(0);
}
static bool
@@ -2054,13 +2016,10 @@ fix_gtid_ignore_duplicates(sys_var *self, THD *thd, enum_var_type type)
bool running;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- running= (!master_info_index ||
- master_info_index->give_error_if_slave_running());
- mysql_mutex_unlock(&LOCK_active_mi);
+ running= give_error_if_slave_running(0);
mysql_mutex_lock(&LOCK_global_system_variables);
- return running ? true : false;
+ return running;
}
@@ -2969,10 +2928,8 @@ Sys_var_replicate_events_marked_for_skip::global_update(THD *thd, set_var *var)
DBUG_ENTER("Sys_var_replicate_events_marked_for_skip::global_update");
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index && !master_info_index->give_error_if_slave_running())
+ if (!give_error_if_slave_running(0))
result= Sys_var_enum::global_update(thd, var);
- mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_global_system_variables);
DBUG_RETURN(result);
}
@@ -4294,35 +4251,31 @@ static Sys_var_mybool Sys_relay_log_recovery(
bool Sys_var_rpl_filter::global_update(THD *thd, set_var *var)
{
bool result= true; // Assume error
- Master_info *mi;
LEX_STRING *base_name= &var->base;
if (!base_name->length)
base_name= &thd->variables.default_master_connection;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
-
- mi= master_info_index->
- get_master_info(base_name, !base_name->length ?
- Sql_condition::WARN_LEVEL_ERROR :
- Sql_condition::WARN_LEVEL_WARN);
- if (mi)
+
+ if (Master_info *mi= get_master_info(base_name, !var->base.length ?
+ Sql_condition::WARN_LEVEL_ERROR :
+ Sql_condition::WARN_LEVEL_WARN))
{
if (mi->rli.slave_running)
{
my_error(ER_SLAVE_MUST_STOP, MYF(0),
- mi->connection_name.length,
- mi->connection_name.str);
+ mi->connection_name.length,
+ mi->connection_name.str);
result= true;
}
else
{
result= set_filter_value(var->save_result.string_value.str, mi);
}
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_global_system_variables);
return result;
}
@@ -4332,6 +4285,8 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi)
bool status= true;
Rpl_filter* rpl_filter= mi->rpl_filter;
+ /* Proctect against other threads */
+ mysql_mutex_lock(&LOCK_active_mi);
switch (opt_id) {
case OPT_REPLICATE_DO_DB:
status= rpl_filter->set_do_db(value);
@@ -4352,7 +4307,7 @@ bool Sys_var_rpl_filter::set_filter_value(const char *value, Master_info *mi)
status= rpl_filter->set_wild_ignore_table(value);
break;
}
-
+ mysql_mutex_unlock(&LOCK_active_mi);
return status;
}
@@ -4366,23 +4321,20 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd,
Rpl_filter *rpl_filter;
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
-
- mi= master_info_index->
- get_master_info(base_name, !base_name->length ?
- Sql_condition::WARN_LEVEL_ERROR :
- Sql_condition::WARN_LEVEL_WARN);
-
- mysql_mutex_lock(&LOCK_global_system_variables);
+ mi= get_master_info(base_name, !base_name->length ?
+ Sql_condition::WARN_LEVEL_ERROR :
+ Sql_condition::WARN_LEVEL_WARN);
if (!mi)
{
- mysql_mutex_unlock(&LOCK_active_mi);
+ mysql_mutex_lock(&LOCK_global_system_variables);
return 0;
}
+
rpl_filter= mi->rpl_filter;
tmp.length(0);
+ mysql_mutex_lock(&LOCK_active_mi);
switch (opt_id) {
case OPT_REPLICATE_DO_DB:
rpl_filter->get_do_db(&tmp);
@@ -4403,9 +4355,12 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd,
rpl_filter->get_wild_ignore_table(&tmp);
break;
}
+ mysql_mutex_unlock(&LOCK_active_mi);
+ mysql_mutex_lock(&LOCK_global_system_variables);
+
+ mi->release();
ret= (uchar *) thd->strmake(tmp.ptr(), tmp.length());
- mysql_mutex_unlock(&LOCK_active_mi);
return ret;
}
@@ -4474,17 +4429,12 @@ get_master_info_ulonglong_value(THD *thd, ptrdiff_t offset)
Master_info *mi;
ulonglong res= 0; // Default value
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_WARN);
- if (mi)
+ if ((mi= get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_WARN)))
{
- mysql_mutex_lock(&mi->rli.data_lock);
res= *((ulonglong*) (((uchar*) mi) + master_info_offset));
- mysql_mutex_unlock(&mi->rli.data_lock);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
mysql_mutex_lock(&LOCK_global_system_variables);
return res;
}
@@ -4499,19 +4449,16 @@ bool update_multi_source_variable(sys_var *self_var, THD *thd,
if (type == OPT_GLOBAL)
mysql_mutex_unlock(&LOCK_global_system_variables);
- mysql_mutex_lock(&LOCK_active_mi);
- mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
- Sql_condition::WARN_LEVEL_ERROR);
- if (mi)
+ if ((mi= (get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_ERROR))))
{
mysql_mutex_lock(&mi->rli.run_lock);
mysql_mutex_lock(&mi->rli.data_lock);
result= self->update_variable(thd, mi);
mysql_mutex_unlock(&mi->rli.data_lock);
mysql_mutex_unlock(&mi->rli.run_lock);
+ mi->release();
}
- mysql_mutex_unlock(&LOCK_active_mi);
if (type == OPT_GLOBAL)
mysql_mutex_lock(&LOCK_global_system_variables);
return result;
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 33f02d8338c..e66f03e8174 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -5173,7 +5173,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
TABLE_SHARE *table_s,
HA_CREATE_INFO *create_info)
{
- char v=0, spc= ',', qch= 0;
+ char v=0;
const char *fncn= "?";
const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src;
const char *col, *ocl, *rnk, *pic, *fcl, *skc, *zfn;
@@ -5225,10 +5225,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
fncn= topt->catfunc;
fnc= GetFuncID(fncn);
sep= topt->separator;
- spc= (!sep) ? ',' : *sep;
- qch= topt->qchar ? *topt->qchar : (signed)topt->quoted >= 0 ? '"' : 0;
- mul = (int)topt->multiple;
- tbl= topt->tablist;
col= topt->colist;
if (topt->oplist) {
diff --git a/storage/connect/ioapi.c b/storage/connect/ioapi.c
index 7f5c191b2af..a49da91f7f0 100644
--- a/storage/connect/ioapi.c
+++ b/storage/connect/ioapi.c
@@ -27,6 +27,7 @@
#include "ioapi.h"
+#include "my_attribute.h"
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
{
@@ -92,7 +93,7 @@ static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPO
static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
-static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque __attribute__((unused)), const char* filename, int mode)
{
FILE* file = NULL;
const char* mode_fopen = NULL;
@@ -110,7 +111,7 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in
return file;
}
-static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque __attribute__((unused)), const void* filename, int mode)
{
FILE* file = NULL;
const char* mode_fopen = NULL;
@@ -129,21 +130,21 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename,
}
-static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+static uLong ZCALLBACK fread_file_func (voidpf opaque __attribute__((unused)), voidpf stream, void* buf, uLong size)
{
uLong ret;
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
-static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque __attribute__((unused)), voidpf stream, const void* buf, uLong size)
{
uLong ret;
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
-static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+static long ZCALLBACK ftell_file_func (voidpf opaque __attribute__((unused)), voidpf stream)
{
long ret;
ret = ftell((FILE *)stream);
@@ -151,14 +152,14 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
}
-static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque __attribute__((unused)), voidpf stream)
{
ZPOS64_T ret;
ret = FTELLO_FUNC((FILE *)stream);
return ret;
}
-static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
+static long ZCALLBACK fseek_file_func (voidpf opaque __attribute__((unused)), voidpf stream, uLong offset, int origin)
{
int fseek_origin=0;
long ret;
@@ -181,7 +182,7 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offs
return ret;
}
-static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
+static long ZCALLBACK fseek64_file_func (voidpf opaque __attribute__((unused)), voidpf stream, ZPOS64_T offset, int origin)
{
int fseek_origin=0;
long ret;
@@ -207,14 +208,14 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
}
-static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+static int ZCALLBACK fclose_file_func (voidpf opaque __attribute__((unused)), voidpf stream)
{
int ret;
ret = fclose((FILE *)stream);
return ret;
}
-static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+static int ZCALLBACK ferror_file_func (voidpf opaque __attribute__((unused)), voidpf stream)
{
int ret;
ret = ferror((FILE *)stream);
diff --git a/storage/connect/zip.c b/storage/connect/zip.c
index ea54853e858..4bbe31ab7dd 100644
--- a/storage/connect/zip.c
+++ b/storage/connect/zip.c
@@ -637,7 +637,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
return relativeOffset;
}
-int LoadCentralDirectoryRecord(zip64_internal* pziinit)
+static int LoadCentralDirectoryRecord(zip64_internal* pziinit)
{
int err=ZIP_OK;
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
@@ -846,7 +846,7 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit)
/************************************************************/
-extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
+static zipFile zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
{
zip64_internal ziinit;
zip64_internal* zi;
@@ -955,7 +955,7 @@ extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
return zipOpen3(pathname,append,NULL,NULL);
}
-int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
+static int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
{
/* write the local header */
int err;
@@ -1752,7 +1752,7 @@ extern int ZEXPORT zipCloseFileInZip (zipFile file)
return zipCloseFileInZipRaw (file,0,0);
}
-int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
+static int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
{
int err = ZIP_OK;
ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
@@ -1774,7 +1774,7 @@ int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eo
return err;
}
-int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+static int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
{
int err = ZIP_OK;
@@ -1813,7 +1813,7 @@ int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centra
}
return err;
}
-int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+static int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
{
int err = ZIP_OK;
@@ -1861,7 +1861,7 @@ int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
return err;
}
-int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
+static int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
{
int err = ZIP_OK;
uInt size_global_comment = 0;
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 8bcdd5da48d..af8013b51c2 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1094,7 +1094,12 @@ fil_space_extend_must_retry(
const ulint n_pages = size - start_page_no;
const os_offset_t len = os_offset_t(n_pages) * page_size;
- int err = posix_fallocate(node->handle, start_offset, len);
+ int err;
+ do {
+ err = posix_fallocate(node->handle, start_offset, len);
+ } while (err == EINTR
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
+
*success = !err;
if (!*success) {
ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s"
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 0e9f1398033..624ee0bb35d 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -1470,17 +1470,7 @@ log_write_up_to(
}
loop:
-#ifdef UNIV_DEBUG
- loop_count++;
-
- ut_ad(loop_count < 5);
-
-# if 0
- if (loop_count > 2) {
- fprintf(stderr, "Log loop count %lu\n", loop_count);
- }
-# endif
-#endif
+ ut_ad(++loop_count < 100);
mutex_enter(&(log_sys->mutex));
ut_ad(!recv_no_log_write);
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index fb6a802e5e5..d212c9bec8c 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -2394,7 +2394,12 @@ os_file_set_size(
# ifdef HAVE_POSIX_FALLOCATE
if (srv_use_posix_fallocate) {
- int err = posix_fallocate(file, 0, size);
+ int err;
+ do {
+ err = posix_fallocate(file, 0, size);
+ } while (err == EINTR
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
+
if (err) {
ib_logf(IB_LOG_LEVEL_ERROR,
"preallocating " INT64PF " bytes for"
diff --git a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
index 45b2c923635..78258789083 100644
--- a/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/lib/CMakeLists.txt
@@ -22,8 +22,14 @@ include_directories(
${ONIGMO_INCLUDE_DIRS}
${MRUBY_INCLUDE_DIRS}
${LIBLZ4_INCLUDE_DIRS})
-link_directories(
- ${LIBLZ4_LIBRARY_DIRS})
+if (LIBLZ4_LIBRARY_DIRS)
+ find_library(LZ4_LIBS
+ NAMES ${LIBLZ4_LIBRARIES}
+ PATHS ${LIBLZ4_LIBRARY_DIRS}
+ NO_DEFAULT_PATH)
+else()
+ set(LZ4_LIBS ${LIBLZ4_LIBRARIES})
+endif()
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am LIBGROONGA_SOURCES)
read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/dat/sources.am LIBGRNDAT_SOURCES)
@@ -60,7 +66,7 @@ set(GRN_ALL_LIBRARIES
${RT_LIBS}
${PTHREAD_LIBS}
${Z_LIBS}
- ${LIBLZ4_LIBRARIES}
+ ${LZ4_LIBS}
${DL_LIBS}
${M_LIBS}
${WS2_32_LIBS}
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 7d518320d50..60764bfd696 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -2182,6 +2182,74 @@ uint ha_myisam::checksum() const
}
+enum_alter_inplace_result
+ha_myisam::check_if_supported_inplace_alter(TABLE *new_table,
+ Alter_inplace_info *alter_info)
+{
+ DBUG_ENTER("ha_myisam::check_if_supported_inplace_alter");
+
+ const uint readd_index= Alter_inplace_info::ADD_INDEX |
+ Alter_inplace_info::DROP_INDEX;
+ const uint readd_unique= Alter_inplace_info::ADD_UNIQUE_INDEX |
+ Alter_inplace_info::DROP_UNIQUE_INDEX;
+ const uint readd_pk= Alter_inplace_info::ADD_PK_INDEX |
+ Alter_inplace_info::DROP_PK_INDEX;
+
+ const uint op= alter_info->handler_flags;
+
+ /*
+ ha_myisam::open() updates table->key_info->block_size to be the actual
+ MYI index block size, overwriting user-specified value (if any).
+ So, the server can not reliably detect whether ALTER TABLE changes
+ key_block_size or not, it might think the block size was changed,
+ when it wasn't, and in this case the server will recreate (drop+add)
+ the index unnecessary. Fix it.
+ */
+
+ if (table->s->keys == new_table->s->keys &&
+ ((op & readd_pk) == readd_pk ||
+ (op & readd_unique) == readd_unique ||
+ (op & readd_index) == readd_index))
+ {
+ for (uint i=0; i < table->s->keys; i++)
+ {
+ KEY *old_key= table->key_info + i;
+ KEY *new_key= new_table->key_info + i;
+
+ if (old_key->block_size == new_key->block_size)
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); // must differ somewhere else
+
+ if (new_key->block_size && new_key->block_size != old_key->block_size)
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); // really changed
+
+ /* any difference besides the block_size, and we give up */
+ if (old_key->key_length != new_key->key_length ||
+ old_key->flags != new_key->flags ||
+ old_key->user_defined_key_parts != new_key->user_defined_key_parts ||
+ old_key->algorithm != new_key->algorithm ||
+ strcmp(old_key->name, new_key->name))
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+
+ for (uint j= 0; j < old_key->user_defined_key_parts; j++)
+ {
+ KEY_PART_INFO *old_kp= old_key->key_part + j;
+ KEY_PART_INFO *new_kp= new_key->key_part + j;
+ if (old_kp->offset != new_kp->offset ||
+ old_kp->null_offset != new_kp->null_offset ||
+ old_kp->length != new_kp->length ||
+ old_kp->fieldnr != new_kp->fieldnr ||
+ old_kp->key_part_flag != new_kp->key_part_flag ||
+ old_kp->type != new_kp->type ||
+ old_kp->null_bit != new_kp->null_bit)
+ DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
+ }
+ }
+ alter_info->handler_flags &= ~(readd_pk | readd_unique | readd_index);
+ }
+ DBUG_RETURN(handler::check_if_supported_inplace_alter(new_table, alter_info));
+}
+
+
bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index 63fb0ea5a2a..b132c955795 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -138,6 +138,8 @@ class ha_myisam: public handler
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt);
int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
+ enum_alter_inplace_result check_if_supported_inplace_alter(TABLE *new_table,
+ Alter_inplace_info *alter_info);
bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
#ifdef HAVE_QUERY_CACHE
my_bool register_query_cache_table(THD *thd, char *table_key,
diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.result b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.result
index 42c86405503..6b1d0a1854d 100644
--- a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.result
+++ b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.result
@@ -33,5 +33,5 @@ FROM `version_history` AS `v` INNER JOIN `db_history` AS `db` ON `db`.`nodeID` =
WHERE `latch` = 'breadth_first' AND `origid` = '1' ORDER BY `weight` DESC LIMIT 1;
version nodeID
0.0.3 3
-DROP TABLE db_history;
DROP TABLE version_history;
+DROP TABLE db_history;
diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.test b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.test
index 3a7a0e5af08..b8f0ae556c8 100644
--- a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.test
+++ b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6282.test
@@ -40,8 +40,8 @@
--disconnect con2
--connect (con3,localhost,root,,test)
-DROP TABLE db_history;
DROP TABLE version_history;
+DROP TABLE db_history;
--disconnect con3
diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.result b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.result
index 8e680e15206..68002ce98a2 100644
--- a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.result
+++ b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.result
@@ -8,5 +8,5 @@ latch origid destid weight seq linkid
breadth_first 1 6 NULL 0 1
breadth_first 1 6 1 1 2
breadth_first 1 6 1 2 6
-DROP TABLE IF EXISTS oq_backing;
DROP TABLE IF EXISTS oq_graph;
+DROP TABLE IF EXISTS oq_backing;
diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.test b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.test
index 72de926da2e..fefd03a7ed9 100644
--- a/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.test
+++ b/storage/oqgraph/mysql-test/oqgraph/regression_mdev6345.test
@@ -14,6 +14,6 @@ CREATE TABLE oq_graph (latch VARCHAR(32) NULL, origid BIGINT UNSIGNED NULL, dest
SELECT * FROM oq_graph WHERE latch='breadth_first' AND origid=1 AND destid=6;
-DROP TABLE IF EXISTS oq_backing;
DROP TABLE IF EXISTS oq_graph;
+DROP TABLE IF EXISTS oq_backing;
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 848406d9061..0357ab43e70 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1099,7 +1099,12 @@ fil_space_extend_must_retry(
const ulint n_pages = size - start_page_no;
const os_offset_t len = os_offset_t(n_pages) * page_size;
- int err = posix_fallocate(node->handle, start_offset, len);
+ int err;
+ do {
+ err = posix_fallocate(node->handle, start_offset, len);
+ } while (err == EINTR
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
+
*success = !err;
if (!*success) {
ib_logf(IB_LOG_LEVEL_ERROR, "extending file %s"
diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc
index dc54aa76dbe..e0259ef80a6 100644
--- a/storage/xtradb/log/log0log.cc
+++ b/storage/xtradb/log/log0log.cc
@@ -1588,17 +1588,7 @@ log_write_up_to(
}
loop:
-#ifdef UNIV_DEBUG
- loop_count++;
-
- ut_ad(loop_count < 5);
-
-# if 0
- if (loop_count > 2) {
- fprintf(stderr, "Log loop count %lu\n", loop_count);
- }
-# endif
-#endif
+ ut_ad(++loop_count < 100);
mutex_enter(&(log_sys->mutex));
ut_ad(!recv_no_log_write);
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 8a83828e7c1..c5be6d45c0e 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -2576,7 +2576,12 @@ os_file_set_size(
# ifdef HAVE_POSIX_FALLOCATE
if (srv_use_posix_fallocate) {
- int err = posix_fallocate(file, 0, size);
+ int err;
+ do {
+ err = posix_fallocate(file, 0, size);
+ } while (err == EINTR
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
+
if (err) {
ib_logf(IB_LOG_LEVEL_ERROR,
"preallocating " INT64PF " bytes for"
diff --git a/support-files/mysql-log-rotate.sh b/support-files/mysql-log-rotate.sh
index 0ee78b0f7ca..5d1b30b208e 100644
--- a/support-files/mysql-log-rotate.sh
+++ b/support-files/mysql-log-rotate.sh
@@ -30,7 +30,8 @@
if test -x @bindir@/mysqladmin && \
@bindir@/mysqladmin ping &>/dev/null
then
- @bindir@/mysqladmin flush-logs
+ @bindir@/mysqladmin --local flush-error-log \
+ flush-engine-log flush-general-log flush-slow-log
fi
endscript
}
diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh
index 9ef9bec3e0d..f6b7a9ba8b6 100644
--- a/support-files/rpm/server-postin.sh
+++ b/support-files/rpm/server-postin.sh
@@ -45,6 +45,11 @@ if [ $1 = 1 ] ; then
# The user may already exist, make sure it has the proper group nevertheless (BUG#12823)
usermod --gid %{mysqld_group} %{mysqld_user} 2> /dev/null || true
+ # Temporary Workaround for MDEV-11386 - will be corrected in Advance Toolchain 10.0-3 and 8.0-8
+ for ldconfig in /opt/at*/sbin/ldconfig; do
+ test -x $ldconfig && $ldconfig
+ done
+
# Change permissions so that the user that will run the MySQL daemon
# owns all database files.
chown -R %{mysqld_user}:%{mysqld_group} $datadir