diff options
author | unknown <heikki@hundin.mysql.fi> | 2003-05-03 19:44:46 +0300 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2003-05-03 19:44:46 +0300 |
commit | 1d64ab5e4705207196d6ff34f866a1070d49f108 (patch) | |
tree | 090aa4a3684b09f490196ae728350fb47902b311 /innobase/srv | |
parent | 18409f75dc3dc5f36fc0a60d6f3eea83f20ee434 (diff) | |
download | mariadb-git-1d64ab5e4705207196d6ff34f866a1070d49f108.tar.gz |
buf0buf.c, srv0srv.h, buf0buf.h, srv0srv.c:
Clean up the working of the main thread; add a tunable parameter srv_max_buf_pool_modified_pct which can be used to make the flush phase in shutdown quicker
innobase/srv/srv0srv.c:
Clean up the working of the main thread; add a tunable parameter srv_max_buf_pool_modified_pct which can be used to make the flush phase in shutdown quicker
innobase/include/buf0buf.h:
Clean up the working of the main thread; add a tunable parameter srv_max_buf_pool_modified_pct which can be used to make the flush phase in shutdown quicker
innobase/include/srv0srv.h:
Clean up the working of the main thread; add a tunable parameter srv_max_buf_pool_modified_pct which can be used to make the flush phase in shutdown quicker
innobase/buf/buf0buf.c:
Clean up the working of the main thread; add a tunable parameter srv_max_buf_pool_modified_pct which can be used to make the flush phase in shutdown quicker
Diffstat (limited to 'innobase/srv')
-rw-r--r-- | innobase/srv/srv0srv.c | 114 |
1 files changed, 86 insertions, 28 deletions
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 07df708e5fb..97841056b1e 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -157,6 +157,13 @@ char* srv_file_flush_method_str = NULL; ulint srv_unix_file_flush_method = SRV_UNIX_FDATASYNC; ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED; +/* The InnoDB main thread tries to keep the ratio of modified pages +in the buffer pool to all database pages in the buffer pool smaller than +the following number. But it is not guaranteed that the value stays below +that during a time of heavy update/insert activity. */ + +ulint srv_max_buf_pool_modified_pct = 30; + /* If the following is != 0 we do not allow inserts etc. This protects the user from forgetting the innodb_force_recovery keyword to my.cnf */ @@ -2770,16 +2777,29 @@ srv_master_thread( os_event_set(srv_sys->operational); loop: + /*****************************************************************/ + /* ---- When there is database activity by users, we cycle in this + loop */ + srv_main_thread_op_info = (char*) "reserving kernel mutex"; n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read + buf_pool->n_pages_written; mutex_enter(&kernel_mutex); + /* Store the user activity counter at the start of this loop */ old_activity_count = srv_activity_count; mutex_exit(&kernel_mutex); + if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) { + + goto suspend_thread; + } + + /* ---- We run the following loop approximately once per second + when there is database activity */ + for (i = 0; i < 10; i++) { n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read + buf_pool->n_pages_written; @@ -2797,11 +2817,6 @@ loop: srv_main_thread_op_info = (char*)""; - if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) { - - goto suspend_thread; - } - if (srv_fast_shutdown && srv_shutdown_state > 0) { goto background_loop; @@ -2814,7 +2829,7 @@ loop: srv_main_thread_op_info = (char*)"flushing log"; log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); - /* If there were less than 10 i/os during the + /* If there were less than 5 i/os during the one second sleep, we assume that there is free disk i/o capacity available, and it makes sense to do an insert buffer merge. */ @@ -2823,7 +2838,7 @@ loop: + log_sys->n_pending_writes; n_ios = log_sys->n_log_ios + buf_pool->n_pages_read + buf_pool->n_pages_written; - if (n_pend_ios < 3 && (n_ios - n_ios_old < 10)) { + if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) { srv_main_thread_op_info = (char*)"doing insert buffer merge"; ibuf_contract_for_n_pages(TRUE, 5); @@ -2834,19 +2849,27 @@ loop: TRUE); } + if (buf_get_modified_ratio_pct() > + srv_max_buf_pool_modified_pct) { + + /* Try to keep the number of modified pages in the + buffer pool under the limit wished by the user */ + + n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, + ut_dulint_max); + } + if (srv_activity_count == old_activity_count) { - if (srv_print_thread_releases) { - printf("Master thread wakes up!\n"); - } + /* There is no user activity at the moment, go to + the background loop */ goto background_loop; } } - if (srv_print_thread_releases) { - printf("Master thread wakes up!\n"); - } + /* ---- We perform the following code approximately once per + 10 seconds when there is database activity */ #ifdef MEM_PERIODIC_CHECK /* Check magic numbers of every allocated mem block once in 10 @@ -2855,7 +2878,7 @@ loop: #endif /* If there were less than 200 i/os during the 10 second period, we assume that there is free disk i/o capacity available, and it - makes sense to do a buffer pool flush. */ + makes sense to flush 100 pages. */ n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes; n_ios = log_sys->n_log_ios + buf_pool->n_pages_read @@ -2905,25 +2928,24 @@ loop: last_flush_time = current_time; } } - -background_loop: - /* In this loop we run background operations when the server - is quiet and we also come here about once in 10 seconds */ - - srv_main_thread_op_info = (char*)"doing background drop tables"; - - n_tables_to_drop = row_drop_tables_for_mysql_in_background(); - - srv_main_thread_op_info = (char*)""; srv_main_thread_op_info = (char*)"flushing buffer pool pages"; - /* Flush a few oldest pages to make the checkpoint younger */ + /* Flush a few oldest pages to make a new checkpoint younger */ + + if (buf_get_modified_ratio_pct() > 70) { + + /* If there are lots of modified pages in the buffer pool + (> 70 %), we assume we can afford reserving the disk(s) for + the time it requires to flush 100 pages */ - if (srv_fast_shutdown && srv_shutdown_state > 0) { n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max); } else { + /* Otherwise, we only flush a small number of pages so that + we do not unnecessarily use much disk i/o capacity from + other work */ + n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, ut_dulint_max); } @@ -2937,16 +2959,31 @@ background_loop: srv_main_thread_op_info = (char*)"reserving kernel mutex"; mutex_enter(&kernel_mutex); + + /* ---- When there is database activity, we jump from here back to + the start of loop */ + if (srv_activity_count != old_activity_count) { mutex_exit(&kernel_mutex); goto loop; } - old_activity_count = srv_activity_count; + mutex_exit(&kernel_mutex); + /* If the database is quiet, we enter the background loop */ + + /*****************************************************************/ +background_loop: + /* ---- In this loop we run background operations when the server + is quiet from user activity */ + /* The server has been quiet for a while: start running background operations */ + srv_main_thread_op_info = (char*)"doing background drop tables"; + + n_tables_to_drop = row_drop_tables_for_mysql_in_background(); + srv_main_thread_op_info = (char*)"purging"; if (srv_fast_shutdown && srv_shutdown_state > 0) { @@ -2981,6 +3018,7 @@ background_loop: } mutex_exit(&kernel_mutex); +flush_loop: srv_main_thread_op_info = (char*)"flushing buffer pool pages"; n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max); @@ -3001,6 +3039,14 @@ background_loop: log_checkpoint(TRUE, FALSE); + if (buf_get_modified_ratio_pct() > srv_max_buf_pool_modified_pct) { + + /* Try to keep the number of modified pages in the + buffer pool under the limit wished by the user */ + + goto flush_loop; + } + srv_main_thread_op_info = (char*)"reserving kernel mutex"; mutex_enter(&kernel_mutex); @@ -3015,15 +3061,24 @@ background_loop: log_archive_do(FALSE, &n_bytes_archived); + /* Keep looping in the background loop if still work to do */ + if (srv_fast_shutdown && srv_shutdown_state > 0) { if (n_tables_to_drop + n_pages_flushed + n_bytes_archived != 0) { + /* If we are doing a fast shutdown (= the default) + we do not do purge or insert buffer merge. But we + flush the buffer pool completely to disk. */ + goto background_loop; } } else if (n_tables_to_drop + - n_pages_purged + n_bytes_merged + n_pages_flushed + n_pages_purged + n_bytes_merged + n_pages_flushed + n_bytes_archived != 0) { + /* In a 'slow' shutdown we run purge and the insert buffer + merge to completion */ + goto background_loop; } @@ -3055,6 +3110,9 @@ suspend_thread: os_event_wait(event); + /* When there is user activity, InnoDB will set the event and the main + thread goes back to loop: */ + goto loop; #ifndef __WIN__ |