1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

if no xa recovery (or after it):

warning on startup if prepared foreign xids
  error on startup if prepared our xids
  temporarily: always rollback prepared our xids instead of an error


sql/mysql_priv.h:
  opt_tc_log_file made extern
sql/mysqld.cc:
  opt_tc_log_file made extern
  always call ha_recover() even if no previous crash was detected
This commit is contained in:
unknown
2005-03-12 20:09:54 +01:00
parent f609d604d2
commit 6b98e786e6
3 changed files with 67 additions and 8 deletions

View File

@ -744,16 +744,48 @@ int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit)
/*
recover() step of xa
NOTE
there are three modes of operation:
- automatic recover after a crash
in this case commit_list != 0, tc_heuristic_recover==0
all xids from commit_list are committed, others are rolled back
- manual (heuristic) recover
in this case commit_list==0, tc_heuristic_recover != 0
DBA has explicitly specified that all prepared transactions should
be committed (or rolled back).
- no recovery (MySQL did not detect a crash)
in this case commit_list==0, tc_heuristic_recover == 0
there should be no prepared transactions in this case.
*/
int ha_recover(HASH *commit_list)
{
int len, got;
int len, got, found_foreign_xids=0, found_my_xids=0;
handlerton **ht= handlertons, **end_ht=ht+total_ha;
XID *list=0;
bool dry_run=(commit_list==0 && tc_heuristic_recover==0);
DBUG_ENTER("ha_recover");
DBUG_ASSERT(total_ha_2pc);
DBUG_ASSERT(commit_list || tc_heuristic_recover);
/* 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);
if (total_ha_2pc == 0)
DBUG_RETURN(0);
#ifndef WILL_BE_DELETED_LATER
/*
for now, only InnoDB supports 2pc. It means we can always safely
rollback all pending transactions, without risking inconsistent data
*/
DBUG_ASSERT(total_ha_2pc == opt_bin_log+1); // only InnoDB and binlog
tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
dry_run=FALSE;
#endif
for (len= MAX_XID_LIST_SIZE ; list==0 && len > MIN_XID_LIST_SIZE; len/=2)
{
@ -761,7 +793,7 @@ int ha_recover(HASH *commit_list)
}
if (!list)
{
my_error(ER_OUTOFMEMORY, MYF(0), len);
sql_print_error(ER(ER_OUTOFMEMORY), len*sizeof(XID));
DBUG_RETURN(1);
}
@ -775,7 +807,16 @@ int ha_recover(HASH *commit_list)
{
my_xid x=list[i].get_my_xid();
if (!x) // not "mine" - that is generated by external TM
{
found_foreign_xids++;
continue;
}
if (dry_run)
{
found_my_xids++;
continue;
}
// recovery mode
if (commit_list ?
hash_search(commit_list, (byte *)&x, sizeof(x)) != 0 :
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
@ -788,6 +829,19 @@ int ha_recover(HASH *commit_list)
}
}
my_free((gptr)list, MYF(0));
if (found_foreign_xids)
sql_print_warning("Found %d prepared XA transactions", found_foreign_xids);
if (dry_run && found_my_xids)
{
sql_print_error("Found %d prepared transactions! It means that mysqld was "
"not shut down properly last time and critical recovery "
"information (last binlog or %s file) was manually deleted "
"after a crash. You have to start mysqld with "
"--tc-heuristic-recover switch to commit or rollback "
"pending transactions.",
found_my_xids, opt_tc_log_file);
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
@ -1385,7 +1439,7 @@ ulonglong handler::get_auto_increment()
/*
Print error that we got from handler function
NOTE:
NOTE
In case of delete table it's only safe to use the following parts of
the 'table' structure:
table->s->path