summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/ha_ndbcluster.cc63
-rw-r--r--sql/ha_ndbcluster.h2
-rw-r--r--sql/ha_ndbcluster_binlog.cc51
3 files changed, 94 insertions, 22 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 29063a7212f..fe0c7118056 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -121,14 +121,14 @@ static uint ndbcluster_alter_table_flags(uint flags)
#define ERR_RETURN(err) \
{ \
const NdbError& tmp= err; \
- ERR_PRINT(tmp); \
+ set_ndb_err(current_thd, tmp); \
DBUG_RETURN(ndb_to_mysql_error(&tmp)); \
}
#define ERR_BREAK(err, code) \
{ \
const NdbError& tmp= err; \
- ERR_PRINT(tmp); \
+ set_ndb_err(current_thd, tmp); \
code= ndb_to_mysql_error(&tmp); \
break; \
}
@@ -516,13 +516,51 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
DBUG_VOID_RETURN;
}
+/*
+ Sets the latest ndb error code on the thd_ndb object such that it
+ can be retrieved later to know which ndb error caused the handler
+ error.
+*/
+static void set_ndb_err(THD *thd, const NdbError &err)
+{
+ DBUG_ENTER("set_ndb_err");
+ ERR_PRINT(err);
+
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
+ if (thd_ndb == NULL)
+ DBUG_VOID_RETURN;
+#ifdef NOT_YET
+ /*
+ Check if error code is overwritten, in this case the original
+ failure cause will be lost. E.g. if 4350 error is given. So
+ push a warning so that it can be detected which is the root
+ error cause.
+ */
+ if (thd_ndb->m_query_id == thd->query_id &&
+ thd_ndb->m_error_code != 0 &&
+ thd_ndb->m_error_code != err.code)
+ {
+ char buf[FN_REFLEN];
+ ndb_error_string(thd_ndb->m_error_code, buf, sizeof(buf));
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
+ thd_ndb->m_error_code, buf, "NDB");
+ }
+#endif
+ thd_ndb->m_query_id= thd->query_id;
+ thd_ndb->m_error_code= err.code;
+ DBUG_VOID_RETURN;
+}
+
int ha_ndbcluster::ndb_err(NdbTransaction *trans)
{
+ THD *thd= current_thd;
int res;
NdbError err= trans->getNdbError();
DBUG_ENTER("ndb_err");
- ERR_PRINT(err);
+ set_ndb_err(thd, err);
+
switch (err.classification) {
case NdbError::SchemaError:
{
@@ -533,7 +571,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
bzero((char*) &table_list,sizeof(table_list));
table_list.db= m_dbname;
table_list.alias= table_list.table_name= m_tabname;
- close_cached_tables(current_thd, 0, &table_list);
+ close_cached_tables(thd, 0, &table_list);
break;
}
default:
@@ -4576,7 +4614,7 @@ static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
{
const NdbError err= trans->getNdbError();
const NdbOperation *error_op= trans->getNdbErrorOperation();
- ERR_PRINT(err);
+ set_ndb_err(thd, err);
res= ndb_to_mysql_error(&err);
if (res != -1)
ndbcluster_print_error(res, error_op);
@@ -4627,7 +4665,7 @@ static int ndbcluster_rollback(handlerton *hton, THD *thd, bool all)
{
const NdbError err= trans->getNdbError();
const NdbOperation *error_op= trans->getNdbErrorOperation();
- ERR_PRINT(err);
+ set_ndb_err(thd, err);
res= ndb_to_mysql_error(&err);
if (res != -1)
ndbcluster_print_error(res, error_op);
@@ -5212,7 +5250,7 @@ int ha_ndbcluster::create(const char *name,
if (dict->createTable(tab) != 0)
{
const NdbError err= dict->getNdbError();
- ERR_PRINT(err);
+ set_ndb_err(thd, err);
my_errno= ndb_to_mysql_error(&err);
DBUG_RETURN(my_errno);
}
@@ -5226,7 +5264,7 @@ int ha_ndbcluster::create(const char *name,
{
/* purecov: begin deadcode */
const NdbError err= dict->getNdbError();
- ERR_PRINT(err);
+ set_ndb_err(thd, err);
my_errno= ndb_to_mysql_error(&err);
DBUG_RETURN(my_errno);
/* purecov: end */
@@ -5398,6 +5436,7 @@ int ha_ndbcluster::create_handler_files(const char *file,
new_tab.setFrm(pack_data, pack_length);
if (dict->alterTableGlobal(*tab, new_tab))
{
+ set_ndb_err(current_thd, dict->getNdbError());
error= ndb_to_mysql_error(&dict->getNdbError());
}
my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
@@ -5873,6 +5912,7 @@ retry_temporary_error1:
default:
break;
}
+ set_ndb_err(thd, dict->getNdbError());
res= ndb_to_mysql_error(&dict->getNdbError());
DBUG_PRINT("info", ("error(1) %u", res));
}
@@ -5912,6 +5952,7 @@ retry_temporary_error1:
}
}
}
+ set_ndb_err(thd, dict->getNdbError());
res= ndb_to_mysql_error(&dict->getNdbError());
DBUG_PRINT("info", ("error(2) %u", res));
break;
@@ -6271,6 +6312,7 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked)
Ndb *ndb= get_ndb();
if (ndb->setDatabaseName(m_dbname))
{
+ set_ndb_err(current_thd, ndb->getNdbError());
res= ndb_to_mysql_error(&ndb->getNdbError());
break;
}
@@ -6631,7 +6673,7 @@ int ndbcluster_drop_database_impl(const char *path)
const NdbError err= dict->getNdbError();
if (err.code != 709 && err.code != 723)
{
- ERR_PRINT(err);
+ set_ndb_err(thd, err);
ret= ndb_to_mysql_error(&err);
}
}
@@ -8352,6 +8394,7 @@ retry:
my_sleep(retry_sleep);
continue;
}
+ set_ndb_err(current_thd, error);
break;
} while(1);
DBUG_PRINT("exit", ("failed, reterr: %u, NdbError %u(%s)", reterr,
@@ -9992,7 +10035,7 @@ int ndbcluster_alter_tablespace(handlerton *hton,
ndberror:
err= dict->getNdbError();
ndberror2:
- ERR_PRINT(err);
+ set_ndb_err(thd, err);
ndb_to_mysql_error(&err);
my_error(error, MYF(0), errmsg);
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index a84ec66f399..5c6646f68af 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -207,6 +207,8 @@ class Thd_ndb
NdbTransaction *stmt;
bool m_error;
bool m_slow_path;
+ int m_error_code;
+ uint32 m_query_id; /* query id whn m_error_code was set */
uint32 options;
uint32 trans_options;
List<NDB_SHARE> changed_tables;
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 391051d8775..3e0e698b2f3 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -81,6 +81,20 @@ static Ndb *injector_ndb= 0;
static Ndb *schema_ndb= 0;
static int ndbcluster_binlog_inited= 0;
+/*
+ Flag "ndbcluster_binlog_terminating" set when shutting down mysqld.
+ Server main loop should call handlerton function:
+
+ ndbcluster_hton->binlog_func ==
+ ndbcluster_binlog_func(...,BFN_BINLOG_END,...) ==
+ ndbcluster_binlog_end
+
+ at shutdown, which sets the flag. And then server needs to wait for it
+ to complete. Otherwise binlog will not be complete.
+
+ ndbcluster_hton->panic == ndbcluster_end() will not return until
+ ndb binlog is completed
+*/
static int ndbcluster_binlog_terminating= 0;
/*
@@ -222,7 +236,7 @@ static void dbug_print_table(const char *info, TABLE *table)
- creating the ndb_apply_status table
*/
static void run_query(THD *thd, char *buf, char *end,
- my_bool print_error, my_bool disable_binlog)
+ const int *no_print_error, my_bool disable_binlog)
{
ulong save_query_length= thd->query_length;
char *save_query= thd->query;
@@ -242,11 +256,18 @@ static void run_query(THD *thd, char *buf, char *end,
DBUG_PRINT("query", ("%s", thd->query));
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
- if (print_error && thd->query_error)
+ if (no_print_error && thd->query_error)
{
- sql_print_error("NDB: %s: error %s %d %d %d",
- buf, thd->net.last_error, thd->net.last_errno,
- thd->net.report_error, thd->query_error);
+ int i;
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
+ for (i= 0; no_print_error[i]; i++)
+ if (thd_ndb->m_error == no_print_error[i])
+ break;
+ if (!no_print_error[i])
+ sql_print_error("NDB: %s: error %s %d(ndb: %d) %d %d",
+ buf, thd->net.last_error, thd->net.last_errno,
+ thd_ndb->m_error,
+ thd->net.report_error, thd->query_error);
}
thd->options= save_thd_options;
@@ -488,7 +509,7 @@ static int ndbcluster_reset_logs(THD *thd)
char buf[1024];
char *end= strmov(buf, "DELETE FROM " NDB_REP_DB "." NDB_REP_TABLE);
- run_query(thd, buf, end, FALSE, TRUE);
+ run_query(thd, buf, end, NULL, TRUE);
DBUG_RETURN(0);
}
@@ -513,7 +534,7 @@ ndbcluster_binlog_index_purge_file(THD *thd, const char *file)
NDB_REP_DB "." NDB_REP_TABLE
" WHERE File='"), file), "'");
- run_query(thd, buf, end, FALSE, TRUE);
+ run_query(thd, buf, end, NULL, TRUE);
DBUG_RETURN(0);
}
@@ -630,7 +651,7 @@ static void ndbcluster_reset_slave(THD *thd)
DBUG_ENTER("ndbcluster_reset_slave");
char buf[1024];
char *end= strmov(buf, "DELETE FROM " NDB_REP_DB "." NDB_APPLY_TABLE);
- run_query(thd, buf, end, FALSE, TRUE);
+ run_query(thd, buf, end, NULL, TRUE);
DBUG_VOID_RETURN;
}
@@ -755,7 +776,8 @@ static int ndbcluster_create_ndb_apply_status_table(THD *thd)
" end_pos BIGINT UNSIGNED NOT NULL, "
" PRIMARY KEY USING HASH (server_id) ) ENGINE=NDB");
- run_query(thd, buf, end, TRUE, TRUE);
+ const int no_print_error[2]= {701, 0}; // do not print error 701
+ run_query(thd, buf, end, no_print_error, TRUE);
DBUG_RETURN(0);
}
@@ -811,7 +833,8 @@ static int ndbcluster_create_schema_table(THD *thd)
" type INT UNSIGNED NOT NULL,"
" PRIMARY KEY USING HASH (db,name) ) ENGINE=NDB");
- run_query(thd, buf, end, TRUE, TRUE);
+ const int no_print_error[2]= {701, 0}; // do not print error 701
+ run_query(thd, buf, end, no_print_error, TRUE);
DBUG_RETURN(0);
}
@@ -1919,9 +1942,10 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
/* Drop the database locally if it only contains ndb tables */
if (! ndbcluster_check_if_local_tables_in_db(thd, schema->db))
{
+ const int no_print_error[1]= {0};
run_query(thd, schema->query,
schema->query + schema->query_length,
- TRUE, /* print error */
+ no_print_error, /* print error */
TRUE); /* don't binlog the query */
/* binlog dropping database after any table operations */
post_epoch_log_list->push_back(schema, mem_root);
@@ -1941,12 +1965,15 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb,
case SOT_CREATE_DB:
/* fall through */
case SOT_ALTER_DB:
+ {
+ const int no_print_error[1]= {0};
run_query(thd, schema->query,
schema->query + schema->query_length,
- TRUE, /* print error */
+ no_print_error, /* print error */
TRUE); /* don't binlog the query */
log_query= 1;
break;
+ }
case SOT_TABLESPACE:
case SOT_LOGFILE_GROUP:
log_query= 1;