2091
2146
pfs_register_thread(srv_monitor_thread_key);
2095
srv_last_monitor_time = time(NULL);
2096
last_table_monitor_time = time(NULL);
2097
last_tablespace_monitor_time = time(NULL);
2098
last_monitor_time = time(NULL);
2149
srv_last_monitor_time = ut_time();
2150
last_table_monitor_time = ut_time();
2151
last_tablespace_monitor_time = ut_time();
2152
last_monitor_time = ut_time();
2099
2153
mutex_skipped = 0;
2100
2154
last_srv_print_monitor = srv_print_innodb_monitor;
2102
2156
srv_monitor_active = TRUE;
2104
2158
/* Wake up every 5 seconds to see if we need to print
2105
monitor information. */
2107
os_thread_sleep(5000000);
2109
current_time = time(NULL);
2159
monitor information or if signalled at shutdown. */
2161
sig_count = os_event_reset(srv_monitor_event);
2163
os_event_wait_time_low(srv_monitor_event, 5000000, sig_count);
2165
current_time = ut_time();
2111
2167
time_elapsed = difftime(current_time, last_monitor_time);
2113
2169
if (time_elapsed > 15) {
2114
last_monitor_time = time(NULL);
2170
last_monitor_time = ut_time();
2116
2172
if (srv_print_innodb_monitor) {
2117
2173
/* Reset mutex_skipped counter everytime
2437
2496
OS_THREAD_DUMMY_RETURN;
2499
/*********************************************************************//**
2500
A thread which restores the buffer pool from a dump file on startup and does
2501
periodic buffer pool dumps.
2502
@return a dummy parameter */
2505
srv_LRU_dump_restore_thread(
2506
/*====================*/
2507
void* /*arg __attribute__((unused))*/)
2508
/*!< in: a dummy parameter required by
2512
time_t last_dump_time;
2513
time_t time_elapsed;
2515
#ifdef UNIV_DEBUG_THREAD_CREATION
2516
fprintf(stderr, "The LRU dump/restore thread has started, id %lu\n",
2517
os_thread_pf(os_thread_get_curr_id()));
2520
if (srv_auto_lru_dump)
2521
buf_LRU_file_restore();
2523
last_dump_time = time(NULL);
2526
os_thread_sleep(5000000);
2528
if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
2532
time_elapsed = time(NULL) - last_dump_time;
2533
auto_lru_dump = srv_auto_lru_dump;
2534
if (auto_lru_dump > 0 && (time_t) auto_lru_dump < time_elapsed) {
2535
last_dump_time = time(NULL);
2536
buf_LRU_file_dump();
2541
/* We count the number of threads in os_thread_exit(). A created
2542
thread should always use that to exit and not use return() to exit. */
2544
os_thread_exit(NULL);
2546
OS_THREAD_DUMMY_RETURN;
2440
2549
/**********************************************************************//**
2441
2550
Check whether any background thread is active.
2442
2551
@return FALSE if all are are suspended or have exited. */
2668
2794
/* Sleep for 1 second on entrying the for loop below the first time. */
2669
2795
next_itr_time = ut_time_ms() + 1000;
2671
2799
for (i = 0; i < 10; i++) {
2672
2800
ulint cur_time = ut_time_ms();
2674
buf_get_total_stat(&buf_stat);
2676
n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
2677
+ buf_stat.n_pages_written;
2679
srv_main_thread_op_info = "sleeping";
2680
srv_main_1_second_loops++;
2682
if (next_itr_time > cur_time) {
2684
/* Get sleep interval in micro seconds. We use
2685
ut_min() to avoid long sleep in case of
2687
os_thread_sleep(ut_min(1000000,
2688
(next_itr_time - cur_time)
2693
/* Each iteration should happen at 1 second interval. */
2694
next_itr_time = ut_time_ms() + 1000;
2802
n_pages_flushed = 0;
2696
2804
/* ALTER TABLE in MySQL requires on Unix that the table handler
2697
2805
can drop tables lazily after there no longer are SELECT
2708
2816
goto background_loop;
2819
buf_get_total_stat(&buf_stat);
2821
n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
2822
+ buf_stat.n_pages_written;
2824
srv_main_thread_op_info = "sleeping";
2825
srv_main_1_second_loops++;
2827
if (skip_sleep == false) {
2828
if (next_itr_time > cur_time
2829
&& srv_shutdown_state == SRV_SHUTDOWN_NONE) {
2831
/* Get sleep interval in micro seconds. We use
2832
ut_min() to avoid long sleep in case of
2834
os_thread_sleep(ut_min(1000000,
2835
(next_itr_time - cur_time)
2840
TODO: tracing code unported to Drizzle
2841
mutex_enter(&(log_sys->mutex));
2842
oldest_lsn = buf_pool_get_oldest_modification();
2843
ib_uint64_t lsn = log_sys->lsn;
2844
mutex_exit(&(log_sys->mutex));
2848
"InnoDB flush: age pct: %lu, lsn progress: %lu\n",
2849
(lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
2855
/* Each iteration should happen at 1 second interval. */
2856
next_itr_time = ut_time_ms() + 1000;
2711
2861
/* Flush logs if needed */
2712
2862
srv_sync_log_buffer_in_background();
2760
2915
IB_ULONGLONG_MAX);
2918
mutex_enter(&(log_sys->mutex));
2919
lsn_old = log_sys->lsn;
2920
mutex_exit(&(log_sys->mutex));
2921
prev_adaptive_flushing_method = ULINT32_UNDEFINED;
2922
} else if (srv_adaptive_flushing
2923
&& srv_adaptive_flushing_method == 1) {
2925
/* Try to keep modified age not to exceed
2926
max_checkpoint_age * 7/8 line */
2928
mutex_enter(&(log_sys->mutex));
2930
oldest_lsn = buf_pool_get_oldest_modification();
2931
if (oldest_lsn == 0) {
2932
lsn_old = log_sys->lsn;
2933
mutex_exit(&(log_sys->mutex));
2936
if ((log_sys->lsn - oldest_lsn)
2937
> (log_sys->max_checkpoint_age)
2938
- ((log_sys->max_checkpoint_age) / 8)) {
2939
/* LOG_POOL_PREFLUSH_RATIO_ASYNC is exceeded. */
2940
/* We should not flush from here. */
2941
lsn_old = log_sys->lsn;
2942
mutex_exit(&(log_sys->mutex));
2943
} else if ((log_sys->lsn - oldest_lsn)
2944
> (log_sys->max_checkpoint_age)/4) {
2946
/* defence line (max_checkpoint_age * 1/2) */
2947
uint64_t lsn = log_sys->lsn;
2949
uint64_t level, bpl;
2953
mutex_exit(&(log_sys->mutex));
2957
for (j = 0; j < srv_buf_pool_instances; j++) {
2958
buf_pool_t* buf_pool;
2959
uint32_t n_blocks = 0;
2961
buf_pool = buf_pool_from_array(j);
2963
/* The scanning flush_list is optimistic here */
2966
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
2968
while (bpage != NULL) {
2969
uint64_t oldest_modification = bpage->oldest_modification;
2970
if (oldest_modification != 0) {
2971
level += log_sys->max_checkpoint_age
2972
- (lsn - oldest_modification);
2974
bpage = UT_LIST_GET_NEXT(list, bpage);
2979
bpl += ((ib_uint64_t) n_blocks * n_blocks
2980
* (lsn - lsn_old)) / level;
2985
if (!srv_use_doublewrite_buf) {
2986
/* flush is faster than when doublewrite */
2987
bpl = (bpl * 7) / 8;
2992
n_pages_flushed = buf_flush_list(bpl,
2993
oldest_lsn + (lsn - lsn_old));
2994
if (n_pages_flushed == ULINT32_UNDEFINED) {
2995
os_thread_sleep(5000);
2996
goto retry_flush_batch;
3002
TODO: tracing code unported to Drizzle
3004
"InnoDB flush: age pct: %lu, lsn progress: %lu, blocks to flush:%llu\n",
3005
(lsn - oldest_lsn) * 100 / log_sys->max_checkpoint_age,
3006
lsn - lsn_old, bpl);
3009
lsn_old = log_sys->lsn;
3010
mutex_exit(&(log_sys->mutex));
3013
prev_adaptive_flushing_method = 1;
3014
} else if (srv_adaptive_flushing && srv_adaptive_flushing_method == 2) {
3015
buf_pool_t* buf_pool;
3020
mutex_enter(&(log_sys->mutex));
3021
oldest_lsn = buf_pool_get_oldest_modification();
3023
mutex_exit(&(log_sys->mutex));
3025
/* upper loop/sec. (x10) */
3026
next_itr_time -= 900; /* 1000 - 900 == 100 */
3028
if (inner_loop < 10) {
3034
if (prev_adaptive_flushing_method == 2) {
3036
int32_t blocks_sum = 0;
3037
uint32_t new_blocks_sum = 0;
3038
uint32_t flushed_blocks_sum = 0;
3040
/* prev_flush_info[j] should be the previous loop's */
3041
for (j = 0; j < srv_buf_pool_instances; j++) {
3042
int32_t blocks_num, new_blocks_num, flushed_blocks_num;
3045
buf_pool = buf_pool_from_array(j);
3047
blocks_num = UT_LIST_GET_LEN(buf_pool->flush_list);
3048
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
3051
while (bpage != NULL) {
3052
if (prev_flush_info[j].space == bpage->space
3053
&& prev_flush_info[j].offset == bpage->offset
3054
&& prev_flush_info[j].oldest_modification
3055
== bpage->oldest_modification) {
3059
bpage = UT_LIST_GET_NEXT(list, bpage);
3063
new_blocks_num = blocks_num;
3065
flushed_blocks_num = new_blocks_num
3066
+ prev_flush_info[j].count
3068
if (flushed_blocks_num < 0) {
3069
flushed_blocks_num = 0;
3072
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
3074
prev_flush_info[j].count = UT_LIST_GET_LEN(buf_pool->flush_list);
3076
prev_flush_info[j].space = bpage->space;
3077
prev_flush_info[j].offset = bpage->offset;
3078
prev_flush_info[j].oldest_modification = bpage->oldest_modification;
3080
prev_flush_info[j].space = 0;
3081
prev_flush_info[j].offset = 0;
3082
prev_flush_info[j].oldest_modification = 0;
3085
new_blocks_sum += new_blocks_num;
3086
flushed_blocks_sum += flushed_blocks_num;
3087
blocks_sum += blocks_num;
3090
n_flush = blocks_sum * (lsn - lsn_old) / log_sys->max_modified_age_async;
3091
if (flushed_blocks_sum > n_pages_flushed_prev) {
3092
n_flush -= (flushed_blocks_sum - n_pages_flushed_prev);
3097
n_pages_flushed = buf_flush_list(n_flush, oldest_lsn + (lsn - lsn_old));
3099
n_pages_flushed = 0;
3102
/* store previous first pages of the flush_list */
3103
for (j = 0; j < srv_buf_pool_instances; j++) {
3104
buf_pool = buf_pool_from_array(j);
3106
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
3108
prev_flush_info[j].count = UT_LIST_GET_LEN(buf_pool->flush_list);
3110
prev_flush_info[j].space = bpage->space;
3111
prev_flush_info[j].offset = bpage->offset;
3112
prev_flush_info[j].oldest_modification = bpage->oldest_modification;
3114
prev_flush_info[j].space = 0;
3115
prev_flush_info[j].offset = 0;
3116
prev_flush_info[j].oldest_modification = 0;
3119
n_pages_flushed = 0;
3123
prev_adaptive_flushing_method = 2;
3125
mutex_enter(&(log_sys->mutex));
3126
lsn_old = log_sys->lsn;
3127
mutex_exit(&(log_sys->mutex));
3128
prev_adaptive_flushing_method = ULINT32_UNDEFINED;
3131
if (n_pages_flushed == ULINT_UNDEFINED) {
3132
n_pages_flushed_prev = 0;
3134
n_pages_flushed_prev = n_pages_flushed;
2764
3137
if (srv_activity_count == old_activity_count) {