3768 Frazer Clement 2012-05-03
WL#6003 Support silent slave transaction retries
Support handler returning error resulting in silent slave
transaction retry.
This feature allows handlers to use automatic, quick transaction
retries for purposes such as conflict detection, error handling etc.
modified:
sql/log_event.cc
sql/rpl_reporting.cc
sql/rpl_reporting.h
sql/rpl_slave.cc
sql/share/errmsg-utf8.txt
3767 Alexander Barkov 2012-05-02
After-fix for WL#946
check_simple_equality() didn't work well with
temporal arguments in some cases, which made
redundant warnings get produced.
Fixing agg_arg_charsets_for_comparison() to store its
result into cmp.cmp_collation instead of a temporary
variable, so Item_bool_func2::compare_collation()
returns a correct result.
modified:
mysql-test/r/type_temporal_fractional.result
sql/item_cmpfunc.cc
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2012-05-02 12:04:42 +0000
+++ b/sql/log_event.cc 2012-05-02 23:45:28 +0000
@@ -4277,6 +4277,35 @@ int Query_log_event::do_apply_event(Rela
return do_apply_event(rli, query, q_len);
}
+/*
+ is_silent_error
+
+ Return true if the thread has an error which should be
+ handled silently
+*/
+
+static bool is_silent_error(THD* thd)
+{
+ DBUG_ENTER("is_silent_error");
+ Diagnostics_area::Sql_condition_iterator it=
+ thd->get_stmt_da()->sql_conditions();
+ const Sql_condition *err;
+ while ((err= it++))
+ {
+ DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(),
+ err->get_message_text()));
+ switch (err->get_sql_errno())
+ {
+ case ER_SLAVE_SILENT_RETRY_TRANSACTION:
+ {
+ DBUG_RETURN(true);
+ }
+ default:
+ break;
+ }
+ }
+ DBUG_RETURN(false);
+}
/**
@todo
@@ -4626,11 +4655,14 @@ Default database: '%s'. Query: '%s'",
*/
else if (thd->is_slave_error || thd->is_fatal_error)
{
- rli->report(ERROR_LEVEL, actual_error,
- "Error '%s' on query. Default database: '%s'. Query: '%s'",
- (actual_error ? thd->get_stmt_da()->message() :
- "unexpected success or fatal error"),
- print_slave_db_safe(thd->db), query_arg);
+ if (!is_silent_error(thd))
+ {
+ rli->report(ERROR_LEVEL, actual_error,
+ "Error '%s' on query. Default database: '%s'. Query: '%s'",
+ (actual_error ? thd->get_stmt_da()->message() :
+ "unexpected success or fatal error"),
+ print_slave_db_safe(thd->db), query_arg);
+ }
thd->is_slave_error= 1;
}
=== modified file 'sql/rpl_reporting.cc'
--- a/sql/rpl_reporting.cc 2011-12-09 21:08:37 +0000
+++ b/sql/rpl_reporting.cc 2012-05-02 23:45:28 +0000
@@ -38,10 +38,12 @@ Slave_reporting_capability::Slave_report
@error_arg the error code for assessment.
defaults to zero which makes the function check the top
of the reported errors stack.
+ @silent bool indicating whether the error should be silently handled.
@return 1 as the positive and 0 as the negative verdict
*/
-int Slave_reporting_capability::has_temporary_error(THD *thd, uint error_arg) const
+int Slave_reporting_capability::has_temporary_error(THD *thd,
+ uint error_arg, bool* silent) const
{
uint error;
DBUG_ENTER("has_temporary_error");
@@ -75,7 +77,6 @@ int Slave_reporting_capability::has_temp
(error == ER_LOCK_DEADLOCK || error == ER_LOCK_WAIT_TIMEOUT))
DBUG_RETURN(1);
-#ifdef HAVE_NDB_BINLOG
/*
currently temporary error set in ndbcluster
*/
@@ -90,11 +91,16 @@ int Slave_reporting_capability::has_temp
{
case ER_GET_TEMPORARY_ERRMSG:
DBUG_RETURN(1);
+ case ER_SLAVE_SILENT_RETRY_TRANSACTION:
+ {
+ if (silent != NULL)
+ *silent= true;
+ DBUG_RETURN(1);
+ }
default:
break;
}
}
-#endif
DBUG_RETURN(0);
}
#endif // EMBEDDED_LIBRARY
=== modified file 'sql/rpl_reporting.h'
--- a/sql/rpl_reporting.h 2011-09-07 10:08:09 +0000
+++ b/sql/rpl_reporting.h 2012-05-02 23:45:28 +0000
@@ -76,7 +76,7 @@ public:
/**
Check if the current error is of temporary nature or not.
*/
- int has_temporary_error(THD *thd, uint error_arg= 0) const;
+ int has_temporary_error(THD *thd, uint error_arg= 0, bool* silent= 0) const;
#endif // EMBEDDED_LIBRARY
/**
=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc 2012-04-27 18:40:38 +0000
+++ b/sql/rpl_slave.cc 2012-05-02 23:45:28 +0000
@@ -3623,8 +3623,9 @@ static int exec_relay_log_event(THD* thd
if (slave_trans_retries)
{
int UNINIT_VAR(temp_err);
+ bool silent= false;
if (exec_res && !is_mts_worker(thd) /* no reexecution in MTS mode */ &&
- (temp_err= rli->has_temporary_error(thd)) &&
+ (temp_err= rli->has_temporary_error(thd, 0, &silent)) &&
!thd->transaction.all.cannot_safely_rollback())
{
const char *errmsg;
@@ -3663,7 +3664,9 @@ static int exec_relay_log_event(THD* thd
slave_sleep(thd, min<ulong>(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
sql_slave_killed, rli);
mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS
- rli->trans_retries++;
+ if (!silent)
+ rli->trans_retries++;
+
rli->retried_trans++;
mysql_mutex_unlock(&rli->data_lock);
DBUG_PRINT("info", ("Slave retries transaction "
=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt 2012-04-21 12:11:15 +0000
+++ b/sql/share/errmsg-utf8.txt 2012-05-02 23:45:28 +0000
@@ -6755,6 +6755,9 @@ ER_MTS_RECOVERY_FAILURE
eng "Cannot recover after SLAVE errored out in parallel execution mode. Additional error messages can be found in the MySQL error log."
ER_MTS_RESET_WORKERS
eng "Cannot clean up worker info tables. Additional error messages can be found in the MySQL error log."
+
+ER_SLAVE_SILENT_RETRY_TRANSACTION
+ eng "Slave must silently retry current transaction"
#
# End of 5.6 error messages.
#
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (frazer.clement:3767 to 3768) WL#6003 | Frazer Clement | 3 May |