From 8986ffebde7495d97bf2476521cf1338b6b1670d Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Sun, 13 Mar 2005 21:58:09 +0100 Subject: [PATCH] print xa recovery progress add names to handlertons trans_need_2pc() macro --- sql/examples/ha_archive.cc | 1 + sql/ha_berkeley.cc | 1 + sql/ha_innodb.cc | 2 + sql/ha_ndbcluster.cc | 1 + sql/handler.cc | 78 +++++++++++++++++++++++++++++++++++--- sql/handler.h | 16 +++++++- sql/log.cc | 1 + 7 files changed, 94 insertions(+), 6 deletions(-) diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc index ad17bd91d69..a88bfc0391b 100644 --- a/sql/examples/ha_archive.cc +++ b/sql/examples/ha_archive.cc @@ -137,6 +137,7 @@ static HASH archive_open_tables; /* dummy handlerton - only to have something to return from archive_db_init */ static handlerton archive_hton = { + "archive", 0, /* slot */ 0, /* savepoint size. */ 0, /* close_connection */ diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index f8e14844875..b91a0624335 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -107,6 +107,7 @@ static int berkeley_commit(THD *thd, bool all); static int berkeley_rollback(THD *thd, bool all); static handlerton berkeley_hton = { + "BerkeleyDB", 0, /* slot */ 0, /* savepoint size */ berkeley_close_connection, diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4dee14c27b4..a1ae5b7d8fb 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -21,6 +21,7 @@ have disables the InnoDB inlining in this file. */ /* TODO list for the InnoDB handler in 5.0: - Remove the flag trx->active_trans and look at the InnoDB trx struct state field + - fix savepoint functions to use savepoint storage area - Find out what kind of problems the OS X case-insensitivity causes to table and database names; should we 'normalize' the names like we do in Windows? @@ -157,6 +158,7 @@ static int innobase_savepoint(THD* thd, void *savepoint); static int innobase_release_savepoint(THD* thd, void *savepoint); static handlerton innobase_hton = { + "InnoDB", 0, /* slot */ sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */ innobase_close_connection, diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 2adfeb7f539..ab7592097e5 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -50,6 +50,7 @@ static int ndbcluster_commit(THD *thd, bool all); static int ndbcluster_rollback(THD *thd, bool all); static handlerton ndbcluster_hton = { + "ndbcluster", 0, /* slot */ 0, /* savepoint size */ ndbcluster_close_connection, diff --git a/sql/handler.cc b/sql/handler.cc index e185ae0f0a0..f33f987ef77 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -325,7 +325,7 @@ static int ha_finish_errors(void) my_free((gptr) errmsgs, MYF(0)); return 0; } - + static inline void ha_was_inited_ok(handlerton **ht) { @@ -485,6 +485,16 @@ void ha_close_connection(THD* thd) /* ======================================================================== ======================= TRANSACTIONS ===================================*/ +/* + Register a storage engine for a transaction + + DESCRIPTION + Every storage engine MUST call this function when it starts + a transaction or a statement (that is it must be called both for the + "beginning of transaction" and "beginning of statement"). + Only storage engines registered for the transaction/statement + will know when to commit/rollback it. +*/ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg) { THD_TRANS *trans; @@ -742,6 +752,45 @@ int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit) return res; } +#ifndef DBUG_OFF +/* this does not need to be multi-byte safe or anything */ +static char* xid_to_str(char *buf, XID *xid) +{ + int i; + char *s=buf; + *s++='\''; + for (i=0; i < xid->gtrid_length+xid->bqual_length; i++) + { + uchar c=(uchar)xid->data[i]; + if (i == xid->gtrid_length) + { + *s++='\''; + if (xid->bqual_length) + { + *s++='.'; + *s++='\''; + } + } + if (c < 32 || c > 126) + { + *s++='\\'; + *s++='x'; + *s++=_dig_vec_lower[c >> 4]; + *s++=_dig_vec_lower[c & 15]; + } + else + { + if (c == '\'' || c == '\\') + *s++='\\'; + *s++=c; + } + } + *s++='\''; + *s=0; + return buf; +} +#endif + /* recover() step of xa @@ -772,11 +821,14 @@ int ha_recover(HASH *commit_list) /* commit_list and tc_heuristic_recover cannot be set both */ DBUG_ASSERT(commit_list==0 || tc_heuristic_recover==0); /* if either is set, total_ha_2pc must be set too */ - DBUG_ASSERT((commit_list==0 && tc_heuristic_recover==0) || total_ha_2pc>0); + DBUG_ASSERT(dry_run || total_ha_2pc>opt_bin_log); - if (total_ha_2pc == 0) + if (total_ha_2pc <= opt_bin_log) DBUG_RETURN(0); + if (commit_list) + sql_print_information("Starting crash recovery..."); + #ifndef WILL_BE_DELETED_LATER /* for now, only InnoDB supports 2pc. It means we can always safely @@ -803,6 +855,8 @@ int ha_recover(HASH *commit_list) continue; while ((got=(*(*ht)->recover)(list, len)) > 0 ) { + sql_print_information("Found %d prepared transaction(s) in %s", + got, (*ht)->name); for (int i=0; i < got; i ++) { my_xid x=list[i].get_my_xid(); @@ -820,9 +874,21 @@ int ha_recover(HASH *commit_list) if (commit_list ? hash_search(commit_list, (byte *)&x, sizeof(x)) != 0 : tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT) + { +#ifndef DBUG_OFF + char buf[XIDDATASIZE*4+6]; // see xid_to_str + sql_print_information("commit xid %s", xid_to_str(buf, list+i)); +#endif (*(*ht)->commit_by_xid)(list+i); + } else + { +#ifndef DBUG_OFF + char buf[XIDDATASIZE*4+6]; // see xid_to_str + sql_print_information("rollback xid %s", xid_to_str(buf, list+i)); +#endif (*(*ht)->rollback_by_xid)(list+i); + } } if (got < len) break; @@ -842,6 +908,8 @@ int ha_recover(HASH *commit_list) found_my_xids, opt_tc_log_file); DBUG_RETURN(1); } + if (commit_list) + sql_print_information("Crash recovery finished."); DBUG_RETURN(0); } @@ -1600,7 +1668,7 @@ void handler::print_error(int error, myf errflag) SYNOPSIS error error code previously returned by handler buf Pointer to String where to add error message - + Returns true if this is a temporary error */ @@ -1636,7 +1704,7 @@ uint handler::get_dup_key(int error) RETURN 0 If we successfully deleted at least one file from base_ext and - didn't get any other errors than ENOENT + didn't get any other errors than ENOENT # Error */ diff --git a/sql/handler.h b/sql/handler.h index d4e24bbb411..c8e1d75f2f7 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -272,6 +272,10 @@ typedef struct xid_t XID; */ typedef struct { + /* + storage engine name as it should be printed to a user + */ + const char *name; /* each storage engine has it's own memory area (actually a pointer) in the thd, for storing per-connection information. @@ -832,10 +836,20 @@ int ha_recover(HASH *commit_list); int ha_commit_trans(THD *thd, bool all); int ha_autocommit_or_rollback(THD *thd, int error); int ha_enable_transaction(THD *thd, bool on); -void trans_register_ha(THD *thd, bool all, handlerton *ht); /* savepoints */ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv); int ha_savepoint(THD *thd, SAVEPOINT *sv); int ha_release_savepoint(THD *thd, SAVEPOINT *sv); +/* these are called by storage engines */ +void trans_register_ha(THD *thd, bool all, handlerton *ht); + +/* + Storage engine has to assume the transaction will end up with 2pc if + - there is more than one 2pc-capable storage engine available + - in the current transaction 2pc was not disabled yet +*/ +#define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \ + !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc)) + diff --git a/sql/log.cc b/sql/log.cc index 9bd1865fc4f..7d6496626d5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -46,6 +46,7 @@ static int binlog_rollback(THD *thd, bool all); static int binlog_prepare(THD *thd, bool all); static handlerton binlog_hton = { + "binlog", 0, sizeof(my_off_t), /* savepoint size = binlog offset */ binlog_close_connection,