all: fix race on close of transaction log

This commit is contained in:
Thomas Schoebel-Theuer 2012-09-11 15:14:07 +02:00 committed by Thomas Schoebel-Theuer
parent 5365063c58
commit c1ba96f0a0
3 changed files with 11 additions and 8 deletions

View File

@ -2089,10 +2089,13 @@ void _exit_inputs(struct trans_logger_brick *brick, bool force)
struct trans_logger_input *input = brick->inputs[i];
struct log_status *logst = &input->logst;
if (force ||
(input->is_operating &&!input->connect)) {
(!input->connect &&
input->is_operating &&
input->is_deletable)) {
MARS_DBG("cleaning up input %d (log = %d old = %d)\n", i, brick->log_input_nr, brick->old_input_nr);
exit_logst(logst);
input->is_operating = false;
input->is_deletable = false;
if (i == brick->old_input_nr)
brick->old_input_nr = brick->log_input_nr;
}

View File

@ -182,14 +182,15 @@ struct trans_logger_input {
// parameters
loff_t log_start_pos; // where to start logging
// informational
long long last_jiffies;
char *inf_host;
int inf_sequence; // logfile sequence number
bool is_prepared;
bool is_deletable;
// readonly from outside
bool is_operating;
long long last_jiffies;
loff_t replay_min_pos; // current replay position (both in replay mode and in logging mode)
loff_t replay_max_pos; // dito, indicating the "dirty" area which could be potentially "inconsistent"
bool is_operating;
// private
struct log_status logst;

View File

@ -2117,6 +2117,7 @@ void __exit_trans_input(struct trans_logger_input *trans_input)
brick_string_free(trans_input->inf_host);
trans_input->inf_host = NULL;
trans_input->is_prepared = false;
trans_input->is_deletable = true;
}
static
@ -2165,23 +2166,21 @@ void _rotate_trans(struct mars_rotate *rot)
if (status < 0) {
MARS_ERR("disconnect failed\n");
} else {
MARS_INF("closed old transaction log (%d -> %d)\n", old_nr, log_nr);
MARS_INF("closing old transaction log (%d -> %d)\n", old_nr, log_nr);
if (likely(rot->replay_link && rot->replay_link->d_parent && rot->replay_link->d_parent->d_path)) {
(void)_update_all_links(rot->global, rot->replay_link->d_parent->d_path, trans_brick, trans_input->inf_host, trans_input->inf_sequence, false, true, false);
} else {
MARS_ERR("bad pointers\n");
}
_exit_trans_input(trans_input);
trans_brick->old_input_nr = old_nr = log_nr;
mars_remote_trigger();
}
} else {
MARS_DBG("old transaction replay not yet finished: %lld != %lld\n", trans_input->replay_min_pos, trans_input->replay_max_pos);
}
}
} else
// try to setup new log
if (log_nr == old_nr &&
log_nr == trans_brick->new_input_nr &&
if (log_nr == trans_brick->new_input_nr &&
rot->next_relevant_log &&
(next_nr = _get_free_input(trans_brick)) >= 0 &&
trans_brick->inputs[next_nr] &&