MWL#116: After-review fixes.
This commit is contained in:
parent
a2d921be36
commit
bc9f6021ff
@ -554,6 +554,8 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *);
|
||||
|
||||
#define my_b_tell(info) ((info)->pos_in_file + \
|
||||
(size_t) (*(info)->current_pos - (info)->request_pos))
|
||||
#define my_b_write_tell(info) ((info)->pos_in_file + \
|
||||
((info)->write_pos - (info)->write_buffer))
|
||||
|
||||
#define my_b_get_buffer_start(info) (info)->request_pos
|
||||
#define my_b_get_bytes_in_buffer(info) (char*) (info)->read_end - \
|
||||
|
32
mysql-test/r/xa_binlog.result
Normal file
32
mysql-test/r/xa_binlog.result
Normal file
@ -0,0 +1,32 @@
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
SET binlog_format= mixed;
|
||||
RESET MASTER;
|
||||
XA START 'xatest';
|
||||
INSERT INTO t1 VALUES (1);
|
||||
XA END 'xatest';
|
||||
XA PREPARE 'xatest';
|
||||
XA COMMIT 'xatest';
|
||||
XA START 'xatest';
|
||||
INSERT INTO t1 VALUES (2);
|
||||
XA END 'xatest';
|
||||
XA COMMIT 'xatest' ONE PHASE;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (3);
|
||||
COMMIT;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
SHOW BINLOG EVENTS LIMIT 1,9;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # BEGIN
|
||||
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (1)
|
||||
master-bin.000001 # Query 1 # COMMIT
|
||||
master-bin.000001 # Query 1 # BEGIN
|
||||
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (2)
|
||||
master-bin.000001 # Query 1 # COMMIT
|
||||
master-bin.000001 # Query 1 # BEGIN
|
||||
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (3)
|
||||
master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
|
||||
DROP TABLE t1;
|
@ -21,7 +21,8 @@ SELECT * FROM t1;
|
||||
# Actually the output from this currently shows a bug.
|
||||
# The injected IO error leaves partially written transactions in the binlog in
|
||||
# the form of stray "BEGIN" events.
|
||||
# These should disappear from the output if binlog error handling is improved.
|
||||
# These should disappear from the output if binlog error handling is improved
|
||||
# (see MySQL Bug#37148 and WL#1790).
|
||||
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
|
||||
--replace_column 1 BINLOG 2 POS 5 ENDPOS
|
||||
SHOW BINLOG EVENTS;
|
||||
|
@ -16,6 +16,7 @@ select * from t2;
|
||||
b
|
||||
2
|
||||
SET sql_log_bin = 0;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (3);
|
||||
INSERT INTO t2 VALUES (4);
|
||||
COMMIT;
|
||||
|
@ -20,6 +20,7 @@ select * from t2;
|
||||
|
||||
# Test 2-phase commit when we disable binlogging.
|
||||
SET sql_log_bin = 0;
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (3);
|
||||
INSERT INTO t2 VALUES (4);
|
||||
COMMIT;
|
||||
|
@ -8,6 +8,10 @@
|
||||
# Don't test this under valgrind, memory leaks will occur as we crash
|
||||
--source include/not_valgrind.inc
|
||||
|
||||
# The test case currently uses grep and tail, which may be unavailable on
|
||||
# some windows systems. But see MWL#191 for how to remove the need for grep.
|
||||
--source include/not_windows.inc
|
||||
|
||||
# XtraDB stores the binlog position corresponding to the last commit, and
|
||||
# prints it during crash recovery.
|
||||
# Test that we get the correct position when we group commit several
|
||||
|
32
mysql-test/t/xa_binlog.test
Normal file
32
mysql-test/t/xa_binlog.test
Normal file
@ -0,0 +1,32 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_log_bin.inc
|
||||
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
|
||||
# Fix binlog format (otherwise SHOW BINLOG EVENTS will fluctuate).
|
||||
SET binlog_format= mixed;
|
||||
|
||||
RESET MASTER;
|
||||
|
||||
XA START 'xatest';
|
||||
INSERT INTO t1 VALUES (1);
|
||||
XA END 'xatest';
|
||||
XA PREPARE 'xatest';
|
||||
XA COMMIT 'xatest';
|
||||
|
||||
XA START 'xatest';
|
||||
INSERT INTO t1 VALUES (2);
|
||||
XA END 'xatest';
|
||||
XA COMMIT 'xatest' ONE PHASE;
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES (3);
|
||||
COMMIT;
|
||||
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
--replace_column 2 # 5 #
|
||||
--replace_regex /xid=[0-9]+/xid=XX/
|
||||
SHOW BINLOG EVENTS LIMIT 1,9;
|
||||
|
||||
DROP TABLE t1;
|
@ -1186,17 +1186,16 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
Sic: we know that prepare() is not NULL since otherwise
|
||||
trans->no_2pc would have been set.
|
||||
*/
|
||||
if ((err= ht->prepare(ht, thd, all)))
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
err= ht->prepare(ht, thd, all);
|
||||
status_var_increment(thd->status_var.ha_prepare_count);
|
||||
if (err)
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
if (ht->prepare_ordered)
|
||||
need_prepare_ordered= TRUE;
|
||||
if (ht->commit_ordered)
|
||||
need_commit_ordered= TRUE;
|
||||
need_prepare_ordered|= (ht->prepare_ordered != NULL);
|
||||
need_commit_ordered|= (ht->commit_ordered != NULL);
|
||||
}
|
||||
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_ABORT(););
|
||||
|
||||
@ -1225,8 +1224,7 @@ int ha_commit_trans(THD *thd, bool all)
|
||||
|
||||
/* Come here if error and we need to rollback. */
|
||||
err:
|
||||
if (!error)
|
||||
error= 1;
|
||||
error= 1; /* Transaction was rolled back */
|
||||
ha_rollback_trans(thd, all);
|
||||
|
||||
end:
|
||||
@ -1877,8 +1875,11 @@ int ha_start_consistent_snapshot(THD *thd)
|
||||
bool warn= true;
|
||||
|
||||
/*
|
||||
Holding the LOCK_commit_ordered mutex ensures that for any transaction
|
||||
we either see it committed in all engines, or in none.
|
||||
Holding the LOCK_commit_ordered mutex ensures that we get the same
|
||||
snapshot for all engines (including the binary log). This allows us
|
||||
among other things to do backups with
|
||||
START TRANSACTION WITH CONSISTENT SNAPSHOT and
|
||||
have a consistent binlog position.
|
||||
*/
|
||||
pthread_mutex_lock(&LOCK_commit_ordered);
|
||||
plugin_foreach(thd, snapshot_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &warn);
|
||||
|
@ -670,7 +670,7 @@ struct handlerton
|
||||
Not that like prepare(), commit_ordered() is only called when 2-phase
|
||||
commit takes place. Ie. when no binary log and only a single engine
|
||||
participates in a transaction, one commit() is called, no
|
||||
commit_orderd(). So engines must be prepared for this.
|
||||
commit_ordered(). So engines must be prepared for this.
|
||||
|
||||
The calls to commit_ordered() in multiple parallel transactions is
|
||||
guaranteed to happen in the same order in every participating
|
||||
@ -683,7 +683,7 @@ struct handlerton
|
||||
transaction visible to other transactions, thereby making the order of
|
||||
transaction commits be defined by the order of commit_ordered() calls.
|
||||
|
||||
The intension is that commit_ordered() should do the minimal amount of
|
||||
The intention is that commit_ordered() should do the minimal amount of
|
||||
work that needs to happen in consistent commit order among handlers. To
|
||||
preserve ordering, calls need to be serialised on a global mutex, so
|
||||
doing any time-consuming or blocking operations in commit_ordered() will
|
||||
@ -727,7 +727,7 @@ struct handlerton
|
||||
order transactions will be eventually committed.
|
||||
|
||||
Like commit_ordered(), prepare_ordered() calls are serialised to maintain
|
||||
ordering, so the intension is that they should execute fast, with only
|
||||
ordering, so the intention is that they should execute fast, with only
|
||||
the minimal amount of work needed to define commit order. Handlers can
|
||||
rely on this serialisation, and do not need to do any extra locking to
|
||||
avoid two prepare_ordered() calls running in parallel.
|
||||
@ -747,8 +747,7 @@ struct handlerton
|
||||
require blocking all other commits for an indefinite time).
|
||||
|
||||
When 2-phase commit is not used (eg. only one engine (and no binlog) in
|
||||
transaction), prepare() is not called and in such cases prepare_ordered()
|
||||
also is not called.
|
||||
transaction), neither prepare() nor prepare_ordered() is called.
|
||||
*/
|
||||
void (*prepare_ordered)(handlerton *hton, THD *thd, bool all);
|
||||
int (*recover)(handlerton *hton, XID *xid_list, uint len);
|
||||
|
191
sql/log.cc
191
sql/log.cc
@ -63,6 +63,30 @@ 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 LEX_STRING const write_error_msg=
|
||||
{ C_STRING_WITH_LEN("error writing to the binary log") };
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
static ulong opt_binlog_dbug_fsync_sleep= 0;
|
||||
#endif
|
||||
|
||||
static my_bool mutexes_inited;
|
||||
pthread_mutex_t LOCK_prepare_ordered;
|
||||
pthread_mutex_t LOCK_commit_ordered;
|
||||
|
||||
static ulonglong binlog_status_var_num_commits;
|
||||
static ulonglong binlog_status_var_num_group_commits;
|
||||
|
||||
static SHOW_VAR binlog_status_vars_detail[]=
|
||||
{
|
||||
{"commits",
|
||||
(char *)&binlog_status_var_num_commits, SHOW_LONGLONG},
|
||||
{"group_commits",
|
||||
(char *)&binlog_status_var_num_group_commits, SHOW_LONGLONG},
|
||||
{NullS, NullS, SHOW_LONG}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Silence all errors and warnings reported when performing a write
|
||||
to a log table.
|
||||
@ -113,41 +137,6 @@ char *make_default_log_name(char *buff,const char* log_ext)
|
||||
MYF(MY_UNPACK_FILENAME|MY_REPLACE_EXT));
|
||||
}
|
||||
|
||||
/*
|
||||
Helper class to hold a mutex for the duration of the
|
||||
block.
|
||||
|
||||
Eliminates the need for explicit unlocking of mutexes on, e.g.,
|
||||
error returns. On passing a null pointer, the sentry will not do
|
||||
anything.
|
||||
*/
|
||||
class Mutex_sentry
|
||||
{
|
||||
public:
|
||||
Mutex_sentry(pthread_mutex_t *mutex)
|
||||
: m_mutex(mutex)
|
||||
{
|
||||
if (m_mutex)
|
||||
pthread_mutex_lock(mutex);
|
||||
}
|
||||
|
||||
~Mutex_sentry()
|
||||
{
|
||||
if (m_mutex)
|
||||
pthread_mutex_unlock(m_mutex);
|
||||
#ifndef DBUG_OFF
|
||||
m_mutex= 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_mutex_t *m_mutex;
|
||||
|
||||
// It's not allowed to copy this object in any way
|
||||
Mutex_sentry(Mutex_sentry const&);
|
||||
void operator=(Mutex_sentry const&);
|
||||
};
|
||||
|
||||
/*
|
||||
Helper class to store binary log transaction data.
|
||||
*/
|
||||
@ -155,7 +144,8 @@ 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), commit_bin_log_file_pos(0),
|
||||
using_xa(FALSE), xa_xid(0)
|
||||
{
|
||||
trans_log.end_of_file= max_binlog_cache_size;
|
||||
}
|
||||
@ -271,6 +261,7 @@ public:
|
||||
XA, false if not.
|
||||
*/
|
||||
bool using_xa;
|
||||
my_xid xa_xid;
|
||||
};
|
||||
|
||||
handlerton *binlog_hton;
|
||||
@ -1415,6 +1406,8 @@ static int binlog_close_connection(handlerton *hton, THD *thd)
|
||||
|
||||
thd The thread whose transaction should be ended
|
||||
trx_data Pointer to the transaction data to use
|
||||
all True if the entire transaction should be ended, false if
|
||||
only the statement transaction should be ended.
|
||||
end_ev The end event to use (COMMIT, ROLLBACK, or commit XID)
|
||||
|
||||
DESCRIPTION
|
||||
@ -1523,9 +1516,6 @@ binlog_truncate_trx_cache(THD *thd, binlog_trx_data *trx_data, bool all)
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
static LEX_STRING const write_error_msg=
|
||||
{ C_STRING_WITH_LEN("error writing to the binary log") };
|
||||
|
||||
static int binlog_prepare(handlerton *hton, THD *thd, bool all)
|
||||
{
|
||||
/*
|
||||
@ -3989,10 +3979,6 @@ err:
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
static ulong opt_binlog_dbug_fsync_sleep= 0;
|
||||
#endif
|
||||
|
||||
bool MYSQL_BIN_LOG::flush_and_sync()
|
||||
{
|
||||
int err=0, fd=log_file.file;
|
||||
@ -4004,9 +3990,8 @@ bool MYSQL_BIN_LOG::flush_and_sync()
|
||||
sync_binlog_counter= 0;
|
||||
err=my_sync(fd, MYF(MY_WME));
|
||||
#ifndef DBUG_OFF
|
||||
ulong usec_sleep= opt_binlog_dbug_fsync_sleep;
|
||||
if (usec_sleep > 0)
|
||||
my_sleep(usec_sleep);
|
||||
if (opt_binlog_dbug_fsync_sleep > 0)
|
||||
my_sleep(opt_binlog_dbug_fsync_sleep);
|
||||
#endif
|
||||
}
|
||||
return err;
|
||||
@ -4444,7 +4429,19 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
||||
#endif /* USING_TRANSACTIONS */
|
||||
DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
|
||||
if (file == &log_file)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
/*
|
||||
We did not want to take LOCK_log unless really necessary.
|
||||
However, now that we hold LOCK_log, we must check is_open() again, lest
|
||||
the log was closed just before.
|
||||
*/
|
||||
if (unlikely(!is_open()))
|
||||
{
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
No check for auto events flag here - this write method should
|
||||
@ -4662,6 +4659,7 @@ uint MYSQL_BIN_LOG::next_file_id()
|
||||
|
||||
int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache)
|
||||
{
|
||||
safe_mutex_assert_owner(&LOCK_log);
|
||||
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
|
||||
return ER_ERROR_ON_WRITE;
|
||||
uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
|
||||
@ -4821,11 +4819,14 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd)
|
||||
Incident_log_event ev(thd, incident, write_error_msg);
|
||||
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
error= ev.write(&log_file);
|
||||
if (!error && !(error= flush_and_sync()))
|
||||
if (likely(is_open()))
|
||||
{
|
||||
signal_update();
|
||||
rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
|
||||
error= ev.write(&log_file);
|
||||
if (!error && !(error= flush_and_sync()))
|
||||
{
|
||||
signal_update();
|
||||
rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
|
||||
@ -4869,6 +4870,9 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, binlog_trx_data *trx_data,
|
||||
entry.all= all;
|
||||
|
||||
/*
|
||||
Log "BEGIN" at the beginning of every transaction. Here, a transaction is
|
||||
either a BEGIN..COMMIT block or a single statement in autocommit mode.
|
||||
|
||||
Create the necessary events here, where we have the correct THD (and
|
||||
thread context).
|
||||
|
||||
@ -4925,7 +4929,7 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
|
||||
else
|
||||
trx_group_commit_leader(entry);
|
||||
|
||||
if (!entry->error)
|
||||
if (likely(!entry->error))
|
||||
return 0;
|
||||
|
||||
switch (entry->error)
|
||||
@ -4953,7 +4957,7 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
|
||||
we need to mark it as not needed for recovery (unlog() is not called
|
||||
for a transaction if log_xid() fails).
|
||||
*/
|
||||
if (entry->trx_data->using_xa)
|
||||
if (entry->trx_data->using_xa && entry->trx_data->xa_xid)
|
||||
mark_xid_done();
|
||||
|
||||
return 1;
|
||||
@ -5018,26 +5022,20 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
|
||||
binlog_trx_data *trx_data= current->trx_data;
|
||||
IO_CACHE *cache= &trx_data->trans_log;
|
||||
|
||||
/* Skip log_xid for transactions without xid, marked by NULL end_event. */
|
||||
if (!current->end_event)
|
||||
continue;
|
||||
|
||||
/*
|
||||
We only bother to write to the binary log if there is anything
|
||||
to write.
|
||||
*/
|
||||
if (my_b_tell(cache) > 0)
|
||||
{
|
||||
current->error= write_transaction(current);
|
||||
if (current->error)
|
||||
if ((current->error= write_transaction(current)))
|
||||
current->commit_errno= errno;
|
||||
|
||||
write_count++;
|
||||
}
|
||||
|
||||
trx_data->commit_bin_log_file_pos=
|
||||
log_file.pos_in_file + (log_file.write_pos - log_file.write_buffer);
|
||||
if (trx_data->using_xa)
|
||||
trx_data->commit_bin_log_file_pos= my_b_write_tell(&log_file);
|
||||
if (trx_data->using_xa && trx_data->xa_xid)
|
||||
xid_count++;
|
||||
}
|
||||
|
||||
@ -5095,6 +5093,8 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
|
||||
current= queue;
|
||||
while (current != NULL)
|
||||
{
|
||||
group_commit_entry *next;
|
||||
|
||||
DEBUG_SYNC(leader->thd, "commit_loop_entry_commit_ordered");
|
||||
++num_commits;
|
||||
if (current->trx_data->using_xa && !current->error)
|
||||
@ -5104,7 +5104,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
|
||||
Careful not to access current->next after waking up the other thread! As
|
||||
it may change immediately after wakeup.
|
||||
*/
|
||||
group_commit_entry *next= current->next;
|
||||
next= current->next;
|
||||
if (current != leader) // Don't wake up ourself
|
||||
current->thd->signal_wakeup_ready();
|
||||
current= next;
|
||||
@ -5120,19 +5120,7 @@ MYSQL_BIN_LOG::write_transaction(group_commit_entry *entry)
|
||||
{
|
||||
binlog_trx_data *trx_data= entry->trx_data;
|
||||
IO_CACHE *cache= &trx_data->trans_log;
|
||||
/*
|
||||
Log "BEGIN" at the beginning of every transaction. Here, a transaction is
|
||||
either a BEGIN..COMMIT block or a single statement in autocommit mode. The
|
||||
event was constructed in write_transaction_to_binlog(), in the thread
|
||||
running the transaction.
|
||||
|
||||
Now this Query_log_event has artificial log_pos 0. It must be
|
||||
adjusted to reflect the real position in the log. Not doing it
|
||||
would confuse the slave: it would prevent this one from
|
||||
knowing where he is in the master's binlog, which would result
|
||||
in wrong positions being shown to the user, MASTER_POS_WAIT
|
||||
undue waiting etc.
|
||||
*/
|
||||
if (entry->begin_event->write(&log_file))
|
||||
return ER_ERROR_ON_WRITE;
|
||||
|
||||
@ -5579,10 +5567,6 @@ void sql_print_information(const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
static my_bool mutexes_inited;
|
||||
pthread_mutex_t LOCK_prepare_ordered;
|
||||
pthread_mutex_t LOCK_commit_ordered;
|
||||
|
||||
void
|
||||
TC_init()
|
||||
{
|
||||
@ -5593,6 +5577,7 @@ TC_init()
|
||||
mutexes_inited= TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TC_destroy()
|
||||
{
|
||||
@ -5604,39 +5589,42 @@ TC_destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TC_LOG::run_prepare_ordered(THD *thd, bool all)
|
||||
{
|
||||
Ha_trx_info *ha_info=
|
||||
all ? thd->transaction.all.ha_list : thd->transaction.stmt.ha_list;
|
||||
|
||||
safe_mutex_assert_owner(&LOCK_prepare_ordered);
|
||||
for (; ha_info; ha_info= ha_info->next())
|
||||
{
|
||||
handlerton *ht= ha_info->ht();
|
||||
if (!ht->prepare_ordered)
|
||||
continue;
|
||||
safe_mutex_assert_owner(&LOCK_prepare_ordered);
|
||||
ht->prepare_ordered(ht, thd, all);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TC_LOG::run_commit_ordered(THD *thd, bool all)
|
||||
{
|
||||
Ha_trx_info *ha_info=
|
||||
all ? thd->transaction.all.ha_list : thd->transaction.stmt.ha_list;
|
||||
|
||||
safe_mutex_assert_owner(&LOCK_commit_ordered);
|
||||
for (; ha_info; ha_info= ha_info->next())
|
||||
{
|
||||
handlerton *ht= ha_info->ht();
|
||||
if (!ht->commit_ordered)
|
||||
continue;
|
||||
safe_mutex_assert_owner(&LOCK_commit_ordered);
|
||||
ht->commit_ordered(ht, thd, all);
|
||||
DEBUG_SYNC(thd, "commit_after_run_commit_ordered");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int TC_LOG_MMAP::log_and_order(THD *thd, my_xid xid, bool all,
|
||||
bool need_prepare_ordered,
|
||||
bool need_commit_ordered)
|
||||
@ -5666,10 +5654,9 @@ int TC_LOG_MMAP::log_and_order(THD *thd, my_xid xid, bool all,
|
||||
pthread_mutex_unlock(&LOCK_prepare_ordered);
|
||||
}
|
||||
|
||||
cookie= 0;
|
||||
if (xid)
|
||||
cookie= log_one_transaction(xid);
|
||||
else
|
||||
cookie= 0;
|
||||
|
||||
if (need_commit_ordered)
|
||||
{
|
||||
@ -6391,13 +6378,23 @@ TC_LOG_BINLOG::log_and_order(THD *thd, my_xid xid, bool all,
|
||||
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
|
||||
|
||||
trx_data->using_xa= TRUE;
|
||||
trx_data->xa_xid= xid;
|
||||
if (xid)
|
||||
{
|
||||
Xid_log_event xid_event(thd, xid);
|
||||
err= binlog_flush_trx_cache(thd, trx_data, &xid_event, all);
|
||||
}
|
||||
else
|
||||
err= binlog_flush_trx_cache(thd, trx_data, NULL, all);
|
||||
{
|
||||
/*
|
||||
Empty xid occurs in XA COMMIT ... ONE PHASE.
|
||||
In this case, we do not have a MySQL xid for the transaction, and the
|
||||
external XA transaction coordinator will have to handle recovery if
|
||||
needed. So we end the transaction with a plain COMMIT query event.
|
||||
*/
|
||||
Query_log_event end_event(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
|
||||
err= binlog_flush_trx_cache(thd, trx_data, &end_event, all);
|
||||
}
|
||||
|
||||
DBUG_RETURN(!err);
|
||||
}
|
||||
@ -6434,14 +6431,17 @@ TC_LOG_BINLOG::mark_xids_active(uint xid_count)
|
||||
void
|
||||
TC_LOG_BINLOG::mark_xid_done()
|
||||
{
|
||||
my_bool send_signal;
|
||||
|
||||
DBUG_ENTER("TC_LOG_BINLOG::mark_xid_done");
|
||||
pthread_mutex_lock(&LOCK_prep_xids);
|
||||
DBUG_ASSERT(prepared_xids > 0);
|
||||
if (--prepared_xids == 0) {
|
||||
send_signal= !--prepared_xids;
|
||||
pthread_mutex_unlock(&LOCK_prep_xids);
|
||||
if (send_signal) {
|
||||
DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
|
||||
pthread_cond_signal(&COND_prep_xids);
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_prep_xids);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -6553,18 +6553,6 @@ mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file)
|
||||
#endif /* INNODB_COMPATIBILITY_HOOKS */
|
||||
|
||||
|
||||
static ulonglong binlog_status_var_num_commits;
|
||||
static ulonglong binlog_status_var_num_group_commits;
|
||||
|
||||
static SHOW_VAR binlog_status_vars_detail[]=
|
||||
{
|
||||
{"commits",
|
||||
(char *)&binlog_status_var_num_commits, SHOW_LONGLONG},
|
||||
{"group_commits",
|
||||
(char *)&binlog_status_var_num_group_commits, SHOW_LONGLONG},
|
||||
{NullS, NullS, SHOW_LONG}
|
||||
};
|
||||
|
||||
static int show_binlog_vars(THD *thd, SHOW_VAR *var, char *buff)
|
||||
{
|
||||
mysql_bin_log.set_status_variables();
|
||||
@ -6608,15 +6596,10 @@ static struct st_mysql_sys_var *binlog_sys_vars[]=
|
||||
void
|
||||
TC_LOG_BINLOG::set_status_variables()
|
||||
{
|
||||
ulonglong num_commits, num_group_commits;
|
||||
|
||||
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;
|
||||
pthread_mutex_unlock(&LOCK_commit_ordered);
|
||||
|
||||
binlog_status_var_num_commits= num_commits;
|
||||
binlog_status_var_num_group_commits= num_group_commits;
|
||||
}
|
||||
|
||||
struct st_mysql_storage_engine binlog_storage_engine=
|
||||
|
@ -4023,8 +4023,8 @@ THD::signal_wakeup_ready()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_wakeup_ready);
|
||||
wakeup_ready= true;
|
||||
pthread_cond_signal(&COND_wakeup_ready);
|
||||
pthread_mutex_unlock(&LOCK_wakeup_ready);
|
||||
pthread_cond_signal(&COND_wakeup_ready);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11643,6 +11643,12 @@ static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
|
||||
"Enable/Disable flushing along modified age. (none, reflex, [estimate])",
|
||||
NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_deprecated_enable_unsafe_group_commit,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine. "
|
||||
"(Deprecated, and does nothing, group commit is always enabled in a safe way)",
|
||||
NULL, NULL, 0, 0, 1, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Enable/Disable converting automatically *.ibd files when import tablespace.",
|
||||
@ -11748,6 +11754,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(read_ahead),
|
||||
MYSQL_SYSVAR(adaptive_checkpoint),
|
||||
MYSQL_SYSVAR(flush_log_at_trx_commit_session),
|
||||
MYSQL_SYSVAR(enable_unsafe_group_commit),
|
||||
MYSQL_SYSVAR(expand_import),
|
||||
MYSQL_SYSVAR(extra_rsegments),
|
||||
MYSQL_SYSVAR(dict_size_limit),
|
||||
|
@ -230,7 +230,7 @@ extern ulong srv_ibuf_active_contract;
|
||||
extern ulong srv_ibuf_accel_rate;
|
||||
extern ulint srv_checkpoint_age_target;
|
||||
extern ulong srv_flush_neighbor_pages;
|
||||
extern ulong srv_enable_unsafe_group_commit;
|
||||
extern ulong srv_deprecated_enable_unsafe_group_commit;
|
||||
extern ulong srv_read_ahead;
|
||||
extern ulong srv_adaptive_checkpoint;
|
||||
|
||||
|
@ -407,7 +407,7 @@ UNIV_INTERN ulong srv_ibuf_accel_rate = 100;
|
||||
UNIV_INTERN ulint srv_checkpoint_age_target = 0;
|
||||
UNIV_INTERN ulong srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */
|
||||
|
||||
UNIV_INTERN ulong srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
|
||||
UNIV_INTERN ulong srv_deprecated_enable_unsafe_group_commit = 0;
|
||||
UNIV_INTERN ulong srv_read_ahead = 3; /* 1: random 2: linear 3: Both */
|
||||
UNIV_INTERN ulong srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user