mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-13437 InnoDB fails to return error for XA COMMIT or XA ROLLBACK in read-only mode
Assertions failed due to incorrect handling of the --tc-heuristic-recover option when InnoDB is in read-only mode either due to innodb_read_only=1 or innodb_force_recovery>3. InnoDB failed to refuse a XA COMMIT or XA ROLLBACK operation, and there were errors in the error handling in the upper layer. This was fixed by making InnoDB XA operations respect the high_level_read_only flag. The InnoDB part of the fix and parts of the test main.tc_heuristic_recover were provided by Marko Mäkelä. LOCK_log mutex lock/unlock had to be added to fix MDEV-13438. The measure is confirmed by mysql sources as well. For testing of the conflicting option combination, mysql-test-run is made to export a new $MYSQLD_LAST_CMD. It holds the very last value generated by mtr.mysqld_start(). Even though the options have been also always stored in $mysqld->{'started_opts'} there were no access to them beyond the automatic server restart by mtr through the expect file interface. Effectively therefore $MYSQLD_LAST_CMD represents a more general interface to $mysqld->{'started_opts'} which can be used in wider scopes including server launch with incompatible options. Notice another existing method to restart the server with incompatible options relying on $MYSQLD_CMD is is aware of $mysqld->{'started_opts'} (the actual options that the server is launched by mtr). In order to use this method they would have to be provided manually. NOTE: When merging to 10.2, the file search_pattern_in_file++.inc should be replaced with the pre-existing search_pattern_in_file.inc.
This commit is contained in:
committed by
Marko Mäkelä
parent
05e7d35e89
commit
888a8b69bd
18
mysql-test/include/fail_start_mysqld.inc
Normal file
18
mysql-test/include/fail_start_mysqld.inc
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# ==== Usage ====
|
||||||
|
#
|
||||||
|
# [--let $restart_parameters= --innodb-force-recovery=0 --innodb-read-only=1]
|
||||||
|
# [--let $mysqld_stub_cmd= $MYSQLD_LAST_CMD]
|
||||||
|
# [--let $error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err]
|
||||||
|
# --source include/fail_restart_mysqld.inc
|
||||||
|
|
||||||
|
# Evaluate the default of $error_log
|
||||||
|
if (!$error_log)
|
||||||
|
{
|
||||||
|
--let $error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||||
|
}
|
||||||
|
|
||||||
|
--error 1
|
||||||
|
--exec $mysqld_stub_cmd $restart_parameters >> $error_log 2>&1
|
||||||
|
|
||||||
|
# As the server is stopped
|
||||||
|
--disable_reconnect
|
@@ -31,7 +31,7 @@ if ($shutdown_timeout == 0)
|
|||||||
--exec echo "wait" > $_expect_file_name
|
--exec echo "wait" > $_expect_file_name
|
||||||
|
|
||||||
# Send shutdown to the connected server and give
|
# Send shutdown to the connected server and give
|
||||||
# it 10 seconds to die before zapping it
|
# it an opted number of seconds to die before zapping it
|
||||||
shutdown_server $server_shutdown_timeout;
|
shutdown_server $server_shutdown_timeout;
|
||||||
|
|
||||||
# Write file to make mysql-test-run.pl start up the server again
|
# Write file to make mysql-test-run.pl start up the server again
|
||||||
|
80
mysql-test/include/search_pattern_in_file++.inc
Normal file
80
mysql-test/include/search_pattern_in_file++.inc
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# Purpose:
|
||||||
|
# Simple search with Perl for a pattern in some file.
|
||||||
|
#
|
||||||
|
# The advantages compared to thinkable auxiliary constructs using the
|
||||||
|
# mysqltest language and SQL are:
|
||||||
|
# 1. We do not need a running MySQL server.
|
||||||
|
# 2. SQL causes "noise" during debugging and increases the size of logs.
|
||||||
|
# Perl code does not disturb at all.
|
||||||
|
#
|
||||||
|
# The environment variables SEARCH_FILE and SEARCH_PATTERN must be set
|
||||||
|
# before sourcing this routine.
|
||||||
|
#
|
||||||
|
# Optionally, SEARCH_RANGE can be set to the max number of bytes of the file
|
||||||
|
# to search. If negative, it will search that many bytes at the end of the
|
||||||
|
# file. By default the search happens from the last CURRENT_TEST:
|
||||||
|
# marker till the end of file (appropriate for searching error logs).
|
||||||
|
#
|
||||||
|
# Optionally, SEARCH_ABORT can be set to "FOUND" or "NOT FOUND" and this
|
||||||
|
# will abort if the search result doesn't match the requested one.
|
||||||
|
#
|
||||||
|
# In case of
|
||||||
|
# - SEARCH_FILE and/or SEARCH_PATTERN is not set
|
||||||
|
# - SEARCH_FILE cannot be opened
|
||||||
|
# the test will abort immediate.
|
||||||
|
#
|
||||||
|
# Typical use case (check invalid server startup options):
|
||||||
|
# let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err;
|
||||||
|
# --error 0,1
|
||||||
|
# --remove_file $error_log
|
||||||
|
# let SEARCH_FILE= $error_log;
|
||||||
|
# # Stop the server
|
||||||
|
# let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
||||||
|
# --exec echo "wait" > $restart_file
|
||||||
|
# --shutdown_server 10
|
||||||
|
# --source include/wait_until_disconnected.inc
|
||||||
|
#
|
||||||
|
# --error 1
|
||||||
|
# --exec $MYSQLD_CMD <whatever wrong setting> > $error_log 2>&1
|
||||||
|
# # The server restart aborts
|
||||||
|
# let SEARCH_PATTERN= \[ERROR\] Aborting;
|
||||||
|
# --source include/search_pattern_in_file.inc
|
||||||
|
#
|
||||||
|
# Created: 2011-11-11 mleich
|
||||||
|
#
|
||||||
|
|
||||||
|
perl;
|
||||||
|
use strict;
|
||||||
|
die "SEARCH_FILE not set" unless $ENV{SEARCH_FILE};
|
||||||
|
my @search_files= glob($ENV{SEARCH_FILE});
|
||||||
|
my $search_pattern= $ENV{SEARCH_PATTERN} or die "SEARCH_PATTERN not set";
|
||||||
|
my $search_range= $ENV{SEARCH_RANGE};
|
||||||
|
my $content;
|
||||||
|
foreach my $search_file (@search_files) {
|
||||||
|
open(FILE, '<', $search_file) || die("Can't open file $search_file: $!");
|
||||||
|
my $file_content;
|
||||||
|
if ($search_range > 0) {
|
||||||
|
read(FILE, $file_content, $search_range, 0);
|
||||||
|
} elsif ($search_range < 0) {
|
||||||
|
my $size= -s $search_file;
|
||||||
|
$search_range = -$size if $size > -$search_range;
|
||||||
|
seek(FILE, $search_range, 2);
|
||||||
|
read(FILE, $file_content, -$search_range, 0);
|
||||||
|
} else {
|
||||||
|
while(<FILE>) { # error log
|
||||||
|
if (/^CURRENT_TEST:/) {
|
||||||
|
$content='';
|
||||||
|
} else {
|
||||||
|
$content.=$_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(FILE);
|
||||||
|
$content.= $file_content;
|
||||||
|
}
|
||||||
|
my @matches=($content =~ m/$search_pattern/gs);
|
||||||
|
my $res=@matches ? "FOUND " . scalar(@matches) : "NOT FOUND";
|
||||||
|
$ENV{SEARCH_FILE} =~ s{^.*?([^/\\]+)$}{$1};
|
||||||
|
print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
|
||||||
|
exit $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/;
|
||||||
|
EOF
|
@@ -1,3 +1,17 @@
|
|||||||
|
# ==== Usage ====
|
||||||
|
#
|
||||||
|
# [--let $shutdown_timeout= 30]
|
||||||
|
# [--let $allow_rpl_inited= 1]
|
||||||
|
# --source include/shutdown_mysqld.inc
|
||||||
|
|
||||||
|
# The default value is empty
|
||||||
|
--let $server_shutdown_timeout=
|
||||||
|
|
||||||
|
if ($shutdown_timeout)
|
||||||
|
{
|
||||||
|
--let $server_shutdown_timeout= $shutdown_timeout
|
||||||
|
}
|
||||||
|
|
||||||
# This is the first half of include/restart_mysqld.inc.
|
# This is the first half of include/restart_mysqld.inc.
|
||||||
if ($rpl_inited)
|
if ($rpl_inited)
|
||||||
{
|
{
|
||||||
@@ -13,6 +27,6 @@ if ($rpl_inited)
|
|||||||
--exec echo "wait" > $_expect_file_name
|
--exec echo "wait" > $_expect_file_name
|
||||||
|
|
||||||
# Send shutdown to the connected server
|
# Send shutdown to the connected server
|
||||||
--shutdown_server
|
--shutdown_server $server_shutdown_timeout
|
||||||
--source include/wait_until_disconnected.inc
|
--source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
@@ -5573,6 +5573,11 @@ sub mysqld_start ($$) {
|
|||||||
# Remember options used when starting
|
# Remember options used when starting
|
||||||
$mysqld->{'started_opts'}= $extra_opts;
|
$mysqld->{'started_opts'}= $extra_opts;
|
||||||
|
|
||||||
|
# "Dynamic" version of MYSQLD_CMD is reevaluated with each mysqld_start.
|
||||||
|
# Use it to restart the server at testing a failing server start (e.g
|
||||||
|
# due to incompatible options).
|
||||||
|
$ENV{'MYSQLD_LAST_CMD'}= "$exe @$args";
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
mysql-test/r/tc_heuristic_recover.result
Normal file
37
mysql-test/r/tc_heuristic_recover.result
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
call mtr.add_suppression("Can't init tc log");
|
||||||
|
call mtr.add_suppression("Found 1 prepared transactions!");
|
||||||
|
call mtr.add_suppression("Aborting");
|
||||||
|
set debug_sync='RESET';
|
||||||
|
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
|
||||||
|
SET GLOBAL innodb_flush_log_at_trx_commit=1;
|
||||||
|
FLUSH TABLES;
|
||||||
|
set debug_sync='ha_commit_trans_after_prepare WAIT_FOR go';
|
||||||
|
INSERT INTO t1 VALUES (1);;
|
||||||
|
# Prove that no COMMIT or ROLLBACK occurred yet.
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i
|
||||||
|
1
|
||||||
|
# Kill the server
|
||||||
|
FOUND 1 /was in the XA prepared state/ in mysqld.1.err
|
||||||
|
FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
|
||||||
|
NOT FOUND /\[ERROR\] Can\'t init tc log/ in mysqld.1.err
|
||||||
|
FOUND 2 /was in the XA prepared state/ in mysqld.1.err
|
||||||
|
FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
|
||||||
|
FOUND 1 /\[ERROR\] Can\'t init tc log/ in mysqld.1.err
|
||||||
|
FOUND 1 /Please restart mysqld without --tc-heuristic-recover/ in mysqld.1.err
|
||||||
|
FOUND 3 /was in the XA prepared state/ in mysqld.1.err
|
||||||
|
FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
|
||||||
|
FOUND 2 /\[ERROR\] Can\'t init tc log/ in mysqld.1.err
|
||||||
|
FOUND 2 /Please restart mysqld without --tc-heuristic-recover/ in mysqld.1.err
|
||||||
|
FOUND 3 /was in the XA prepared state/ in mysqld.1.err
|
||||||
|
FOUND 1 /Found 1 prepared transactions!/ in mysqld.1.err
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i
|
||||||
|
DROP TABLE t1;
|
106
mysql-test/t/tc_heuristic_recover.test
Normal file
106
mysql-test/t/tc_heuristic_recover.test
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# The test verifies a few server/engine recovery option combinations.
|
||||||
|
# Specifically, MDEV-13437,13438 are concerned with no crashes
|
||||||
|
# due to InnoDB being read-only during --tc-heuristic-recover=ROLLBACK|COMMIT.
|
||||||
|
#
|
||||||
|
# Initially the test commits a transaction and in the following proceeds
|
||||||
|
# throughout some phases.
|
||||||
|
# Within them the server is shut down and attempted to restart, to succeed
|
||||||
|
# that in the end.
|
||||||
|
# All this proves no crashes and effective rollback of the transaction.
|
||||||
|
#
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
# The test logics really requires --log-bin.
|
||||||
|
--source include/have_binlog_format_mixed.inc
|
||||||
|
--source include/have_debug_sync.inc
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
|
call mtr.add_suppression("Can't init tc log");
|
||||||
|
call mtr.add_suppression("Found 1 prepared transactions!");
|
||||||
|
call mtr.add_suppression("Aborting");
|
||||||
|
|
||||||
|
# Now take a shapshot of the last time server options.
|
||||||
|
#
|
||||||
|
# The "restart" expect-file facility can't be engaged because the server
|
||||||
|
# having conflicting options may not succeed to boot up.
|
||||||
|
# Also notice $MYSQLD_CMD is too "static" being unaware of the actual options
|
||||||
|
# of the last (before shutdown or kill) server run.
|
||||||
|
# That's why $MYSQLD_LAST_CMD that allows for the server new start
|
||||||
|
# with more options appended to a stub set which is settled at this very point.
|
||||||
|
--let $mysqld_stub_cmd= $MYSQLD_LAST_CMD
|
||||||
|
--let $error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||||
|
--let SEARCH_FILE= $error_log
|
||||||
|
set debug_sync='RESET';
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
|
||||||
|
SET GLOBAL innodb_flush_log_at_trx_commit=1;
|
||||||
|
FLUSH TABLES; # we need the table post crash-restart, see MDEV-8841.
|
||||||
|
|
||||||
|
# Run transaction in a separate "prey" connection
|
||||||
|
--connect (con1,localhost,root,,)
|
||||||
|
# The signal won't arrive though
|
||||||
|
set debug_sync='ha_commit_trans_after_prepare WAIT_FOR go';
|
||||||
|
--send INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
|
||||||
|
--let $table= information_schema.processlist
|
||||||
|
--let $where= where state = 'debug sync point: ha_commit_trans_after_prepare'
|
||||||
|
--let $wait_condition= SELECT count(*) = 1 FROM $table $where
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
--echo # Prove that no COMMIT or ROLLBACK occurred yet.
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
# TODO: MDEV-12700 Allow innodb_read_only startup without prior slow shutdown.
|
||||||
|
--source include/kill_mysqld.inc
|
||||||
|
--let $restart_parameters= --innodb-force-recovery=4
|
||||||
|
--source include/fail_start_mysqld.inc
|
||||||
|
|
||||||
|
--let SEARCH_PATTERN= was in the XA prepared state
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= Found 1 prepared transactions!
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
|
||||||
|
--let $restart_parameters= --innodb-force-recovery=4 --tc-heuristic-recover=COMMIT
|
||||||
|
--source include/fail_start_mysqld.inc
|
||||||
|
--let SEARCH_PATTERN= was in the XA prepared state
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= Found 1 prepared transactions!
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= Please restart mysqld without --tc-heuristic-recover
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
|
||||||
|
--let $restart_parameters= --tc-heuristic-recover=ROLLBACK
|
||||||
|
--source include/fail_start_mysqld.inc
|
||||||
|
|
||||||
|
--let SEARCH_PATTERN= was in the XA prepared state
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= Found 1 prepared transactions!
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= \\[ERROR\\] Can\\'t init tc log
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= Please restart mysqld without --tc-heuristic-recover
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
|
||||||
|
--let $restart_parameters=
|
||||||
|
--source include/start_mysqld.inc
|
||||||
|
|
||||||
|
--let SEARCH_PATTERN= was in the XA prepared state
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
--let SEARCH_PATTERN= Found 1 prepared transactions!
|
||||||
|
--source include/search_pattern_in_file++.inc
|
||||||
|
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
#
|
||||||
|
# Cleanup
|
||||||
|
#
|
||||||
|
DROP TABLE t1;
|
@@ -69,6 +69,14 @@ KEY_CREATE_INFO default_key_create_info=
|
|||||||
ulong total_ha= 0;
|
ulong total_ha= 0;
|
||||||
/* number of storage engines (from handlertons[]) that support 2pc */
|
/* number of storage engines (from handlertons[]) that support 2pc */
|
||||||
ulong total_ha_2pc= 0;
|
ulong total_ha_2pc= 0;
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
/*
|
||||||
|
Number of non-mandatory 2pc handlertons whose initialization failed
|
||||||
|
to estimate total_ha_2pc value under supposition of the failures
|
||||||
|
have not occcured.
|
||||||
|
*/
|
||||||
|
ulong failed_ha_2pc= 0;
|
||||||
|
#endif
|
||||||
/* size of savepoint storage area (see ha_init) */
|
/* size of savepoint storage area (see ha_init) */
|
||||||
ulong savepoint_alloc_size= 0;
|
ulong savepoint_alloc_size= 0;
|
||||||
|
|
||||||
@@ -641,6 +649,10 @@ err_deinit:
|
|||||||
(void) plugin->plugin->deinit(NULL);
|
(void) plugin->plugin->deinit(NULL);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
if (hton->prepare && hton->state == SHOW_OPTION_YES)
|
||||||
|
failed_ha_2pc++;
|
||||||
|
#endif
|
||||||
my_free(hton);
|
my_free(hton);
|
||||||
err_no_hton_memory:
|
err_no_hton_memory:
|
||||||
plugin->data= NULL;
|
plugin->data= NULL;
|
||||||
@@ -1823,7 +1835,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
|
|||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
char buf[XIDDATASIZE*4+6]; // see xid_to_str
|
char buf[XIDDATASIZE*4+6]; // see xid_to_str
|
||||||
sql_print_information("ignore xid %s", xid_to_str(buf, info->list+i));
|
DBUG_PRINT("info", ("ignore xid %s", xid_to_str(buf, info->list+i)));
|
||||||
#endif
|
#endif
|
||||||
xid_cache_insert(info->list+i, XA_PREPARED);
|
xid_cache_insert(info->list+i, XA_PREPARED);
|
||||||
info->found_foreign_xids++;
|
info->found_foreign_xids++;
|
||||||
@@ -1840,19 +1852,31 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
|
|||||||
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
|
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
|
||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
char buf[XIDDATASIZE*4+6]; // see xid_to_str
|
int rc=
|
||||||
sql_print_information("commit xid %s", xid_to_str(buf, info->list+i));
|
#endif
|
||||||
|
hton->commit_by_xid(hton, info->list+i);
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
if (rc == 0)
|
||||||
|
{
|
||||||
|
char buf[XIDDATASIZE*4+6]; // see xid_to_str
|
||||||
|
DBUG_PRINT("info", ("commit xid %s", xid_to_str(buf, info->list+i)));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
hton->commit_by_xid(hton, info->list+i);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
char buf[XIDDATASIZE*4+6]; // see xid_to_str
|
int rc=
|
||||||
sql_print_information("rollback xid %s",
|
#endif
|
||||||
xid_to_str(buf, info->list+i));
|
hton->rollback_by_xid(hton, info->list+i);
|
||||||
|
#ifndef DBUG_OFF
|
||||||
|
if (rc == 0)
|
||||||
|
{
|
||||||
|
char buf[XIDDATASIZE*4+6]; // see xid_to_str
|
||||||
|
DBUG_PRINT("info", ("rollback xid %s",
|
||||||
|
xid_to_str(buf, info->list+i)));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
hton->rollback_by_xid(hton, info->list+i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (got < info->len)
|
if (got < info->len)
|
||||||
@@ -1874,7 +1898,8 @@ int ha_recover(HASH *commit_list)
|
|||||||
/* commit_list and tc_heuristic_recover cannot be set both */
|
/* commit_list and tc_heuristic_recover cannot be set both */
|
||||||
DBUG_ASSERT(info.commit_list==0 || tc_heuristic_recover==0);
|
DBUG_ASSERT(info.commit_list==0 || tc_heuristic_recover==0);
|
||||||
/* if either is set, total_ha_2pc must be set too */
|
/* if either is set, total_ha_2pc must be set too */
|
||||||
DBUG_ASSERT(info.dry_run || total_ha_2pc>(ulong)opt_bin_log);
|
DBUG_ASSERT(info.dry_run ||
|
||||||
|
(failed_ha_2pc + total_ha_2pc) > (ulong)opt_bin_log);
|
||||||
|
|
||||||
if (total_ha_2pc <= (ulong)opt_bin_log)
|
if (total_ha_2pc <= (ulong)opt_bin_log)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@@ -8960,8 +8960,10 @@ int TC_LOG_BINLOG::open(const char *opt_name)
|
|||||||
|
|
||||||
if (using_heuristic_recover())
|
if (using_heuristic_recover())
|
||||||
{
|
{
|
||||||
|
mysql_mutex_lock(&LOCK_log);
|
||||||
/* generate a new binlog to mask a corrupted one */
|
/* generate a new binlog to mask a corrupted one */
|
||||||
open(opt_name, LOG_BIN, 0, WRITE_CACHE, max_binlog_size, 0, TRUE);
|
open(opt_name, LOG_BIN, 0, WRITE_CACHE, max_binlog_size, 0, TRUE);
|
||||||
|
mysql_mutex_unlock(&LOCK_log);
|
||||||
cleanup();
|
cleanup();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -14446,6 +14446,10 @@ innobase_commit_by_xid(
|
|||||||
|
|
||||||
DBUG_ASSERT(hton == innodb_hton_ptr);
|
DBUG_ASSERT(hton == innodb_hton_ptr);
|
||||||
|
|
||||||
|
if (high_level_read_only) {
|
||||||
|
return(XAER_RMFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
trx = trx_get_trx_by_xid(xid);
|
trx = trx_get_trx_by_xid(xid);
|
||||||
|
|
||||||
if (trx) {
|
if (trx) {
|
||||||
@@ -14473,8 +14477,11 @@ innobase_rollback_by_xid(
|
|||||||
|
|
||||||
DBUG_ASSERT(hton == innodb_hton_ptr);
|
DBUG_ASSERT(hton == innodb_hton_ptr);
|
||||||
|
|
||||||
trx = trx_get_trx_by_xid(xid);
|
if (high_level_read_only) {
|
||||||
|
return(XAER_RMFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
trx = trx_get_trx_by_xid(xid);
|
||||||
if (trx) {
|
if (trx) {
|
||||||
int ret = innobase_rollback_trx(trx);
|
int ret = innobase_rollback_trx(trx);
|
||||||
trx_free_for_background(trx);
|
trx_free_for_background(trx);
|
||||||
|
@@ -15395,6 +15395,10 @@ innobase_commit_by_xid(
|
|||||||
|
|
||||||
DBUG_ASSERT(hton == innodb_hton_ptr);
|
DBUG_ASSERT(hton == innodb_hton_ptr);
|
||||||
|
|
||||||
|
if (high_level_read_only) {
|
||||||
|
return(XAER_RMFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
trx = trx_get_trx_by_xid(xid);
|
trx = trx_get_trx_by_xid(xid);
|
||||||
|
|
||||||
if (trx) {
|
if (trx) {
|
||||||
@@ -15422,8 +15426,11 @@ innobase_rollback_by_xid(
|
|||||||
|
|
||||||
DBUG_ASSERT(hton == innodb_hton_ptr);
|
DBUG_ASSERT(hton == innodb_hton_ptr);
|
||||||
|
|
||||||
trx = trx_get_trx_by_xid(xid);
|
if (high_level_read_only) {
|
||||||
|
return(XAER_RMFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
trx = trx_get_trx_by_xid(xid);
|
||||||
if (trx) {
|
if (trx) {
|
||||||
int ret = innobase_rollback_trx(trx);
|
int ret = innobase_rollback_trx(trx);
|
||||||
trx_free_for_background(trx);
|
trx_free_for_background(trx);
|
||||||
|
Reference in New Issue
Block a user