Skip to content

PS-11120 [8.4]: Reduce contention on BUF_BLOCK_MUTEX by reading ahead the access_time#6026

Open
polchawa-percona wants to merge 1 commit into
percona:8.4from
polchawa-percona:PS-11120
Open

PS-11120 [8.4]: Reduce contention on BUF_BLOCK_MUTEX by reading ahead the access_time#6026
polchawa-percona wants to merge 1 commit into
percona:8.4from
polchawa-percona:PS-11120

Conversation

@polchawa-percona

@polchawa-percona polchawa-percona commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

https://perconadev.atlassian.net/browse/PS-11120

This patch reduces contention inside buf_page_optimistic_get. We acquire the BUF_BLOCK_MUTEX twice there. But the second time we acquire it only to update the access time. Given that we would update the access time only if it was zero, we could avoid acquiring the mutex when we knew that the access time was already non-zero. This we could learn the first time we acquired the mutex by reading the access time field of the page.

Note:

  • the second time we acquired the mutex, we would check again if it still was zero anyway
  • we never reset the access time to zero (unless we reinitialize new page)
  • the page would not be reinitialized meanwhile, because the first time we accessed it, we "fix it" (call buf_block_buf_fix_inc), which is to keep the page alive (purpose of fixing) until it is "unfixed" (much later)

The patch is safe and allows us to save a significant number of times we needed to acquire the mutex.

This is a contribution from: Anna Glasgall aglasgal@akamai.com / Akamai, with a minor fix added.

@polchawa-percona polchawa-percona self-assigned this Jun 22, 2026
@polchawa-percona

Copy link
Copy Markdown
Contributor Author

Reproduction steps:

Initialize a new data directory:

./bin/mysqld --defaults-file=my.cnf --datadir=/bigdisk_solidigm/your-datadir --initialize-insecure

Run via client:

create database test;
use test;
CREATE TABLE `contention_test` (   `id` int NOT NULL AUTO_INCREMENT,   `col_a` int DEFAULT NULL,   `col_b` int DEFAULT NULL,   PRIMARY KEY (`id`),   KEY `col_a` (`col_a`) ) ENGINE=InnoDB AUTO_INCREMENT=9000002 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

insert into contention_test (col_a, col_b) select round(rand() * 300), round(rand() * 100000) from sequence_table(30000) t;

use my.cnf:

[mysqld]
skip-networking
socket=/tmp/m.sock
max_connections=1000
max_connect_errors=10000
max_prepared_stmt_count=100000
thread_cache_size=256
back_log=4096
innodb_buffer_pool_size=12G
innodb_io_capacity=10000
innodb_io_capacity_max=20000
innodb_read_io_threads=16
innodb_use_native_aio=ON
innodb_sync_array_size=16

Run test (a few times):

function start_profiling() {
        sudo funclatency-bpfcc -d 3 -p $(pidof mysqld) ./bin/mysqld:_Z23buf_page_optimistic_getmP11buf_block_tm10Page_fetchPKcmP5mtr_t &
}

echo "Hot-page test"

start_profiling
time mysqlslap --user=root --socket=/tmp/m.sock \
  --concurrency=100 --iterations=100 --create-schema=test \
  --query="SELECT * FROM contention_test WHERE col_a = 1"
wait

echo "Spread 10"
start_profiling
time ( j=0; for i in {1..10}; do
  mysqlslap --user=root --socket=/tmp/m.sock \
    --concurrency=10 --iterations=1000 --create-schema=test \
    --query="SELECT * FROM contention_test WHERE col_a = ${j}" &
  j=$((j+25))
done; wait; )
wait

echo "Spread 20"
start_profiling
time ( j=0; for i in {1..20}; do
  mysqlslap --user=root --socket=/tmp/m.sock \
    --concurrency=10 --iterations=1000 --create-schema=test \
    --query="SELECT * FROM contention_test WHERE col_a = ${j}" &
  j=$((j+13))
done; wait; )
wait

@polchawa-percona polchawa-percona changed the title PS-11120: Reduce contention on BUF_BLOCK_MUTEX by reading ahead the access_time PS-11120 [8.4]: Reduce contention on BUF_BLOCK_MUTEX by reading ahead the access_time Jun 22, 2026
Comment thread storage/innobase/buf/buf0buf.cc

@satya-bodapati satya-bodapati left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash the commits before merge

…ccess_time

This patch reduces contention inside buf_page_optimistic_get. We acquire there
the BUF_BLOCK_MUTEX twice. But the second time we acquire only to update the
access time. Given that we would update the access time only if it was zero,
we could avoid acquiring the mutex when we knew that the access time was already
non-zero. This we could learn the first time we acquired the mutex by reading
the access time field of the page.

Note: the second time we acquired the mutex, we re-check if it still was zero
anyway, so the patch is safe and allows to save significant number of times
we needed to acquire the mutex.

This is a contribution from: Anna Glasgall (with a minor fix).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants