diff options
author | <Li-Bing.Song@sun.com> | 2010-03-28 19:57:33 +0800 |
---|---|---|
committer | <Li-Bing.Song@sun.com> | 2010-03-28 19:57:33 +0800 |
commit | 2049d1afc05ae8164353263f6e9ae7c0cd9b961b (patch) | |
tree | 656156db7cdeef9ce027bbc4cd40c78d35b284f9 /sql | |
parent | 8d22c5f3efe4ab127cbe7bc3064b856e9f4849ff (diff) | |
download | mariadb-git-2049d1afc05ae8164353263f6e9ae7c0cd9b961b.tar.gz |
Bug #50407 mysqlbinlog --database=X produces bad output for SAVEPOINTs
When mysqlbinlog was given the --database=X flag, it always printed
'ROLLBACK TO', but the corresponding 'SAVEPOINT' statement was not
printed. The replicated filter(replicated-do/ignore-db) and binlog
filter (binlog-do/ignore-db) has the same problem. They are solved
in this patch together.
After this patch, We always check whether the query is 'SAVEPOINT'
statement or not. Because this is a literal check, 'SAVEPOINT' and
'ROLLBACK TO' statements are also binlogged in uppercase with no
any comments.
The binlog before this patch can be handled correctly except one case
that any comments are in front of the keywords. for example:
/* bla bla */ SAVEPOINT a;
/* bla bla */ ROLLBACK TO a;
Diffstat (limited to 'sql')
-rw-r--r-- | sql/log.cc | 26 | ||||
-rw-r--r-- | sql/log_event.cc | 5 | ||||
-rw-r--r-- | sql/log_event.h | 22 |
3 files changed, 40 insertions, 13 deletions
diff --git a/sql/log.cc b/sql/log.cc index 6dfb8128ce9..e7090a98fd9 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1714,11 +1714,14 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) binlog_trans_log_savepos(thd, (my_off_t*) sv); /* Write it to the binary log */ + String log_query; + if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) || + log_query.append(thd->lex->ident.str, thd->lex->ident.length)) + DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - int const error= - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query(), thd->query_length(), TRUE, FALSE, errcode); - DBUG_RETURN(error); + Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + TRUE, TRUE, errcode); + DBUG_RETURN(mysql_bin_log.write(&qinfo)); } static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) @@ -1733,11 +1736,14 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) if (unlikely(thd->transaction.all.modified_non_trans_table || (thd->options & OPTION_KEEP_LOG))) { + String log_query; + if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) || + log_query.append(thd->lex->ident.str, thd->lex->ident.length)) + DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - int error= - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query(), thd->query_length(), TRUE, FALSE, errcode); - DBUG_RETURN(error); + Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + TRUE, TRUE, errcode); + DBUG_RETURN(mysql_bin_log.write(&qinfo)); } binlog_trans_log_truncate(thd, *(my_off_t*)sv); DBUG_RETURN(0); @@ -4272,7 +4278,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) */ const char *local_db= event_info->get_db(); if ((thd && !(thd->options & OPTION_BIN_LOG)) || - (!binlog_filter->db_ok(local_db))) + (thd->lex->sql_command != SQLCOM_ROLLBACK_TO_SAVEPOINT && + thd->lex->sql_command != SQLCOM_SAVEPOINT && + !binlog_filter->db_ok(local_db))) { VOID(pthread_mutex_unlock(&LOCK_log)); DBUG_RETURN(0); diff --git a/sql/log_event.cc b/sql/log_event.cc index e560580a909..a8e227fa99b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3063,10 +3063,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, ::do_apply_event(), then the companion SET also have so we don't need to reset_one_shot_variables(). */ - if (!strncmp(query_arg, "BEGIN", q_len_arg) || - !strncmp(query_arg, "COMMIT", q_len_arg) || - !strncmp(query_arg, "ROLLBACK", q_len_arg) || - rpl_filter->db_ok(thd->db)) + if (is_trans_keyword() || rpl_filter->db_ok(thd->db)) { thd->set_time((time_t)when); thd->set_query((char*)query_arg, q_len_arg); diff --git a/sql/log_event.h b/sql/log_event.h index 30a68955fb3..9b7f000648d 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1682,6 +1682,28 @@ public: /* !!! Public in this patch to allow old usage */ const char *query_arg, uint32 q_len_arg); #endif /* HAVE_REPLICATION */ + /* + If true, the event always be applied by slave SQL thread or be printed by + mysqlbinlog + */ + bool is_trans_keyword() + { + /* + Before the patch for bug#50407, The 'SAVEPOINT and ROLLBACK TO' + queries input by user was written into log events directly. + So the keywords can be written in both upper case and lower case + together, strncasecmp is used to check both cases. they also could be + binlogged with comments in the front of these keywords. for examples: + / * bla bla * / SAVEPOINT a; + / * bla bla * / ROLLBACK TO a; + but we don't handle these cases and after the patch, both quiries are + binlogged in upper case with no comments. + */ + return !strncmp(query, "BEGIN", q_len) || + !strncmp(query, "COMMIT", q_len) || + !strncasecmp(query, "SAVEPOINT", 9) || + !strncasecmp(query, "ROLLBACK", 8); + } }; |