Commit 54abde5e authored by Mikael Ronstrom's avatar Mikael Ronstrom

Google IO rate patch with a portability fix

parent 9daa56fd
...@@ -133,6 +133,13 @@ static my_bool innobase_adaptive_hash_index = TRUE; ...@@ -133,6 +133,13 @@ static my_bool innobase_adaptive_hash_index = TRUE;
static char* internal_innobase_data_file_path = NULL; static char* internal_innobase_data_file_path = NULL;
/* Default number of IO per second supported by server. Tunes background
IO rate. */
static long innobase_io_capacity = 100;
/* Write dirty pages when pct dirty is less than max pct dirty */
static my_bool innobase_extra_dirty_writes = TRUE;
/* The following counter is used to convey information to InnoDB /* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call about server activity: in selects it is not sensible to call
srv_active_wake_master_thread after each fetch or search, we only do srv_active_wake_master_thread after each fetch or search, we only do
...@@ -1586,6 +1593,9 @@ innobase_init( ...@@ -1586,6 +1593,9 @@ innobase_init(
#endif /* UNIV_LOG_ARCHIVE */ #endif /* UNIV_LOG_ARCHIVE */
srv_log_buffer_size = (ulint) innobase_log_buffer_size; srv_log_buffer_size = (ulint) innobase_log_buffer_size;
srv_io_capacity = (ulint) innobase_io_capacity;
srv_extra_dirty_writes = (ulint) innobase_extra_dirty_writes;
/* We set srv_pool_size here in units of 1 kB. InnoDB internally /* We set srv_pool_size here in units of 1 kB. InnoDB internally
changes the value so that it becomes the number of database pages. */ changes the value so that it becomes the number of database pages. */
...@@ -8010,6 +8020,16 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite, ...@@ -8010,6 +8020,16 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.", "Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE); NULL, NULL, TRUE);
static MYSQL_SYSVAR_BOOL(extra_dirty_writes, innobase_extra_dirty_writes,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Flush dirty buffer pages when dirty max pct is not exceeded",
NULL, NULL, TRUE);
static MYSQL_SYSVAR_LONG(io_capacity, innobase_io_capacity,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Number of IOPs the server can do. Tunes the background IO rate",
NULL, NULL, 100, 100, ~0L, 0);
static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown, static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
PLUGIN_VAR_OPCMDARG, PLUGIN_VAR_OPCMDARG,
"Speeds up the shutdown process of the InnoDB storage engine. Possible " "Speeds up the shutdown process of the InnoDB storage engine. Possible "
...@@ -8225,6 +8245,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { ...@@ -8225,6 +8245,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(thread_concurrency), MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_sleep_delay), MYSQL_SYSVAR(thread_sleep_delay),
MYSQL_SYSVAR(autoinc_lock_mode), MYSQL_SYSVAR(autoinc_lock_mode),
MYSQL_SYSVAR(extra_dirty_writes),
MYSQL_SYSVAR(io_capacity),
NULL NULL
}; };
......
...@@ -169,6 +169,13 @@ void ...@@ -169,6 +169,13 @@ void
log_buffer_flush_to_disk(void); log_buffer_flush_to_disk(void);
/*==========================*/ /*==========================*/
/******************************************************************** /********************************************************************
Flushes the log buffer. Forces it to disk depending on the value of
the configuration parameter innodb_flush_log_at_trx_commit. */
void
log_buffer_flush_maybe_sync(void);
/*==========================*/
/********************************************************************
Advances the smallest lsn for which there are unflushed dirty blocks in the Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool and also may make a new checkpoint. NOTE: this function may only buffer pool and also may make a new checkpoint. NOTE: this function may only
be called if the calling thread owns no synchronization objects! */ be called if the calling thread owns no synchronization objects! */
......
...@@ -91,6 +91,14 @@ extern ulint srv_lock_table_size; ...@@ -91,6 +91,14 @@ extern ulint srv_lock_table_size;
extern ulint srv_n_file_io_threads; extern ulint srv_n_file_io_threads;
/* Number of IO operations per second the server can do */
extern ulint srv_io_capacity;
/* Flush dirty pages when below max dirty percent */
extern ibool srv_extra_dirty_writes;
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
extern ibool srv_log_archive_on; extern ibool srv_log_archive_on;
extern ibool srv_archive_recovery; extern ibool srv_archive_recovery;
......
...@@ -1516,6 +1516,26 @@ log_buffer_flush_to_disk(void) ...@@ -1516,6 +1516,26 @@ log_buffer_flush_to_disk(void)
log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE); log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE);
} }
/********************************************************************
Flush the log buffer. Force it to disk depending on the value of
innodb_flush_log_at_trx_commit. */
void
log_buffer_flush_maybe_sync(void)
/*==========================*/
{
dulint lsn;
mutex_enter(&(log_sys->mutex));
lsn = log_sys->lsn;
mutex_exit(&(log_sys->mutex));
/* Force log buffer to disk when innodb_flush_log_at_trx_commit = 1. */
log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS,
srv_flush_log_at_trx_commit == 1 ? TRUE : FALSE);
}
/******************************************************************** /********************************************************************
Tries to establish a big enough margin of free space in the log buffer, such Tries to establish a big enough margin of free space in the log buffer, such
that a new log entry can be catenated without an immediate need for a flush. */ that a new log entry can be catenated without an immediate need for a flush. */
......
...@@ -171,6 +171,12 @@ ulint srv_awe_window_size = 0; /* size in pages; MySQL inits ...@@ -171,6 +171,12 @@ ulint srv_awe_window_size = 0; /* size in pages; MySQL inits
ulint srv_mem_pool_size = ULINT_MAX; /* size in bytes */ ulint srv_mem_pool_size = ULINT_MAX; /* size in bytes */
ulint srv_lock_table_size = ULINT_MAX; ulint srv_lock_table_size = ULINT_MAX;
ulint srv_io_capacity = ULINT_MAX; /* Number of IO operations per
second the server can do */
ibool srv_extra_dirty_writes = TRUE; /* Write dirty pages to disk when pct
dirty < max dirty pct */
ulint srv_n_file_io_threads = ULINT_MAX; ulint srv_n_file_io_threads = ULINT_MAX;
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
...@@ -411,6 +417,30 @@ FILE* srv_misc_tmpfile; ...@@ -411,6 +417,30 @@ FILE* srv_misc_tmpfile;
ulint srv_main_thread_process_no = 0; ulint srv_main_thread_process_no = 0;
ulint srv_main_thread_id = 0; ulint srv_main_thread_id = 0;
// The following count work done by srv_master_thread.
// Iterations by the 'once per second' loop.
ulint srv_main_1_second_loops = 0;
// Calls to sleep by the 'once per second' loop.
ulint srv_main_sleeps = 0;
// Iterations by the 'once per 10 seconds' loop.
ulint srv_main_10_second_loops = 0;
// Iterations of the loop bounded by the 'background_loop' label.
ulint srv_main_background_loops = 0;
// Iterations of the loop bounded by the 'flush_loop' label.
ulint srv_main_flush_loops = 0;
// Calls to log_buffer_flush_to_disk.
ulint srv_sync_flush = 0;
// Calls to log_buffer_flush_maybe_sync.
ulint srv_async_flush = 0;
// Number of microseconds threads wait because of
// innodb_thread_concurrency
static ib_longlong srv_thread_wait_mics = 0;
// Number of microseconds for spinlock delay
static ib_longlong srv_timed_spin_delay = 0;
/* /*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM IMPLEMENTATION OF THE SERVER MAIN PROGRAM
========================================= =========================================
...@@ -630,6 +660,65 @@ are indexed by the type of the thread. */ ...@@ -630,6 +660,65 @@ are indexed by the type of the thread. */
ulint srv_n_threads_active[SRV_MASTER + 1]; ulint srv_n_threads_active[SRV_MASTER + 1];
ulint srv_n_threads[SRV_MASTER + 1]; ulint srv_n_threads[SRV_MASTER + 1];
static void srv_reset_free_tickets(trx_t* trx);
/*************************************************************************
Return the difference in microseconds between 'end' and 'start'
*/
static ib_longlong mics_diff(ulint start_sec, ulint start_usec,
ulint end_sec, ulint end_usec)
{
ib_longlong end_mics = end_sec * 1000000LL + end_usec;
ib_longlong start_mics = start_sec * 1000000LL + start_usec;
if (end_mics > start_mics)
return end_mics - start_mics;
else
return 0;
}
static void time_spin_delay()
{
ulint start_sec, end_sec;
ulint start_usec, end_usec;
int i;
srv_timed_spin_delay = 0;
ut_usectime(&start_sec, &start_usec);
for (i = 0; i < SYNC_SPIN_ROUNDS; ++i)
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
ut_usectime(&end_sec, &end_usec);
srv_timed_spin_delay = mics_diff(start_sec, start_usec, end_sec, end_usec);
}
/*************************************************************************
Prints counters for work done by srv_master_thread. */
static
void
srv_print_extra(
/*===================*/
FILE *file) /* in: output stream */
{
fprintf(file, "srv_master_thread loops: %lu 1_second, %lu sleeps, "
"%lu 10_second, %lu background, %lu flush\n",
srv_main_1_second_loops, srv_main_sleeps,
srv_main_10_second_loops, srv_main_background_loops,
srv_main_flush_loops);
fprintf(file, "srv_master_thread log flush: %lu sync, %lu async\n",
srv_sync_flush, srv_async_flush);
fprintf(file, "srv_wait_thread_mics %lld microseconds, %.1f seconds\n",
srv_thread_wait_mics,
(double) srv_thread_wait_mics / 1000000.0);
fprintf(file,
"spinlock delay for %d delay %d rounds is %lld mics\n",
srv_spin_wait_delay, SYNC_SPIN_ROUNDS, srv_timed_spin_delay);
}
/************************************************************************* /*************************************************************************
Sets the info describing an i/o thread current state. */ Sets the info describing an i/o thread current state. */
...@@ -863,6 +952,8 @@ srv_init(void) ...@@ -863,6 +952,8 @@ srv_init(void)
dict_table_t* table; dict_table_t* table;
ulint i; ulint i;
time_spin_delay();
srv_sys = mem_alloc(sizeof(srv_sys_t)); srv_sys = mem_alloc(sizeof(srv_sys_t));
kernel_mutex_temp = mem_alloc(sizeof(mutex_t)); kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
...@@ -1646,6 +1737,11 @@ srv_printf_innodb_monitor( ...@@ -1646,6 +1737,11 @@ srv_printf_innodb_monitor(
"Per second averages calculated from the last %lu seconds\n", "Per second averages calculated from the last %lu seconds\n",
(ulong)time_elapsed); (ulong)time_elapsed);
fputs("----------\n"
"BACKGROUND THREAD\n"
"----------\n", file);
srv_print_extra(file);
fputs("----------\n" fputs("----------\n"
"SEMAPHORES\n" "SEMAPHORES\n"
"----------\n", file); "----------\n", file);
...@@ -1667,24 +1763,6 @@ srv_printf_innodb_monitor( ...@@ -1667,24 +1763,6 @@ srv_printf_innodb_monitor(
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
lock_print_info_summary(file);
if (trx_start) {
long t = ftell(file);
if (t < 0) {
*trx_start = ULINT_UNDEFINED;
} else {
*trx_start = (ulint) t;
}
}
lock_print_info_all_transactions(file);
if (trx_end) {
long t = ftell(file);
if (t < 0) {
*trx_end = ULINT_UNDEFINED;
} else {
*trx_end = (ulint) t;
}
}
fputs("--------\n" fputs("--------\n"
"FILE I/O\n" "FILE I/O\n"
"--------\n", file); "--------\n", file);
...@@ -2186,6 +2264,14 @@ srv_wake_master_thread(void) ...@@ -2186,6 +2264,14 @@ srv_wake_master_thread(void)
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
} }
/*************************************************************************
Returns the number of IO operations that is X percent of the capacity.
PCT_IO(5) -> returns the number of IO operations that is 5% of the max
where max is srv_io_capacity.
*/
#define PCT_IO(pct) ((ulint) (srv_io_capacity * ((double) pct / 100.0)))
/************************************************************************* /*************************************************************************
The master thread controlling the server. */ The master thread controlling the server. */
...@@ -2217,6 +2303,9 @@ srv_master_thread( ...@@ -2217,6 +2303,9 @@ srv_master_thread(
fprintf(stderr, "Master thread starts, id %lu\n", fprintf(stderr, "Master thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id())); os_thread_pf(os_thread_get_curr_id()));
#endif #endif
fprintf(stderr, "InnoDB master thread running with io_capacity %lu\n",
srv_io_capacity);
srv_main_thread_process_no = os_proc_get_number(); srv_main_thread_process_no = os_proc_get_number();
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id()); srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
...@@ -2258,10 +2347,12 @@ loop: ...@@ -2258,10 +2347,12 @@ loop:
n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written; + buf_pool->n_pages_written;
srv_main_thread_op_info = "sleeping"; srv_main_thread_op_info = "sleeping";
srv_main_1_second_loops++;
if (!skip_sleep) { if (!skip_sleep) {
os_thread_sleep(1000000); os_thread_sleep(1000000);
srv_main_sleeps++;
} }
skip_sleep = FALSE; skip_sleep = FALSE;
...@@ -2287,27 +2378,28 @@ loop: ...@@ -2287,27 +2378,28 @@ loop:
srv_main_thread_op_info = "flushing log"; srv_main_thread_op_info = "flushing log";
log_buffer_flush_to_disk(); log_buffer_flush_to_disk();
srv_sync_flush++;
srv_main_thread_op_info = "making checkpoint"; srv_main_thread_op_info = "making checkpoint";
log_free_check(); log_free_check();
/* If there were less than 5 i/os during the /* If i/os during one second sleep were less than 5% of
one second sleep, we assume that there is free capacity, we assume that there is free disk i/o capacity
disk i/o capacity available, and it makes sense to available, and it makes sense to do an insert buffer merge. */
do an insert buffer merge. */
n_pend_ios = buf_get_n_pending_ios() n_pend_ios = buf_get_n_pending_ios()
+ log_sys->n_pending_writes; + log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written; + buf_pool->n_pages_written;
if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) { if (n_pend_ios < PCT_IO(3) && (n_ios - n_ios_old < PCT_IO(5))) {
srv_main_thread_op_info = "doing insert buffer merge"; srv_main_thread_op_info = "doing insert buffer merge";
ibuf_contract_for_n_pages( ibuf_contract_for_n_pages(TRUE, PCT_IO(20) / 4);
TRUE, srv_insert_buffer_batch_size / 4);
srv_main_thread_op_info = "flushing log"; srv_main_thread_op_info = "flushing log";
log_buffer_flush_to_disk(); /* No fsync when srv_flush_log_at_trx_commit != 1 */
log_buffer_flush_maybe_sync();
srv_async_flush++;
} }
if (UNIV_UNLIKELY(buf_get_modified_ratio_pct() if (UNIV_UNLIKELY(buf_get_modified_ratio_pct()
...@@ -2316,7 +2408,8 @@ loop: ...@@ -2316,7 +2408,8 @@ loop:
/* Try to keep the number of modified pages in the /* Try to keep the number of modified pages in the
buffer pool under the limit wished by the user */ buffer pool under the limit wished by the user */
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
PCT_IO(100),
ut_dulint_max); ut_dulint_max);
/* If we had to do the flush, it may have taken /* If we had to do the flush, it may have taken
...@@ -2344,30 +2437,40 @@ loop: ...@@ -2344,30 +2437,40 @@ loop:
seconds */ seconds */
mem_validate_all_blocks(); mem_validate_all_blocks();
#endif #endif
/* If there were less than 200 i/os during the 10 second period, /* If i/os during the 10 second period were less than 200% of
we assume that there is free disk i/o capacity available, and it capacity, we assume that there is free disk i/o capacity
makes sense to flush 100 pages. */ available, and it makes sense to flush srv_io_capacity pages.
Note that this is done regardless of the fraction of dirty
pages relative to the max requested by the user. The one second
loop above requests writes for that case. The writes done here
are not required, and may be disabled. */
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes; 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 n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written; + buf_pool->n_pages_written;
if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) { if (srv_extra_dirty_writes &&
n_pend_ios < 3 && (n_ios - n_ios_very_old < PCT_IO(200))) {
srv_main_thread_op_info = "flushing buffer pool pages"; srv_main_thread_op_info = "flushing buffer pool pages";
buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max); buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100), ut_dulint_max);
srv_main_thread_op_info = "flushing log"; srv_main_thread_op_info = "flushing log";
log_buffer_flush_to_disk(); /* No fsync when srv_flush_log_at_trx_commit != 1 */
log_buffer_flush_maybe_sync();
srv_async_flush++;
} }
/* We run a batch of insert buffer merge every 10 seconds, /* We run a batch of insert buffer merge every 10 seconds,
even if the server were active */ even if the server were active */
srv_main_thread_op_info = "doing insert buffer merge"; srv_main_thread_op_info = "doing insert buffer merge";
ibuf_contract_for_n_pages(TRUE, srv_insert_buffer_batch_size / 4); ibuf_contract_for_n_pages(TRUE, PCT_IO(20) / 4);
srv_main_thread_op_info = "flushing log"; srv_main_thread_op_info = "flushing log";
log_buffer_flush_to_disk(); /* No fsync when srv_flush_log_at_trx_commit != 1 */
log_buffer_flush_maybe_sync();
srv_async_flush++;
/* We run a full purge every 10 seconds, even if the server /* We run a full purge every 10 seconds, even if the server
were active */ were active */
...@@ -2393,6 +2496,7 @@ loop: ...@@ -2393,6 +2496,7 @@ loop:
log_buffer_flush_to_disk(); log_buffer_flush_to_disk();
last_flush_time = current_time; last_flush_time = current_time;
srv_sync_flush++;
} }
} }
...@@ -2406,14 +2510,16 @@ loop: ...@@ -2406,14 +2510,16 @@ loop:
(> 70 %), we assume we can afford reserving the disk(s) for (> 70 %), we assume we can afford reserving the disk(s) for
the time it requires to flush 100 pages */ the time it requires to flush 100 pages */
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
PCT_IO(100),
ut_dulint_max); ut_dulint_max);
} else { } else {
/* Otherwise, we only flush a small number of pages so that /* Otherwise, we only flush a small number of pages so that
we do not unnecessarily use much disk i/o capacity from we do not unnecessarily use much disk i/o capacity from
other work */ other work */
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
PCT_IO(10),
ut_dulint_max); ut_dulint_max);
} }
...@@ -2447,7 +2553,7 @@ background_loop: ...@@ -2447,7 +2553,7 @@ background_loop:
/* The server has been quiet for a while: start running background /* The server has been quiet for a while: start running background
operations */ operations */
srv_main_background_loops++;
srv_main_thread_op_info = "doing background drop tables"; srv_main_thread_op_info = "doing background drop tables";
n_tables_to_drop = row_drop_tables_for_mysql_in_background(); n_tables_to_drop = row_drop_tables_for_mysql_in_background();
...@@ -2485,6 +2591,7 @@ background_loop: ...@@ -2485,6 +2591,7 @@ background_loop:
log_buffer_flush_to_disk(); log_buffer_flush_to_disk();
last_flush_time = current_time; last_flush_time = current_time;
srv_sync_flush++;
} }
} }
...@@ -2502,8 +2609,11 @@ background_loop: ...@@ -2502,8 +2609,11 @@ background_loop:
if (srv_fast_shutdown && srv_shutdown_state > 0) { if (srv_fast_shutdown && srv_shutdown_state > 0) {
n_bytes_merged = 0; n_bytes_merged = 0;
} else { } else {
n_bytes_merged = ibuf_contract_for_n_pages( /* This should do an amount of IO similar to the number of
TRUE, srv_insert_buffer_batch_size); * dirty pages that will be flushed in the call to
* buf_flush_batch below. Otherwise, the system favors
* clean pages over cleanup throughput. */
n_bytes_merged = ibuf_contract_for_n_pages(TRUE, PCT_IO(100));
} }
srv_main_thread_op_info = "reserving kernel mutex"; srv_main_thread_op_info = "reserving kernel mutex";
...@@ -2517,9 +2627,10 @@ background_loop: ...@@ -2517,9 +2627,10 @@ background_loop:
flush_loop: flush_loop:
srv_main_thread_op_info = "flushing buffer pool pages"; srv_main_thread_op_info = "flushing buffer pool pages";
srv_main_flush_loops++;
if (srv_fast_shutdown < 2) { if (srv_fast_shutdown < 2) {
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100, n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
PCT_IO(100),
ut_dulint_max); ut_dulint_max);
} else { } else {
/* In the fastest shutdown we do not flush the buffer pool /* In the fastest shutdown we do not flush the buffer pool
...@@ -2542,7 +2653,17 @@ flush_loop: ...@@ -2542,7 +2653,17 @@ flush_loop:
srv_main_thread_op_info = "flushing log"; srv_main_thread_op_info = "flushing log";
current_time = time(NULL);
if (difftime(current_time, last_flush_time) > 1) {
srv_main_thread_op_info = (char*) "flushing log";
log_buffer_flush_to_disk(); log_buffer_flush_to_disk();
last_flush_time = current_time;
srv_sync_flush++;
} else {
/* No fsync when srv_flush_log_at_trx_commit != 1 */
log_buffer_flush_maybe_sync();
srv_async_flush++;
}
srv_main_thread_op_info = "making checkpoint"; srv_main_thread_op_info = "making checkpoint";
......
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