Lab 07: Buffer Pool & Memory Tuning

Time: 45 minutes | Level: Advanced | DB: MySQL 8.0, PostgreSQL 15

Overview

The buffer pool (MySQL) and shared_buffers (PostgreSQL) are the most impactful memory settings. Proper tuning can reduce disk I/O by 99% by keeping hot data in RAM. This lab covers sizing, monitoring, and validating memory configurations.


Step 1: MySQL InnoDB Buffer Pool Sizing

docker run -d --name mysql-lab \
  -e MYSQL_ROOT_PASSWORD=rootpass \
  mysql:8.0 \
  --innodb_buffer_pool_size=512M \
  --innodb_buffer_pool_instances=2 \
  --innodb_buffer_pool_chunk_size=128M \
  --innodb_log_file_size=256M \
  --innodb_flush_log_at_trx_commit=1

for i in $(seq 1 30); do docker exec mysql-lab mysql -uroot -prootpass -e "SELECT 1" 2>/dev/null && break || sleep 2; done

# Verify buffer pool settings
docker exec mysql-lab mysql -uroot -prootpass -e "
SHOW VARIABLES LIKE 'innodb_buffer_pool%';
SHOW VARIABLES LIKE 'innodb_log_file_size';
"

📸 Verified Output:

💡 Rule of thumb: Set innodb_buffer_pool_size to 70-80% of available RAM on a dedicated MySQL server. For a 16GB server → ~12GB buffer pool. innodb_buffer_pool_instances should match the number of CPU cores (or buffer pool GB, whichever is smaller).


Step 2: Create Test Data and Warm Up Buffer Pool

📸 Verified Output:


Step 3: SHOW ENGINE INNODB STATUS — Buffer Pool Section

📸 Verified Output:

💡 Buffer pool hit rate: The ratio shown as 1000/1000 means 100% hit rate — all reads served from memory. A rate below 950/1000 (95%) indicates the buffer pool is too small.


Step 4: Calculate Buffer Pool Hit Rate

📸 Verified Output:

💡 A hit rate below 95% means your buffer pool is too small — pages are being evicted before they can be reused, forcing expensive disk reads.


Step 5: Monitor Buffer Pool Instances

📸 Verified Output:


Step 6: PostgreSQL Memory Configuration

📸 Verified Output:

💡 PostgreSQL memory tuning triangle:

  • shared_buffers = 25% of RAM (PostgreSQL relies on OS page cache too)

  • work_mem = RAM / (max_connections × 2-4) — can be used multiple times per query!

  • effective_cache_size = 75% of RAM (hint to planner about available cache)


Step 7: pg_buffercache Extension

📸 Verified Output:


Step 8: Capstone — Memory Tuning Recommendations Script

📸 Verified Output:


Summary

Setting
MySQL
PostgreSQL
Rule of Thumb

Main buffer

innodb_buffer_pool_size

shared_buffers

MySQL: 70-80% RAM; PG: 25% RAM

Instances

innodb_buffer_pool_instances

N/A

One per GB of buffer pool

Sort memory

sort_buffer_size

work_mem

Per-operation; careful with high connections

Cache hint

N/A

effective_cache_size

75% of total RAM

Hit rate target

>95% (1000/1000)

>99%

Lower = buffer pool too small

Key Takeaways

  • Buffer pool hit rate is the most important InnoDB metric — below 95% → increase buffer pool

  • MySQL: innodb_buffer_pool_size = 70-80% of RAM on dedicated DB servers

  • PostgreSQL: shared_buffers = 25% (PG uses OS page cache too); work_mem is per-sort, can multiply

  • SHOW ENGINE INNODB STATUS is your MySQL buffer pool dashboard

  • pg_buffercache shows exactly what's cached — invaluable for hot data analysis

Last updated