2468
2489
OS_THREAD_DUMMY_RETURN;
2492
/*********************************************************************//**
2493
A thread which restores the buffer pool from a dump file on startup and does
2494
periodic buffer pool dumps.
2495
@return a dummy parameter */
2498
srv_LRU_dump_restore_thread(
2499
/*====================*/
2500
void* /*arg __attribute__((unused))*/)
2501
/*!< in: a dummy parameter required by
2505
time_t last_dump_time;
2506
time_t time_elapsed;
2508
#ifdef UNIV_DEBUG_THREAD_CREATION
2509
fprintf(stderr, "The LRU dump/restore thread has started, id %lu\n",
2510
os_thread_pf(os_thread_get_curr_id()));
2513
if (srv_auto_lru_dump)
2514
buf_LRU_file_restore();
2516
last_dump_time = time(NULL);
2519
os_thread_sleep(5000000);
2521
if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
2525
time_elapsed = time(NULL) - last_dump_time;
2526
auto_lru_dump = srv_auto_lru_dump;
2527
if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
2528
last_dump_time = time(NULL);
2529
buf_LRU_file_dump();
2534
/* We count the number of threads in os_thread_exit(). A created
2535
thread should always use that to exit and not use return() to exit. */
2537
os_thread_exit(NULL);
2539
OS_THREAD_DUMMY_RETURN;
2471
2542
/**********************************************************************//**
2472
2543
Check whether any background thread is active.
2473
2544
@return FALSE if all are are suspended or have exited. */
2725
2817
srv_main_thread_op_info = "sleeping";
2726
2818
srv_main_1_second_loops++;
2728
if (next_itr_time > cur_time
2729
&& srv_shutdown_state == SRV_SHUTDOWN_NONE) {
2820
if (skip_sleep == false) {
2821
if (next_itr_time > cur_time
2822
&& srv_shutdown_state == SRV_SHUTDOWN_NONE) {
2731
2824
/* Get sleep interval in micro seconds. We use
2732
ut_min() to avoid long sleep in case of
2825
ut_min() to avoid long sleep in case of
2734
2827
os_thread_sleep(ut_min(1000000,
2735
(next_itr_time - cur_time)
2828
(next_itr_time - cur_time)
2737
2830
srv_main_sleeps++;
2833
TODO: tracing code unported to Drizzle
2834
mutex_enter(&(log_sys->mutex));
2835
oldest_lsn = buf_pool_get_oldest_modification();
2836
ib_uint64_t lsn = log_sys->lsn;
2837
mutex_exit(&(log_sys->mutex));
2841
"InnoDB flush: age pct: %lu, lsn progress: %lu\n",
2842
(lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
2848
/* Each iteration should happen at 1 second interval. */
2849
next_itr_time = ut_time_ms() + 1000;
2740
/* Each iteration should happen at 1 second interval. */
2741
next_itr_time = ut_time_ms() + 1000;
2743
2854
/* Flush logs if needed */
2744
2855
srv_sync_log_buffer_in_background();
2792
2908
IB_ULONGLONG_MAX);
2911
mutex_enter(&(log_sys->mutex));
2912
lsn_old = log_sys->lsn;
2913
mutex_exit(&(log_sys->mutex));
2914
prev_adaptive_flushing_method = ULINT32_UNDEFINED;
2915
} else if (srv_adaptive_flushing
2916
&& srv_adaptive_flushing_method == 1) {
2918
/* Try to keep modified age not to exceed
2919
max_checkpoint_age * 7/8 line */
2921
mutex_enter(&(log_sys->mutex));
2923
oldest_lsn = buf_pool_get_oldest_modification();
2924
if (oldest_lsn == 0) {
2925
lsn_old = log_sys->lsn;
2926
mutex_exit(&(log_sys->mutex));
2929
if ((log_sys->lsn - oldest_lsn)
2930
> (log_sys->max_checkpoint_age)
2931
- ((log_sys->max_checkpoint_age) / 8)) {
2932
/* LOG_POOL_PREFLUSH_RATIO_ASYNC is exceeded. */
2933
/* We should not flush from here. */
2934
lsn_old = log_sys->lsn;
2935
mutex_exit(&(log_sys->mutex));
2936
} else if ((log_sys->lsn - oldest_lsn)
2937
> (log_sys->max_checkpoint_age)/4) {
2939
/* defence line (max_checkpoint_age * 1/2) */
2940
uint64_t lsn = log_sys->lsn;
2942
uint64_t level, bpl;
2946
mutex_exit(&(log_sys->mutex));
2950
for (j = 0; j < srv_buf_pool_instances; j++) {
2951
buf_pool_t* buf_pool;
2952
uint32_t n_blocks = 0;
2954
buf_pool = buf_pool_from_array(j);
2956
/* The scanning flush_list is optimistic here */
2959
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
2961
while (bpage != NULL) {
2962
uint64_t oldest_modification = bpage->oldest_modification;
2963
if (oldest_modification != 0) {
2964
level += log_sys->max_checkpoint_age
2965
- (lsn - oldest_modification);
2967
bpage = UT_LIST_GET_NEXT(list, bpage);
2972
bpl += ((ib_uint64_t) n_blocks * n_blocks
2973
* (lsn - lsn_old)) / level;
2978
if (!srv_use_doublewrite_buf) {
2979
/* flush is faster than when doublewrite */
2980
bpl = (bpl * 7) / 8;
2985
n_pages_flushed = buf_flush_list(bpl,
2986
oldest_lsn + (lsn - lsn_old));
2987
if (n_pages_flushed == ULINT32_UNDEFINED) {
2988
os_thread_sleep(5000);
2989
goto retry_flush_batch;
2995
TODO: tracing code unported to Drizzle
2997
"InnoDB flush: age pct: %lu, lsn progress: %lu, blocks to flush:%llu\n",
2998
(lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
2999
lsn - lsn_old, bpl);
3002
lsn_old = log_sys->lsn;
3003
mutex_exit(&(log_sys->mutex));
3006
prev_adaptive_flushing_method = 1;
3007
} else if (srv_adaptive_flushing && srv_adaptive_flushing_method == 2) {
3008
buf_pool_t* buf_pool;
3013
mutex_enter(&(log_sys->mutex));
3014
oldest_lsn = buf_pool_get_oldest_modification();
3016
mutex_exit(&(log_sys->mutex));
3018
/* upper loop/sec. (x10) */
3019
next_itr_time -= 900; /* 1000 - 900 == 100 */
3021
if (inner_loop < 10) {
3027
if (prev_adaptive_flushing_method == 2) {
3029
int32_t blocks_sum = 0;
3030
uint32_t new_blocks_sum = 0;
3031
uint32_t flushed_blocks_sum = 0;
3033
/* prev_flush_info[j] should be the previous loop's */
3034
for (j = 0; j < srv_buf_pool_instances; j++) {
3035
int32_t blocks_num, new_blocks_num, flushed_blocks_num;
3038
buf_pool = buf_pool_from_array(j);
3040
blocks_num = UT_LIST_GET_LEN(buf_pool->flush_list);
3041
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
3044
while (bpage != NULL) {
3045
if (prev_flush_info[j].space == bpage->space
3046
&& prev_flush_info[j].offset == bpage->offset
3047
&& prev_flush_info[j].oldest_modification
3048
== bpage->oldest_modification) {
3052
bpage = UT_LIST_GET_NEXT(list, bpage);
3056
new_blocks_num = blocks_num;
3058
flushed_blocks_num = new_blocks_num
3059
+ prev_flush_info[j].count
3061
if (flushed_blocks_num < 0) {
3062
flushed_blocks_num = 0;
3065
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
3067
prev_flush_info[j].count = UT_LIST_GET_LEN(buf_pool->flush_list);
3069
prev_flush_info[j].space = bpage->space;
3070
prev_flush_info[j].offset = bpage->offset;
3071
prev_flush_info[j].oldest_modification = bpage->oldest_modification;
3073
prev_flush_info[j].space = 0;
3074
prev_flush_info[j].offset = 0;
3075
prev_flush_info[j].oldest_modification = 0;
3078
new_blocks_sum += new_blocks_num;
3079
flushed_blocks_sum += flushed_blocks_num;
3080
blocks_sum += blocks_num;
3083
n_flush = blocks_sum * (lsn - lsn_old) / log_sys->max_modified_age_async;
3084
if (flushed_blocks_sum > n_pages_flushed_prev) {
3085
n_flush -= (flushed_blocks_sum - n_pages_flushed_prev);
3090
n_pages_flushed = buf_flush_list(n_flush, oldest_lsn + (lsn - lsn_old));
3092
n_pages_flushed = 0;
3095
/* store previous first pages of the flush_list */
3096
for (j = 0; j < srv_buf_pool_instances; j++) {
3097
buf_pool = buf_pool_from_array(j);
3099
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
3101
prev_flush_info[j].count = UT_LIST_GET_LEN(buf_pool->flush_list);
3103
prev_flush_info[j].space = bpage->space;
3104
prev_flush_info[j].offset = bpage->offset;
3105
prev_flush_info[j].oldest_modification = bpage->oldest_modification;
3107
prev_flush_info[j].space = 0;
3108
prev_flush_info[j].offset = 0;
3109
prev_flush_info[j].oldest_modification = 0;
3112
n_pages_flushed = 0;
3116
prev_adaptive_flushing_method = 2;
3118
mutex_enter(&(log_sys->mutex));
3119
lsn_old = log_sys->lsn;
3120
mutex_exit(&(log_sys->mutex));
3121
prev_adaptive_flushing_method = ULINT32_UNDEFINED;
3124
if (n_pages_flushed == ULINT_UNDEFINED) {
3125
n_pages_flushed_prev = 0;
3127
n_pages_flushed_prev = n_pages_flushed;
2796
3130
if (srv_activity_count == old_activity_count) {