Commit a2ec3906 authored by unknown's avatar unknown

trx0roll.c:

  Print progress of background rollback of transactions with more than 1000 undo log entries
srv0start.c, trx0roll.c, log0recv.c, trx0roll.h:
  Cleanup background rollback code in crash recovery; do not flush all modified pages from the buffer pool after a crash recovery: this makes mysqld accesible for users more quickly


innobase/include/trx0roll.h:
  Cleanup background rollback code in crash recovery; do not flush all modified pages from the buffer pool after a crash recovery: this makes mysqld accesible for users more quickly
innobase/log/log0recv.c:
  Cleanup background rollback code in crash recovery; do not flush all modified pages from the buffer pool after a crash recovery: this makes mysqld accesible for users more quickly
innobase/srv/srv0start.c:
  Cleanup background rollback code in crash recovery; do not flush all modified pages from the buffer pool after a crash recovery: this makes mysqld accesible for users more quickly
innobase/trx/trx0roll.c:
  Print progress of background rollback of transactions with more than 1000 undo log entries
parent 5a8d528f
...@@ -105,11 +105,19 @@ trx_rollback( ...@@ -105,11 +105,19 @@ trx_rollback(
Rollback or clean up transactions which have no user session. If the Rollback or clean up transactions which have no user session. If the
transaction already was committed, then we clean up a possible insert transaction already was committed, then we clean up a possible insert
undo log. If the transaction was not yet committed, then we roll it back. undo log. If the transaction was not yet committed, then we roll it back.
Note: this is done in a background thread */ Note: this is done in a background thread. */
void * #ifndef __WIN__
trx_rollback_or_clean_all_without_sess(void *); void*
/*============================================*/ #else
ulint
#endif
trx_rollback_or_clean_all_without_sess(
/*===================================*/
/* out: a dummy parameter */
void* arg __attribute__((unused)));
/* in: a dummy parameter required by
os_thread_create */
/******************************************************************** /********************************************************************
Finishes a transaction rollback. */ Finishes a transaction rollback. */
......
...@@ -2937,7 +2937,6 @@ recv_recovery_from_checkpoint_finish(void) ...@@ -2937,7 +2937,6 @@ recv_recovery_from_checkpoint_finish(void)
#ifndef UNIV_LOG_DEBUG #ifndef UNIV_LOG_DEBUG
recv_sys_free(); recv_sys_free();
#endif #endif
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) { if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) {
os_thread_create(trx_rollback_or_clean_all_without_sess, os_thread_create(trx_rollback_or_clean_all_without_sess,
(void *)&i, &recovery_thread_id); (void *)&i, &recovery_thread_id);
......
...@@ -1403,15 +1403,13 @@ NetWare. */ ...@@ -1403,15 +1403,13 @@ NetWare. */
fsp_header_inc_size(0, sum_of_new_sizes, &mtr); fsp_header_inc_size(0, sum_of_new_sizes, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
}
if (recv_needed_recovery) { /* Immediately write the log record about increased tablespace
ut_print_timestamp(stderr); size to disk, so that it is durable even if mysqld would crash
fprintf(stderr, quickly */
" InnoDB: Flushing modified pages from the buffer pool...\n");
}
log_make_checkpoint_at(ut_dulint_max, TRUE); log_buffer_flush_to_disk();
}
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
/* Archiving is always off under MySQL */ /* Archiving is always off under MySQL */
......
...@@ -332,11 +332,19 @@ trx_savept_take( ...@@ -332,11 +332,19 @@ trx_savept_take(
Rollback or clean up transactions which have no user session. If the Rollback or clean up transactions which have no user session. If the
transaction already was committed, then we clean up a possible insert transaction already was committed, then we clean up a possible insert
undo log. If the transaction was not yet committed, then we roll it back. undo log. If the transaction was not yet committed, then we roll it back.
Note: this is done in a background thread */ Note: this is done in a background thread. */
void * #ifndef __WIN__
trx_rollback_or_clean_all_without_sess(void *i) void*
/*========================================*/ #else
ulint
#endif
trx_rollback_or_clean_all_without_sess(
/*===================================*/
/* out: a dummy parameter */
void* arg __attribute__((unused)))
/* in: a dummy parameter required by
os_thread_create */
{ {
mem_heap_t* heap; mem_heap_t* heap;
que_fork_t* fork; que_fork_t* fork;
...@@ -361,9 +369,9 @@ trx_rollback_or_clean_all_without_sess(void *i) ...@@ -361,9 +369,9 @@ trx_rollback_or_clean_all_without_sess(void *i)
if (UT_LIST_GET_FIRST(trx_sys->trx_list)) { if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Starting rollback of uncommitted transactions\n"); "InnoDB: Starting in background the rollback of uncommitted transactions\n");
} else { } else {
os_thread_exit(i); goto leave_function;
} }
loop: loop:
heap = mem_heap_create(512); heap = mem_heap_create(512);
...@@ -373,7 +381,6 @@ trx_rollback_or_clean_all_without_sess(void *i) ...@@ -373,7 +381,6 @@ trx_rollback_or_clean_all_without_sess(void *i)
trx = UT_LIST_GET_FIRST(trx_sys->trx_list); trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
while (trx) { while (trx) {
if ((trx->sess || (trx->conc_state == TRX_NOT_STARTED))) { if ((trx->sess || (trx->conc_state == TRX_NOT_STARTED))) {
trx = UT_LIST_GET_NEXT(trx_list, trx); trx = UT_LIST_GET_NEXT(trx_list, trx);
} else if (trx->conc_state == TRX_PREPARED) { } else if (trx->conc_state == TRX_PREPARED) {
...@@ -386,17 +393,17 @@ trx_rollback_or_clean_all_without_sess(void *i) ...@@ -386,17 +393,17 @@ trx_rollback_or_clean_all_without_sess(void *i)
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
if (trx == NULL) { if (trx == NULL) {
ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
"InnoDB: Rollback of uncommitted transactions completed\n"); " InnoDB: Rollback of uncommitted transactions completed\n");
mem_heap_free(heap); mem_heap_free(heap);
os_thread_exit(i); goto leave_function;
} }
trx->sess = trx_dummy_sess; trx->sess = trx_dummy_sess;
if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) { if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) {
fprintf(stderr, "InnoDB: Cleaning up trx with id %lu %lu\n", fprintf(stderr, "InnoDB: Cleaning up trx with id %lu %lu\n",
(ulong) ut_dulint_get_high(trx->id), (ulong) ut_dulint_get_high(trx->id),
...@@ -428,13 +435,15 @@ trx_rollback_or_clean_all_without_sess(void *i) ...@@ -428,13 +435,15 @@ trx_rollback_or_clean_all_without_sess(void *i)
trx_roll_max_undo_no = ut_conv_dulint_to_longlong(trx->undo_no); trx_roll_max_undo_no = ut_conv_dulint_to_longlong(trx->undo_no);
trx_roll_progress_printed_pct = 0; trx_roll_progress_printed_pct = 0;
rows_to_undo = trx_roll_max_undo_no; rows_to_undo = trx_roll_max_undo_no;
if (rows_to_undo > 1000000000) { if (rows_to_undo > 1000000000) {
rows_to_undo = rows_to_undo / 1000000; rows_to_undo = rows_to_undo / 1000000;
unit = "M"; unit = "M";
} }
ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
"InnoDB: Rolling back trx with id %lu %lu, %lu%s rows to undo", " InnoDB: Rolling back trx with id %lu %lu, %lu%s rows to undo",
(ulong) ut_dulint_get_high(trx->id), (ulong) ut_dulint_get_high(trx->id),
(ulong) ut_dulint_get_low(trx->id), (ulong) ut_dulint_get_low(trx->id),
(ulong) rows_to_undo, unit); (ulong) rows_to_undo, unit);
...@@ -454,7 +463,7 @@ trx_rollback_or_clean_all_without_sess(void *i) ...@@ -454,7 +463,7 @@ trx_rollback_or_clean_all_without_sess(void *i)
fprintf(stderr, fprintf(stderr,
"InnoDB: Waiting for rollback of trx id %lu to end\n", "InnoDB: Waiting for rollback of trx id %lu to end\n",
(ulong) ut_dulint_get_low(trx->id)); (ulong) ut_dulint_get_low(trx->id));
os_thread_sleep(100000); os_thread_sleep(100000);
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
...@@ -495,7 +504,19 @@ trx_rollback_or_clean_all_without_sess(void *i) ...@@ -495,7 +504,19 @@ trx_rollback_or_clean_all_without_sess(void *i)
goto loop; goto loop;
os_thread_exit(i); /* not reached */ leave_function:
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
/* The following is dummy code to keep the compiler happy: */
#ifndef __WIN__
return(NULL);
#else
return(0);
#endif
} }
/*********************************************************************** /***********************************************************************
...@@ -856,16 +877,17 @@ trx_roll_pop_top_rec_of_trx( ...@@ -856,16 +877,17 @@ trx_roll_pop_top_rec_of_trx(
ut_ad(ut_dulint_cmp(ut_dulint_add(undo_no, 1), trx->undo_no) == 0); ut_ad(ut_dulint_cmp(ut_dulint_add(undo_no, 1), trx->undo_no) == 0);
/* We print rollback progress info if we are in a crash recovery /* We print rollback progress info if we are in a crash recovery
and the transaction has at least 1000 row operations to undo */ and the transaction has at least 1000 row operations to undo.
Transactions in crash recovery have sess == NULL. */
if (srv_is_being_started && trx_roll_max_undo_no > 1000) { if (trx->sess == NULL && trx_roll_max_undo_no > 1000) {
progress_pct = 100 - (ulint) progress_pct = 100 - (ulint)
((ut_conv_dulint_to_longlong(undo_no) * 100) ((ut_conv_dulint_to_longlong(undo_no) * 100)
/ trx_roll_max_undo_no); / trx_roll_max_undo_no);
if (progress_pct != trx_roll_progress_printed_pct) { if (progress_pct != trx_roll_progress_printed_pct) {
if (trx_roll_progress_printed_pct == 0) { if (trx_roll_progress_printed_pct == 0) {
fprintf(stderr, fprintf(stderr,
"\nInnoDB: Progress in percents: %lu", (ulong) progress_pct); "\nInnoDB: Progress in percents: %lu", (ulong) progress_pct);
} else { } else {
fprintf(stderr, fprintf(stderr,
" %lu", (ulong) progress_pct); " %lu", (ulong) progress_pct);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment