diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-03-15 13:13:59 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-03-15 13:13:59 +0200 |
commit | 7d8714d70bbc9f7bc6aff641e8007413fa0e01cd (patch) | |
tree | 188b7cfc4851d32319653de59d2388d98bfaa643 | |
parent | 83b5b9a654af2ab152c39e69fe0750e3ea247308 (diff) | |
download | mariadb-git-bb-10.2-perf.tar.gz |
Merge insert_undo and update_undo into a single log.bb-10.2-perf
NOTE: Like the previous "reset DB_TRX_ID" patch, this is changing
the InnoDB file format! Proper guards for upgrading are missing!
Let InnoDB purge reset DB_TRX_ID,DB_ROLL_PTR also for insert_undo.
And let purge free the insert_undo log.
Always initialize the TRX_UNDO_PAGE_TYPE to 0. Remove undo->type.
MLOG_UNDO_HDR_REUSE: Remove. This changes the redo log format!
-rw-r--r-- | extra/innochecksum.cc | 33 | ||||
-rw-r--r-- | mysql-test/suite/innodb_zip/r/innochecksum_3.result | 4 | ||||
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 14 | ||||
-rw-r--r-- | storage/innobase/include/mtr0types.h | 3 | ||||
-rw-r--r-- | storage/innobase/include/trx0rseg.h | 18 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 6 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.ic | 3 | ||||
-rw-r--r-- | storage/innobase/include/trx0undo.h | 35 | ||||
-rw-r--r-- | storage/innobase/log/log0log.cc | 2 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 7 | ||||
-rw-r--r-- | storage/innobase/row/row0import.cc | 7 | ||||
-rw-r--r-- | storage/innobase/row/row0purge.cc | 37 | ||||
-rw-r--r-- | storage/innobase/row/row0trunc.cc | 7 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.cc | 3 | ||||
-rw-r--r-- | storage/innobase/trx/trx0purge.cc | 16 | ||||
-rw-r--r-- | storage/innobase/trx/trx0rec.cc | 38 | ||||
-rw-r--r-- | storage/innobase/trx/trx0roll.cc | 66 | ||||
-rw-r--r-- | storage/innobase/trx/trx0rseg.cc | 26 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 307 | ||||
-rw-r--r-- | storage/innobase/trx/trx0undo.cc | 359 |
20 files changed, 208 insertions, 783 deletions
diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index 393b1af062c..682dd26c6cc 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -142,9 +142,6 @@ struct innodb_page_type { int n_undo_state_to_purge; int n_undo_state_prepared; int n_undo_state_other; - int n_undo_insert; - int n_undo_update; - int n_undo_other; int n_fil_page_index; int n_fil_page_undo_log; int n_fil_page_inode; @@ -1023,26 +1020,10 @@ parse_page( case FIL_PAGE_UNDO_LOG: page_type.n_fil_page_undo_log++; - undo_page_type = mach_read_from_2(page + - TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE); if (page_type_dump) { fprintf(file, "#::%8" PRIuMAX "\t\t|\t\tUndo log page\t\t\t|", cur_page_num); } - if (undo_page_type == TRX_UNDO_INSERT) { - page_type.n_undo_insert++; - if (page_type_dump) { - fprintf(file, "\t%s", - "Insert Undo log page"); - } - - } else if (undo_page_type == TRX_UNDO_UPDATE) { - page_type.n_undo_update++; - if (page_type_dump) { - fprintf(file, "\t%s", - "Update undo log page"); - } - } undo_page_type = mach_read_from_2(page + TRX_UNDO_SEG_HDR + TRX_UNDO_STATE); @@ -1063,14 +1044,6 @@ parse_page( } break; - case TRX_UNDO_TO_FREE: - page_type.n_undo_state_to_free++; - if (page_type_dump) { - fprintf(file, ", %s", "Insert undo " - "segment that can be freed"); - } - break; - case TRX_UNDO_TO_PURGE: page_type.n_undo_state_to_purge++; if (page_type_dump) { @@ -1293,10 +1266,8 @@ print_summary( fprintf(fil_out, "\n===============================================\n"); fprintf(fil_out, "Additional information:\n"); - fprintf(fil_out, "Undo page type: %d insert, %d update, %d other\n", - page_type.n_undo_insert, - page_type.n_undo_update, - page_type.n_undo_other); + fprintf(fil_out, "Undo page type: %d\n", + page_type.n_fil_page_undo_log); fprintf(fil_out, "Undo page state: %d active, %d cached, %d to_free, %d" " to_purge, %d prepared, %d other\n", page_type.n_undo_state_active, diff --git a/mysql-test/suite/innodb_zip/r/innochecksum_3.result b/mysql-test/suite/innodb_zip/r/innochecksum_3.result index da7de031f42..b6d84adefda 100644 --- a/mysql-test/suite/innodb_zip/r/innochecksum_3.result +++ b/mysql-test/suite/innodb_zip/r/innochecksum_3.result @@ -107,7 +107,7 @@ File::tab#.ibd # Other type of page =============================================== Additional information: -Undo page type: # insert, # update, # other +Undo page type: # Undo page state: # active, # cached, # to_free, # to_purge, # prepared, # other index_id #pages #leaf_pages #recs_per_page #bytes_per_page # # # # # @@ -141,7 +141,7 @@ File::tab#.ibd # Other type of page =============================================== Additional information: -Undo page type: # insert, # update, # other +Undo page type: # Undo page state: # active, # cached, # to_free, # to_purge, # prepared, # other index_id #pages #leaf_pages #recs_per_page #bytes_per_page # # # # # diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index a1827e7b3b5..2ad1f5db4cb 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1375,17 +1375,6 @@ buf_page_print( read_buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); } - if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE) - == TRX_UNDO_INSERT) { - fprintf(stderr, - "InnoDB: Page may be an insert undo log page\n"); - } else if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR - + TRX_UNDO_PAGE_TYPE) - == TRX_UNDO_UPDATE) { - fprintf(stderr, - "InnoDB: Page may be an update undo log page\n"); - } - switch (fil_page_get_type(read_buf)) { index_id_t index_id; case FIL_PAGE_INDEX: @@ -1403,6 +1392,9 @@ buf_page_print( << " in table " << index->table->name; } break; + case FIL_PAGE_UNDO_LOG: + fputs("InnoDB: Page may be an undo log page\n", stderr); + break; case FIL_PAGE_INODE: fputs("InnoDB: Page may be an 'inode' page\n", stderr); break; diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h index 0725a5405a4..d61455f5c9f 100644 --- a/storage/innobase/include/mtr0types.h +++ b/storage/innobase/include/mtr0types.h @@ -112,9 +112,6 @@ enum mlog_id_t { /** discard an update undo log header */ MLOG_UNDO_HDR_DISCARD = 23, - /** reuse an insert undo log header */ - MLOG_UNDO_HDR_REUSE = 24, - /** create an undo log header */ MLOG_UNDO_HDR_CREATE = 25, diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index a3e770b4f21..5a36f8a3038 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -169,20 +169,12 @@ struct trx_rseg_t { ulint curr_size; /*--------------------------------------------------------*/ - /* Fields for update undo logs */ - /** List of update undo logs */ - UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_list; + /* Fields for undo logs */ + /** List of undo logs */ + UT_LIST_BASE_NODE_T(trx_undo_t) undo_list; - /** List of update undo log segments cached for fast reuse */ - UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_cached; - - /*--------------------------------------------------------*/ - /* Fields for insert undo logs */ - /** List of insert undo logs */ - UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_list; - - /** List of insert undo log segments cached for fast reuse */ - UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_cached; + /** List of undo log segments cached for fast reuse */ + UT_LIST_BASE_NODE_T(trx_undo_t) undo_cached; /*--------------------------------------------------------*/ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 55f80f584c5..9e0c3401460 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -850,10 +850,8 @@ struct trx_undo_ptr_t { trx_rseg_t* rseg; /*!< rollback segment assigned to the transaction, or NULL if not assigned yet */ - trx_undo_t* insert_undo; /*!< pointer to the insert undo log, or - NULL if no inserts performed yet */ - trx_undo_t* update_undo; /*!< pointer to the update undo log, or - NULL if no update performed yet */ + trx_undo_t* undo; /*!< pointer to the undo log, or + NULL if nothing logged yet */ }; /** An instance of temporary rollback segment. */ diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic index e5fdcec919a..e6ce7886345 100644 --- a/storage/innobase/include/trx0trx.ic +++ b/storage/innobase/include/trx0trx.ic @@ -221,8 +221,7 @@ trx_is_redo_rseg_updated( /*=====================*/ const trx_t* trx) /*!< in: transaction */ { - return(trx->rsegs.m_redo.insert_undo != 0 - || trx->rsegs.m_redo.update_undo != 0); + return(trx->rsegs.m_redo.undo != 0); } /********************************************************************//** diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index dcfbaaa02de..82a88f2ae96 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -257,18 +257,13 @@ A new undo log is created or a cached undo log reused. @param[in,out] trx transaction @param[in] rseg rollback segment @param[out] undo the undo log -@param[in] type TRX_UNDO_INSERT or TRX_UNDO_UPDATE @retval DB_SUCCESS on success @retval DB_TOO_MANY_CONCURRENT_TRXS @retval DB_OUT_OF_FILE_SPACE @retval DB_READ_ONLY @retval DB_OUT_OF_MEMORY */ dberr_t -trx_undo_assign_undo( - trx_t* trx, - trx_rseg_t* rseg, - trx_undo_t** undo, - ulint type) +trx_undo_assign_undo(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo) MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Sets the state of the undo log segment at a transaction finish. @@ -281,7 +276,7 @@ trx_undo_set_state_at_finish( /** Set the state of the undo log segment at a XA PREPARE or XA ROLLBACK. @param[in,out] trx transaction -@param[in,out] undo insert_undo or update_undo log +@param[in,out] undo undo log @param[in] rollback false=XA PREPARE, true=XA ROLLBACK @param[in,out] mtr mini-transaction @return undo log segment header page, x-latched */ @@ -305,13 +300,12 @@ trx_undo_update_cleanup( x-latched */ mtr_t* mtr); /*!< in: mtr */ -/** Free an insert or temporary undo log after commit or rollback. +/** Free a temporary undo log after commit or rollback. The information is not needed after a commit or rollback, therefore the data can be discarded. -@param[in,out] undo undo log -@param[in] is_temp whether this is temporary undo log */ +@param[in,out] undo undo log */ void -trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp); +trx_undo_commit_cleanup(trx_undo_t* undo); /********************************************************************//** At shutdown, frees the undo logs of a PREPARED transaction. */ @@ -343,8 +337,7 @@ trx_undo_parse_page_init( const byte* end_ptr,/*!< in: buffer end */ page_t* page, /*!< in: page or NULL */ mtr_t* mtr); /*!< in: mtr or NULL */ -/** Parse the redo log entry of an undo log page header create or reuse. -@param[in] type MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE +/** Parse the redo log entry of an undo log page header create. @param[in] ptr redo log record @param[in] end_ptr end of log buffer @param[in,out] page page frame or NULL @@ -352,7 +345,6 @@ trx_undo_parse_page_init( @return end of log record or NULL */ byte* trx_undo_parse_page_header( - mlog_id_t type, const byte* ptr, const byte* end_ptr, page_t* page, @@ -376,17 +368,10 @@ trx_undo_mem_free( #endif /* !UNIV_INNOCHECKSUM */ -/* Types of an undo log segment */ -#define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */ -#define TRX_UNDO_UPDATE 2 /* contains undo entries for updates - and delete markings: in short, - modifys (the name 'UPDATE' is a - historical relic) */ /* States of an undo log segment */ #define TRX_UNDO_ACTIVE 1 /* contains an undo log of an active transaction */ #define TRX_UNDO_CACHED 2 /* cached for quick reuse */ -#define TRX_UNDO_TO_FREE 3 /* insert undo segment can be freed */ #define TRX_UNDO_TO_PURGE 4 /* update undo segment will not be reused: it can be freed in purge when all undo data in it is removed */ @@ -402,8 +387,6 @@ struct trx_undo_t { /*-----------------------------*/ ulint id; /*!< undo log slot number within the rollback segment */ - ulint type; /*!< TRX_UNDO_INSERT or - TRX_UNDO_UPDATE */ ulint state; /*!< state of the corresponding undo log segment */ ibool del_marks; /*!< relevant only in an update undo @@ -460,8 +443,8 @@ struct trx_undo_t { /*-------------------------------------------------------------*/ /** Transaction undo log page header offsets */ /* @{ */ -#define TRX_UNDO_PAGE_TYPE 0 /*!< TRX_UNDO_INSERT or - TRX_UNDO_UPDATE */ +#define TRX_UNDO_PAGE_TYPE 0 /*!< unused (was: TRX_UNDO_INSERT or + TRX_UNDO_UPDATE) */ #define TRX_UNDO_PAGE_START 2 /*!< Byte offset where the undo log records for the LATEST transaction start on this page (remember that @@ -559,7 +542,7 @@ page of an update undo log segment. */ #define TRX_UNDO_LOG_OLD_HDR_SIZE (34 + FLST_NODE_SIZE) /* Note: the writing of the undo log old header is coded by a log record -MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE. The appending of an XID to the +MLOG_UNDO_HDR_CREATE. The appending of an XID to the header is logged separately. In this sense, the XID is not really a member of the undo log header. TODO: do not append the XID to the log header if XA is not needed by the user. The XID wastes about 150 bytes of space in every diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 00799895e47..c86fceded1c 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -72,7 +72,7 @@ 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()) + (e.g. trx_undo_header_create()) 3b) You should not add such functionality which either change working when compared with the old or are dependent on data diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 7beb9a906dc..6dfa6016b23 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1422,10 +1422,8 @@ parse_log: ptr = trx_undo_parse_discard_latest(ptr, end_ptr, page, mtr); break; case MLOG_UNDO_HDR_CREATE: - case MLOG_UNDO_HDR_REUSE: ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG); - ptr = trx_undo_parse_page_header(type, ptr, end_ptr, - page, mtr); + ptr = trx_undo_parse_page_header(ptr, end_ptr, page, mtr); break; case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK: ut_ad(!page || fil_page_type_is_index(page_type)); @@ -3582,9 +3580,6 @@ get_mlog_string(mlog_id_t type) case MLOG_UNDO_HDR_DISCARD: return("MLOG_UNDO_HDR_DISCARD"); - case MLOG_UNDO_HDR_REUSE: - return("MLOG_UNDO_HDR_REUSE"); - case MLOG_UNDO_HDR_CREATE: return("MLOG_UNDO_HDR_CREATE"); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 27f5067fbfb..e1eb5bfe478 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -3389,9 +3389,8 @@ row_import_for_mysql( mutex_enter(&trx->undo_mutex); /* TODO: Do not write any undo log for the IMPORT cleanup. */ - trx_undo_t** pundo = &trx->rsegs.m_redo.update_undo; - err = trx_undo_assign_undo(trx, trx->rsegs.m_redo.rseg, pundo, - TRX_UNDO_UPDATE); + err = trx_undo_assign_undo(trx, trx->rsegs.m_redo.rseg, + &trx->rsegs.m_redo.undo); mutex_exit(&trx->undo_mutex); @@ -3402,7 +3401,7 @@ row_import_for_mysql( return(row_import_cleanup(prebuilt, trx, err)); - } else if (trx->rsegs.m_redo.update_undo == 0) { + } else if (trx->rsegs.m_redo.undo == 0) { err = DB_TOO_MANY_CONCURRENT_TRXS; return(row_import_cleanup(prebuilt, trx, err)); diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 905be5d70d9..0e49775d314 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -890,10 +890,8 @@ row_purge_parse_undo_rec( { dict_index_t* clust_index; byte* ptr; - trx_t* trx; undo_no_t undo_no; table_id_t table_id; - trx_id_t trx_id; roll_ptr_t roll_ptr; ulint info_bits; ulint type; @@ -907,16 +905,22 @@ row_purge_parse_undo_rec( node->rec_type = type; - if (type == TRX_UNDO_UPD_DEL_REC && !*updated_extern) { - - return(false); + switch (type) { + case TRX_UNDO_INSERT_REC: + break; + default: +#ifdef UNIV_DEBUG + ut_ad(0); + return false; + case TRX_UNDO_UPD_DEL_REC: + case TRX_UNDO_UPD_EXIST_REC: + case TRX_UNDO_DEL_MARK_REC: +#endif /* UNIV_DEBUG */ + ptr = trx_undo_update_rec_get_sys_cols(ptr, &node->trx_id, + &roll_ptr, &info_bits); + break; } - ptr = trx_undo_update_rec_get_sys_cols(ptr, &trx_id, &roll_ptr, - &info_bits); - node->table = NULL; - node->trx_id = trx_id; - /* Prevent DROP TABLE etc. from running when we are doing the purge for this row */ @@ -932,7 +936,8 @@ try_again: } ut_ad(!dict_table_is_temporary(node->table)); - if (node->table->n_v_cols && !node->table->vc_templ + if (type != TRX_UNDO_INSERT_REC + && node->table->n_v_cols && !node->table->vc_templ && dict_table_has_indexed_v_cols(node->table)) { /* Need server fully up for virtual column computation */ if (!mysqld_server_started) { @@ -966,10 +971,14 @@ err_exit: ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref), node->heap); - trx = thr_get_trx(thr); + if (type == TRX_UNDO_INSERT_REC) { + return(true); + } - ptr = trx_undo_update_rec_get_update(ptr, clust_index, type, trx_id, - roll_ptr, info_bits, trx, + ptr = trx_undo_update_rec_get_update(ptr, clust_index, type, + node->trx_id, + roll_ptr, info_bits, + thr_get_trx(thr), node->heap, &(node->update)); /* Read to the partial row the fields that occur in indexes */ diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc index 152970d9413..c2fba905d89 100644 --- a/storage/innobase/row/row0trunc.cc +++ b/storage/innobase/row/row0trunc.cc @@ -1838,11 +1838,8 @@ row_truncate_table_for_mysql( till some point. Associate rollback segment to record undo log. */ if (!dict_table_is_temporary(table)) { mutex_enter(&trx->undo_mutex); - - trx_undo_t** pundo = &trx->rsegs.m_redo.update_undo; - err = trx_undo_assign_undo( - trx, trx->rsegs.m_redo.rseg, pundo, TRX_UNDO_UPDATE); - + err = trx_undo_assign_undo(trx, trx->rsegs.m_redo.rseg, + &trx->rsegs.m_redo.undo); mutex_exit(&trx->undo_mutex); DBUG_EXECUTE_IF("ib_err_trunc_assigning_undo_log", diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 72271598a6c..c8e5b096172 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2591,8 +2591,7 @@ row_upd_clust_rec_by_insert_inherit_func( data[BTR_EXTERN_LEN] &= ~BTR_EXTERN_OWNER_FLAG; data[BTR_EXTERN_LEN] |= BTR_EXTERN_INHERITED_FLAG; /* The BTR_EXTERN_INHERITED_FLAG only matters in - rollback of a fresh insert (insert_undo log). - Purge (operating on update_undo log) will always free + rollback of a fresh insert. Purge will always free the extern fields of a delete-marked row. */ inherit = true; diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index e674957aeda..0c1d3a6fb4f 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -256,7 +256,7 @@ trx_purge_add_update_undo_to_history( x-latched */ mtr_t* mtr) /*!< in: mtr */ { - trx_undo_t* undo = trx->rsegs.m_redo.update_undo; + trx_undo_t* undo = trx->rsegs.m_redo.undo; trx_rseg_t* rseg = undo->rseg; trx_rsegf_t* rseg_header = trx_rsegf_get( rseg->space, rseg->page_no, mtr); @@ -965,19 +965,7 @@ trx_purge_initiate_truncate( ulint cached_undo_size = 0; for (trx_undo_t* undo = - UT_LIST_GET_FIRST(rseg->update_undo_cached); - undo != NULL && all_free; - undo = UT_LIST_GET_NEXT(undo_list, undo)) { - - if (limit->trx_no < undo->trx_id) { - all_free = false; - } else { - cached_undo_size += undo->size; - } - } - - for (trx_undo_t* undo = - UT_LIST_GET_FIRST(rseg->insert_undo_cached); + UT_LIST_GET_FIRST(rseg->undo_cached); undo != NULL && all_free; undo = UT_LIST_GET_NEXT(undo_list, undo)) { diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 47dd05487b9..38adf59f74b 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -474,8 +474,8 @@ trx_undo_page_report_insert( ulint i; ut_ad(dict_index_is_clust(index)); - ut_ad(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR - + TRX_UNDO_PAGE_TYPE) == TRX_UNDO_INSERT); + ut_ad(*reinterpret_cast<uint16*>(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + + undo_page) == 0); first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE); @@ -879,13 +879,10 @@ trx_undo_page_report_modify( ut_a(dict_index_is_clust(index)); ut_ad(rec_offs_validate(rec, index, offsets)); - ut_ad(mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE - + undo_page) == TRX_UNDO_UPDATE - || (dict_table_is_temporary(table) - && mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE - + undo_page) == TRX_UNDO_INSERT)); - trx_undo_t* update_undo = dict_table_is_temporary(table) - ? NULL : trx->rsegs.m_redo.update_undo; + ut_ad(*reinterpret_cast<uint16*>(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + + undo_page) == 0); + trx_undo_t* undo = dict_table_is_temporary(table) + ? NULL : trx->rsegs.m_redo.undo; first_free = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE); @@ -1109,8 +1106,8 @@ trx_undo_page_report_modify( /* Notify purge that it eventually has to free the old externally stored field */ - if (update_undo) { - update_undo->del_marks = TRUE; + if (undo) { + undo->del_marks = TRUE; } *type_cmpl_ptr |= TRX_UNDO_UPD_EXTERN; @@ -1180,8 +1177,8 @@ trx_undo_page_report_modify( double mbr[SPDIMS * 2]; mem_heap_t* row_heap = NULL; - if (update_undo) { - update_undo->del_marks = TRUE; + if (undo) { + undo->del_marks = TRUE; } if (trx_undo_left(undo_page, ptr) < 5) { @@ -1912,23 +1909,12 @@ trx_undo_report_row_operation( not listed there. */ trx->mod_tables.insert(index->table); - pundo = op_type == TRX_UNDO_INSERT_OP - ? &trx->rsegs.m_redo.insert_undo - : &trx->rsegs.m_redo.update_undo; + pundo = &trx->rsegs.m_redo.undo; rseg = trx->rsegs.m_redo.rseg; } mutex_enter(&trx->undo_mutex); - dberr_t err; - - if (*pundo) { - err = DB_SUCCESS; - } else if (op_type == TRX_UNDO_INSERT_OP || is_temp) { - err = trx_undo_assign_undo(trx, rseg, pundo, TRX_UNDO_INSERT); - } else { - err = trx_undo_assign_undo(trx, rseg, pundo, TRX_UNDO_UPDATE); - } - + dberr_t err = *pundo ? DB_SUCCESS : trx_undo_assign_undo(trx, rseg, pundo); trx_undo_t* undo = *pundo; ut_ad((err == DB_SUCCESS) == (undo != NULL)); diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 21d08b79876..38512d4873c 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -217,26 +217,17 @@ trx_rollback_low( case TRX_STATE_PREPARED: ut_ad(!trx_is_autocommit_non_locking(trx)); - if (trx_is_redo_rseg_updated(trx)) { + if (trx_undo_t* undo = trx->rsegs.m_redo.undo) { /* Change the undo log state back from TRX_UNDO_PREPARED to TRX_UNDO_ACTIVE so that if the system gets killed, recovery will perform the rollback. */ - trx_undo_ptr_t* undo_ptr = &trx->rsegs.m_redo; + ut_ad(undo->rseg == trx->rsegs.m_redo.rseg); mtr_t mtr; mtr.start(); - mutex_enter(&trx->rsegs.m_redo.rseg->mutex); - if (undo_ptr->insert_undo != NULL) { - trx_undo_set_state_at_prepare( - trx, undo_ptr->insert_undo, - true, &mtr); - } - if (undo_ptr->update_undo != NULL) { - trx_undo_set_state_at_prepare( - trx, undo_ptr->update_undo, - true, &mtr); - } - mutex_exit(&trx->rsegs.m_redo.rseg->mutex); + mutex_enter(&undo->rseg->mutex); + trx_undo_set_state_at_prepare(trx, undo, true, &mtr); + mutex_exit(&undo->rseg->mutex); /* Persist the XA ROLLBACK, so that crash recovery will replay the rollback in case the redo log gets applied past this point. */ @@ -901,20 +892,12 @@ trx_roll_try_truncate(trx_t* trx) trx->pages_undone = 0; undo_no_t undo_no = trx->undo_no; - trx_undo_t* insert_undo = trx->rsegs.m_redo.insert_undo; - trx_undo_t* update_undo = trx->rsegs.m_redo.update_undo; - - if (insert_undo || update_undo) { - mutex_enter(&trx->rsegs.m_redo.rseg->mutex); - if (insert_undo) { - ut_ad(insert_undo->rseg == trx->rsegs.m_redo.rseg); - trx_undo_truncate_end(insert_undo, undo_no, false); - } - if (update_undo) { - ut_ad(update_undo->rseg == trx->rsegs.m_redo.rseg); - trx_undo_truncate_end(update_undo, undo_no, false); - } - mutex_exit(&trx->rsegs.m_redo.rseg->mutex); + + if (trx_undo_t* undo = trx->rsegs.m_redo.undo) { + ut_ad(undo->rseg == trx->rsegs.m_redo.rseg); + mutex_enter(&undo->rseg->mutex); + trx_undo_truncate_end(undo, undo_no, false); + mutex_exit(&undo->rseg->mutex); } if (trx_undo_t* undo = trx->rsegs.m_noredo.undo) { @@ -988,28 +971,14 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap) trx_roll_try_truncate(trx); } - trx_undo_t* undo; - trx_undo_t* insert = trx->rsegs.m_redo.insert_undo; - trx_undo_t* update = trx->rsegs.m_redo.update_undo; + trx_undo_t* undo = trx->rsegs.m_redo.undo; trx_undo_t* temp = trx->rsegs.m_noredo.undo; const undo_no_t limit = trx->roll_limit; - ut_ad(!insert || !update || !insert->top_undo_no - || insert->top_undo_no != update->top_undo_no); - ut_ad(!insert || !temp || !insert->top_undo_no - || insert->top_undo_no != temp->top_undo_no); - ut_ad(!update || !temp || !update->top_undo_no - || update->top_undo_no != temp->top_undo_no); - - if (insert && !insert->empty && limit <= insert->top_undo_no) { - if (update && !update->empty - && update->top_undo_no > insert->top_undo_no) { - undo = update; - } else { - undo = insert; - } - } else if (update && !update->empty && limit <= update->top_undo_no) { - undo = update; + ut_ad(!undo || !temp || !undo->top_undo_no + || undo->top_undo_no != temp->top_undo_no); + + if (undo && !undo->empty && limit <= undo->top_undo_no) { } else if (temp && !temp->empty && limit <= temp->top_undo_no) { undo = temp; } else { @@ -1035,10 +1004,7 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap) trx_undo_rec_t* undo_rec = trx_roll_pop_top_rec(trx, undo, &mtr); const undo_no_t undo_no = trx_undo_rec_get_undo_no(undo_rec); if (trx_undo_rec_get_type(undo_rec) == TRX_UNDO_INSERT_REC) { - ut_ad(undo == insert || undo == temp); *roll_ptr |= 1ULL << ROLL_PTR_INSERT_FLAG_POS; - } else { - ut_ad(undo == update || undo == temp); } ut_ad(trx_roll_check_undo_rec_ordering( diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 9fcc10ec975..5dab1ea8df5 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -125,29 +125,15 @@ trx_rseg_mem_free(trx_rseg_t* rseg) mutex_free(&rseg->mutex); /* There can't be any active transactions. */ - ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0); - ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0); + ut_a(UT_LIST_GET_LEN(rseg->undo_list) == 0); - for (undo = UT_LIST_GET_FIRST(rseg->update_undo_cached); + for (undo = UT_LIST_GET_FIRST(rseg->undo_cached); undo != NULL; undo = next_undo) { next_undo = UT_LIST_GET_NEXT(undo_list, undo); - UT_LIST_REMOVE(rseg->update_undo_cached, undo); - - MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED); - - trx_undo_mem_free(undo); - } - - for (undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached); - undo != NULL; - undo = next_undo) { - - next_undo = UT_LIST_GET_NEXT(undo_list, undo); - - UT_LIST_REMOVE(rseg->insert_undo_cached, undo); + UT_LIST_REMOVE(rseg->undo_cached, undo); MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED); @@ -194,10 +180,8 @@ trx_rseg_mem_create( mutex_create(LATCH_ID_REDO_RSEG, &rseg->mutex); } - UT_LIST_INIT(rseg->update_undo_list, &trx_undo_t::undo_list); - UT_LIST_INIT(rseg->update_undo_cached, &trx_undo_t::undo_list); - UT_LIST_INIT(rseg->insert_undo_list, &trx_undo_t::undo_list); - UT_LIST_INIT(rseg->insert_undo_cached, &trx_undo_t::undo_list); + UT_LIST_INIT(rseg->undo_list, &trx_undo_t::undo_list); + UT_LIST_INIT(rseg->undo_cached, &trx_undo_t::undo_list); trx_sys->rseg_array[id] = rseg; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index c9616023d85..52b3d559982 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -729,8 +729,6 @@ void trx_resurrect_table_locks( /*======================*/ trx_t* trx, /*!< in/out: transaction */ - const trx_undo_ptr_t* undo_ptr, - /*!< in: pointer to undo segment. */ const trx_undo_t* undo) /*!< in: undo log */ { mtr_t mtr; @@ -738,8 +736,6 @@ trx_resurrect_table_locks( trx_undo_rec_t* undo_rec; table_id_set tables; - ut_ad(undo == undo_ptr->insert_undo || undo == undo_ptr->update_undo); - if (trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY) || undo->empty) { return; @@ -800,27 +796,22 @@ trx_resurrect_table_locks( DBUG_PRINT("ib_trx", ("resurrect" TRX_ID_FMT - " table '%s' IX lock from %s undo", + " table '%s' IX lock", trx_get_id_for_print(trx), - table->name.m_name, - undo == undo_ptr->insert_undo - ? "insert" : "update")); + table->name.m_name)); dict_table_close(table, FALSE, FALSE); } } } -/****************************************************************//** -Resurrect the transactions that were doing inserts the time of the -crash, they need to be undone. -@return trx_t instance */ +/** Resurrect the transactions that exited at the time of the +previous crash or shutdown. +@param[in,out] undo undo log +@return transaction instance */ static trx_t* -trx_resurrect_insert( -/*=================*/ - trx_undo_t* undo, /*!< in: entry to UNDO */ - trx_rseg_t* rseg) /*!< in: rollback segment */ +trx_resurrect(trx_undo_t* undo) { trx_t* trx; @@ -829,71 +820,45 @@ trx_resurrect_insert( ut_d(trx->start_file = __FILE__); ut_d(trx->start_line = __LINE__); - trx->rsegs.m_redo.rseg = rseg; - /* For transactions with active data will not have rseg size = 1 - or will not qualify for purge limit criteria. So it is safe to increment - this trx_ref_count w/o mutex protection. */ - ++trx->rsegs.m_redo.rseg->trx_ref_count; + trx->rsegs.m_redo.rseg = undo->rseg; + trx->rsegs.m_redo.undo = undo; + /* It is safe to skip the mutex protection, because purge is + not running and transactions cannot be created yet. */ + ++undo->rseg->trx_ref_count; *trx->xid = undo->xid; trx->id = undo->trx_id; - trx->rsegs.m_redo.insert_undo = undo; trx->is_recovered = true; - /* This is single-threaded startup code, we do not need the - protection of trx->mutex or trx_sys->mutex here. */ - - if (undo->state != TRX_UNDO_ACTIVE) { + /* We assign a dummy value for the commit number; this should + have no relevance since purge is not interested in committed + transaction numbers, unless they are in the history list, in + which case it looks the number from the disk based undo log + structure */ + trx->no = trx->id; + switch (undo->state) { + case TRX_UNDO_PREPARED: /* Prepared transactions are left in the prepared state waiting for a commit or abort decision from MySQL */ - if (undo->state == TRX_UNDO_PREPARED) { - - ib::info() << "Transaction " - << trx_get_id_for_print(trx) - << " was in the XA prepared state."; - - if (srv_force_recovery == 0) { - - trx->state = TRX_STATE_PREPARED; - ++trx_sys->n_prepared_trx; - ++trx_sys->n_prepared_recovered_trx; - } else { - - ib::info() << "Since innodb_force_recovery" - " > 0, we will force a rollback."; - - trx->state = TRX_STATE_ACTIVE; - } - } else { - trx->state = TRX_STATE_COMMITTED_IN_MEMORY; - } - - /* We give a dummy value for the trx no; this should have no - relevance since purge is not interested in committed - transaction numbers, unless they are in the history - list, in which case it looks the number from the disk based - undo log structure */ + ib::info() << "Transaction " << ib::hex(trx->id) + << " was in the XA prepared state."; - trx->no = trx->id; + trx->state = TRX_STATE_PREPARED; + ++trx_sys->n_prepared_trx; + ++trx_sys->n_prepared_recovered_trx; + break; + default: + trx->state = TRX_STATE_COMMITTED_IN_MEMORY; + break; - } else { + case TRX_UNDO_ACTIVE: trx->state = TRX_STATE_ACTIVE; - /* A running transaction always has the number field inited to TRX_ID_MAX */ - trx->no = TRX_ID_MAX; } - /* trx_start_low() is not called with resurrect, so need to initialize - start time here.*/ - if (trx->state == TRX_STATE_ACTIVE - || trx->state == TRX_STATE_PREPARED) { - - trx->start_time = ut_time(); - } - if (undo->dict_operation) { trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); trx->table_id = undo->table_id; @@ -907,105 +872,6 @@ trx_resurrect_insert( return(trx); } -/****************************************************************//** -Prepared transactions are left in the prepared state waiting for a -commit or abort decision from MySQL */ -static -void -trx_resurrect_update_in_prepared_state( -/*===================================*/ - trx_t* trx, /*!< in,out: transaction */ - const trx_undo_t* undo) /*!< in: update UNDO record */ -{ - /* This is single-threaded startup code, we do not need the - protection of trx->mutex or trx_sys->mutex here. */ - - if (undo->state == TRX_UNDO_PREPARED) { - ib::info() << "Transaction " << trx_get_id_for_print(trx) - << " was in the XA prepared state."; - - if (srv_force_recovery == 0) { - - ut_ad(trx->state != TRX_STATE_FORCED_ROLLBACK); - - 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; - } else { - ib::info() << "Since innodb_force_recovery > 0, we" - " will rollback it anyway."; - - trx->state = TRX_STATE_ACTIVE; - } - } else { - trx->state = TRX_STATE_COMMITTED_IN_MEMORY; - } -} - -/****************************************************************//** -Resurrect the transactions that were doing updates the time of the -crash, they need to be undone. */ -static -void -trx_resurrect_update( -/*=================*/ - trx_t* trx, /*!< in/out: transaction */ - trx_undo_t* undo, /*!< in/out: update UNDO record */ - trx_rseg_t* rseg) /*!< in/out: rollback segment */ -{ - trx->rsegs.m_redo.rseg = rseg; - /* For transactions with active data will not have rseg size = 1 - or will not qualify for purge limit criteria. So it is safe to increment - this trx_ref_count w/o mutex protection. */ - ++trx->rsegs.m_redo.rseg->trx_ref_count; - *trx->xid = undo->xid; - trx->id = undo->trx_id; - trx->rsegs.m_redo.update_undo = undo; - trx->is_recovered = true; - - /* This is single-threaded startup code, we do not need the - protection of trx->mutex or trx_sys->mutex here. */ - - if (undo->state != TRX_UNDO_ACTIVE) { - trx_resurrect_update_in_prepared_state(trx, undo); - - /* We give a dummy value for the trx number */ - - trx->no = trx->id; - - } else { - trx->state = TRX_STATE_ACTIVE; - - /* A running transaction always has the number field inited to - TRX_ID_MAX */ - - trx->no = TRX_ID_MAX; - } - - /* trx_start_low() is not called with resurrect, so need to initialize - start time here.*/ - if (trx->state == TRX_STATE_ACTIVE - || trx->state == TRX_STATE_PREPARED) { - trx->start_time = ut_time(); - } - - if (undo->dict_operation) { - trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); - trx->table_id = undo->table_id; - } - - if (!undo->empty && undo->top_undo_no >= trx->undo_no) { - - trx->undo_no = undo->top_undo_no + 1; - trx->undo_rseg_space = undo->rseg->space; - } -} - /** Initialize (resurrect) transactions at startup. */ void trx_lists_init_at_db_start() @@ -1022,9 +888,9 @@ trx_lists_init_at_db_start() /* Look from the rollback segments if there exist undo logs for transactions. */ + ib_time_t start_time = ut_time(); for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) { - trx_undo_t* undo; trx_rseg_t* rseg = trx_sys->rseg_array[i]; /* At this stage non-redo rseg slots are all NULL as they are @@ -1033,46 +899,16 @@ trx_lists_init_at_db_start() continue; } - /* Resurrect transactions that were doing inserts. */ - for (undo = UT_LIST_GET_FIRST(rseg->insert_undo_list); - undo != NULL; - undo = UT_LIST_GET_NEXT(undo_list, undo)) { - - trx_t* trx; - - trx = trx_resurrect_insert(undo, rseg); - - trx_sys_rw_trx_add(trx); - - trx_resurrect_table_locks( - trx, &trx->rsegs.m_redo, undo); - } - - /* Ressurrect transactions that were doing updates. */ - for (undo = UT_LIST_GET_FIRST(rseg->update_undo_list); + /* Resurrect transactions. */ + for (trx_undo_t* undo = UT_LIST_GET_FIRST(rseg->undo_list); undo != NULL; undo = UT_LIST_GET_NEXT(undo_list, undo)) { - /* Check the trx_sys->rw_trx_set first. */ - trx_sys_mutex_enter(); - - trx_t* trx = trx_get_rw_trx_by_id(undo->trx_id); - - trx_sys_mutex_exit(); - - if (trx == NULL) { - trx = trx_allocate_for_background(); - - ut_d(trx->start_file = __FILE__); - ut_d(trx->start_line = __LINE__); - } - - trx_resurrect_update(trx, undo, rseg); - + ut_ad(undo->rseg == rseg); + trx_t* trx = trx_resurrect(undo); + trx->start_time = start_time; trx_sys_rw_trx_add(trx); - - trx_resurrect_table_locks( - trx, &trx->rsegs.m_redo, undo); + trx_resurrect_table_locks(trx, undo); } } @@ -1489,7 +1325,7 @@ trx_start_low( /** Set the serialisation number for a persistent committed transaction. @param[in,out] trx committed transaction with persistent changes -@param[in,out] rseg rollback segment for update_undo, or NULL */ +@param[in,out] rseg rollback segment for undo, or NULL */ static void trx_serialise(trx_t* trx, trx_rseg_t* rseg) @@ -1564,39 +1400,32 @@ trx_write_serialisation_history( } if (!trx->rsegs.m_redo.rseg) { - ut_ad(!trx->rsegs.m_redo.insert_undo); - ut_ad(!trx->rsegs.m_redo.update_undo); + ut_ad(!trx->rsegs.m_redo.undo); return false; } - trx_undo_t* insert = trx->rsegs.m_redo.insert_undo; - trx_undo_t* update = trx->rsegs.m_redo.update_undo; + trx_undo_t* undo = trx->rsegs.m_redo.undo; - if (!insert && !update) { + if (!undo) { return false; } ut_ad(!trx->read_only); - trx_rseg_t* update_rseg = update ? trx->rsegs.m_redo.rseg : NULL; + trx_rseg_t* undo_rseg = undo ? undo->rseg : NULL; + ut_ad(!undo || undo->rseg == trx->rsegs.m_redo.rseg); mutex_enter(&trx->rsegs.m_redo.rseg->mutex); /* Assign the transaction serialisation number and add any - update_undo log to the purge queue. */ - trx_serialise(trx, update_rseg); + undo log to the purge queue. */ + trx_serialise(trx, undo_rseg); /* It is not necessary to acquire trx->undo_mutex here because only a single OS thread is allowed to commit this transaction. */ - if (insert) { - trx_undo_set_state_at_finish(insert, mtr); - } - if (update) { - /* The undo logs and possible delete-marked records - for updates and deletes will be purged later. */ - page_t* undo_hdr_page = trx_undo_set_state_at_finish( - update, mtr); - trx_undo_update_cleanup(trx, undo_hdr_page, mtr); - } + /* The undo logs and possible delete-marked records for + updates and deletes will be purged later. */ + page_t* undo_hdr_page = trx_undo_set_state_at_finish(undo, mtr); + trx_undo_update_cleanup(trx, undo_hdr_page, mtr); mutex_exit(&trx->rsegs.m_redo.rseg->mutex); @@ -1912,27 +1741,19 @@ trx_commit_in_memory( } } - ut_ad(!trx->rsegs.m_redo.update_undo); + ut_ad(!trx->rsegs.m_redo.undo); if (trx_rseg_t* rseg = trx->rsegs.m_redo.rseg) { mutex_enter(&rseg->mutex); ut_ad(rseg->trx_ref_count > 0); --rseg->trx_ref_count; mutex_exit(&rseg->mutex); - - if (trx_undo_t*& insert = trx->rsegs.m_redo.insert_undo) { - ut_ad(insert->rseg == rseg); - trx_undo_commit_cleanup(insert, false); - insert = NULL; - } } - ut_ad(!trx->rsegs.m_redo.insert_undo); - if (mtr != NULL) { if (trx_undo_t*& undo = trx->rsegs.m_noredo.undo) { ut_ad(undo->rseg == trx->rsegs.m_noredo.rseg); - trx_undo_commit_cleanup(undo, true); + trx_undo_commit_cleanup(undo); undo = NULL; } @@ -2159,13 +1980,7 @@ trx_cleanup_at_db_startup( { ut_ad(trx->is_recovered); ut_ad(!trx->rsegs.m_noredo.undo); - ut_ad(!trx->rsegs.m_redo.update_undo); - - if (trx_undo_t*& undo = trx->rsegs.m_redo.insert_undo) { - ut_ad(undo->rseg == trx->rsegs.m_redo.rseg); - trx_undo_commit_cleanup(undo, false); - undo = NULL; - } + ut_ad(!trx->rsegs.m_redo.undo); memset(&trx->rsegs, 0x0, sizeof(trx->rsegs)); trx->undo_no = 0; @@ -2707,15 +2522,15 @@ trx_prepare_low(trx_t* trx) mtr.commit(); } - trx_undo_t* insert = trx->rsegs.m_redo.insert_undo; - trx_undo_t* update = trx->rsegs.m_redo.update_undo; + trx_undo_t* undo = trx->rsegs.m_redo.undo; - if (!insert && !update) { + if (!undo) { /* There were no changes to persistent tables. */ return(0); } trx_rseg_t* rseg = trx->rsegs.m_redo.rseg; + ut_ad(undo->rseg == rseg); mtr.start(true); @@ -2725,17 +2540,7 @@ trx_prepare_low(trx_t* trx) world, at the serialization point of lsn. */ mutex_enter(&rseg->mutex); - - if (insert) { - ut_ad(insert->rseg == rseg); - trx_undo_set_state_at_prepare(trx, insert, false, &mtr); - } - - if (update) { - ut_ad(update->rseg == rseg); - trx_undo_set_state_at_prepare(trx, update, false, &mtr); - } - + trx_undo_set_state_at_prepare(trx, undo, false, &mtr); mutex_exit(&rseg->mutex); /* Make the XA PREPARE durable. */ diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index ed22a636c4e..dd6db0ad2e7 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -105,7 +105,6 @@ void trx_undo_page_init( /*===============*/ page_t* undo_page, /*!< in: undo log segment page */ - ulint type, /*!< in: undo log segment type */ mtr_t* mtr); /*!< in: mtr */ /********************************************************************//** @@ -117,26 +116,11 @@ trx_undo_mem_create( /*================*/ trx_rseg_t* rseg, /*!< in: rollback segment memory object */ ulint id, /*!< in: slot index within rseg */ - ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or - TRX_UNDO_UPDATE */ trx_id_t trx_id, /*!< in: id of the trx for which the undo log is created */ const 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 */ -/***************************************************************//** -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! -@return undo log header byte offset on page */ -static -ulint -trx_undo_insert_header_reuse( -/*=========================*/ - page_t* undo_page, /*!< in/out: insert undo log segment - header page, x-latched */ - trx_id_t trx_id, /*!< in: transaction id */ - mtr_t* mtr); /*!< in: mtr */ /**********************************************************************//** If an update undo log can be discarded immediately, this function frees the space, resetting the page to the proper state for caching. */ @@ -346,12 +330,11 @@ void trx_undo_page_init_log( /*===================*/ page_t* undo_page, /*!< in: undo log page */ - ulint type, /*!< in: undo log type */ mtr_t* mtr) /*!< in: mtr */ { mlog_write_initial_log_record(undo_page, MLOG_UNDO_INIT, mtr); - mlog_catenate_ulint_compressed(mtr, type); + mlog_catenate_ulint_compressed(mtr, 0); } /***********************************************************//** @@ -365,9 +348,9 @@ trx_undo_parse_page_init( page_t* page, /*!< in: page or NULL */ mtr_t* mtr) /*!< in: mtr or NULL */ { - ulint type; - - type = mach_parse_compressed(&ptr, end_ptr); + if (mach_parse_compressed(&ptr, end_ptr)) { + recv_sys->found_corrupt_log = true; + } if (ptr == NULL) { @@ -375,7 +358,7 @@ trx_undo_parse_page_init( } if (page) { - trx_undo_page_init(page, type, mtr); + trx_undo_page_init(page, mtr); } return(const_cast<byte*>(ptr)); @@ -388,14 +371,13 @@ void trx_undo_page_init( /*===============*/ page_t* undo_page, /*!< in: undo log segment page */ - ulint type, /*!< in: undo log segment type */ mtr_t* mtr) /*!< in: mtr */ { trx_upagef_t* page_hdr; page_hdr = undo_page + TRX_UNDO_PAGE_HDR; - mach_write_to_2(page_hdr + TRX_UNDO_PAGE_TYPE, type); + *reinterpret_cast<uint16*>(page_hdr + TRX_UNDO_PAGE_TYPE) = 0; mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE); @@ -404,7 +386,7 @@ trx_undo_page_init( fil_page_set_type(undo_page, FIL_PAGE_UNDO_LOG); - trx_undo_page_init_log(undo_page, type, mtr); + trx_undo_page_init_log(undo_page, mtr); } /***************************************************************//** @@ -418,8 +400,6 @@ trx_undo_seg_create( trx_rseg_t* rseg MY_ATTRIBUTE((unused)),/*!< in: rollback segment */ trx_rsegf_t* rseg_hdr,/*!< in: rollback segment header, page x-latched */ - ulint type, /*!< in: type of the segment: TRX_UNDO_INSERT or - TRX_UNDO_UPDATE */ ulint* id, /*!< out: slot index within rseg header */ page_t** undo_page, /*!< out: segment header page x-latched, NULL @@ -440,9 +420,6 @@ trx_undo_seg_create( ut_ad(rseg_hdr != NULL); ut_ad(mutex_own(&(rseg->mutex))); - /* fputs(type == TRX_UNDO_INSERT - ? "Creating insert undo log segment\n" - : "Creating update undo log segment\n", stderr); */ slot_no = trx_rsegf_undo_find_free(rseg_hdr, mtr); if (slot_no == ULINT_UNDEFINED) { @@ -482,7 +459,7 @@ trx_undo_seg_create( page_hdr = *undo_page + TRX_UNDO_PAGE_HDR; seg_hdr = *undo_page + TRX_UNDO_SEG_HDR; - trx_undo_page_init(*undo_page, type, mtr); + trx_undo_page_init(*undo_page, mtr); mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE, TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE, @@ -679,23 +656,7 @@ trx_undo_header_add_space_for_xid( MLOG_2BYTES, mtr); } -/**********************************************************************//** -Writes the mtr log entry of an undo log header reuse. */ -UNIV_INLINE -void -trx_undo_insert_header_reuse_log( -/*=============================*/ - const page_t* undo_page, /*!< in: undo log header page */ - trx_id_t trx_id, /*!< in: transaction id */ - mtr_t* mtr) /*!< in: mtr */ -{ - mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_REUSE, mtr); - - mlog_catenate_ull_compressed(mtr, trx_id); -} - -/** Parse the redo log entry of an undo log page header create or reuse. -@param[in] type MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE +/** Parse the redo log entry of an undo log page header create. @param[in] ptr redo log record @param[in] end_ptr end of log buffer @param[in,out] page page frame or NULL @@ -703,7 +664,6 @@ trx_undo_insert_header_reuse_log( @return end of log record or NULL */ byte* trx_undo_parse_page_header( - mlog_id_t type, const byte* ptr, const byte* end_ptr, page_t* page, @@ -712,82 +672,13 @@ trx_undo_parse_page_header( trx_id_t trx_id = mach_u64_parse_compressed(&ptr, end_ptr); if (ptr != NULL && page != NULL) { - switch (type) { - case MLOG_UNDO_HDR_CREATE: - trx_undo_header_create(page, trx_id, mtr); - return(const_cast<byte*>(ptr)); - case MLOG_UNDO_HDR_REUSE: - trx_undo_insert_header_reuse(page, trx_id, mtr); - return(const_cast<byte*>(ptr)); - default: - break; - } - ut_ad(0); + trx_undo_header_create(page, trx_id, mtr); + return(const_cast<byte*>(ptr)); } return(const_cast<byte*>(ptr)); } -/***************************************************************//** -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! -@return undo log header byte offset on page */ -static -ulint -trx_undo_insert_header_reuse( -/*=========================*/ - page_t* undo_page, /*!< in/out: insert undo log segment - header page, x-latched */ - trx_id_t trx_id, /*!< in: transaction id */ - mtr_t* mtr) /*!< in: mtr */ -{ - trx_upagef_t* page_hdr; - trx_usegf_t* seg_hdr; - trx_ulogf_t* log_hdr; - ulint free; - ulint new_free; - - ut_ad(mtr && undo_page); - - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - - 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_OLD_HDR_SIZE; - - /* Insert undo data is not needed after commit: we may free all - the space on the page */ - - ut_a(mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR - + TRX_UNDO_PAGE_TYPE) - == TRX_UNDO_INSERT); - - mach_write_to_2(page_hdr + TRX_UNDO_PAGE_START, new_free); - - mach_write_to_2(page_hdr + TRX_UNDO_PAGE_FREE, new_free); - - mach_write_to_2(seg_hdr + TRX_UNDO_STATE, TRX_UNDO_ACTIVE); - - log_hdr = undo_page + free; - - 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_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); -} - /**********************************************************************//** Writes the redo log entry of an update undo log header discard. */ UNIV_INLINE @@ -910,7 +801,7 @@ trx_undo_add_page(trx_t* trx, trx_undo_t* undo, mtr_t* mtr) buf_block_dbg_add_level(new_block, SYNC_TRX_UNDO_PAGE); undo->last_page_no = new_block->page.id.page_no(); - trx_undo_page_init(new_block->frame, undo->type, mtr); + trx_undo_page_init(new_block->frame, mtr); flst_add_last(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + header_page, @@ -1217,11 +1108,9 @@ trx_undo_mem_create_at_db_start( mtr_t* mtr) /*!< in: mtr */ { page_t* undo_page; - trx_upagef_t* page_header; trx_usegf_t* seg_header; trx_ulogf_t* undo_header; trx_undo_t* undo; - ulint type; ulint state; trx_id_t trx_id; ulint offset; @@ -1235,10 +1124,8 @@ trx_undo_mem_create_at_db_start( undo_page = trx_undo_page_get(page_id_t(rseg->space, page_no), mtr); - page_header = undo_page + TRX_UNDO_PAGE_HDR; - - type = mtr_read_ulint(page_header + TRX_UNDO_PAGE_TYPE, MLOG_2BYTES, - mtr); + ut_ad(*reinterpret_cast<uint16*>(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE + + undo_page) == 0); seg_header = undo_page + TRX_UNDO_SEG_HDR; state = mach_read_from_2(seg_header + TRX_UNDO_STATE); @@ -1262,8 +1149,7 @@ trx_undo_mem_create_at_db_start( mutex_enter(&(rseg->mutex)); - undo = trx_undo_mem_create(rseg, id, type, trx_id, &xid, - page_no, offset); + undo = trx_undo_mem_create(rseg, id, trx_id, &xid, page_no, offset); mutex_exit(&(rseg->mutex)); undo->dict_operation = mtr_read_ulint( @@ -1273,12 +1159,6 @@ trx_undo_mem_create_at_db_start( undo->state = state; undo->size = flst_get_len(seg_header + TRX_UNDO_PAGE_LIST); - /* If the log segment is being freed, the page list is inconsistent! */ - if (state == TRX_UNDO_TO_FREE) { - - goto add_to_list; - } - last_addr = flst_get_last(seg_header + TRX_UNDO_PAGE_LIST, mtr); undo->last_page_no = last_addr.page; @@ -1296,28 +1176,12 @@ trx_undo_mem_create_at_db_start( undo->top_offset = rec - last_page; undo->top_undo_no = trx_undo_rec_get_undo_no(rec); } -add_to_list: - if (type == TRX_UNDO_INSERT) { - if (state != TRX_UNDO_CACHED) { - UT_LIST_ADD_LAST(rseg->insert_undo_list, undo); - } else { - - UT_LIST_ADD_LAST(rseg->insert_undo_cached, undo); - - MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED); - } + if (state != TRX_UNDO_CACHED) { + UT_LIST_ADD_LAST(rseg->undo_list, undo); } else { - ut_ad(type == TRX_UNDO_UPDATE); - if (state != TRX_UNDO_CACHED) { - - UT_LIST_ADD_LAST(rseg->update_undo_list, undo); - } else { - - UT_LIST_ADD_LAST(rseg->update_undo_cached, undo); - - MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED); - } + UT_LIST_ADD_LAST(rseg->undo_cached, undo); + MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED); } return(undo); @@ -1388,8 +1252,6 @@ trx_undo_mem_create( /*================*/ trx_rseg_t* rseg, /*!< in: rollback segment memory object */ ulint id, /*!< in: slot index within rseg */ - ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or - TRX_UNDO_UPDATE */ trx_id_t trx_id, /*!< in: id of the trx for which the undo log is created */ const XID* xid, /*!< in: X/Open transaction identification */ @@ -1410,7 +1272,6 @@ trx_undo_mem_create( } undo->id = id; - undo->type = type; undo->state = TRX_UNDO_ACTIVE; undo->del_marks = FALSE; undo->trx_id = trx_id; @@ -1484,8 +1345,6 @@ trx_undo_create( /*============*/ trx_t* trx, /*!< in: transaction */ trx_rseg_t* rseg, /*!< in: rollback segment memory copy */ - ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or - TRX_UNDO_UPDATE */ trx_id_t trx_id, /*!< in: id of the trx for which the undo log is created */ const XID* xid, /*!< in: X/Open transaction identification*/ @@ -1511,8 +1370,7 @@ trx_undo_create( rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr); - err = trx_undo_seg_create(rseg, rseg_header, type, &id, - &undo_page, mtr); + err = trx_undo_seg_create(rseg, rseg_header, &id, &undo_page, mtr); if (err != DB_SUCCESS) { /* Did not succeed */ @@ -1528,8 +1386,7 @@ trx_undo_create( 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); + *undo = trx_undo_mem_create(rseg, id, trx_id, xid, page_no, offset); if (*undo == NULL) { err = DB_OUT_OF_MEMORY; @@ -1549,8 +1406,6 @@ trx_undo_reuse_cached( /*==================*/ trx_t* trx, /*!< in: transaction */ trx_rseg_t* rseg, /*!< in: rollback segment memory object */ - ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or - TRX_UNDO_UPDATE */ trx_id_t trx_id, /*!< in: id of the trx for which the undo log is used */ const XID* xid, /*!< in: X/Open XA transaction identification */ @@ -1562,30 +1417,12 @@ trx_undo_reuse_cached( ut_ad(mutex_own(&(rseg->mutex))); - if (type == TRX_UNDO_INSERT) { - - undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached); - if (undo == NULL) { - - return(NULL); - } - - UT_LIST_REMOVE(rseg->insert_undo_cached, undo); - - MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED); - } else { - ut_ad(type == TRX_UNDO_UPDATE); - - undo = UT_LIST_GET_FIRST(rseg->update_undo_cached); - if (undo == NULL) { - - return(NULL); - } - - UT_LIST_REMOVE(rseg->update_undo_cached, undo); - - MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED); + undo = UT_LIST_GET_FIRST(rseg->undo_cached); + if (undo == NULL) { + return(NULL); } + UT_LIST_REMOVE(rseg->undo_cached, undo); + MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED); ut_ad(undo->size == 1); ut_a(undo->id < TRX_RSEG_N_SLOTS); @@ -1593,22 +1430,9 @@ trx_undo_reuse_cached( undo_page = trx_undo_page_get( page_id_t(undo->space, undo->hdr_page_no), mtr); - if (type == TRX_UNDO_INSERT) { - offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr); - - 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 - + TRX_UNDO_PAGE_TYPE) - == TRX_UNDO_UPDATE); - - offset = trx_undo_header_create(undo_page, trx_id, mtr); - - trx_undo_header_add_space_for_xid( - undo_page, undo_page + offset, mtr); - } + offset = trx_undo_header_create(undo_page, trx_id, mtr); + trx_undo_header_add_space_for_xid(undo_page, undo_page + offset, mtr); trx_undo_mem_init_for_reuse(undo, trx_id, xid, offset); return(undo); @@ -1657,18 +1481,13 @@ A new undo log is created or a cached undo log reused. @param[in,out] trx transaction @param[in] rseg rollback segment @param[out] undo the undo log -@param[in] type TRX_UNDO_INSERT or TRX_UNDO_UPDATE @retval DB_SUCCESS on success @retval DB_TOO_MANY_CONCURRENT_TRXS @retval DB_OUT_OF_FILE_SPACE @retval DB_READ_ONLY @retval DB_OUT_OF_MEMORY */ dberr_t -trx_undo_assign_undo( - trx_t* trx, - trx_rseg_t* rseg, - trx_undo_t** undo, - ulint type) +trx_undo_assign_undo(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo) { const bool is_temp = rseg == trx->rsegs.m_noredo.rseg; mtr_t mtr; @@ -1677,40 +1496,31 @@ trx_undo_assign_undo( ut_ad(mutex_own(&trx->undo_mutex)); ut_ad(rseg == trx->rsegs.m_redo.rseg || rseg == trx->rsegs.m_noredo.rseg); - ut_ad(type == TRX_UNDO_INSERT || type == TRX_UNDO_UPDATE); + ut_ad(undo == (is_temp + ? &trx->rsegs.m_noredo.undo + : &trx->rsegs.m_redo.undo)); mtr.start(trx); if (is_temp) { mtr.set_log_mode(MTR_LOG_NO_REDO); - ut_ad(undo == &trx->rsegs.m_noredo.undo); - } else { - ut_ad(undo == (type == TRX_UNDO_INSERT - ? &trx->rsegs.m_redo.insert_undo - : &trx->rsegs.m_redo.update_undo)); } mutex_enter(&rseg->mutex); - *undo = trx_undo_reuse_cached(trx, rseg, type, trx->id, trx->xid, - &mtr); + *undo = trx_undo_reuse_cached(trx, rseg, trx->id, trx->xid, &mtr); if (*undo == NULL) { - err = trx_undo_create(trx, rseg, type, trx->id, trx->xid, + err = trx_undo_create(trx, rseg, trx->id, trx->xid, undo, &mtr); if (err != DB_SUCCESS) { goto func_exit; } } - if (is_temp) { - UT_LIST_ADD_FIRST(rseg->insert_undo_list, *undo); - } else { - UT_LIST_ADD_FIRST(type == TRX_UNDO_INSERT - ? rseg->insert_undo_list - : rseg->update_undo_list, *undo); - if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { - trx_undo_mark_as_dict_operation(trx, *undo, &mtr); - } + UT_LIST_ADD_FIRST(rseg->undo_list, *undo); + + if (!is_temp && trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { + trx_undo_mark_as_dict_operation(trx, *undo, &mtr); } func_exit: @@ -1747,10 +1557,6 @@ trx_undo_set_state_at_finish( < TRX_UNDO_PAGE_REUSE_LIMIT) { state = TRX_UNDO_CACHED; - - } else if (undo->type == TRX_UNDO_INSERT) { - - state = TRX_UNDO_TO_FREE; } else { state = TRX_UNDO_TO_PURGE; } @@ -1764,7 +1570,7 @@ trx_undo_set_state_at_finish( /** Set the state of the undo log segment at a XA PREPARE or XA ROLLBACK. @param[in,out] trx transaction -@param[in,out] undo insert_undo or update_undo log +@param[in,out] undo undo log @param[in] rollback false=XA PREPARE, true=XA ROLLBACK @param[in,out] mtr mini-transaction @return undo log segment header page, x-latched */ @@ -1829,20 +1635,20 @@ trx_undo_update_cleanup( x-latched */ mtr_t* mtr) /*!< in: mtr */ { - trx_undo_t* undo = trx->rsegs.m_redo.update_undo; + trx_undo_t* undo = trx->rsegs.m_redo.undo; trx_rseg_t* rseg = undo->rseg; ut_ad(mutex_own(&rseg->mutex)); trx_purge_add_update_undo_to_history(trx, undo_page, mtr); - UT_LIST_REMOVE(rseg->update_undo_list, undo); + UT_LIST_REMOVE(rseg->undo_list, undo); - trx->rsegs.m_redo.update_undo = NULL; + trx->rsegs.m_redo.undo = NULL; if (undo->state == TRX_UNDO_CACHED) { - UT_LIST_ADD_FIRST(rseg->update_undo_cached, undo); + UT_LIST_ADD_FIRST(rseg->undo_cached, undo); MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED); } else { @@ -1852,30 +1658,29 @@ trx_undo_update_cleanup( } } -/** Free an insert or temporary undo log after commit or rollback. +/** Free a temporary undo log after commit or rollback. The information is not needed after a commit or rollback, therefore the data can be discarded. -@param[in,out] undo undo log -@param[in] is_temp whether this is temporary undo log */ +@param[in,out] undo undo log */ void -trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp) +trx_undo_commit_cleanup(trx_undo_t* undo) { trx_rseg_t* rseg = undo->rseg; - ut_ad(is_temp == trx_sys_is_noredo_rseg_slot(rseg->id)); + ut_ad(trx_sys_is_noredo_rseg_slot(rseg->id)); mutex_enter(&rseg->mutex); - UT_LIST_REMOVE(rseg->insert_undo_list, undo); + UT_LIST_REMOVE(rseg->undo_list, undo); if (undo->state == TRX_UNDO_CACHED) { - UT_LIST_ADD_FIRST(rseg->insert_undo_cached, undo); + UT_LIST_ADD_FIRST(rseg->undo_cached, undo); MONITOR_INC(MONITOR_NUM_UNDO_SLOT_CACHED); } else { - ut_ad(undo->state == TRX_UNDO_TO_FREE); + ut_ad(undo->state == TRX_UNDO_TO_PURGE); /* Delete first the undo log segment in the file */ mutex_exit(&rseg->mutex); - trx_undo_seg_free(undo, is_temp); + trx_undo_seg_free(undo, true); mutex_enter(&rseg->mutex); ut_ad(rseg->curr_size > undo->size); @@ -1896,30 +1701,8 @@ trx_undo_free_prepared( { ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS); - if (trx->rsegs.m_redo.update_undo) { - switch (trx->rsegs.m_redo.update_undo->state) { - case TRX_UNDO_PREPARED: - break; - case TRX_UNDO_ACTIVE: - /* lock_trx_release_locks() assigns - trx->is_recovered=false */ - ut_a(!srv_was_started - || srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); - break; - default: - ut_error; - } - - UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->update_undo_list, - trx->rsegs.m_redo.update_undo); - trx_undo_mem_free(trx->rsegs.m_redo.update_undo); - - trx->rsegs.m_redo.update_undo = NULL; - } - - if (trx->rsegs.m_redo.insert_undo) { - switch (trx->rsegs.m_redo.insert_undo->state) { + if (trx_undo_t*& undo = trx->rsegs.m_redo.undo) { + switch (undo->state) { case TRX_UNDO_PREPARED: break; case TRX_UNDO_ACTIVE: @@ -1933,18 +1716,15 @@ trx_undo_free_prepared( ut_error; } - UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->insert_undo_list, - trx->rsegs.m_redo.insert_undo); - trx_undo_mem_free(trx->rsegs.m_redo.insert_undo); - - trx->rsegs.m_redo.insert_undo = NULL; + UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->undo_list, undo); + trx_undo_mem_free(undo); + undo = NULL; } if (trx_undo_t*& undo = trx->rsegs.m_noredo.undo) { ut_a(undo->state == TRX_UNDO_PREPARED); - UT_LIST_REMOVE(trx->rsegs.m_noredo.rseg->insert_undo_list, - undo); + UT_LIST_REMOVE(trx->rsegs.m_noredo.rseg->undo_list, undo); trx_undo_mem_free(undo); undo = NULL; } @@ -1996,37 +1776,22 @@ trx_undo_truncate_tablespace( /* Before re-initialization ensure that we free the existing structure. There can't be any active transactions. */ - ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0); - ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0); + ut_a(UT_LIST_GET_LEN(rseg->undo_list) == 0); trx_undo_t* next_undo; - for (trx_undo_t* undo = - UT_LIST_GET_FIRST(rseg->update_undo_cached); - undo != NULL; - undo = next_undo) { - - next_undo = UT_LIST_GET_NEXT(undo_list, undo); - UT_LIST_REMOVE(rseg->update_undo_cached, undo); - MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED); - trx_undo_mem_free(undo); - } - - for (trx_undo_t* undo = - UT_LIST_GET_FIRST(rseg->insert_undo_cached); + for (trx_undo_t* undo = UT_LIST_GET_FIRST(rseg->undo_cached); undo != NULL; undo = next_undo) { next_undo = UT_LIST_GET_NEXT(undo_list, undo); - UT_LIST_REMOVE(rseg->insert_undo_cached, undo); + UT_LIST_REMOVE(rseg->undo_cached, undo); MONITOR_DEC(MONITOR_NUM_UNDO_SLOT_CACHED); trx_undo_mem_free(undo); } - UT_LIST_INIT(rseg->update_undo_list, &trx_undo_t::undo_list); - UT_LIST_INIT(rseg->update_undo_cached, &trx_undo_t::undo_list); - UT_LIST_INIT(rseg->insert_undo_list, &trx_undo_t::undo_list); - UT_LIST_INIT(rseg->insert_undo_cached, &trx_undo_t::undo_list); + UT_LIST_INIT(rseg->undo_list, &trx_undo_t::undo_list); + UT_LIST_INIT(rseg->undo_cached, &trx_undo_t::undo_list); rseg->max_size = mtr_read_ulint( rseg_header + TRX_RSEG_MAX_SIZE, MLOG_4BYTES, &mtr); |