summaryrefslogtreecommitdiff
path: root/storage/innobase/trx
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/trx')
-rw-r--r--storage/innobase/trx/trx0trx.c6
-rw-r--r--storage/innobase/trx/trx0undo.c26
2 files changed, 25 insertions, 7 deletions
diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index 55b244abb0a..69b72451f2b 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/trx/trx0trx.c
@@ -757,8 +757,8 @@ trx_commit_off_kernel(
mutex_enter(&(rseg->mutex));
if (trx->insert_undo != NULL) {
- trx_undo_set_state_at_finish(trx, trx->insert_undo,
- &mtr);
+ trx_undo_set_state_at_finish(
+ rseg, trx, trx->insert_undo, &mtr);
}
undo = trx->update_undo;
@@ -774,7 +774,7 @@ trx_commit_off_kernel(
transaction commit for this transaction. */
update_hdr_page = trx_undo_set_state_at_finish(
- trx, undo, &mtr);
+ rseg, trx, undo, &mtr);
/* We have to do the cleanup for the update log while
holding the rseg mutex because update log headers
diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c
index 64e5ad3c9a8..2aa7752d292 100644
--- a/storage/innobase/trx/trx0undo.c
+++ b/storage/innobase/trx/trx0undo.c
@@ -1725,6 +1725,7 @@ trx_undo_set_state_at_finish(
/*=========================*/
/* out: undo log segment header page,
x-latched */
+ trx_rseg_t* rseg, /* in: rollback segment memory object */
trx_t* trx __attribute__((unused)), /* in: transaction */
trx_undo_t* undo, /* in: undo log memory copy */
mtr_t* mtr) /* in: mtr */
@@ -1734,7 +1735,10 @@ trx_undo_set_state_at_finish(
page_t* undo_page;
ulint state;
- ut_ad(trx && undo && mtr);
+ ut_ad(trx);
+ ut_ad(undo);
+ ut_ad(mtr);
+ ut_ad(mutex_own(&rseg->mutex));
if (undo->id >= TRX_RSEG_N_SLOTS) {
fprintf(stderr, "InnoDB: Error: undo->id is %lu\n",
@@ -1748,9 +1752,23 @@ trx_undo_set_state_at_finish(
seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
- if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
- < TRX_UNDO_PAGE_REUSE_LIMIT) {
- state = TRX_UNDO_CACHED;
+ if (undo->size == 1
+ && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
+ < TRX_UNDO_PAGE_REUSE_LIMIT) {
+
+ /* This is a heuristic to avoid the problem of all UNDO
+ slots ending up in one of the UNDO lists. Previously if
+ the server crashed with all the slots in one of the lists,
+ transactions that required the slots of a different type
+ would fail for lack of slots. */
+
+ if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500
+ && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
+
+ state = TRX_UNDO_CACHED;
+ } else {
+ state = TRX_UNDO_TO_FREE;
+ }
} else if (undo->type == TRX_UNDO_INSERT) {