MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rpl_reporting.cc
1 /* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #include "sql_priv.h"
17 #include "rpl_reporting.h"
18 #include "log.h" // sql_print_error, sql_print_warning,
19  // sql_print_information
20 #include "rpl_slave.h"
21 
23  : m_thread_name(thread_name)
24 {
25  mysql_mutex_init(key_mutex_slave_reporting_capability_err_lock,
26  &err_lock, MY_MUTEX_INIT_FAST);
27 }
28 
29 #if !defined(EMBEDDED_LIBRARY)
30 
46  uint error_arg, bool* silent) const
47 {
48  uint error;
49  DBUG_ENTER("has_temporary_error");
50 
51  DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
52  if (thd->get_stmt_da()->is_error())
53  {
54  thd->clear_error();
55  my_error(ER_LOCK_DEADLOCK, MYF(0));
56  });
57 
58  /*
59  The state of the slave thread can't be regarded as
60  experiencing a temporary failure in cases of @c is_slave_error was set TRUE,
61  or if there is no message in THD, we can't say if it's a temporary
62  error or not. This is currently the case for Incident_log_event,
63  which sets no message.
64  */
65  if (thd->is_fatal_error || !thd->is_error())
66  DBUG_RETURN(0);
67 
68  error= (error_arg == 0)? thd->get_stmt_da()->sql_errno() : error_arg;
69 
70  /*
71  Temporary error codes:
72  currently, InnoDB deadlock detected by InnoDB or lock
73  wait timeout (innodb_lock_wait_timeout exceeded).
74  Notice, the temporary error requires slave_trans_retries != 0)
75  */
76  if (slave_trans_retries &&
77  (error == ER_LOCK_DEADLOCK || error == ER_LOCK_WAIT_TIMEOUT))
78  DBUG_RETURN(1);
79 
80  /*
81  currently temporary error set in ndbcluster
82  */
84  thd->get_stmt_da()->sql_conditions();
85  const Sql_condition *err;
86  while ((err= it++))
87  {
88  DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(),
89  err->get_message_text()));
90  switch (err->get_sql_errno())
91  {
92  case ER_GET_TEMPORARY_ERRMSG:
93  DBUG_RETURN(1);
94  case ER_SLAVE_SILENT_RETRY_TRANSACTION:
95  {
96  if (silent != NULL)
97  *silent= true;
98  DBUG_RETURN(1);
99  }
100  default:
101  break;
102  }
103  }
104  DBUG_RETURN(0);
105 }
106 #endif // EMBEDDED_LIBRARY
107 
108 
109 void
111  const char *msg, ...) const
112 {
113  va_list args;
114  va_start(args, msg);
115  do_report(level, err_code, msg, args);
116  va_end(args);
117 }
118 
119 void
120 Slave_reporting_capability::va_report(loglevel level, int err_code,
121  const char *prefix_msg,
122  const char *msg, va_list args) const
123 {
124 #if !defined(EMBEDDED_LIBRARY)
125  THD *thd= current_thd;
126  void (*report_function)(const char *, ...);
127  char buff[MAX_SLAVE_ERRMSG];
128  char *pbuff= buff;
129  char *curr_buff;
130  uint pbuffsize= sizeof(buff);
131 
132  if (thd && level == ERROR_LEVEL && has_temporary_error(thd, err_code) &&
133  !thd->transaction.all.cannot_safely_rollback())
134  level= WARNING_LEVEL;
135 
137  switch (level)
138  {
139  case ERROR_LEVEL:
140  /*
141  It's an error, it must be reported in Last_error and Last_errno in SHOW
142  SLAVE STATUS.
143  */
144  pbuff= m_last_error.message;
145  pbuffsize= sizeof(m_last_error.message);
146  m_last_error.number = err_code;
147  m_last_error.update_timestamp();
148  report_function= sql_print_error;
149  break;
150  case WARNING_LEVEL:
151  report_function= log_warnings?
152  sql_print_warning : NULL;
153  break;
154  case INFORMATION_LEVEL:
155  report_function= log_warnings?
156  sql_print_information : NULL;
157  break;
158  default:
159  DBUG_ASSERT(0); // should not come here
160  return; // don't crash production builds, just do nothing
161  }
162  curr_buff= pbuff;
163  if (prefix_msg)
164  curr_buff += sprintf(curr_buff, "%s; ", prefix_msg);
165  my_vsnprintf(curr_buff, pbuffsize, msg, args);
166 
168 
169  /* If the msg string ends with '.', do not add a ',' it would be ugly */
170  if (report_function)
171  report_function("Slave %s: %s%s Error_code: %d",
172  m_thread_name, pbuff,
173  (curr_buff[0] && *(strend(curr_buff)-1) == '.') ? "" : ",",
174  err_code);
175 #endif
176 }
177 
178 Slave_reporting_capability::~Slave_reporting_capability()
179 {
181 }