Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-15384

buf_flush_LRU_list_batch() always reports n->flushed=0, n->evicted=0

Details

    • 10.2.14

    Description

      The flush_counters_t that were introduced in MDEV-6936 were broken in the merge of InnoDB from MySQL 5.7.9 to MariaDB 10.2.2. After that change, the function buf_flush_LRU_list_batch() initializes all counts to 0 and will not update them.

      I would fix this as follows. I still need to figure out how to add a regression test for this.

      diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
      index e938c27cfec..17f915a9d12 100644
      --- a/storage/innobase/buf/buf0flu.cc
      +++ b/storage/innobase/buf/buf0flu.cc
      @@ -1654,8 +1654,6 @@ buf_flush_LRU_list_batch(
       {
       	buf_page_t*	bpage;
       	ulint		scanned = 0;
      -	ulint		evict_count = 0;
      -	ulint		count = 0;
       	ulint		free_len = UT_LIST_GET_LEN(buf_pool->free);
       	ulint		lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
       	ulint		withdraw_depth = 0;
      @@ -1671,7 +1669,7 @@ buf_flush_LRU_list_batch(
       	}
       
       	for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
      -	     bpage != NULL && count + evict_count < max
      +	     bpage != NULL && n->flushed + n->evicted < max
       	     && free_len < srv_LRU_scan_depth + withdraw_depth
       	     && lru_len > BUF_LRU_MIN_LEN;
       	     ++scanned,
      @@ -1689,7 +1687,7 @@ buf_flush_LRU_list_batch(
       			clean and is not IO-fixed or buffer fixed. */
       			mutex_exit(block_mutex);
       			if (buf_LRU_free_page(bpage, true)) {
      -				++evict_count;
      +				++n->evicted;
       			}
       		} else if (buf_flush_ready_for_flush(bpage, BUF_FLUSH_LRU)) {
       			/* Block is ready for flush. Dispatch an IO
      @@ -1697,7 +1695,7 @@ buf_flush_LRU_list_batch(
       			free list in IO completion routine. */
       			mutex_exit(block_mutex);
       			buf_flush_page_and_try_neighbors(
      -				bpage, BUF_FLUSH_LRU, max, &count);
      +				bpage, BUF_FLUSH_LRU, max, &n->flushed);
       		} else {
       			/* Can't evict or dispatch this block. Go to
       			previous. */
      @@ -1721,12 +1719,12 @@ buf_flush_LRU_list_batch(
       
       	ut_ad(buf_pool_mutex_own(buf_pool));
       
      -	if (evict_count) {
      +	if (n->evicted) {
       		MONITOR_INC_VALUE_CUMULATIVE(
       			MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE,
       			MONITOR_LRU_BATCH_EVICT_COUNT,
       			MONITOR_LRU_BATCH_EVICT_PAGES,
      -			evict_count);
      +			n->evicted);
       	}
       
       	if (scanned) {
      @@ -2182,17 +2180,16 @@ buf_flush_lists(
       			help in the retry which will follow the
       			failure. */
       			success = false;
      -
      -			continue;
       		}
      +
      +		n_flushed += n.flushed;
       	}
       
       	if (n_flushed) {
       		buf_flush_stats(n_flushed, 0);
      -	}
      -
      -	if (n_processed) {
      -		*n_processed = n_flushed;
      +		if (n_processed) {
      +			*n_processed = n_flushed;
      +		}
       	}
       
       	return(success);
      

      Attachments

        Issue Links

          Activity

            Even with the patch, I cannot get a test to report any page flushes:

            diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test
            index 47cfaec41ca..3ffaa9b9802 100644
            --- a/mysql-test/suite/innodb/t/purge_secondary.test
            +++ b/mysql-test/suite/innodb/t/purge_secondary.test
            @@ -1,5 +1,8 @@
             --source include/have_innodb.inc
             
            +SET GLOBAL innodb_monitor_enable = '%flush%';
            +SET GLOBAL innodb_monitor_enable = DEFAULT;
            +
             # Ensure that the history list length will actually be decremented by purge.
             SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
             SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
            @@ -121,11 +124,21 @@ SELECT OTHER_INDEX_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS
             WHERE NAME='test/t1';
             
             --echo # Note: The OTHER_INDEX_SIZE does not cover any SPATIAL INDEX.
            ---echo # To test that all indexes were emptied, replace DROP TABLE
            ---echo # with the following, and examine the root pages in t1.ibd:
            ---echo # FLUSH TABLES t1 FOR EXPORT;
            ---echo # UNLOCK TABLES;
            +--echo # To test that all indexes were emptied, remove DROP TABLE
            +--echo # and examine the root pages in t1.ibd:
            +FLUSH TABLES t1 FOR EXPORT;
            +UNLOCK TABLES;
             
             DROP TABLE t1;
             
             SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
            +
            +SELECT * FROM information_schema.global_status
            +WHERE LOWER(variable_name) LIKE 'innodb%flush%';
            +
            +SELECT name, max_count, min_count, count,
            +	max_count_reset, min_count_reset, count_reset, status
            +FROM information_schema.innodb_metrics
            +WHERE name LIKE '%flush%';
            +SET GLOBAL innodb_monitor_disable = '%flush%';
            +SET GLOBAL innodb_monitor_disable = DEFAULT;
            

            Please revise this to make this work.
            I noticed the problem when working on MDEV-15053, on the MySQL 8.0 BUG#23102834 INNODB: ZERO FLUSH FROM LRU.
            Preferrably I would test this in some existing tests, instead of adding a separate big test for this, like the above Oracle change did.
            Also, we might want to check INNODB_ENCRYPTION_ROTATION_PAGES_FLUSHED in some of the encryption tests.

            marko Marko Mäkelä added a comment - Even with the patch, I cannot get a test to report any page flushes: diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test index 47cfaec41ca..3ffaa9b9802 100644 --- a/mysql-test/suite/innodb/t/purge_secondary.test +++ b/mysql-test/suite/innodb/t/purge_secondary.test @@ -1,5 +1,8 @@ --source include/have_innodb.inc +SET GLOBAL innodb_monitor_enable = '%flush%'; +SET GLOBAL innodb_monitor_enable = DEFAULT; + # Ensure that the history list length will actually be decremented by purge. SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; @@ -121,11 +124,21 @@ SELECT OTHER_INDEX_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE NAME='test/t1'; --echo # Note: The OTHER_INDEX_SIZE does not cover any SPATIAL INDEX. ---echo # To test that all indexes were emptied, replace DROP TABLE ---echo # with the following, and examine the root pages in t1.ibd: ---echo # FLUSH TABLES t1 FOR EXPORT; ---echo # UNLOCK TABLES; +--echo # To test that all indexes were emptied, remove DROP TABLE +--echo # and examine the root pages in t1.ibd: +FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; DROP TABLE t1; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; + +SELECT * FROM information_schema.global_status +WHERE LOWER(variable_name) LIKE 'innodb%flush%'; + +SELECT name, max_count, min_count, count, + max_count_reset, min_count_reset, count_reset, status +FROM information_schema.innodb_metrics +WHERE name LIKE '%flush%'; +SET GLOBAL innodb_monitor_disable = '%flush%'; +SET GLOBAL innodb_monitor_disable = DEFAULT; Please revise this to make this work. I noticed the problem when working on MDEV-15053 , on the MySQL 8.0 BUG#23102834 INNODB: ZERO FLUSH FROM LRU . Preferrably I would test this in some existing tests, instead of adding a separate big test for this, like the above Oracle change did. Also, we might want to check INNODB_ENCRYPTION_ROTATION_PAGES_FLUSHED in some of the encryption tests.

            OK to push.

            marko Marko Mäkelä added a comment - OK to push.

            People

              thiru Thirunarayanan Balathandayuthapani
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.