Commit ec372b09 authored by unknown's avatar unknown

print xa recovery progress

add names to handlertons
trans_need_2pc() macro


sql/examples/ha_archive.cc:
  add names to handlertons
sql/ha_berkeley.cc:
  add names to handlertons
sql/ha_innodb.cc:
  add names to handlertons
sql/ha_ndbcluster.cc:
  add names to handlertons
sql/handler.cc:
  print xa recovery progress
sql/handler.h:
  add names to handlertons
  trans_need_2pc() macro
sql/log.cc:
  add names to handlertons
parent deabb450
...@@ -137,6 +137,7 @@ static HASH archive_open_tables; ...@@ -137,6 +137,7 @@ static HASH archive_open_tables;
/* dummy handlerton - only to have something to return from archive_db_init */ /* dummy handlerton - only to have something to return from archive_db_init */
static handlerton archive_hton = { static handlerton archive_hton = {
"archive",
0, /* slot */ 0, /* slot */
0, /* savepoint size. */ 0, /* savepoint size. */
0, /* close_connection */ 0, /* close_connection */
......
...@@ -107,6 +107,7 @@ static int berkeley_commit(THD *thd, bool all); ...@@ -107,6 +107,7 @@ static int berkeley_commit(THD *thd, bool all);
static int berkeley_rollback(THD *thd, bool all); static int berkeley_rollback(THD *thd, bool all);
static handlerton berkeley_hton = { static handlerton berkeley_hton = {
"BerkeleyDB",
0, /* slot */ 0, /* slot */
0, /* savepoint size */ 0, /* savepoint size */
berkeley_close_connection, berkeley_close_connection,
......
...@@ -21,6 +21,7 @@ have disables the InnoDB inlining in this file. */ ...@@ -21,6 +21,7 @@ have disables the InnoDB inlining in this file. */
/* TODO list for the InnoDB handler in 5.0: /* TODO list for the InnoDB handler in 5.0:
- Remove the flag trx->active_trans and look at the InnoDB - Remove the flag trx->active_trans and look at the InnoDB
trx struct state field 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 - 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 table and database names; should we 'normalize' the names like we do
in Windows? in Windows?
...@@ -157,6 +158,7 @@ static int innobase_savepoint(THD* thd, void *savepoint); ...@@ -157,6 +158,7 @@ static int innobase_savepoint(THD* thd, void *savepoint);
static int innobase_release_savepoint(THD* thd, void *savepoint); static int innobase_release_savepoint(THD* thd, void *savepoint);
static handlerton innobase_hton = { static handlerton innobase_hton = {
"InnoDB",
0, /* slot */ 0, /* slot */
sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */ sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */
innobase_close_connection, innobase_close_connection,
......
...@@ -50,6 +50,7 @@ static int ndbcluster_commit(THD *thd, bool all); ...@@ -50,6 +50,7 @@ static int ndbcluster_commit(THD *thd, bool all);
static int ndbcluster_rollback(THD *thd, bool all); static int ndbcluster_rollback(THD *thd, bool all);
static handlerton ndbcluster_hton = { static handlerton ndbcluster_hton = {
"ndbcluster",
0, /* slot */ 0, /* slot */
0, /* savepoint size */ 0, /* savepoint size */
ndbcluster_close_connection, ndbcluster_close_connection,
......
...@@ -485,6 +485,16 @@ void ha_close_connection(THD* thd) ...@@ -485,6 +485,16 @@ void ha_close_connection(THD* thd)
/* ======================================================================== /* ========================================================================
======================= TRANSACTIONS ===================================*/ ======================= 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) void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
{ {
THD_TRANS *trans; THD_TRANS *trans;
...@@ -742,6 +752,45 @@ int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit) ...@@ -742,6 +752,45 @@ int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit)
return res; 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 recover() step of xa
...@@ -772,11 +821,14 @@ int ha_recover(HASH *commit_list) ...@@ -772,11 +821,14 @@ int ha_recover(HASH *commit_list)
/* commit_list and tc_heuristic_recover cannot be set both */ /* commit_list and tc_heuristic_recover cannot be set both */
DBUG_ASSERT(commit_list==0 || tc_heuristic_recover==0); DBUG_ASSERT(commit_list==0 || tc_heuristic_recover==0);
/* if either is set, total_ha_2pc must be set too */ /* 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); DBUG_RETURN(0);
if (commit_list)
sql_print_information("Starting crash recovery...");
#ifndef WILL_BE_DELETED_LATER #ifndef WILL_BE_DELETED_LATER
/* /*
for now, only InnoDB supports 2pc. It means we can always safely for now, only InnoDB supports 2pc. It means we can always safely
...@@ -803,6 +855,8 @@ int ha_recover(HASH *commit_list) ...@@ -803,6 +855,8 @@ int ha_recover(HASH *commit_list)
continue; continue;
while ((got=(*(*ht)->recover)(list, len)) > 0 ) 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 ++) for (int i=0; i < got; i ++)
{ {
my_xid x=list[i].get_my_xid(); my_xid x=list[i].get_my_xid();
...@@ -820,10 +874,22 @@ int ha_recover(HASH *commit_list) ...@@ -820,10 +874,22 @@ int ha_recover(HASH *commit_list)
if (commit_list ? if (commit_list ?
hash_search(commit_list, (byte *)&x, sizeof(x)) != 0 : hash_search(commit_list, (byte *)&x, sizeof(x)) != 0 :
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT) 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); (*(*ht)->commit_by_xid)(list+i);
}
else 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); (*(*ht)->rollback_by_xid)(list+i);
} }
}
if (got < len) if (got < len)
break; break;
} }
...@@ -842,6 +908,8 @@ int ha_recover(HASH *commit_list) ...@@ -842,6 +908,8 @@ int ha_recover(HASH *commit_list)
found_my_xids, opt_tc_log_file); found_my_xids, opt_tc_log_file);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (commit_list)
sql_print_information("Crash recovery finished.");
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -272,6 +272,10 @@ typedef struct xid_t XID; ...@@ -272,6 +272,10 @@ typedef struct xid_t XID;
*/ */
typedef struct 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) each storage engine has it's own memory area (actually a pointer)
in the thd, for storing per-connection information. in the thd, for storing per-connection information.
...@@ -832,10 +836,20 @@ int ha_recover(HASH *commit_list); ...@@ -832,10 +836,20 @@ int ha_recover(HASH *commit_list);
int ha_commit_trans(THD *thd, bool all); int ha_commit_trans(THD *thd, bool all);
int ha_autocommit_or_rollback(THD *thd, int error); int ha_autocommit_or_rollback(THD *thd, int error);
int ha_enable_transaction(THD *thd, bool on); int ha_enable_transaction(THD *thd, bool on);
void trans_register_ha(THD *thd, bool all, handlerton *ht);
/* savepoints */ /* savepoints */
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv); int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
int ha_savepoint(THD *thd, SAVEPOINT *sv); int ha_savepoint(THD *thd, SAVEPOINT *sv);
int ha_release_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))
...@@ -46,6 +46,7 @@ static int binlog_rollback(THD *thd, bool all); ...@@ -46,6 +46,7 @@ static int binlog_rollback(THD *thd, bool all);
static int binlog_prepare(THD *thd, bool all); static int binlog_prepare(THD *thd, bool all);
static handlerton binlog_hton = { static handlerton binlog_hton = {
"binlog",
0, 0,
sizeof(my_off_t), /* savepoint size = binlog offset */ sizeof(my_off_t), /* savepoint size = binlog offset */
binlog_close_connection, binlog_close_connection,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment