Commit 8986ffeb authored by serg@serg.mylan's avatar serg@serg.mylan

print xa recovery progress

add names to handlertons
trans_need_2pc() macro
parent 0c31836f
...@@ -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,
......
...@@ -325,7 +325,7 @@ static int ha_finish_errors(void) ...@@ -325,7 +325,7 @@ static int ha_finish_errors(void)
my_free((gptr) errmsgs, MYF(0)); my_free((gptr) errmsgs, MYF(0));
return 0; return 0;
} }
static inline void ha_was_inited_ok(handlerton **ht) static inline void ha_was_inited_ok(handlerton **ht)
{ {
...@@ -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,9 +874,21 @@ int ha_recover(HASH *commit_list) ...@@ -820,9 +874,21 @@ 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);
} }
...@@ -1600,7 +1668,7 @@ void handler::print_error(int error, myf errflag) ...@@ -1600,7 +1668,7 @@ void handler::print_error(int error, myf errflag)
SYNOPSIS SYNOPSIS
error error code previously returned by handler error error code previously returned by handler
buf Pointer to String where to add error message buf Pointer to String where to add error message
Returns true if this is a temporary error Returns true if this is a temporary error
*/ */
...@@ -1636,7 +1704,7 @@ uint handler::get_dup_key(int error) ...@@ -1636,7 +1704,7 @@ uint handler::get_dup_key(int error)
RETURN RETURN
0 If we successfully deleted at least one file from base_ext and 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 # Error
*/ */
......
...@@ -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