summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jplindst@mariadb.org>2013-12-04 13:46:28 +0200
committerJan Lindström <jplindst@mariadb.org>2013-12-04 13:46:28 +0200
commited26f7012640f4e1f65776f7bbc57fba5e87b0a5 (patch)
tree3cb3d4f9b445752ada8a608ec09ae664a735c0c4
parenteea69c57b2479192a6e5cb59e7631029edb3b35a (diff)
downloadmariadb-git-ed26f7012640f4e1f65776f7bbc57fba5e87b0a5.tar.gz
MDEV-443: Galera: Server crashes on flushing tables for SST if started with character_set_server utf16 or utf32 or ucs2, and with wsrep_sst_method=rsync
Analysis: In SST Galera directly calls parser using current client character set. Similarly in BF Galera uses client character set to apply. However, there are character sets that are not currently supported by the parser. Fix: If currenct client character set is one of those that is not supported by the parser, temporally set character set to latin1 before we enter parser and restore it after we have parsed.
-rw-r--r--sql/sql_parse.cc23
-rw-r--r--sql/wsrep_sst.cc33
2 files changed, 55 insertions, 1 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7933d95de68..21eb62149ca 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -892,8 +892,17 @@ bool do_command(THD *thd)
if (WSREP(thd)) {
while (thd->wsrep_conflict_state== RETRY_AUTOCOMMIT)
{
- return_value= dispatch_command(command, thd, thd->wsrep_retry_query,
+ CHARSET_INFO *current_charset = thd->variables.character_set_client;
+ if (!is_supported_parser_charset(current_charset))
+ {
+ /* Do not use non-supported parser character sets */
+ WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
+ thd->variables.character_set_client = &my_charset_latin1;
+ WSREP_WARN("For retry temporally setting character set to : %s", my_charset_latin1.csname);
+ }
+ return_value= dispatch_command(command, thd, thd->wsrep_retry_query,
thd->wsrep_retry_query_len);
+ thd->variables.character_set_client = current_charset;
}
}
if (thd->wsrep_retry_query && thd->wsrep_conflict_state != REPLAYING)
@@ -8119,6 +8128,7 @@ static enum wsrep_status wsrep_apply_sql(
{
int error;
enum wsrep_status ret_code= WSREP_OK;
+ CHARSET_INFO *current_charset = thd->variables.character_set_client;
DBUG_ENTER("wsrep_bf_execute_cb");
thd->wsrep_exec_mode= REPL_RECV;
@@ -8137,11 +8147,22 @@ static enum wsrep_status wsrep_apply_sql(
thd->wsrep_conflict_state= NO_CONFLICT;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
+ if (!is_supported_parser_charset(current_charset))
+ {
+ /* Do not use non-supported parser character sets */
+ WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
+ thd->variables.character_set_client = &my_charset_latin1;
+ WSREP_WARN("For BF SQL apply temporally setting character set to : %s",
+ my_charset_latin1.csname);
+ }
+
if ((error= dispatch_command(COM_QUERY, thd, (char*)sql, sql_len))) {
WSREP_WARN("BF SQL apply failed: %d, %lld",
thd->wsrep_conflict_state, (long long)thd->wsrep_trx_seqno);
+ thd->variables.character_set_client = current_charset;
DBUG_RETURN(WSREP_FATAL);
}
+ thd->variables.character_set_client = current_charset;
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if (thd->wsrep_conflict_state!= NO_CONFLICT &&
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 204a937ea8f..7afdb4909e4 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -14,6 +14,9 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <mysqld.h>
+#include <m_ctype.h>
+#include <my_sys.h>
+#include <strfunc.h>
#include <sql_class.h>
#include <set_var.h>
#include <sql_acl.h>
@@ -742,6 +745,19 @@ static int sst_flush_tables(THD* thd)
int err;
int not_used;
+ CHARSET_INFO *current_charset;
+
+ current_charset = thd->variables.character_set_client;
+
+ if (!is_supported_parser_charset(current_charset))
+ {
+ /* Do not use non-supported parser character sets */
+ WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
+ thd->variables.character_set_client = &my_charset_latin1;
+ WSREP_WARN("For SST temporally setting character set to : %s",
+ my_charset_latin1.csname);
+ }
+
if (run_sql_command(thd, "FLUSH TABLES WITH READ LOCK"))
{
WSREP_ERROR("Failed to flush and lock tables");
@@ -754,6 +770,9 @@ static int sst_flush_tables(THD* thd)
(TABLE_LIST*) 0, &not_used);
}
+ thd->variables.character_set_client = current_charset;
+
+
if (err)
{
WSREP_ERROR("Failed to flush tables: %d (%s)", err, strerror(err));
@@ -796,6 +815,19 @@ static void sst_disallow_writes (THD* thd, bool yes)
{
char query_str[64] = { 0, };
ssize_t const query_max = sizeof(query_str) - 1;
+ CHARSET_INFO *current_charset;
+
+ current_charset = thd->variables.character_set_client;
+
+ if (!is_supported_parser_charset(current_charset))
+ {
+ /* Do not use non-supported parser character sets */
+ WSREP_WARN("Current client character set is non-supported parser character set: %s", current_charset->csname);
+ thd->variables.character_set_client = &my_charset_latin1;
+ WSREP_WARN("For SST temporally setting character set to : %s",
+ my_charset_latin1.csname);
+ }
+
snprintf (query_str, query_max, "SET GLOBAL innodb_disallow_writes=%d",
yes ? 1 : 0);
@@ -803,6 +835,7 @@ static void sst_disallow_writes (THD* thd, bool yes)
{
WSREP_ERROR("Failed to disallow InnoDB writes");
}
+ thd->variables.character_set_client = current_charset;
}
static void* sst_donor_thread (void* a)