Skip to content

Commit

Permalink
move queries to inspect module and exclude system schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
encima committed Apr 10, 2024
1 parent 024d247 commit ba690a4
Show file tree
Hide file tree
Showing 20 changed files with 372 additions and 332 deletions.
65 changes: 2 additions & 63 deletions internal/inspect/bloat/bloat.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,73 +8,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

const QUERY = `
WITH constants AS (
SELECT current_setting('block_size')::numeric AS bs, 23 AS hdr, 4 AS ma
), bloat_info AS (
SELECT
ma,bs,schemaname,tablename,
(datawidth+(hdr+ma-(case when hdr%ma=0 THEN ma ELSE hdr%ma END)))::numeric AS datahdr,
(maxfracsum*(nullhdr+ma-(case when nullhdr%ma=0 THEN ma ELSE nullhdr%ma END))) AS nullhdr2
FROM (
SELECT
schemaname, tablename, hdr, ma, bs,
SUM((1-null_frac)*avg_width) AS datawidth,
MAX(null_frac) AS maxfracsum,
hdr+(
SELECT 1+count(*)/8
FROM pg_stats s2
WHERE null_frac<>0 AND s2.schemaname = s.schemaname AND s2.tablename = s.tablename
) AS nullhdr
FROM pg_stats s, constants
GROUP BY 1,2,3,4,5
) AS foo
), table_bloat AS (
SELECT
schemaname, tablename, cc.relpages, bs,
CEIL((cc.reltuples*((datahdr+ma-
(CASE WHEN datahdr%ma=0 THEN ma ELSE datahdr%ma END))+nullhdr2+4))/(bs-20::float)) AS otta
FROM bloat_info
JOIN pg_class cc ON cc.relname = bloat_info.tablename
JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname = bloat_info.schemaname AND nn.nspname <> 'information_schema'
), index_bloat AS (
SELECT
schemaname, tablename, bs,
COALESCE(c2.relname,'?') AS iname, COALESCE(c2.reltuples,0) AS ituples, COALESCE(c2.relpages,0) AS ipages,
COALESCE(CEIL((c2.reltuples*(datahdr-12))/(bs-20::float)),0) AS iotta -- very rough approximation, assumes all cols
FROM bloat_info
JOIN pg_class cc ON cc.relname = bloat_info.tablename
JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname = bloat_info.schemaname AND nn.nspname <> 'information_schema'
JOIN pg_index i ON indrelid = cc.oid
JOIN pg_class c2 ON c2.oid = i.indexrelid
)
SELECT
type, schemaname, object_name, bloat, pg_size_pretty(raw_waste) as waste
FROM
(SELECT
'table' as type,
schemaname,
tablename as object_name,
ROUND(CASE WHEN otta=0 THEN 0.0 ELSE table_bloat.relpages/otta::numeric END,1) AS bloat,
CASE WHEN relpages < otta THEN '0' ELSE (bs*(table_bloat.relpages-otta)::bigint)::bigint END AS raw_waste
FROM
table_bloat
UNION
SELECT
'index' as type,
schemaname,
tablename || '::' || iname as object_name,
ROUND(CASE WHEN iotta=0 OR ipages=0 THEN 0.0 ELSE ipages/iotta::numeric END,1) AS bloat,
CASE WHEN ipages < iotta THEN '0' ELSE (bs*(ipages-iotta))::bigint END AS raw_waste
FROM
index_bloat) bloat_summary
ORDER BY raw_waste DESC, bloat DESC`

type Result struct {
Type string
Schemaname string
Expand All @@ -88,7 +27,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.BloatQuery())
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
22 changes: 2 additions & 20 deletions internal/inspect/blocking/blocking.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

// Ref: https://github.com/heroku/heroku-pg-extras/blob/main/commands/blocking.js#L7
const QUERY = `
SELECT
bl.pid AS blocked_pid,
ka.query AS blocking_statement,
now() - ka.query_start AS blocking_duration,
kl.pid AS blocking_pid,
a.query AS blocked_statement,
now() - a.query_start AS blocked_duration
FROM pg_catalog.pg_locks bl
JOIN pg_catalog.pg_stat_activity a
ON bl.pid = a.pid
JOIN pg_catalog.pg_locks kl
JOIN pg_catalog.pg_stat_activity ka
ON kl.pid = ka.pid
ON bl.transactionid = kl.transactionid AND bl.pid != kl.pid
WHERE NOT bl.granted
`

type Result struct {
Blocked_pid string
Blocking_statement string
Expand All @@ -47,7 +29,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.BLOCKING_QUERY)
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
17 changes: 3 additions & 14 deletions internal/inspect/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

// Ref: https://github.com/heroku/heroku-pg-extras/blob/main/commands/cache_hit.js#L7
const QUERY = `
SELECT
'index hit rate' AS name,
(sum(idx_blks_hit)) / nullif(sum(idx_blks_hit + idx_blks_read),0) AS ratio
FROM pg_statio_user_indexes
UNION ALL
SELECT
'table hit rate' AS name,
sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read),0) AS ratio
FROM pg_statio_user_tables;
`

type Result struct {
Name string
Ratio float64
Expand All @@ -36,7 +24,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.CACHE_QUERY)
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand All @@ -48,6 +36,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
table := "|Name|Ratio|\n|-|-|\n"
for _, r := range result {
table += fmt.Sprintf("|`%s`|`%.6f`|\n", r.Name, r.Ratio)

}
return list.RenderTable(table)
}
15 changes: 2 additions & 13 deletions internal/inspect/calls/calls.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

const QUERY = `
SELECT
query,
interval '1 millisecond' * total_exec_time AS total_exec_time,
to_char((total_exec_time/sum(total_exec_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
to_char(calls, 'FM999G999G990') AS ncalls,
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time
FROM pg_stat_statements
ORDER BY calls DESC
LIMIT 10
`

type Result struct {
Total_exec_time string
Prop_exec_time string
Expand All @@ -39,7 +28,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.CALLS_QUERY)
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
14 changes: 2 additions & 12 deletions internal/inspect/index_sizes/index_sizes.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

const QUERY = `
SELECT c.relname AS name,
pg_size_pretty(sum(c.relpages::bigint*8192)::bigint) AS size
FROM pg_class c
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
AND n.nspname !~ '^pg_toast'
AND c.relkind='i'
GROUP BY c.relname
ORDER BY sum(c.relpages) DESC;`

type Result struct {
Name string
Size string
Expand All @@ -34,7 +24,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.IndexSizesQuery())
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
22 changes: 2 additions & 20 deletions internal/inspect/index_usage/index_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

const QUERY = `
SELECT relname,
CASE
WHEN idx_scan IS NULL THEN 'Insufficient data'
WHEN idx_scan = 0 THEN 'Insufficient data'
ELSE (100 * idx_scan / (seq_scan + idx_scan))::text
END percent_of_times_index_used,
n_live_tup rows_in_table
FROM
pg_stat_user_tables
ORDER BY
CASE
WHEN idx_scan is null then 1
WHEN idx_scan = 0 then 1
ELSE 0
END,
n_live_tup DESC;
`

type Result struct {
Relname string
Percent_of_times_index_used string
Expand All @@ -43,7 +25,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.INDEX_USAGE_QUERY)
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
18 changes: 2 additions & 16 deletions internal/inspect/locks/locks.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

const QUERY = `
SELECT
pg_stat_activity.pid,
COALESCE(pg_class.relname, 'null') AS relname,
COALESCE(pg_locks.transactionid, 'null') AS transactionid,
pg_locks.granted,
pg_stat_activity.query,
age(now(),pg_stat_activity.query_start) AS age
FROM pg_stat_activity, pg_locks LEFT OUTER JOIN pg_class ON (pg_locks.relation = pg_class.oid)
WHERE pg_stat_activity.query <> '<insufficient privilege>'
AND pg_locks.pid=pg_stat_activity.pid
AND pg_locks.mode = 'ExclusiveLock'
ORDER BY query_start;
`

type Result struct {
Pid string
Relname string
Expand All @@ -43,7 +29,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.LOCKS_QUERY)
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
17 changes: 2 additions & 15 deletions internal/inspect/long_running_queries/long_running_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

const QUERY = `
SELECT
pid,
now() - pg_stat_activity.query_start AS duration,
query AS query
FROM
pg_stat_activity
WHERE
pg_stat_activity.query <> ''::text
AND state <> 'idle'
AND now() - pg_stat_activity.query_start > interval '5 minutes'
ORDER BY
now() - pg_stat_activity.query_start DESC;`

type Result struct {
Pid string
Duration string
Expand All @@ -38,7 +25,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.LONG_RUNNING_QUERY)
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
15 changes: 2 additions & 13 deletions internal/inspect/outliers/outliers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,12 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/inspect"
"github.com/supabase/cli/internal/migration/list"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/pgxv5"
)

const QUERY = `
SELECT
interval '1 millisecond' * total_exec_time AS total_exec_time,
to_char((total_exec_time/sum(total_exec_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
to_char(calls, 'FM999G999G999G990') AS ncalls,
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time,
query
FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
ORDER BY total_exec_time DESC
LIMIT 10
`

type Result struct {
Total_exec_time string
Prop_exec_time string
Expand All @@ -39,7 +28,7 @@ func Run(ctx context.Context, config pgconn.Config, fsys afero.Fs, options ...fu
if err != nil {
return err
}
rows, err := conn.Query(ctx, QUERY)
rows, err := conn.Query(ctx, inspect.OUTLIERS_QUERY)
if err != nil {
return errors.Errorf("failed to query rows: %w", err)
}
Expand Down
Loading

0 comments on commit ba690a4

Please sign in to comment.