mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +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:
@@ -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
|
||||
|
@@ -1033,7 +1033,7 @@ extern Le_creator le_creator;
|
||||
extern char language[FN_REFLEN], reg_ext[FN_EXTLEN];
|
||||
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
|
||||
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
|
||||
extern char log_error_file[FN_REFLEN];
|
||||
extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
|
||||
extern double last_query_cost;
|
||||
extern double log_10[32];
|
||||
extern ulonglong log_10_int[20];
|
||||
|
@@ -366,7 +366,7 @@ char* log_error_file_ptr= log_error_file;
|
||||
char mysql_real_data_home[FN_REFLEN],
|
||||
language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
|
||||
*mysqld_user,*mysqld_chroot, *opt_init_file,
|
||||
*opt_init_connect, *opt_init_slave,
|
||||
*opt_init_connect, *opt_init_slave, *opt_tc_log_file,
|
||||
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
|
||||
|
||||
const char *opt_date_time_formats[3];
|
||||
@@ -457,7 +457,7 @@ static my_bool opt_do_pstack, opt_noacl, opt_bootstrap, opt_myisam_log;
|
||||
static int cleanup_done;
|
||||
static ulong opt_specialflag, opt_myisam_block_size;
|
||||
static char *opt_logname, *opt_update_logname, *opt_binlog_index_name;
|
||||
static char *opt_slow_logname, *opt_tc_log_file, *opt_tc_heuristic_recover;
|
||||
static char *opt_slow_logname, *opt_tc_heuristic_recover;
|
||||
static char *mysql_home_ptr, *pidfile_name_ptr;
|
||||
static char **defaults_argv;
|
||||
static char *opt_bin_logname;
|
||||
@@ -2800,6 +2800,11 @@ server.");
|
||||
unireg_abort(1);
|
||||
}
|
||||
|
||||
if (ha_recover(0))
|
||||
{
|
||||
unireg_abort(1);
|
||||
}
|
||||
|
||||
if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
|
||||
WRITE_CACHE, 0, max_binlog_size, 0))
|
||||
unireg_abort(1);
|
||||
|
Reference in New Issue
Block a user