summaryrefslogtreecommitdiff
path: root/innobase/trx/trx0undo.c
diff options
context:
space:
mode:
authorunknown <jan@hundin.mysql.fi>2004-11-30 12:11:02 +0200
committerunknown <jan@hundin.mysql.fi>2004-11-30 12:11:02 +0200
commit739b630ed7c1a832ff4e8075cd8739c93286e61f (patch)
tree84e8ec4376e25d1f3cb8c8ba19936ac217f93266 /innobase/trx/trx0undo.c
parent857bd559ec956c4be44422f3f185d310029fb765 (diff)
parentdf0e057a52db9f085c42ec593f3000da4afdbbd7 (diff)
downloadmariadb-git-739b630ed7c1a832ff4e8075cd8739c93286e61f.tar.gz
Auto merged.
innobase/row/row0ins.c: Auto merged innobase/trx/trx0undo.c: Auto merged sql/ha_innodb.h: Auto merged sql/handler.h: Auto merged
Diffstat (limited to 'innobase/trx/trx0undo.c')
-rw-r--r--innobase/trx/trx0undo.c202
1 files changed, 181 insertions, 21 deletions
diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c
index 8d1518753dd..4e216808775 100644
--- a/innobase/trx/trx0undo.c
+++ b/innobase/trx/trx0undo.c
@@ -19,6 +19,7 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "trx0rec.h"
#include "trx0purge.h"
+#include "xa.h"
/* How should the old versions in the history list be managed?
----------------------------------------------------------
@@ -97,6 +98,7 @@ trx_undo_mem_create(
TRX_UNDO_UPDATE */
dulint trx_id, /* in: id of the trx for which the undo log
is created */
+ XID* xid, /* in: X/Open XA transaction identification*/
ulint page_no,/* in: undo log header page number */
ulint offset); /* in: undo log header byte offset on page */
/*******************************************************************
@@ -109,6 +111,7 @@ trx_undo_insert_header_reuse(
page_t* undo_page, /* in: insert undo log segment header page,
x-latched */
dulint trx_id, /* in: transaction id */
+ XID* xid, /* in: X/Open XA transaction identification*/
mtr_t* mtr); /* in: mtr */
/**************************************************************************
If an update undo log can be discarded immediately, this function frees the
@@ -484,6 +487,7 @@ trx_undo_header_create(
TRX_UNDO_LOG_HDR_SIZE bytes free space
on it */
dulint trx_id, /* in: transaction id */
+ XID* xid, /* in: X/Open XA XID */
mtr_t* mtr) /* in: mtr */
{
trx_upagef_t* page_hdr;
@@ -530,11 +534,24 @@ trx_undo_header_create(
mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id);
mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free);
- mach_write_to_2(log_hdr + TRX_UNDO_DICT_OPERATION, FALSE);
-
+ /* If X/Open XID exits in the log header we store a
+ flag of it in upper byte of dict operation flag. */
+
+ if ( xid == NULL || xid->formatID == -1) {
+ mach_write_to_2(log_hdr + TRX_UNDO_DICT_OPERATION, FALSE);
+ } else {
+ mach_write_to_2(log_hdr + TRX_UNDO_DICT_OPERATION,
+ TRX_UNDO_XA_EXISTS|FALSE);
+ }
+
mach_write_to_2(log_hdr + TRX_UNDO_NEXT_LOG, 0);
mach_write_to_2(log_hdr + TRX_UNDO_PREV_LOG, prev_log);
-
+
+ /* Write X/Open XA transaction identification if exists */
+ if ( xid && xid->formatID != -1) {
+ trx_undo_write_xid(log_hdr, xid);
+ }
+
trx_undo_header_create_log(undo_page, trx_id, mtr);
return(free);
@@ -569,6 +586,11 @@ trx_undo_parse_page_header(
mtr_t* mtr) /* in: mtr or NULL */
{
dulint trx_id;
+ XID xid;
+
+ /* Set X/Open XA transaction identification to NULL */
+ memset(&xid, 0, sizeof(xid));
+ xid.formatID = -1;
ptr = mach_dulint_parse_compressed(ptr, end_ptr, &trx_id);
@@ -579,10 +601,10 @@ trx_undo_parse_page_header(
if (page) {
if (type == MLOG_UNDO_HDR_CREATE) {
- trx_undo_header_create(page, trx_id, mtr);
+ trx_undo_header_create(page, trx_id, &xid, mtr);
} else {
ut_ad(type == MLOG_UNDO_HDR_REUSE);
- trx_undo_insert_header_reuse(page, trx_id, mtr);
+ trx_undo_insert_header_reuse(page, trx_id, &xid, mtr);
}
}
@@ -599,6 +621,7 @@ trx_undo_insert_header_reuse(
page_t* undo_page, /* in: insert undo log segment header page,
x-latched */
dulint trx_id, /* in: transaction id */
+ XID* xid, /* in: X/Open XA transaction identification */
mtr_t* mtr) /* in: mtr */
{
trx_upagef_t* page_hdr;
@@ -636,7 +659,17 @@ trx_undo_insert_header_reuse(
mach_write_to_8(log_hdr + TRX_UNDO_TRX_ID, trx_id);
mach_write_to_2(log_hdr + TRX_UNDO_LOG_START, new_free);
- mach_write_to_2(log_hdr + TRX_UNDO_DICT_OPERATION, FALSE);
+ /* If X/Open XID exits in the log header we store a
+ flag of it in upper byte of dict operation flag and
+ then write the xid. */
+
+ if ( xid && xid->formatID != -1) {
+ mach_write_to_2(log_hdr + TRX_UNDO_DICT_OPERATION,
+ TRX_UNDO_XA_EXISTS|FALSE);
+ trx_undo_write_xid(log_hdr, xid);
+ } else {
+ mach_write_to_2(log_hdr + TRX_UNDO_DICT_OPERATION, FALSE);
+ }
trx_undo_insert_header_reuse_log(undo_page, trx_id, mtr);
@@ -718,6 +751,52 @@ trx_undo_discard_latest_update_undo(
}
/************************************************************************
+Write X/Open XA Transaction Identification (XID) to undo log header */
+
+void
+trx_undo_write_xid(
+/*===============*/
+ trx_ulogf_t* log_hdr,/* in: undo log header */
+ XID* xid) /* in: X/Open XA Transaction Identification */
+{
+ ulint i;
+
+ mach_write_to_4(log_hdr + TRX_UNDO_XA_FORMAT, xid->formatID);
+
+ mach_write_to_4(log_hdr + TRX_UNDO_XA_TRID_LEN, xid->gtrid_length);
+
+ mach_write_to_4(log_hdr + TRX_UNDO_XA_BQUAL_LEN, xid->bqual_length);
+
+ for(i=0; i < XIDDATASIZE; i++) {
+ mach_write_to_1(log_hdr + TRX_UNDO_XA_XID + i,
+ (ulint)(xid->data[i]));
+ }
+}
+
+/************************************************************************
+Read X/Open XA Transaction Identification (XID) from undo log header */
+
+void
+trx_undo_read_xid(
+/*==============*/
+ trx_ulogf_t* log_hdr,/* in: undo log header */
+ XID* xid) /* out: X/Open XA Transaction Identification */
+{
+ ulint i;
+
+ xid->formatID = mach_read_from_4(log_hdr + TRX_UNDO_XA_FORMAT);
+
+ xid->gtrid_length = mach_read_from_4(log_hdr + TRX_UNDO_XA_TRID_LEN);
+
+ xid->bqual_length = mach_read_from_4(log_hdr + TRX_UNDO_XA_BQUAL_LEN);
+
+ for(i=0; i < XIDDATASIZE; i++) {
+ xid->data[i] = (char)mach_read_from_1(log_hdr +
+ TRX_UNDO_XA_XID +i);
+ }
+}
+
+/************************************************************************
Tries to add a page to the undo log segment where the undo log is placed. */
ulint
@@ -1123,6 +1202,8 @@ trx_undo_mem_create_at_db_start(
fil_addr_t last_addr;
page_t* last_page;
trx_undo_rec_t* rec;
+ XID xid;
+ ulint dict_op;
if (id >= TRX_RSEG_N_SLOTS) {
fprintf(stderr,
@@ -1145,15 +1226,29 @@ trx_undo_mem_create_at_db_start(
undo_header = undo_page + offset;
trx_id = mtr_read_dulint(undo_header + TRX_UNDO_TRX_ID, mtr);
+
+ dict_op = mtr_read_ulint(
+ undo_header + TRX_UNDO_DICT_OPERATION,
+ MLOG_2BYTES, mtr);
+
+ /* Read X/Open XA transaction identification if exists or
+ set it to NULL. */
+
+ memset(&xid, 0, sizeof(xid));
+ xid.formatID = -1;
+
+ if (dict_op & TRX_UNDO_XA_EXISTS) {
+ trx_undo_read_xid(undo_header, &xid);
+ }
+
mutex_enter(&(rseg->mutex));
- undo = trx_undo_mem_create(rseg, id, type, trx_id, page_no, offset);
+ undo = trx_undo_mem_create(rseg, id, type, trx_id, &xid,
+ page_no, offset);
mutex_exit(&(rseg->mutex));
- undo->dict_operation = mtr_read_ulint(
- undo_header + TRX_UNDO_DICT_OPERATION,
- MLOG_2BYTES, mtr);
+ undo->dict_operation = (dict_op & 1);
undo->table_id = mtr_read_dulint(undo_header + TRX_UNDO_TABLE_ID, mtr);
undo->state = state;
undo->size = flst_get_len(seg_header + TRX_UNDO_PAGE_LIST, mtr);
@@ -1272,7 +1367,8 @@ trx_undo_mem_create(
ulint type, /* in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
dulint trx_id, /* in: id of the trx for which the undo log
- is created */
+ is created */
+ XID* xid, /* in: X/Open transaction identification */
ulint page_no,/* in: undo log header page number */
ulint offset) /* in: undo log header byte offset on page */
{
@@ -1295,6 +1391,7 @@ trx_undo_mem_create(
undo->state = TRX_UNDO_ACTIVE;
undo->del_marks = FALSE;
undo->trx_id = trx_id;
+ undo->xid = *xid;
undo->dict_operation = FALSE;
@@ -1322,6 +1419,7 @@ trx_undo_mem_init_for_reuse(
trx_undo_t* undo, /* in: undo log to init */
dulint trx_id, /* in: id of the trx for which the undo log
is created */
+ XID* xid, /* in: X/Open XA transaction identification*/
ulint offset) /* in: undo log header byte offset on page */
{
#ifdef UNIV_SYNC_DEBUG
@@ -1339,6 +1437,7 @@ trx_undo_mem_init_for_reuse(
undo->state = TRX_UNDO_ACTIVE;
undo->del_marks = FALSE;
undo->trx_id = trx_id;
+ undo->xid = *xid;
undo->dict_operation = FALSE;
@@ -1376,6 +1475,7 @@ trx_undo_create(
TRX_UNDO_UPDATE */
dulint trx_id, /* in: id of the trx for which the undo log
is created */
+ XID* xid, /* in: X/Open transaction identification*/
mtr_t* mtr) /* in: mtr */
{
trx_rsegf_t* rseg_header;
@@ -1410,9 +1510,10 @@ trx_undo_create(
page_no = buf_frame_get_page_no(undo_page);
- offset = trx_undo_header_create(undo_page, trx_id, mtr);
+ offset = trx_undo_header_create(undo_page, trx_id, xid, mtr);
- undo = trx_undo_mem_create(rseg, id, type, trx_id, page_no, offset);
+ undo = trx_undo_mem_create(rseg, id, type, trx_id, xid ,
+ page_no, offset);
return(undo);
}
@@ -1432,6 +1533,7 @@ trx_undo_reuse_cached(
TRX_UNDO_UPDATE */
dulint trx_id, /* in: id of the trx for which the undo log
is used */
+ XID* xid, /* in: X/Open XA transaction identification*/
mtr_t* mtr) /* in: mtr */
{
trx_undo_t* undo;
@@ -1475,16 +1577,17 @@ trx_undo_reuse_cached(
undo_page = trx_undo_page_get(undo->space, undo->hdr_page_no, mtr);
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,
+ xid, mtr);
} else {
ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
+ TRX_UNDO_PAGE_TYPE)
== TRX_UNDO_UPDATE);
- offset = trx_undo_header_create(undo_page, trx_id, mtr);
+ offset = trx_undo_header_create(undo_page, trx_id, xid, mtr);
}
- trx_undo_mem_init_for_reuse(undo, trx_id, offset);
+ trx_undo_mem_init_for_reuse(undo, trx_id, xid, offset);
return(undo);
}
@@ -1506,9 +1609,19 @@ trx_undo_mark_as_dict_operation(
hdr_page = trx_undo_page_get(undo->space, undo->hdr_page_no, mtr);
- mlog_write_ulint(hdr_page + undo->hdr_offset + TRX_UNDO_DICT_OPERATION,
- trx->dict_operation, MLOG_2BYTES, mtr);
-
+ /* Mark X/Open XA XID if it is not NULL to dict operation bit */
+
+ if ( trx->xid.formatID == -1) {
+ mlog_write_ulint(hdr_page + undo->hdr_offset +
+ TRX_UNDO_DICT_OPERATION,
+ trx->dict_operation, MLOG_2BYTES, mtr);
+ } else {
+ mlog_write_ulint(hdr_page + undo->hdr_offset +
+ TRX_UNDO_DICT_OPERATION,
+ trx->dict_operation | TRX_UNDO_XA_EXISTS,
+ MLOG_2BYTES, mtr);
+ }
+
mlog_write_dulint(hdr_page + undo->hdr_offset + TRX_UNDO_TABLE_ID,
trx->table_id, mtr);
@@ -1548,10 +1661,10 @@ trx_undo_assign_undo(
#endif /* UNIV_SYNC_DEBUG */
mutex_enter(&(rseg->mutex));
- undo = trx_undo_reuse_cached(rseg, type, trx->id, &mtr);
+ undo = trx_undo_reuse_cached(rseg, type, trx->id, &trx->xid, &mtr);
if (undo == NULL) {
- undo = trx_undo_create(rseg, type, trx->id, &mtr);
+ undo = trx_undo_create(rseg, type, trx->id, &trx->xid, &mtr);
if (undo == NULL) {
/* Did not succeed */
@@ -1632,6 +1745,53 @@ trx_undo_set_state_at_finish(
return(undo_page);
}
+/**********************************************************************
+Sets the state of the undo log segment at a transaction prepare. */
+
+page_t*
+trx_undo_set_state_at_prepare(
+/*==========================*/
+ /* out: undo log segment header page,
+ x-latched */
+ trx_t* trx, /* in: transaction */
+ trx_undo_t* undo, /* in: undo log memory copy */
+ mtr_t* mtr) /* in: mtr */
+{
+ trx_usegf_t* seg_hdr;
+ trx_upagef_t* page_hdr;
+ trx_ulogf_t* undo_header;
+ page_t* undo_page;
+ ulint offset;
+
+ ut_ad(trx && undo && mtr);
+
+ if (undo->id >= TRX_RSEG_N_SLOTS) {
+ fprintf(stderr, "InnoDB: Error: undo->id is %lu\n",
+ (ulong) undo->id);
+ mem_analyze_corruption((byte*)undo);
+ ut_error;
+ }
+
+ undo_page = trx_undo_page_get(undo->space, undo->hdr_page_no, mtr);
+
+ seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
+ page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
+
+ /*------------------------------*/
+ undo->state = TRX_UNDO_PREPARED;
+ undo->xid = trx->xid;
+ /*------------------------------*/
+
+ mlog_write_ulint(seg_hdr + TRX_UNDO_STATE, undo->state,
+ MLOG_2BYTES, mtr);
+
+ offset = mach_read_from_2(seg_hdr + TRX_UNDO_LAST_LOG);
+ undo_header = undo_page + offset;
+
+ trx_undo_write_xid(undo_header, &undo->xid);
+ return(undo_page);
+}
+
/**************************************************************************
Adds the update undo log header as the first in the history list, and
frees the memory object, or puts it to the list of cached update undo log