log.cc, handler.cc:
Add BEGIN andd COMMIT around transactions in the binlog sql/handler.cc: Add BEGIN andd COMMIT around transactions in the binlog sql/log.cc: Add BEGIN andd COMMIT around transactions in the binlog
This commit is contained in:
parent
23dbcb0fa4
commit
4237b04189
@ -251,6 +251,7 @@ int ha_autocommit_or_rollback(THD *thd, int error)
|
||||
}
|
||||
else
|
||||
(void) ha_rollback_stmt(thd);
|
||||
|
||||
thd->tx_isolation=thd->session_tx_isolation;
|
||||
}
|
||||
#endif
|
||||
@ -309,6 +310,36 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
||||
if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
|
||||
my_b_tell(&thd->transaction.trans_log))
|
||||
{
|
||||
/* We write the command "COMMIT" as the last SQL command in the
|
||||
binlog segment cached for this transaction */
|
||||
|
||||
int save_query_length = thd->query_length;
|
||||
|
||||
thd->query_length = 6; /* length of 'COMMIT'; note that we may come
|
||||
here because a DROP TABLE, for instance,
|
||||
makes an implicit commit, and then
|
||||
thd->query is not 'COMMIT'! */
|
||||
|
||||
Query_log_event qinfo(thd, "COMMIT", TRUE);
|
||||
|
||||
/* When we come here, and the user wrapped the transaction into
|
||||
BEGIN and COMMIT, then qinfo got above the field cache_stmt
|
||||
erroneously set to 0. Let us set it to 1: */
|
||||
|
||||
qinfo.cache_stmt = 1;
|
||||
|
||||
/* Write the 'COMMIT' entry to the cache */
|
||||
|
||||
if (mysql_bin_log.write(&qinfo)) {
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), 5000);
|
||||
error=1;
|
||||
}
|
||||
|
||||
thd->query_length = save_query_length;
|
||||
|
||||
/* Now we write the binlog segment cached for this transaction to
|
||||
the real binlog */
|
||||
|
||||
mysql_bin_log.write(thd, &thd->transaction.trans_log);
|
||||
reinit_io_cache(&thd->transaction.trans_log,
|
||||
WRITE_CACHE, (my_off_t) 0, 0, 1);
|
||||
|
40
sql/log.cc
40
sql/log.cc
@ -442,8 +442,8 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
|
||||
#ifdef HAVE_FTRUNCATE
|
||||
if (ftruncate(index_file,0))
|
||||
{
|
||||
sql_print_error("Could not truncate the binlog index file \
|
||||
during log purge for write");
|
||||
sql_print_error(
|
||||
"Could not truncate the binlog index file during log purge for write");
|
||||
error = LOG_INFO_FATAL;
|
||||
goto err;
|
||||
}
|
||||
@ -455,8 +455,8 @@ during log purge for write");
|
||||
O_CREAT | O_BINARY | O_RDWR | O_APPEND,
|
||||
MYF(MY_WME))))
|
||||
{
|
||||
sql_print_error("Could not re-open the binlog index file \
|
||||
during log purge for write");
|
||||
sql_print_error(
|
||||
"Could not re-open the binlog index file during log purge for write");
|
||||
error = LOG_INFO_FATAL;
|
||||
goto err;
|
||||
}
|
||||
@ -661,6 +661,38 @@ bool MYSQL_LOG::write(Query_log_event* event_info)
|
||||
|
||||
error=1;
|
||||
|
||||
if (file == &thd->transaction.trans_log
|
||||
&& !my_b_tell(&thd->transaction.trans_log)) {
|
||||
|
||||
/* Add the "BEGIN" and "COMMIT" in the binlog around transactions
|
||||
which may contain more than 1 SQL statement. If we run with
|
||||
AUTOCOMMIT=1, then MySQL immediately writes each SQL statement to
|
||||
the binlog when the statement has been completed. No need to add
|
||||
"BEGIN" ... "COMMIT" around such statements. Otherwise, MySQL uses
|
||||
thd->transaction.trans_log to cache the SQL statements until the
|
||||
explicit commit, and at the commit writes the contents in .trans_log
|
||||
to the binlog.
|
||||
|
||||
We write the "BEGIN" mark first in the buffer (.trans_log) where we
|
||||
store the SQL statements for a transaction. At the transaction commit
|
||||
we will add the "COMMIT mark and write the buffer to the binlog.
|
||||
The function my_b_tell above returns != 0 if there already is data
|
||||
in the buffer. */
|
||||
|
||||
int save_query_length = thd->query_length;
|
||||
|
||||
thd->query_length = 5; /* length of string BEGIN */
|
||||
|
||||
Query_log_event qinfo(thd, "BEGIN", TRUE);
|
||||
|
||||
error = ((&qinfo)->write(file));
|
||||
|
||||
thd->query_length = save_query_length;
|
||||
|
||||
if (error)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (thd->last_insert_id_used)
|
||||
{
|
||||
Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user