diff options
author | unknown <heikki@hundin.mysql.fi> | 2005-02-25 22:35:33 +0200 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2005-02-25 22:35:33 +0200 |
commit | a6e56b05382a83e369e60e9c6852ae14376b5d54 (patch) | |
tree | 8d46d49add3eee84441bb2f737733ea9444c6cce /innobase/trx | |
parent | 3d8aed6d83096102d8273bd238cc186e0fbbf0cb (diff) | |
download | mariadb-git-a6e56b05382a83e369e60e9c6852ae14376b5d54.tar.gz |
trx0undo.h, trx0undo.c, trx0trx.c, trx0roll.c:
Make InnoDB-5.0.3 to process log records of 4.1 undo log header create and reuse just like in 4.1; storing XID to the start of the undo log is a separately logged operation; this conforms to Rule 3 of InnoDB redo logging
innobase/trx/trx0roll.c:
Make InnoDB-5.0.3 to process log records of 4.1 undo log header create and reuse just like in 4.1; storing XID to the start of the undo log is a separately logged operation; this conforms to Rule 3 of InnoDB redo logging
innobase/trx/trx0trx.c:
Make InnoDB-5.0.3 to process log records of 4.1 undo log header create and reuse just like in 4.1; storing XID to the start of the undo log is a separately logged operation; this conforms to Rule 3 of InnoDB redo logging
innobase/trx/trx0undo.c:
Make InnoDB-5.0.3 to process log records of 4.1 undo log header create and reuse just like in 4.1; storing XID to the start of the undo log is a separately logged operation; this conforms to Rule 3 of InnoDB redo logging
innobase/include/trx0undo.h:
Make InnoDB-5.0.3 to process log records of 4.1 undo log header create and reuse just like in 4.1; storing XID to the start of the undo log is a separately logged operation; this conforms to Rule 3 of InnoDB redo logging
Diffstat (limited to 'innobase/trx')
-rw-r--r-- | innobase/trx/trx0roll.c | 2 | ||||
-rw-r--r-- | innobase/trx/trx0trx.c | 81 | ||||
-rw-r--r-- | innobase/trx/trx0undo.c | 229 |
3 files changed, 158 insertions, 154 deletions
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index e57057de7ff..559c2cb5128 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -950,7 +950,7 @@ try_again: if (progress_pct != trx_roll_progress_printed_pct) { if (trx_roll_progress_printed_pct == 0) { fprintf(stderr, -"\nInnoDB: Progress in percents: %lu\n", (ulong) progress_pct); +"\nInnoDB: Progress in percents: %lu", (ulong) progress_pct); } else { fprintf(stderr, " %lu", (ulong) progress_pct); diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 40e12f206dc..bc9775c21fb 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -162,7 +162,7 @@ trx_create( trx->read_view = NULL; /* Set X/Open XA transaction identification to NULL */ - memset(&trx->xid,0,sizeof(trx->xid)); + memset(&trx->xid, 0, sizeof(trx->xid)); trx->xid.formatID = -1; return(trx); @@ -436,16 +436,12 @@ trx_lists_init_at_db_start(void) if (undo->state == TRX_UNDO_PREPARED) { fprintf(stderr, -"InnoDB: Transaction %lu %lu was in the XA prepared state. We change it to\n" -"InnoDB: the 'active' state, so that InnoDB's true-and-tested crash\n" -"InnoDB: recovery will roll it back. If mysqld refuses to start after\n" -"InnoDB: this, you may be able to resolve the problem by moving the binlog\n" -"InnoDB: files to a safe place, and deleting all binlog files and the binlog\n" -"InnoDB: .index file from the datadir.\n", ut_dulint_get_high(trx->id), - ut_dulint_get_low(trx->id)); +"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->conc_state = TRX_PREPARED; */ + trx->conc_state = TRX_ACTIVE; } else { trx->conc_state = @@ -504,13 +500,9 @@ trx_lists_init_at_db_start(void) if (undo->state == TRX_UNDO_PREPARED) { fprintf(stderr, -"InnoDB: Transaction %lu %lu was in the XA prepared state. We change it to\n" -"InnoDB: the 'active' state, so that InnoDB's true-and-tested crash\n" -"InnoDB: recovery will roll it back. If mysqld refuses to start after\n" -"InnoDB: this, you may be able to resolve the problem by moving the binlog\n" -"InnoDB: files to a safe place, and deleting all binlog files and the binlog\n" -"InnoDB: .index file from the datadir.\n", ut_dulint_get_high(trx->id), - ut_dulint_get_low(trx->id)); +"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 = @@ -786,8 +778,8 @@ trx_commit_off_kernel( mutex_enter(&kernel_mutex); } - ut_ad(trx->conc_state == TRX_ACTIVE || trx->conc_state == TRX_PREPARED); - + ut_ad(trx->conc_state == TRX_ACTIVE + || trx->conc_state == TRX_PREPARED); #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -1744,10 +1736,10 @@ trx_prepare_off_kernel( trx_t* trx) /* in: transaction */ { page_t* update_hdr_page; - dulint lsn; trx_rseg_t* rseg; trx_undo_t* undo; ibool must_flush_log = FALSE; + dulint lsn; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG @@ -1765,35 +1757,36 @@ trx_prepare_off_kernel( must_flush_log = TRUE; /* Change the undo log segment states from TRX_UNDO_ACTIVE - to some other state: these modifications to the file data - structure define the transaction as prepared in the file - based world, at the serialization point of the log sequence - number lsn obtained below. */ + to TRX_UNDO_PREPARED: these modifications to the file data + structure define the transaction as prepared in the + file-based world, at the serialization point of lsn. */ mutex_enter(&(rseg->mutex)); if (trx->insert_undo != NULL) { trx_undo_set_state_at_prepare(trx, trx->insert_undo, - &mtr); + &mtr); } undo = trx->update_undo; if (undo) { - /* It is not necessary to obtain trx->undo_mutex here because only a single OS thread is allowed to do the transaction prepare for this transaction. */ - update_hdr_page = trx_undo_set_state_at_prepare(trx, undo, &mtr); + update_hdr_page = trx_undo_set_state_at_prepare(trx, + undo, &mtr); } mutex_exit(&(rseg->mutex)); /*--------------*/ - mtr_commit(&mtr); + mtr_commit(&mtr); /* This mtr commit makes the + transaction prepared in the file-based + world */ /*--------------*/ - lsn = mtr.end_lsn; + lsn = mtr.end_lsn; mutex_enter(&kernel_mutex); } @@ -1806,13 +1799,6 @@ trx_prepare_off_kernel( trx->conc_state = TRX_PREPARED; /*--------------------------------------*/ - if (trx->read_view) { - read_view_close(trx->read_view); - - mem_heap_empty(trx->read_view_heap); - trx->read_view = NULL; - } - if (must_flush_log) { mutex_exit(&kernel_mutex); @@ -1834,7 +1820,7 @@ Does the transaction prepare for MySQL. */ ulint trx_prepare_for_mysql( -/*=================*/ +/*====-=============*/ /* out: 0 or error number */ trx_t* trx) /* in: trx handle */ { @@ -1881,9 +1867,8 @@ trx_recover_for_mysql( fprintf(stderr, " InnoDB: Starting recovery for XA transactions...\n"); - - /* We should set those transactions which are in - the prepared state to the xid_list */ + /* We should set those transactions which are in the prepared state + to the xid_list */ mutex_enter(&kernel_mutex); @@ -1891,14 +1876,7 @@ trx_recover_for_mysql( while (trx) { if (trx->conc_state == TRX_PREPARED) { - xid_list[count].formatID = trx->xid.formatID; - xid_list[count].gtrid_length = trx->xid.gtrid_length; - xid_list[count].bqual_length = trx->xid.bqual_length; - - memcpy(xid_list[count].data, - trx->xid.data, - trx->xid.gtrid_length + - trx->xid.bqual_length); + xid_list[count] = trx->xid; ut_print_timestamp(stderr); fprintf(stderr, @@ -1935,15 +1913,16 @@ trx_recover_for_mysql( This function is used to find one X/Open XA distributed transaction which is in the prepared state */ -trx_t * +trx_t* trx_get_trx_by_xid( /*===============*/ /* out: trx or NULL */ - XID* xid) /* in: X/Open XA Transaction Idenfication */ + XID* xid) /* in: X/Open XA Transaction Idenfication */ { trx_t* trx; if (xid == NULL) { + return (NULL); } @@ -1972,6 +1951,7 @@ trx_get_trx_by_xid( if (trx) { if (trx->conc_state != TRX_PREPARED) { + return(NULL); } @@ -1980,4 +1960,3 @@ trx_get_trx_by_xid( return(NULL); } } - diff --git a/innobase/trx/trx0undo.c b/innobase/trx/trx0undo.c index e9296d1d9c7..545e1b77fee 100644 --- a/innobase/trx/trx0undo.c +++ b/innobase/trx/trx0undo.c @@ -100,9 +100,11 @@ trx_undo_mem_create( 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 */ + ulint offset);/* in: undo log header byte offset on page */ /******************************************************************* -Initializes a cached insert undo log header page for new use. */ +Initializes a cached insert undo log header page for new use. NOTE that this +function has its own log record type MLOG_UNDO_HDR_REUSE. You must NOT change +the operation of this function! */ static ulint trx_undo_insert_header_reuse( @@ -111,7 +113,6 @@ 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 @@ -184,7 +185,8 @@ trx_undo_get_prev_rec( /* We have to go to the previous undo log page to look for the previous record */ - return(trx_undo_get_prev_rec_from_prev_page(rec, page_no, offset, mtr)); + return(trx_undo_get_prev_rec_from_prev_page(rec, page_no, offset, + mtr)); } /*************************************************************************** @@ -476,18 +478,19 @@ trx_undo_header_create_log( } /******************************************************************* -Creates a new undo log header in file. */ +Creates a new undo log header in file. NOTE that this function has its own +log record type MLOG_UNDO_HDR_CREATE. You must NOT change the operation of +this function! */ static ulint trx_undo_header_create( /*===================*/ /* out: header byte offset on page */ page_t* undo_page, /* in: undo log segment header page, - x-latched; it is assumed that there is - TRX_UNDO_LOG_HDR_SIZE bytes free space + x-latched; it is assumed that there are + TRX_UNDO_LOG_XA_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; @@ -507,9 +510,9 @@ trx_undo_header_create( log_hdr = undo_page + free; - new_free = free + TRX_UNDO_LOG_HDR_SIZE; + new_free = free + TRX_UNDO_LOG_OLD_HDR_SIZE; - ut_ad(new_free <= UNIV_PAGE_SIZE); + ut_a(free + TRX_UNDO_LOG_XA_HDR_SIZE < UNIV_PAGE_SIZE - 100); mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free); @@ -534,30 +537,104 @@ 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); - /* 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_1(log_hdr + TRX_UNDO_XID_EXISTS, TRUE); - } else { - mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE); - } - + mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE); mach_write_to_1(log_hdr + TRX_UNDO_DICT_TRANS, 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); - } - + /* Write the log record about the header creation */ trx_undo_header_create_log(undo_page, trx_id, mtr); return(free); } +/************************************************************************ +Write X/Open XA Transaction Identification (XID) to undo log header */ +static +void +trx_undo_write_xid( +/*===============*/ + trx_ulogf_t* log_hdr,/* in: undo log header */ + XID* xid, /* in: X/Open XA Transaction Identification */ + mtr_t* mtr) /* in: mtr */ +{ + mlog_write_ulint(log_hdr + TRX_UNDO_XA_FORMAT, xid->formatID, + MLOG_4BYTES, mtr); + + mlog_write_ulint(log_hdr + TRX_UNDO_XA_TRID_LEN, xid->gtrid_length, + MLOG_4BYTES, mtr); + + mlog_write_ulint(log_hdr + TRX_UNDO_XA_BQUAL_LEN, xid->bqual_length, + MLOG_4BYTES, mtr); + + mlog_write_string(log_hdr + TRX_UNDO_XA_XID, xid->data, + XIDDATASIZE, mtr); +} + +/************************************************************************ +Read X/Open XA Transaction Identification (XID) from undo log header */ +static +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); + } +} + +/******************************************************************* +Adds the XA XID after an undo log old-style header. */ +static +void +trx_undo_header_add_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; + ulint free; + ulint new_free; + + page_hdr = undo_page + TRX_UNDO_PAGE_HDR; + + free = mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE); + + /* free is now the end offset of the old style undo log header */ + + ut_a(free == (ulint)(log_hdr - undo_page) + TRX_UNDO_LOG_OLD_HDR_SIZE); + + 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 + fields on the undo log page and in the undo log header */ + + mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_START, new_free, + MLOG_2BYTES, mtr); + + mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE, new_free, + MLOG_2BYTES, mtr); + + mlog_write_ulint(log_hdr + TRX_UNDO_LOG_START, new_free, + MLOG_2BYTES, mtr); +} + /************************************************************************** Writes the mtr log entry of an undo log header reuse. */ UNIV_INLINE @@ -587,11 +664,6 @@ 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); @@ -602,10 +674,10 @@ trx_undo_parse_page_header( if (page) { if (type == MLOG_UNDO_HDR_CREATE) { - trx_undo_header_create(page, trx_id, &xid, mtr); + trx_undo_header_create(page, trx_id, mtr); } else { ut_ad(type == MLOG_UNDO_HDR_REUSE); - trx_undo_insert_header_reuse(page, trx_id, &xid, mtr); + trx_undo_insert_header_reuse(page, trx_id, mtr); } } @@ -613,7 +685,9 @@ trx_undo_parse_page_header( } /******************************************************************* -Initializes a cached insert undo log header page for new use. */ +Initializes a cached insert undo log header page for new use. NOTE that this +function has its own log record type MLOG_UNDO_HDR_REUSE. You must NOT change +the operation of this function! */ static ulint trx_undo_insert_header_reuse( @@ -622,7 +696,6 @@ 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; @@ -638,9 +711,11 @@ trx_undo_insert_header_reuse( free = TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE; + ut_a(free + TRX_UNDO_LOG_XA_HDR_SIZE < UNIV_PAGE_SIZE - 100); + log_hdr = undo_page + free; - new_free = free + TRX_UNDO_LOG_HDR_SIZE; + new_free = free + TRX_UNDO_LOG_OLD_HDR_SIZE; /* Insert undo data is not needed after commit: we may free all the space on the page */ @@ -660,18 +735,10 @@ 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); - /* If X/Open XID exits in the log header we store it - to log header. */ - - if (xid && xid->formatID != -1) { - mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, TRUE); - - trx_undo_write_xid(log_hdr, xid); - } else { - mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE); - } - + mach_write_to_1(log_hdr + TRX_UNDO_XID_EXISTS, FALSE); mach_write_to_1(log_hdr + TRX_UNDO_DICT_TRANS, FALSE); + + /* Write the log record MLOG_UNDO_HDR_REUSE */ trx_undo_insert_header_reuse_log(undo_page, trx_id, mtr); return(free); @@ -752,52 +819,6 @@ 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 @@ -1228,7 +1249,7 @@ trx_undo_mem_create_at_db_start( xid_exists = mtr_read_ulint(undo_header + TRX_UNDO_XID_EXISTS, MLOG_1BYTE, mtr); - /* Read X/Open XA transaction identification if exists or + /* Read X/Open XA transaction identification if it exists, or set it to NULL. */ memset(&xid, 0, sizeof(xid)); @@ -1242,7 +1263,6 @@ trx_undo_mem_create_at_db_start( undo = trx_undo_mem_create(rseg, id, type, trx_id, &xid, page_no, offset); - mutex_exit(&(rseg->mutex)); undo->dict_operation = mtr_read_ulint( @@ -1510,11 +1530,12 @@ trx_undo_create( page_no = buf_frame_get_page_no(undo_page); - offset = trx_undo_header_create(undo_page, trx_id, xid, mtr); + offset = trx_undo_header_create(undo_page, trx_id, mtr); + + trx_undo_header_add_xid(undo_page, undo_page + offset, xid, 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); - return(undo); } @@ -1533,7 +1554,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*/ + XID* xid, /* in: X/Open XA transaction identification */ mtr_t* mtr) /* in: mtr */ { trx_undo_t* undo; @@ -1577,14 +1598,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, - xid, mtr); + offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr); + trx_undo_header_add_xid(undo_page, undo_page + offset, 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, xid, 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_mem_init_for_reuse(undo, trx_id, xid, offset); @@ -1782,7 +1806,8 @@ trx_undo_set_state_at_prepare( mlog_write_ulint(undo_header + TRX_UNDO_XID_EXISTS, TRUE, MLOG_1BYTE, mtr); - trx_undo_write_xid(undo_header, &undo->xid); + trx_undo_write_xid(undo_header, &undo->xid, mtr); + return(undo_page); } |