(
cases: &[SpeedCase],
id: &str,
statements: &[&str],
)
| 3707 | } |
| 3708 | |
| 3709 | fn run_buffer_cache_diagnostic_case( |
| 3710 | cases: &[SpeedCase], |
| 3711 | id: &str, |
| 3712 | statements: &[&str], |
| 3713 | ) -> Result<BufferCacheDiagnosticCase> { |
| 3714 | let target_index = cases |
| 3715 | .iter() |
| 3716 | .position(|case| case.id == id) |
| 3717 | .ok_or_else(|| anyhow!("unknown speed hotspot case {id}"))?; |
| 3718 | let target = &cases[target_index]; |
| 3719 | |
| 3720 | let mut db = Pglite::builder() |
| 3721 | .temporary() |
| 3722 | .open() |
| 3723 | .with_context(|| format!("open buffer-cache diagnostic database for {}", target.id))?; |
| 3724 | |
| 3725 | let setup_started = Instant::now(); |
| 3726 | for setup_case in &cases[..target_index] { |
| 3727 | db.exec(&setup_case.sql, None) |
| 3728 | .with_context(|| format!("run buffer-cache setup case {}", setup_case.id))?; |
| 3729 | } |
| 3730 | let setup_micros = setup_started.elapsed().as_micros(); |
| 3731 | |
| 3732 | let settings = exec_rows_json( |
| 3733 | &mut db, |
| 3734 | "SELECT current_setting('shared_buffers') AS shared_buffers, current_setting('fsync') AS fsync, current_setting('synchronous_commit') AS synchronous_commit, current_setting('wal_buffers') AS wal_buffers, current_setting('work_mem') AS work_mem", |
| 3735 | )?; |
| 3736 | let relation_sizes = exec_rows_json( |
| 3737 | &mut db, |
| 3738 | "SELECT relname, pg_relation_size(oid)::bigint AS bytes FROM pg_class WHERE relname IN ('t1', 't2', 'i2a', 'i2b') ORDER BY relname", |
| 3739 | )?; |
| 3740 | |
| 3741 | let mut explained = Vec::new(); |
| 3742 | for statement in statements { |
| 3743 | if matches!(*statement, "BEGIN" | "COMMIT") { |
| 3744 | let (result, phases) = capture_phase_timings(|| { |
| 3745 | let started = Instant::now(); |
| 3746 | let result = db.exec(statement, None); |
| 3747 | (result, started.elapsed()) |
| 3748 | }); |
| 3749 | let (result, elapsed) = result; |
| 3750 | result.with_context(|| format!("run transaction control statement {statement}"))?; |
| 3751 | explained.push(BufferCacheDiagnosticStatement { |
| 3752 | sql: (*statement).to_owned(), |
| 3753 | elapsed_micros: elapsed.as_micros(), |
| 3754 | explain_rows: serde_json::Value::Null, |
| 3755 | fs_trace: serde_json::Value::Null, |
| 3756 | phases, |
| 3757 | }); |
| 3758 | continue; |
| 3759 | } |
| 3760 | |
| 3761 | reset_fs_trace(); |
| 3762 | let explain_sql = format!("EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) {statement}"); |
| 3763 | let (result, phases) = capture_phase_timings(|| { |
| 3764 | let started = Instant::now(); |
| 3765 | let result = db.exec(&explain_sql, None); |
| 3766 | (result, started.elapsed()) |
nothing calls this directly
no test coverage detected