add: log schema cache queries' timings
This adds a new log line that shows each schema cache query time individually, only on `log-level=debug`. Like so: ``` $ PGRST_LOG_LEVEL=debug postgrest-with-pg-17 -f test/spec/fixtures/load.sql postgrest-run .... 10/Apr/2026:21:48:45 -0500: Schema cache queried in 192.2 milliseconds 10/Apr/2026:21:48:45 -0500: tables: 72.027 ms, keydeps: 20.118 ms, rels: 6.189 ms, funcs: 35.010 ms, comprels: 4.319 ms, dreps: 1.614 ms, mhandlers: 7.419 ms, tzones: 43.025 ms ``` This helps debug specific schema cache queries being slow like on https://github.com/PostgREST/postgrest/issues/4613#issuecomment-4210191065 and https://github.com/PostgREST/postgrest/issues/3046#issuecomment-3469059948. It also closes https://github.com/PostgREST/postgrest/issues/3215, which main motivation was to find out which query is slow. Implementation details --------------------- To time each query inside a transaction in pure SQL, we do: ```sql -- start timer select set_config('pgrst.tmp_x', clock_timestamp()::text, false); -- run the query select <query> -- end timer select set_config('pgrst.tmp_x', (clock_timestamp() - current_setting('pgrst.tmp_x', false)::timestamptz)::text, false); -- .... repeated for every query -- at the end we capture all the timings with select extract('milliseconds' from current_setting('pgrst.tmp_x', false)::interval), extract(..; ``` Considerations -------------- Only added this on `log-level=debug` because while the queries are fast and the data is valuable, it triples the amount of queries we run during schema cache refresh, which could be troublesome on slow networks. It's possible to reduce the amount of queries by starting and stopping timers in one statement, but this would still double the amount of queries and makes the code messy, doesn't seem worth it. Also it would pollute pg_stat_statements, it's only required to debug certain extreme cases anyway.
This commit is contained in:
committed by
Steve Chavez
parent
6af77360d3
commit
bcc8998e5e
@@ -36,6 +36,7 @@ import PostgREST.Config (LogLevel (..), Verbosity (..))
|
||||
import PostgREST.Debounce (makeDebouncer)
|
||||
import PostgREST.Observation
|
||||
import PostgREST.Query (MainQuery (..))
|
||||
import PostgREST.SchemaCache (queryTimingsWLabels)
|
||||
|
||||
import qualified Data.ByteString.Lazy as LBS
|
||||
import qualified Data.Text as T
|
||||
@@ -168,8 +169,10 @@ observationMessages = \case
|
||||
<> " and "
|
||||
<> "db-extra-search-path=" <> T.intercalate "," extraPaths
|
||||
<> ". " <> jsonMessage usageErr
|
||||
SchemaCacheQueriedObs resultTime ->
|
||||
pure $ "Schema cache queried in " <> showMillis resultTime <> " milliseconds"
|
||||
SchemaCacheQueriedObs resultTime timings ->
|
||||
[ "Schema cache queried in " <> showMillis resultTime <> " milliseconds " ] <>
|
||||
let showTimings qt = [ T.intercalate ", " $ (\(l, v) -> T.decodeUtf8 l <> ": " <> v <> " ms") <$> queryTimingsWLabels qt ] in
|
||||
maybe mempty showTimings timings
|
||||
SchemaCacheLoadedObs resultTime summary ->
|
||||
[
|
||||
"Schema cache loaded " <> summary
|
||||
|
||||
Reference in New Issue
Block a user