mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
Fixed XA recovery for InnoDB. Note that XA recovery is still disabled
until it has been comprehensive tested.
This commit is contained in:
@@ -24,6 +24,32 @@ Created 12/9/1995 Heikki Tuuri
|
||||
#include "trx0sys.h"
|
||||
#include "trx0trx.h"
|
||||
|
||||
/*
|
||||
General philosophy of InnoDB redo-logs:
|
||||
|
||||
1) Every change to a contents of a data page must be done
|
||||
through mtr, which in mtr_commit() writes log records
|
||||
to the InnoDB redo log.
|
||||
|
||||
2) Normally these changes are performed using a mlog_write_ulint()
|
||||
or similar function.
|
||||
|
||||
3) In some page level operations only a code number of a
|
||||
c-function and its parameters are written to the log to
|
||||
reduce the size of the log.
|
||||
|
||||
3a) You should not add parameters to these kind of functions
|
||||
(e.g. trx_undo_header_create(), trx_undo_insert_header_reuse())
|
||||
|
||||
3b) You should not add such functionality which either change
|
||||
working when compared with the old or are dependent on data
|
||||
outside of the page. These kind of functions should implement
|
||||
self-contained page transformation and it should be unchanged
|
||||
if you don't have very essential reasons to change log
|
||||
semantics or format.
|
||||
|
||||
*/
|
||||
|
||||
/* Current free limit of space 0; protected by the log sys mutex; 0 means
|
||||
uninitialized */
|
||||
ulint log_fsp_current_free_limit = 0;
|
||||
|
@@ -440,7 +440,17 @@ loop:
|
||||
if ((trx->sess || (trx->conc_state == TRX_NOT_STARTED))) {
|
||||
trx = UT_LIST_GET_NEXT(trx_list, trx);
|
||||
} else if (trx->conc_state == TRX_PREPARED) {
|
||||
|
||||
/* Roll back all prepared transactions if
|
||||
innobase_force_recovery > 0 in my.cnf */
|
||||
|
||||
if (srv_force_recovery > 0) {
|
||||
trx->conc_state = TRX_ACTIVE;
|
||||
break;
|
||||
} else {
|
||||
trx->sess = trx_dummy_sess;
|
||||
trx = UT_LIST_GET_NEXT(trx_list, trx);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@@ -440,9 +440,9 @@ trx_lists_init_at_db_start(void)
|
||||
ut_dulint_get_high(trx->id),
|
||||
ut_dulint_get_low(trx->id));
|
||||
|
||||
/* trx->conc_state = TRX_PREPARED; */
|
||||
trx->conc_state =
|
||||
TRX_ACTIVE;
|
||||
trx->conc_state = TRX_ACTIVE;
|
||||
|
||||
/* trx->conc_state = TRX_PREPARED;*/
|
||||
} else {
|
||||
trx->conc_state =
|
||||
TRX_COMMITTED_IN_MEMORY;
|
||||
@@ -498,16 +498,15 @@ trx_lists_init_at_db_start(void)
|
||||
commit or abort decision from MySQL */
|
||||
|
||||
if (undo->state == TRX_UNDO_PREPARED) {
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Transaction %lu %lu was in the XA prepared state.\n",
|
||||
ut_dulint_get_high(trx->id),
|
||||
ut_dulint_get_low(trx->id));
|
||||
|
||||
/* trx->conc_state = TRX_PREPARED; */
|
||||
trx->conc_state =
|
||||
TRX_ACTIVE;
|
||||
trx->conc_state = TRX_ACTIVE;
|
||||
|
||||
/* trx->conc_state =
|
||||
TRX_PREPARED; */
|
||||
} else {
|
||||
trx->conc_state =
|
||||
TRX_COMMITTED_IN_MEMORY;
|
||||
@@ -1638,10 +1637,13 @@ trx_print(
|
||||
fputs(", not started", f);
|
||||
break;
|
||||
case TRX_ACTIVE:
|
||||
case TRX_PREPARED:
|
||||
fprintf(f, ", ACTIVE %lu sec",
|
||||
(ulong)difftime(time(NULL), trx->start_time));
|
||||
break;
|
||||
case TRX_PREPARED:
|
||||
fprintf(f, ", ACTIVE (PREPARED) %lu sec",
|
||||
(ulong)difftime(time(NULL), trx->start_time));
|
||||
break;
|
||||
case TRX_COMMITTED_IN_MEMORY:
|
||||
fputs(", COMMITTED IN MEMORY", f);
|
||||
break;
|
||||
@@ -1938,7 +1940,7 @@ trx_get_trx_by_xid(
|
||||
|
||||
if (xid->gtrid_length == trx->xid.gtrid_length &&
|
||||
xid->bqual_length == trx->xid.bqual_length &&
|
||||
memcmp(xid, &trx->xid,
|
||||
memcmp(xid->data, trx->xid.data,
|
||||
xid->gtrid_length +
|
||||
xid->bqual_length) == 0) {
|
||||
break;
|
||||
|
@@ -599,11 +599,10 @@ trx_undo_read_xid(
|
||||
Adds the XA XID after an undo log old-style header. */
|
||||
static
|
||||
void
|
||||
trx_undo_header_add_xid(
|
||||
/*====================*/
|
||||
trx_undo_header_add_space_for_xid(
|
||||
/*==============================*/
|
||||
page_t* undo_page,/* in: undo log segment header page */
|
||||
trx_ulogf_t* log_hdr,/* in: undo log header */
|
||||
XID* xid, /* in: X/Open XA transaction identification */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
trx_upagef_t* page_hdr;
|
||||
@@ -620,9 +619,8 @@ trx_undo_header_add_xid(
|
||||
|
||||
new_free = free + (TRX_UNDO_LOG_XA_HDR_SIZE
|
||||
- TRX_UNDO_LOG_OLD_HDR_SIZE);
|
||||
trx_undo_write_xid(log_hdr, xid, mtr);
|
||||
|
||||
/* Now that we added the XID after the header, update the free offset
|
||||
/* Add space for a XID after the header, update the free offset
|
||||
fields on the undo log page and in the undo log header */
|
||||
|
||||
mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_START, new_free,
|
||||
@@ -1532,7 +1530,7 @@ trx_undo_create(
|
||||
|
||||
offset = trx_undo_header_create(undo_page, trx_id, mtr);
|
||||
|
||||
trx_undo_header_add_xid(undo_page, undo_page + offset, xid, mtr);
|
||||
trx_undo_header_add_space_for_xid(undo_page, undo_page + offset, mtr);
|
||||
|
||||
undo = trx_undo_mem_create(rseg, id, type, trx_id, xid,
|
||||
page_no, offset);
|
||||
@@ -1599,7 +1597,7 @@ trx_undo_reuse_cached(
|
||||
|
||||
if (type == TRX_UNDO_INSERT) {
|
||||
offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr);
|
||||
trx_undo_header_add_xid(undo_page, undo_page + offset, xid,
|
||||
trx_undo_header_add_space_for_xid(undo_page, undo_page + offset,
|
||||
mtr);
|
||||
} else {
|
||||
ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
|
||||
@@ -1607,7 +1605,7 @@ trx_undo_reuse_cached(
|
||||
== TRX_UNDO_UPDATE);
|
||||
|
||||
offset = trx_undo_header_create(undo_page, trx_id, mtr);
|
||||
trx_undo_header_add_xid(undo_page, undo_page + offset, xid,
|
||||
trx_undo_header_add_space_for_xid(undo_page, undo_page + offset,
|
||||
mtr);
|
||||
}
|
||||
|
||||
|
@@ -3071,9 +3071,6 @@ ha_innobase::unlock_row(void)
|
||||
|
||||
DBUG_ENTER("ha_innobase::unlock_row");
|
||||
|
||||
ut_ad(prebuilt->trx ==
|
||||
(trx_t*) current_thd->transaction.all.innobase_tid);
|
||||
|
||||
if (last_query_id != user_thd->query_id) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
|
Reference in New Issue
Block a user