Merge MWL#136 into mariadb-5.2-rpl

This commit is contained in:
unknown 2010-12-25 16:14:50 +01:00
commit 31ed214a00
9 changed files with 520 additions and 45 deletions

View file

@ -62,6 +62,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv);
static int binlog_commit(handlerton *hton, THD *thd, bool all);
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
static int binlog_start_consistent_snapshot(handlerton *hton, THD *thd);
/**
Silence all errors and warnings reported when performing a write
@ -155,9 +156,10 @@ class binlog_trx_data {
public:
binlog_trx_data()
: at_least_one_stmt_committed(0), incident(FALSE), m_pending(0),
before_stmt_pos(MY_OFF_T_UNDEF), commit_bin_log_file_pos(0), using_xa(0)
before_stmt_pos(MY_OFF_T_UNDEF), last_commit_pos_offset(0), using_xa(0)
{
trans_log.end_of_file= max_binlog_cache_size;
strcpy(last_commit_pos_file, "");
}
~binlog_trx_data()
@ -215,7 +217,8 @@ public:
incident= FALSE;
trans_log.end_of_file= max_binlog_cache_size;
using_xa= FALSE;
commit_bin_log_file_pos= 0;
strcpy(last_commit_pos_file, "");
last_commit_pos_offset= 0;
DBUG_ASSERT(empty());
}
@ -261,10 +264,14 @@ public:
*/
my_off_t before_stmt_pos;
/*
Binlog position after current commit, available to storage engines during
commit_ordered() and commit().
Binlog position for current transaction.
For START TRANSACTION WITH CONSISTENT SNAPSHOT, this is the binlog
position corresponding to the snapshot taken. During (and after) commit,
this is set to the binlog position corresponding to just after the
commit (so storage engines can store it in their transaction log).
*/
ulonglong commit_bin_log_file_pos;
char last_commit_pos_file[FN_REFLEN];
my_off_t last_commit_pos_offset;
/*
Flag set true if this transaction is committed with log_xid() as part of
@ -1414,6 +1421,7 @@ int binlog_init(void *p)
binlog_hton->commit= binlog_commit;
binlog_hton->rollback= binlog_rollback;
binlog_hton->prepare= binlog_prepare;
binlog_hton->start_consistent_snapshot= binlog_start_consistent_snapshot;
binlog_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN;
return 0;
}
@ -2797,6 +2805,11 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
if (flush_io_cache(&log_file) ||
my_sync(log_file.file, MYF(MY_WME)))
goto err;
pthread_mutex_lock(&LOCK_commit_ordered);
strmake(last_commit_pos_file, log_file_name,
sizeof(last_commit_pos_file)-1);
last_commit_pos_offset= my_b_tell(&log_file);
pthread_mutex_unlock(&LOCK_commit_ordered);
if (write_file_name_to_index_file)
{
@ -4225,6 +4238,25 @@ void THD::binlog_set_stmt_begin() {
trx_data->before_stmt_pos= pos;
}
static int
binlog_start_consistent_snapshot(handlerton *hton, THD *thd)
{
int err= 0;
binlog_trx_data *trx_data;
DBUG_ENTER("binlog_start_consistent_snapshot");
thd->binlog_setup_trx_data();
trx_data= (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
/* Server layer calls us with LOCK_commit_ordered locked, so this is safe. */
strmake(trx_data->last_commit_pos_file, mysql_bin_log.last_commit_pos_file,
sizeof(trx_data->last_commit_pos_file)-1);
trx_data->last_commit_pos_offset= mysql_bin_log.last_commit_pos_offset;
trans_register_ha(thd, TRUE, hton);
DBUG_RETURN(err);
}
/*
Write a table map to the binary log.
@ -4363,6 +4395,9 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
}
pthread_mutex_lock(&LOCK_commit_ordered);
last_commit_pos_offset= my_b_tell(&log_file);
pthread_mutex_unlock(&LOCK_commit_ordered);
pthread_mutex_unlock(&LOCK_log);
}
@ -4554,7 +4589,12 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
err_unlock:
if (file == &log_file)
{
pthread_mutex_lock(&LOCK_commit_ordered);
last_commit_pos_offset= my_b_tell(&log_file);
pthread_mutex_unlock(&LOCK_commit_ordered);
pthread_mutex_unlock(&LOCK_log);
}
err:
if (error)
@ -4860,6 +4900,9 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd)
signal_update();
rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
}
pthread_mutex_lock(&LOCK_commit_ordered);
last_commit_pos_offset= my_b_tell(&log_file);
pthread_mutex_unlock(&LOCK_commit_ordered);
pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
@ -5005,9 +5048,11 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
void
MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
{
DBUG_ENTER("MYSQL_BIN_LOG::trx_group_commit_leader");
uint xid_count= 0;
uint write_count= 0;
my_off_t commit_offset;
DBUG_ENTER("MYSQL_BIN_LOG::trx_group_commit_leader");
LINT_INIT(commit_offset);
/*
Lock the LOCK_log(), and once we get it, collect any additional writes
@ -5068,8 +5113,11 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
write_count++;
}
trx_data->commit_bin_log_file_pos=
strmake(trx_data->last_commit_pos_file, log_file_name,
sizeof(trx_data->last_commit_pos_file)-1);
commit_offset=
log_file.pos_in_file + (log_file.write_pos - log_file.write_buffer);
trx_data->last_commit_pos_offset= commit_offset;
if (trx_data->using_xa)
xid_count++;
}
@ -5111,6 +5159,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
DEBUG_SYNC(leader->thd, "commit_before_get_LOCK_commit_ordered");
pthread_mutex_lock(&LOCK_commit_ordered);
last_commit_pos_offset= commit_offset;
/*
We cannot unlock LOCK_log until we have locked LOCK_commit_ordered;
otherwise scheduling could allow the next group commit to run ahead of us,
@ -6580,10 +6629,6 @@ ulonglong mysql_bin_log_file_pos(void)
Since it stores the position inside THD, it is safe to call without any
locking.
Note that currently the binlog file name is not stored inside THD, but this
is still safe as it can only change when the log is rotated, and we never
rotate the binlog while commits are pending inside storage engines.
*/
void
mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file)
@ -6592,8 +6637,8 @@ mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file)
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
if (trx_data)
{
*out_pos= trx_data->commit_bin_log_file_pos;
*out_file= mysql_bin_log.get_log_fname();
*out_file= trx_data->last_commit_pos_file;
*out_pos= (ulonglong)(trx_data->last_commit_pos_offset);
}
else
{
@ -6606,6 +6651,8 @@ mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file)
static ulonglong binlog_status_var_num_commits;
static ulonglong binlog_status_var_num_group_commits;
static char binlog_snapshot_file[FN_REFLEN];
static ulonglong binlog_snapshot_position;
static SHOW_VAR binlog_status_vars_detail[]=
{
@ -6613,12 +6660,16 @@ static SHOW_VAR binlog_status_vars_detail[]=
(char *)&binlog_status_var_num_commits, SHOW_LONGLONG},
{"group_commits",
(char *)&binlog_status_var_num_group_commits, SHOW_LONGLONG},
{"snapshot_file",
(char *)&binlog_snapshot_file, SHOW_CHAR},
{"snapshot_position",
(char *)&binlog_snapshot_position, SHOW_LONGLONG},
{NullS, NullS, SHOW_LONG}
};
static int show_binlog_vars(THD *thd, SHOW_VAR *var, char *buff)
{
mysql_bin_log.set_status_variables();
mysql_bin_log.set_status_variables(thd);
var->type= SHOW_ARRAY;
var->value= (char *)&binlog_status_vars_detail;
return 0;
@ -6657,17 +6708,32 @@ static struct st_mysql_sys_var *binlog_sys_vars[]=
This is called only under LOCK_status, so we can fill in a static array.
*/
void
TC_LOG_BINLOG::set_status_variables()
TC_LOG_BINLOG::set_status_variables(THD *thd)
{
ulonglong num_commits, num_group_commits;
binlog_trx_data *trx_data;
if (thd)
trx_data= (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
else
trx_data= NULL;
pthread_mutex_lock(&LOCK_commit_ordered);
num_commits= this->num_commits;
num_group_commits= this->num_group_commits;
binlog_status_var_num_commits= this->num_commits;
binlog_status_var_num_group_commits= this->num_group_commits;
if (!trx_data || 0 == strcmp(trx_data->last_commit_pos_file, ""))
{
strmake(binlog_snapshot_file, last_commit_pos_file,
sizeof(binlog_snapshot_file)-1);
binlog_snapshot_position= last_commit_pos_offset;
}
pthread_mutex_unlock(&LOCK_commit_ordered);
binlog_status_var_num_commits= num_commits;
binlog_status_var_num_group_commits= num_group_commits;
if (trx_data && 0 != strcmp(trx_data->last_commit_pos_file, ""))
{
strmake(binlog_snapshot_file, trx_data->last_commit_pos_file,
sizeof(binlog_snapshot_file)-1);
binlog_snapshot_position= trx_data->last_commit_pos_offset;
}
}
struct st_mysql_storage_engine binlog_storage_engine=