and statistics sub-systems • I/O Benchmarking and Linux kernel storage performance tuning • Recently worked on prefetching for direct I/O and I/O statistics https://github.com/melanieplageman @ Microsoft
write time pg_statio_all_tables • hits, reads pg_stat_bgwriter • backend writes, backend fsyncs pg_stat_statements • shared and local buffer hits, reads, writes, read time, write time
enough space to fit the new data i. If no block has enough free space, extend the file. 2. Check for the block in shared buffers. i. If it is already loaded, cache hit! INSERT INTO foo VALUES(1,1); foo shared buffers No I/O needed
enough space to fit the new data i. If no block has enough free space, extend the file. 2. Check for the block in shared buffers. i. If it is already loaded, success! 3. Otherwise, find a shared buffer we can use. i. If it is dirty, flush it. INSERT INTO foo VALUES(1,1); foo shared buffers flush Flush = “write” in pg_stat_io
enough space to fit the new data i. If no block has enough free space, extend the file. 2. Check for the block in shared buffers. i. If it is already loaded, success! 3. Otherwise, find a shared buffer we can use. i. If it is dirty, flush it. 4. Read our block into the buffer. INSERT INTO foo VALUES(1,1); foo shared buffers load
enough space to fit the new data i. If no block has enough free space, extend the file. 2. Check for the block in shared buffers. i. If it is already loaded, success! 3. Otherwise, find a shared buffer we can use. i. If it is dirty, flush it. 4. Read our block into the buffer. 5. Write our data into the buffer. INSERT INTO foo VALUES(1,1); foo (1,1) shared buffers
2. Check for the block in shared buffers. i. If it is, vacuum it! 3. Otherwise, find the next reserved buffer to use. i. If we are not at the reservation cap, evict a shared buffer. reservation cap: 4 used: 3 foo R shared buffers R R 0, 3, 5, 6
2. Check for the block in shared buffers. i. If it is, vacuum it! 3. Otherwise, find the next reserved buffer to use. i. If we are not at the reservation cap, evict a shared buffer. ii. If we are reusing a dirty, reserved buffer, flush it. reservation cap: 4 used: 4 foo R R shared buffers flush R R 0, 3, 5, 6
2. Check for the block in shared buffers. i. If it is, vacuum it! 3. Find the next reserved buffer to use. i. If we are not at the reservation cap, evict a shared buffer. ii. If we are reusing a dirty, reserved buffer, flush it. 4. Read the block into the buffer. reservation cap: 4 used: 4 foo R R shared buffers load R R 0, 3, 5, 6
2. Check for the block in shared buffers. i. If it is, vacuum it! 3. Find the next reserved buffer to use. i. If we are not at the reservation cap, evict a shared buffer. ii. If we are reusing a dirty, reserved buffer, flush it. 4. Read the block into the buffer. 5. Vacuum the buffer and mark it dirty. reservation cap: 4 used: 4 foo R R shared buffers R R 0, 3, 5, 6
is for blocks that are part of the working set • Autovacuum worker reads are often of older data client backend read autovacuum worker read load R load
during bulk read operations of data not in shared buffers. • Shared buffers not used for all I/O • Large* SELECTs not in shared buffers large SELECT (bulkread context) read client backend normal context cache miss foo R R shared buffers R R load load evict *large = table blocks > shared buffers / 4