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 "trx0sys.h"
|
||||||
#include "trx0trx.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
|
/* Current free limit of space 0; protected by the log sys mutex; 0 means
|
||||||
uninitialized */
|
uninitialized */
|
||||||
ulint log_fsp_current_free_limit = 0;
|
ulint log_fsp_current_free_limit = 0;
|
||||||
|
@@ -440,7 +440,17 @@ loop:
|
|||||||
if ((trx->sess || (trx->conc_state == TRX_NOT_STARTED))) {
|
if ((trx->sess || (trx->conc_state == TRX_NOT_STARTED))) {
|
||||||
trx = UT_LIST_GET_NEXT(trx_list, trx);
|
trx = UT_LIST_GET_NEXT(trx_list, trx);
|
||||||
} else if (trx->conc_state == TRX_PREPARED) {
|
} else if (trx->conc_state == TRX_PREPARED) {
|
||||||
trx->sess = trx_dummy_sess;
|
|
||||||
|
/* 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 {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -435,14 +435,14 @@ trx_lists_init_at_db_start(void)
|
|||||||
|
|
||||||
if (undo->state == TRX_UNDO_PREPARED) {
|
if (undo->state == TRX_UNDO_PREPARED) {
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Transaction %lu %lu was in the XA prepared state.\n",
|
"InnoDB: Transaction %lu %lu was in the XA prepared state.\n",
|
||||||
ut_dulint_get_high(trx->id),
|
ut_dulint_get_high(trx->id),
|
||||||
ut_dulint_get_low(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 {
|
} else {
|
||||||
trx->conc_state =
|
trx->conc_state =
|
||||||
TRX_COMMITTED_IN_MEMORY;
|
TRX_COMMITTED_IN_MEMORY;
|
||||||
@@ -498,16 +498,15 @@ trx_lists_init_at_db_start(void)
|
|||||||
commit or abort decision from MySQL */
|
commit or abort decision from MySQL */
|
||||||
|
|
||||||
if (undo->state == TRX_UNDO_PREPARED) {
|
if (undo->state == TRX_UNDO_PREPARED) {
|
||||||
|
fprintf(stderr,
|
||||||
fprintf(stderr,
|
|
||||||
"InnoDB: Transaction %lu %lu was in the XA prepared state.\n",
|
"InnoDB: Transaction %lu %lu was in the XA prepared state.\n",
|
||||||
ut_dulint_get_high(trx->id),
|
ut_dulint_get_high(trx->id),
|
||||||
ut_dulint_get_low(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 {
|
} else {
|
||||||
trx->conc_state =
|
trx->conc_state =
|
||||||
TRX_COMMITTED_IN_MEMORY;
|
TRX_COMMITTED_IN_MEMORY;
|
||||||
@@ -1638,10 +1637,13 @@ trx_print(
|
|||||||
fputs(", not started", f);
|
fputs(", not started", f);
|
||||||
break;
|
break;
|
||||||
case TRX_ACTIVE:
|
case TRX_ACTIVE:
|
||||||
case TRX_PREPARED:
|
|
||||||
fprintf(f, ", ACTIVE %lu sec",
|
fprintf(f, ", ACTIVE %lu sec",
|
||||||
(ulong)difftime(time(NULL), trx->start_time));
|
(ulong)difftime(time(NULL), trx->start_time));
|
||||||
break;
|
break;
|
||||||
|
case TRX_PREPARED:
|
||||||
|
fprintf(f, ", ACTIVE (PREPARED) %lu sec",
|
||||||
|
(ulong)difftime(time(NULL), trx->start_time));
|
||||||
|
break;
|
||||||
case TRX_COMMITTED_IN_MEMORY:
|
case TRX_COMMITTED_IN_MEMORY:
|
||||||
fputs(", COMMITTED IN MEMORY", f);
|
fputs(", COMMITTED IN MEMORY", f);
|
||||||
break;
|
break;
|
||||||
@@ -1938,7 +1940,7 @@ trx_get_trx_by_xid(
|
|||||||
|
|
||||||
if (xid->gtrid_length == trx->xid.gtrid_length &&
|
if (xid->gtrid_length == trx->xid.gtrid_length &&
|
||||||
xid->bqual_length == trx->xid.bqual_length &&
|
xid->bqual_length == trx->xid.bqual_length &&
|
||||||
memcmp(xid, &trx->xid,
|
memcmp(xid->data, trx->xid.data,
|
||||||
xid->gtrid_length +
|
xid->gtrid_length +
|
||||||
xid->bqual_length) == 0) {
|
xid->bqual_length) == 0) {
|
||||||
break;
|
break;
|
||||||
|
@@ -599,11 +599,10 @@ trx_undo_read_xid(
|
|||||||
Adds the XA XID after an undo log old-style header. */
|
Adds the XA XID after an undo log old-style header. */
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
trx_undo_header_add_xid(
|
trx_undo_header_add_space_for_xid(
|
||||||
/*====================*/
|
/*==============================*/
|
||||||
page_t* undo_page,/* in: undo log segment header page */
|
page_t* undo_page,/* in: undo log segment header page */
|
||||||
trx_ulogf_t* log_hdr,/* in: undo log header */
|
trx_ulogf_t* log_hdr,/* in: undo log header */
|
||||||
XID* xid, /* in: X/Open XA transaction identification */
|
|
||||||
mtr_t* mtr) /* in: mtr */
|
mtr_t* mtr) /* in: mtr */
|
||||||
{
|
{
|
||||||
trx_upagef_t* page_hdr;
|
trx_upagef_t* page_hdr;
|
||||||
@@ -620,9 +619,8 @@ trx_undo_header_add_xid(
|
|||||||
|
|
||||||
new_free = free + (TRX_UNDO_LOG_XA_HDR_SIZE
|
new_free = free + (TRX_UNDO_LOG_XA_HDR_SIZE
|
||||||
- TRX_UNDO_LOG_OLD_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 */
|
fields on the undo log page and in the undo log header */
|
||||||
|
|
||||||
mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_START, new_free,
|
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);
|
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,
|
undo = trx_undo_mem_create(rseg, id, type, trx_id, xid,
|
||||||
page_no, offset);
|
page_no, offset);
|
||||||
@@ -1599,7 +1597,7 @@ trx_undo_reuse_cached(
|
|||||||
|
|
||||||
if (type == TRX_UNDO_INSERT) {
|
if (type == TRX_UNDO_INSERT) {
|
||||||
offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr);
|
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);
|
mtr);
|
||||||
} else {
|
} else {
|
||||||
ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
|
ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
|
||||||
@@ -1607,7 +1605,7 @@ trx_undo_reuse_cached(
|
|||||||
== TRX_UNDO_UPDATE);
|
== TRX_UNDO_UPDATE);
|
||||||
|
|
||||||
offset = trx_undo_header_create(undo_page, trx_id, mtr);
|
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);
|
mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3071,9 +3071,6 @@ ha_innobase::unlock_row(void)
|
|||||||
|
|
||||||
DBUG_ENTER("ha_innobase::unlock_row");
|
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) {
|
if (last_query_id != user_thd->query_id) {
|
||||||
ut_print_timestamp(stderr);
|
ut_print_timestamp(stderr);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
Reference in New Issue
Block a user