Commit b8b3ba63 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-13606 XA PREPARE transactions should survive innodb_force_recovery=1 or 2

When MySQL 5.0.3 introduced InnoDB support for two-phase commit,
it also introduced the questionable logic to roll back XA PREPARE
transactions on startup when innodb_force_recovery is 1 or 2.

Remove this logic in order to avoid unwanted side effects when
innodb_force_recovery is being set for other reasons. That is,
XA PREPARE transactions will always remain in that state until
InnoDB receives an explicit XA ROLLBACK or XA COMMIT request
from the upper layer.

At the time the logic was introduced in MySQL 5.0.3, there already
was a startup parameter that is the preferred way of achieving
the behaviour: --tc-heuristic-recover=ROLLBACK.
parent ce6c0e58
......@@ -4,7 +4,7 @@ XA START 'x';
UPDATE t1 set a=2;
XA END 'x';
XA PREPARE 'x';
# Kill and restart
# Kill and restart: --innodb-force-recovery=2
SELECT * FROM t1 LOCK IN SHARE MODE;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t1;
......
......@@ -15,7 +15,12 @@ connect (con1,localhost,root);
XA START 'x'; UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x';
connection default;
# innodb_force_recovery=2 prevents the purge and tests that the fix of
# MDEV-13606 XA PREPARE transactions should survive innodb_force_recovery=1 or 2
# is present.
--let $restart_parameters= --innodb-force-recovery=2
--source include/kill_and_restart_mysqld.inc
--let $restart_parameters=
disconnect con1;
connect (con1,localhost,root);
......
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -536,18 +537,9 @@ trx_resurrect_insert(
"InnoDB: Transaction " TRX_ID_FMT " was in the"
" XA prepared state.\n", trx->id);
if (srv_force_recovery == 0) {
trx->state = TRX_STATE_PREPARED;
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
fprintf(stderr,
"InnoDB: Since innodb_force_recovery"
" > 0, we will rollback it anyway.\n");
trx->state = TRX_STATE_ACTIVE;
}
trx->state = TRX_STATE_PREPARED;
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
}
......@@ -605,22 +597,14 @@ trx_resurrect_update_in_prepared_state(
"InnoDB: Transaction " TRX_ID_FMT
" was in the XA prepared state.\n", trx->id);
if (srv_force_recovery == 0) {
if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
}
trx->state = TRX_STATE_PREPARED;
if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
fprintf(stderr,
"InnoDB: Since innodb_force_recovery"
" > 0, we will rollback it anyway.\n");
trx->state = TRX_STATE_ACTIVE;
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
}
trx->state = TRX_STATE_PREPARED;
} else {
trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
}
......
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -714,18 +715,9 @@ trx_resurrect_insert(
"InnoDB: Transaction " TRX_ID_FMT " was in the"
" XA prepared state.\n", trx->id);
if (srv_force_recovery == 0) {
trx->state = TRX_STATE_PREPARED;
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
fprintf(stderr,
"InnoDB: Since innodb_force_recovery"
" > 0, we will rollback it anyway.\n");
trx->state = TRX_STATE_ACTIVE;
}
trx->state = TRX_STATE_PREPARED;
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
}
......@@ -783,22 +775,14 @@ trx_resurrect_update_in_prepared_state(
"InnoDB: Transaction " TRX_ID_FMT
" was in the XA prepared state.\n", trx->id);
if (srv_force_recovery == 0) {
if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
}
trx->state = TRX_STATE_PREPARED;
if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
trx_sys->n_prepared_trx++;
trx_sys->n_prepared_recovered_trx++;
} else {
fprintf(stderr,
"InnoDB: Since innodb_force_recovery"
" > 0, we will rollback it anyway.\n");
trx->state = TRX_STATE_ACTIVE;
ut_ad(trx_state_eq(trx, TRX_STATE_PREPARED));
}
trx->state = TRX_STATE_PREPARED;
} else {
trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment