Commit fa8a46eb authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-33613 InnoDB may still hang when temporarily running out of buffer pool

By design, InnoDB has always hung when permanently running out of
buffer pool, for example when several threads are waiting to allocate
a block, and all of the buffer pool is buffer-fixed by the active threads.

The hang that we are fixing here occurs when the buffer pool is only
temporarily running out and the situation could be rescued by writing out
some dirty pages or evicting some clean pages.

buf_LRU_get_free_block(): Simplify the way how we wait for
the buf_flush_page_cleaner thread. This fixes occasional hangs
of the test encryption.innochecksum that were introduced by
commit a55b951e (MDEV-26827).
To play it safe, we use a timed wait when waiting for the
buf_flush_page_cleaner() thread to perform its job. Should that
thread get stuck, we will invoke buf_pool.LRU_warn() in order to
display a message that pages could not be freed, and keep trying
to wake up the buf_flush_page_cleaner() thread.

The INFORMATION_SCHEMA.INNODB_METRICS counters
buffer_LRU_single_flush_failure_count and
buffer_LRU_get_free_waits will be removed.
The latter is represented by buffer_pool_wait_free.

Also removed will be the message
"InnoDB: Difficult to find free blocks in the buffer pool"
because in d34479dc we
introduced a more precise message
"InnoDB: Could not free any blocks in the buffer pool"
in the buf_flush_page_cleaner thread.

buf_pool_t::LRU_warn(): Issue the warning message that we could
not free any blocks in the buffer pool. This may also be invoked
by buf_LRU_get_free_block() if buf_flush_page_cleaner() appears
to be stuck.

buf_pool_t::n_flush_dec(): Remove.

buf_pool_t::n_flush_dec_holding_mutex(): Rename to n_flush_dec().

buf_flush_LRU_list_batch(): Increment the eviction counter for blocks
of temporary, discarded or dropped tablespaces.

buf_flush_LRU(): Make static, and remove the constant parameter
evict=false. The only caller will be the buf_flush_page_cleaner()
thread.

IORequest::is_LRU(): Remove. The only case of evicting pages on
write completion will be when we are writing out pages of the
temporary tablespace. Those pages are not in buf_pool.flush_list,
only in buf_pool.LRU.

buf_page_t::flush(): Remove the parameter evict.

buf_page_t::write_complete(): Change the parameter "bool temporary"
to "bool persistent" and add a parameter for an already read state().

Reviewed by: Debarun Banerjee
parent 75c7c6dc
......@@ -51,7 +51,7 @@ ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c),
ALGORITHM=COPY;
connection default;
SET DEBUG_SYNC='now WAIT_FOR hung';
# restart: --innodb-force-recovery=3 --debug_dbug=+d,recv_ran_out_of_buffer
# restart: --innodb-force-recovery=3
disconnect hang;
FTS_INDEX_1.ibd
FTS_INDEX_2.ibd
......
SET @saved_debug = @@SESSION.debug_dbug;
SET SESSION debug_dbug="+d,ib_lru_force_no_free_page";
CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB;
BEGIN;
INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
COMMIT;
SET debug_dbug = @saved_debug;
DROP TABLE t1;
FOUND 1 /InnoDB: Difficult to find free blocks / in mysqld.1.err
......@@ -88,7 +88,6 @@ buffer_flush_n_to_flush_by_age buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NUL
buffer_flush_adaptive_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently.
buffer_flush_adaptive_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of adaptive flushes passed during the recent Avg period.
buffer_LRU_get_free_loops buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total loops in LRU get free.
buffer_LRU_get_free_waits buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total sleep waits in LRU get free.
buffer_flush_avg_page_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average number of pages at which flushing is happening
buffer_flush_lsn_avg_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average redo generation rate
buffer_flush_pct_for_dirty buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Percent of IO capacity used to avoid max dirty page limit
......@@ -108,7 +107,6 @@ buffer_LRU_batch_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NUL
buffer_LRU_batch_scanned_per_call buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages scanned per LRU batch call
buffer_LRU_batch_flush_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages flushed as part of LRU batches
buffer_LRU_batch_evict_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages evicted as part of LRU batches
buffer_LRU_single_flush_failure_count Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times attempt to flush a single page from LRU failed
buffer_LRU_get_free_search Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of searches performed for a clean page
buffer_LRU_search_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of LRU search
buffer_LRU_search_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of times LRU search is performed
......
......@@ -53,7 +53,6 @@ buffer_flush_n_to_flush_by_age disabled
buffer_flush_adaptive_avg_time disabled
buffer_flush_adaptive_avg_pass disabled
buffer_LRU_get_free_loops disabled
buffer_LRU_get_free_waits disabled
buffer_flush_avg_page_rate disabled
buffer_flush_lsn_avg_rate disabled
buffer_flush_pct_for_dirty disabled
......@@ -73,7 +72,6 @@ buffer_LRU_batch_num_scan disabled
buffer_LRU_batch_scanned_per_call disabled
buffer_LRU_batch_flush_total_pages enabled
buffer_LRU_batch_evict_total_pages enabled
buffer_LRU_single_flush_failure_count disabled
buffer_LRU_get_free_search disabled
buffer_LRU_search_scanned disabled
buffer_LRU_search_num_scan disabled
......
......@@ -57,7 +57,7 @@ ALTER TABLE t ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX
connection default;
SET DEBUG_SYNC='now WAIT_FOR hung';
let $shutdown_timeout=0;
--let $restart_parameters= --innodb-force-recovery=3 --debug_dbug="+d,recv_ran_out_of_buffer"
--let $restart_parameters= --innodb-force-recovery=3
--source include/restart_mysqld.inc
disconnect hang;
let $shutdown_timeout=;
......
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/not_embedded.inc
SET @saved_debug = @@SESSION.debug_dbug;
SET SESSION debug_dbug="+d,ib_lru_force_no_free_page";
CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB;
BEGIN;
INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200));
COMMIT;
SET debug_dbug = @saved_debug;
DROP TABLE t1;
#
# There should be only one message
#
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--let SEARCH_PATTERN=InnoDB: Difficult to find free blocks
--source include/search_pattern_in_file.inc
......@@ -4,10 +4,6 @@
SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
SET GLOBAL innodb_stats_persistent = 0;
--disable_query_log
call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool");
--enable_query_log
CREATE TABLE t1 (
a SERIAL, b CHAR(255) NOT NULL DEFAULT '', c BOOLEAN DEFAULT false,
l LINESTRING NOT NULL DEFAULT ST_linefromtext('linestring(448 -689,
......
......@@ -9,11 +9,6 @@
--source include/not_embedded.inc
-- source include/big_test.inc
--disable_query_log
# This warning occurs due to small buffer pool size(i.e. 8MB). It doesn't occur
# with --mysqld=--innodb_buffer_pool_size=10MB
call mtr.add_suppression("\\[Warning\\] InnoDB: Difficult to find free blocks in the buffer pool.*");
--enable_query_log
let MYSQLD_BASEDIR= `SELECT @@basedir`;
let MYSQLD_DATADIR= `SELECT @@datadir`;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err;
......
......@@ -1397,17 +1397,14 @@ inline bool buf_pool_t::withdraw_blocks()
/* reserve free_list length */
if (UT_LIST_GET_LEN(withdraw) < withdraw_target) {
buf_flush_LRU(
std::max<ulint>(withdraw_target
- UT_LIST_GET_LEN(withdraw),
srv_LRU_scan_depth),
true);
mysql_mutex_unlock(&buf_pool.mutex);
buf_dblwr.flush_buffered_writes();
mysql_mutex_lock(&buf_pool.flush_list_mutex);
buf_flush_wait_LRU_batch_end();
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
mysql_mutex_lock(&buf_pool.mutex);
try_LRU_scan = false;
mysql_mutex_unlock(&mutex);
mysql_mutex_lock(&flush_list_mutex);
page_cleaner_wakeup(true);
my_cond_wait(&done_flush_list,
&flush_list_mutex.m_mutex);
mysql_mutex_unlock(&flush_list_mutex);
mysql_mutex_lock(&mutex);
}
/* relocate blocks/buddies in withdrawn area */
......@@ -2003,7 +2000,10 @@ buf_page_t *buf_pool_t::watch_set(const page_id_t id,
got_block:
bpage->fix();
if (watch_is_sentinel(*bpage))
{
ut_ad(!bpage->oldest_modification());
bpage= nullptr;
}
page_hash.lock_get(chain).unlock();
return bpage;
}
......@@ -2075,6 +2075,7 @@ void buf_pool_t::watch_unset(const page_id_t id, buf_pool_t::hash_chain &chain)
}
else
{
ut_ad(!w->oldest_modification());
const auto state= w->state();
ut_ad(~buf_page_t::LRU_MASK & state);
ut_ad(state >= buf_page_t::UNFIXED + 1);
......
This diff is collapsed.
......@@ -385,144 +385,76 @@ we put it to free list to be used.
@return the free control block, in state BUF_BLOCK_MEMORY */
buf_block_t *buf_LRU_get_free_block(bool have_mutex)
{
ulint n_iterations = 0;
ulint flush_failures = 0;
bool waited= false;
MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH);
if (have_mutex) {
mysql_mutex_assert_owner(&buf_pool.mutex);
goto got_mutex;
}
DBUG_EXECUTE_IF("recv_ran_out_of_buffer",
if (recv_recovery_is_on()
&& recv_sys.apply_log_recs) {
mysql_mutex_lock(&buf_pool.mutex);
goto flush_lru;
});
get_mutex:
if (!have_mutex)
mysql_mutex_lock(&buf_pool.mutex);
got_mutex:
buf_LRU_check_size_of_non_data_objects();
buf_block_t* block;
IF_DBUG(static bool buf_lru_free_blocks_error_printed,);
DBUG_EXECUTE_IF("ib_lru_force_no_free_page",
if (!buf_lru_free_blocks_error_printed) {
n_iterations = 21;
goto not_found;});
buf_block_t *block;
retry:
/* If there is a block in the free list, take it */
if ((block = buf_LRU_get_free_only()) != nullptr) {
block= buf_LRU_get_free_only();
if (block)
{
got_block:
const ulint LRU_size = UT_LIST_GET_LEN(buf_pool.LRU);
const ulint available = UT_LIST_GET_LEN(buf_pool.free);
const ulint scan_depth = srv_LRU_scan_depth / 2;
ut_ad(LRU_size <= BUF_LRU_MIN_LEN || available >= scan_depth
|| buf_pool.need_LRU_eviction());
const ulint LRU_size= UT_LIST_GET_LEN(buf_pool.LRU);
const ulint available= UT_LIST_GET_LEN(buf_pool.free);
const ulint scan_depth= srv_LRU_scan_depth / 2;
ut_ad(LRU_size <= BUF_LRU_MIN_LEN ||
available >= scan_depth || buf_pool.need_LRU_eviction());
if (!have_mutex) {
mysql_mutex_unlock(&buf_pool.mutex);
}
if (UNIV_UNLIKELY(available < scan_depth)
&& LRU_size > BUF_LRU_MIN_LEN) {
if (UNIV_UNLIKELY(available < scan_depth) && LRU_size > BUF_LRU_MIN_LEN)
{
mysql_mutex_lock(&buf_pool.flush_list_mutex);
if (!buf_pool.page_cleaner_active()) {
if (!buf_pool.page_cleaner_active())
buf_pool.page_cleaner_wakeup(true);
}
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
}
if (!have_mutex)
mysql_mutex_unlock(&buf_pool.mutex);
block->page.zip.clear();
return block;
}
MONITOR_INC( MONITOR_LRU_GET_FREE_LOOPS );
if (n_iterations || buf_pool.try_LRU_scan) {
/* If no block was in the free list, search from the
end of the LRU list and try to free a block there.
If we are doing for the first time we'll scan only
tail of the LRU list otherwise we scan the whole LRU
list. */
if (buf_LRU_scan_and_free_block(n_iterations
? ULINT_UNDEFINED : 100)) {
MONITOR_INC(MONITOR_LRU_GET_FREE_LOOPS);
if (waited || buf_pool.try_LRU_scan)
{
/* If no block was in the free list, search from the end of the
LRU list and try to free a block there. If we are doing for the
first time we'll scan only tail of the LRU list otherwise we scan
the whole LRU list. */
if (buf_LRU_scan_and_free_block(waited ? ULINT_UNDEFINED : 100))
goto retry;
}
/* Tell other threads that there is no point
in scanning the LRU list. */
buf_pool.try_LRU_scan = false;
}
for (;;) {
if ((block = buf_LRU_get_free_only()) != nullptr) {
goto got_block;
}
const bool wake = buf_pool.need_LRU_eviction();
mysql_mutex_unlock(&buf_pool.mutex);
mysql_mutex_lock(&buf_pool.flush_list_mutex);
const auto n_flush = buf_pool.n_flush();
if (wake && !buf_pool.page_cleaner_active()) {
buf_pool.page_cleaner_wakeup(true);
}
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
mysql_mutex_lock(&buf_pool.mutex);
if (!n_flush) {
goto not_found;
}
if (!buf_pool.try_LRU_scan) {
my_cond_wait(&buf_pool.done_free,
&buf_pool.mutex.m_mutex);
}
/* Tell other threads that there is no point in scanning the LRU
list. */
buf_pool.try_LRU_scan= false;
}
not_found:
if (n_iterations > 1) {
MONITOR_INC( MONITOR_LRU_GET_FREE_WAITS );
}
waited= true;
if (n_iterations == 21
&& srv_buf_pool_old_size == srv_buf_pool_size
&& buf_pool.LRU_warned.test_and_set(std::memory_order_acquire)) {
IF_DBUG(buf_lru_free_blocks_error_printed = true,);
mysql_mutex_unlock(&buf_pool.mutex);
ib::warn() << "Difficult to find free blocks in the buffer pool"
" (" << n_iterations << " search iterations)! "
<< flush_failures << " failed attempts to"
" flush a page!"
" Consider increasing innodb_buffer_pool_size."
" Pending flushes (fsync) log: "
<< log_sys.get_pending_flushes()
<< "; buffer pool: "
<< fil_n_pending_tablespace_flushes
<< ". " << os_n_file_reads << " OS file reads, "
<< os_n_file_writes << " OS file writes, "
<< os_n_fsyncs
<< " OS fsyncs.";
mysql_mutex_lock(&buf_pool.mutex);
}
while (!(block= buf_LRU_get_free_only()))
{
buf_pool.stat.LRU_waits++;
/* No free block was found: try to flush the LRU list.
The freed blocks will be up for grabs for all threads.
timespec abstime;
set_timespec(abstime, 1);
TODO: A more elegant way would have been to return one freed
up block to the caller here but the code that deals with
removing the block from buf_pool.page_hash and buf_pool.LRU is fairly
involved (particularly in case of ROW_FORMAT=COMPRESSED pages). We
can do that in a separate patch sometime in future. */
#ifndef DBUG_OFF
flush_lru:
#endif
if (!buf_flush_LRU(innodb_lru_flush_size, true)) {
MONITOR_INC(MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT);
++flush_failures;
mysql_mutex_lock(&buf_pool.flush_list_mutex);
if (!buf_pool.page_cleaner_active())
buf_pool.page_cleaner_wakeup(true);
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
if (my_cond_timedwait(&buf_pool.done_free, &buf_pool.mutex.m_mutex,
&abstime))
buf_pool.LRU_warn();
}
n_iterations++;
buf_pool.stat.LRU_waits++;
mysql_mutex_unlock(&buf_pool.mutex);
buf_dblwr.flush_buffered_writes();
goto get_mutex;
goto got_block;
}
/** Move the LRU_old pointer so that the length of the old blocks list
......
......@@ -766,17 +766,16 @@ class buf_page_t
@retval DB_FAIL if the page contains the wrong ID */
dberr_t read_complete(const fil_node_t &node);
/** Note that a block is no longer dirty, while not removing
it from buf_pool.flush_list
@param temporary whether the page belongs to the temporary tablespace
@param error whether an error may have occurred while writing */
inline void write_complete(bool temporary, bool error);
/** Release a write fix after a page write was completed.
@param persistent whether the page belongs to a persistent tablespace
@param error whether an error may have occurred while writing
@param state recently read state() value with the correct io-fix */
void write_complete(bool persistent, bool error, uint32_t state);
/** Write a flushable page to a file or free a freeable block.
@param evict whether to evict the page on write completion
@param space tablespace
@return whether a page write was initiated and buf_pool.mutex released */
bool flush(bool evict, fil_space_t *space);
bool flush(fil_space_t *space);
/** Notify that a page in a temporary tablespace has been modified. */
void set_temp_modified()
......@@ -1740,10 +1739,6 @@ class buf_pool_t
/** Decrement the number of pending LRU flush */
inline void n_flush_dec();
/** Decrement the number of pending LRU flush
while holding flush_list_mutex */
inline void n_flush_dec_holding_mutex();
/** @return whether flush_list flushing is active */
bool flush_list_active() const
{
......@@ -1893,6 +1888,9 @@ class buf_pool_t
/** Free a page whose underlying file page has been freed. */
ATTRIBUTE_COLD void release_freed_page(buf_page_t *bpage);
/** Issue a warning that we could not free up buffer pool pages. */
ATTRIBUTE_COLD void LRU_warn();
private:
/** Temporary memory for page_compressed and encrypted I/O */
struct io_buf_t
......
......@@ -85,16 +85,6 @@ buf_flush_init_for_writing(
bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed= nullptr)
MY_ATTRIBUTE((warn_unused_result));
/** Write out dirty blocks from buf_pool.LRU,
and move clean blocks to buf_pool.free.
The caller must invoke buf_dblwr.flush_buffered_writes()
after releasing buf_pool.mutex.
@param max_n wished maximum mumber of blocks flushed
@param evict whether to evict pages after flushing
@return evict ? number of processed pages : number of pages written
@retval 0 if a buf_pool.LRU batch is already running */
ulint buf_flush_LRU(ulint max_n, bool evict);
/** Wait until a LRU flush batch ends. */
void buf_flush_wait_LRU_batch_end();
/** Wait until all persistent pages are flushed up to a limit.
......
......@@ -200,14 +200,10 @@ class IORequest
WRITE_ASYNC= WRITE_SYNC | 1,
/** A doublewrite batch */
DBLWR_BATCH= WRITE_ASYNC | 8,
/** Write data; evict the block on write completion */
WRITE_LRU= WRITE_ASYNC | 32,
/** Write data and punch hole for the rest */
PUNCH= WRITE_ASYNC | 64,
/** Write data and punch hole; evict the block on write completion */
PUNCH_LRU= PUNCH | WRITE_LRU,
PUNCH= WRITE_ASYNC | 16,
/** Zero out a range of bytes in fil_space_t::io() */
PUNCH_RANGE= WRITE_SYNC | 128,
PUNCH_RANGE= WRITE_SYNC | 32,
};
constexpr IORequest(buf_page_t *bpage, buf_tmp_buffer_t *slot,
......@@ -220,7 +216,6 @@ class IORequest
bool is_read() const { return (type & READ_SYNC) != 0; }
bool is_write() const { return (type & WRITE_SYNC) != 0; }
bool is_LRU() const { return (type & (WRITE_LRU ^ WRITE_ASYNC)) != 0; }
bool is_async() const { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; }
void write_complete(int io_error) const;
......
......@@ -196,7 +196,6 @@ enum monitor_id_t {
MONITOR_FLUSH_ADAPTIVE_AVG_PASS,
MONITOR_LRU_GET_FREE_LOOPS,
MONITOR_LRU_GET_FREE_WAITS,
MONITOR_FLUSH_AVG_PAGE_RATE,
MONITOR_FLUSH_LSN_AVG_RATE,
......@@ -217,7 +216,6 @@ enum monitor_id_t {
MONITOR_LRU_BATCH_SCANNED_PER_CALL,
MONITOR_LRU_BATCH_FLUSH_TOTAL_PAGE,
MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE,
MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT,
MONITOR_LRU_GET_FREE_SEARCH,
MONITOR_LRU_SEARCH_SCANNED,
MONITOR_LRU_SEARCH_SCANNED_NUM_CALL,
......
......@@ -376,11 +376,6 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_NONE,
MONITOR_DEFAULT_START, MONITOR_LRU_GET_FREE_LOOPS},
{"buffer_LRU_get_free_waits", "buffer",
"Total sleep waits in LRU get free.",
MONITOR_NONE,
MONITOR_DEFAULT_START, MONITOR_LRU_GET_FREE_WAITS},
{"buffer_flush_avg_page_rate", "buffer",
"Average number of pages at which flushing is happening",
MONITOR_NONE,
......@@ -484,11 +479,6 @@ static monitor_info_t innodb_counter_info[] =
MONITOR_EXISTING | MONITOR_DEFAULT_ON),
MONITOR_DEFAULT_START, MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE},
{"buffer_LRU_single_flush_failure_count", "Buffer",
"Number of times attempt to flush a single page from LRU failed",
MONITOR_NONE,
MONITOR_DEFAULT_START, MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT},
{"buffer_LRU_get_free_search", "Buffer",
"Number of searches performed for a clean page",
MONITOR_NONE,
......
......@@ -70,7 +70,6 @@ buffer_flush_n_to_flush_by_age buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NUL
buffer_flush_adaptive_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently.
buffer_flush_adaptive_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of adaptive flushes passed during the recent Avg period.
buffer_LRU_get_free_loops buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total loops in LRU get free.
buffer_LRU_get_free_waits buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total sleep waits in LRU get free.
buffer_flush_avg_page_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average number of pages at which flushing is happening
buffer_flush_lsn_avg_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average redo generation rate
buffer_flush_pct_for_dirty buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Percent of IO capacity used to avoid max dirty page limit
......@@ -90,7 +89,6 @@ buffer_LRU_batch_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NUL
buffer_LRU_batch_scanned_per_call buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages scanned per LRU batch call
buffer_LRU_batch_flush_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages flushed as part of LRU batches
buffer_LRU_batch_evict_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages evicted as part of LRU batches
buffer_LRU_single_flush_failure_count Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times attempt to flush a single page from LRU failed
buffer_LRU_get_free_search Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of searches performed for a clean page
buffer_LRU_search_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of LRU search
buffer_LRU_search_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of times LRU search is performed
......
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