pg-stats 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/executables/pg-stats-bloat +7 -0
- data/executables/pg-stats-blocking-queries +7 -0
- data/executables/pg-stats-cache-hit-rate +7 -0
- data/executables/pg-stats-extensions +7 -0
- data/executables/pg-stats-index-size +7 -0
- data/executables/pg-stats-index-usage +7 -0
- data/executables/pg-stats-locks +7 -0
- data/executables/pg-stats-long-running-queries +7 -0
- data/executables/pg-stats-outliers +7 -0
- data/executables/pg-stats-records-rank +7 -0
- data/executables/pg-stats-seq-scans +7 -0
- data/executables/pg-stats-slow-statements +7 -0
- data/executables/pg-stats-statements-reset +7 -0
- data/executables/pg-stats-table-indexes-size +7 -0
- data/executables/pg-stats-table-size +7 -0
- data/executables/pg-stats-total-index-size +7 -0
- data/executables/pg-stats-total-table-size +7 -0
- data/executables/pg-stats-unused-indexes +7 -0
- data/executables/pg-stats-vacuum +7 -0
- data/queries/MIT-License.txt +20 -0
- data/queries/bloat.sql +63 -0
- data/queries/blocking-queries.sql +16 -0
- data/queries/cache-hit-rate.sql +11 -0
- data/queries/extensions.sql +4 -0
- data/queries/index-size.sql +11 -0
- data/queries/index-usage.sql +12 -0
- data/queries/locks.sql +16 -0
- data/queries/long-running-queries.sql +14 -0
- data/queries/outliers.sql +10 -0
- data/queries/records-rank.sql +9 -0
- data/queries/seq-scans.sql +7 -0
- data/queries/slow-statements.sql +9 -0
- data/queries/table-indexes-size.sql +10 -0
- data/queries/table-size.sql +10 -0
- data/queries/total-index-size.sql +8 -0
- data/queries/total-table-size.sql +10 -0
- data/queries/unused-indexes.sql +16 -0
- data/queries/vacuum.sql +40 -0
- data/scripts/bloat.sh +13 -0
- data/scripts/blocking-queries.sh +13 -0
- data/scripts/cache-hit-rate.sh +13 -0
- data/scripts/extensions.sh +13 -0
- data/scripts/index-size.sh +13 -0
- data/scripts/index-usage.sh +13 -0
- data/scripts/locks.sh +13 -0
- data/scripts/long-running-queries.sh +13 -0
- data/scripts/outliers.sh +16 -0
- data/scripts/records-rank.sh +13 -0
- data/scripts/run.sh +19 -0
- data/scripts/seq-scans.sh +13 -0
- data/scripts/slow-statements.sh +16 -0
- data/scripts/statements-reset.sh +14 -0
- data/scripts/table-indexes-size.sh +13 -0
- data/scripts/table-size.sh +13 -0
- data/scripts/total-index-size.sh +13 -0
- data/scripts/total-table-size.sh +13 -0
- data/scripts/unused-indexes.sh +13 -0
- data/scripts/vacuum.sh +13 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2f0b03f1555456bb9186044dd2e591d03905c61a3861dec3852a7aeb2778625d
|
4
|
+
data.tar.gz: 11bc08a05d97bc1c75e2486d4e5768f6e5a50022e927c9102e889d7dbeaeccd9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b1d30f8938922f6a7a31cb3c703bbd0348b3b7b0a38f591ab1c3483901c7a1fb194464b467d32806468012ba0625fbe72416225022be034af9e22908033a25da
|
7
|
+
data.tar.gz: db963d167755e828781bf57cffa49a6a13943899000ff4c2ea9bd671c079f92d9424f017d3e2c4935324ec5f676a7cafc4770fd97f08212a5366880e4a08c1d4
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright © Paweł Urbanek 2019
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/queries/bloat.sql
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
/* Table and index bloat in your database ordered by most wasteful */
|
2
|
+
|
3
|
+
WITH constants AS (
|
4
|
+
SELECT current_setting('block_size')::numeric AS bs, 23 AS hdr, 4 AS ma
|
5
|
+
), bloat_info AS (
|
6
|
+
SELECT
|
7
|
+
ma,bs,schemaname,tablename,
|
8
|
+
(datawidth+(hdr+ma-(case when hdr%ma=0 THEN ma ELSE hdr%ma END)))::numeric AS datahdr,
|
9
|
+
(maxfracsum*(nullhdr+ma-(case when nullhdr%ma=0 THEN ma ELSE nullhdr%ma END))) AS nullhdr2
|
10
|
+
FROM (
|
11
|
+
SELECT
|
12
|
+
schemaname, tablename, hdr, ma, bs,
|
13
|
+
SUM((1-null_frac)*avg_width) AS datawidth,
|
14
|
+
MAX(null_frac) AS maxfracsum,
|
15
|
+
hdr+(
|
16
|
+
SELECT 1+count(*)/8
|
17
|
+
FROM pg_stats s2
|
18
|
+
WHERE null_frac<>0 AND s2.schemaname = s.schemaname AND s2.tablename = s.tablename
|
19
|
+
) AS nullhdr
|
20
|
+
FROM pg_stats s, constants
|
21
|
+
GROUP BY 1,2,3,4,5
|
22
|
+
) AS foo
|
23
|
+
), table_bloat AS (
|
24
|
+
SELECT
|
25
|
+
schemaname, tablename, cc.relpages, bs,
|
26
|
+
CEIL((cc.reltuples*((datahdr+ma-
|
27
|
+
(CASE WHEN datahdr%ma=0 THEN ma ELSE datahdr%ma END))+nullhdr2+4))/(bs-20::float)) AS otta
|
28
|
+
FROM bloat_info
|
29
|
+
JOIN pg_class cc ON cc.relname = bloat_info.tablename
|
30
|
+
JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname = bloat_info.schemaname AND nn.nspname <> 'information_schema'
|
31
|
+
), index_bloat AS (
|
32
|
+
SELECT
|
33
|
+
schemaname, tablename, bs,
|
34
|
+
COALESCE(c2.relname,'?') AS iname, COALESCE(c2.reltuples,0) AS ituples, COALESCE(c2.relpages,0) AS ipages,
|
35
|
+
COALESCE(CEIL((c2.reltuples*(datahdr-12))/(bs-20::float)),0) AS iotta -- very rough approximation, assumes all cols
|
36
|
+
FROM bloat_info
|
37
|
+
JOIN pg_class cc ON cc.relname = bloat_info.tablename
|
38
|
+
JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname = bloat_info.schemaname AND nn.nspname <> 'information_schema'
|
39
|
+
JOIN pg_index i ON indrelid = cc.oid
|
40
|
+
JOIN pg_class c2 ON c2.oid = i.indexrelid
|
41
|
+
)
|
42
|
+
SELECT
|
43
|
+
type, schemaname, object_name, bloat, pg_size_pretty(raw_waste) as waste
|
44
|
+
FROM
|
45
|
+
(SELECT
|
46
|
+
'table' as type,
|
47
|
+
schemaname,
|
48
|
+
tablename as object_name,
|
49
|
+
ROUND(CASE WHEN otta=0 THEN 0.0 ELSE table_bloat.relpages/otta::numeric END,1) AS bloat,
|
50
|
+
CASE WHEN relpages < otta THEN '0' ELSE (bs*(table_bloat.relpages-otta)::bigint)::bigint END AS raw_waste
|
51
|
+
FROM
|
52
|
+
table_bloat
|
53
|
+
UNION
|
54
|
+
SELECT
|
55
|
+
'index' as type,
|
56
|
+
schemaname,
|
57
|
+
tablename || '::' || iname as object_name,
|
58
|
+
ROUND(CASE WHEN iotta=0 OR ipages=0 THEN 0.0 ELSE ipages/iotta::numeric END,1) AS bloat,
|
59
|
+
CASE WHEN ipages < iotta THEN '0' ELSE (bs*(ipages-iotta))::bigint END AS raw_waste
|
60
|
+
FROM
|
61
|
+
index_bloat) bloat_summary
|
62
|
+
ORDER BY raw_waste DESC, bloat DESC;
|
63
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/* Queries holding locks which other queries are waiting to be released */
|
2
|
+
|
3
|
+
SELECT bl.pid AS blocked_pid,
|
4
|
+
ka.query AS blocking_statement,
|
5
|
+
now() - ka.query_start AS blocking_duration,
|
6
|
+
kl.pid AS blocking_pid,
|
7
|
+
a.query AS blocked_statement,
|
8
|
+
now() - a.query_start AS blocked_duration
|
9
|
+
FROM pg_catalog.pg_locks bl
|
10
|
+
JOIN pg_catalog.pg_stat_activity a
|
11
|
+
ON bl.pid = a.pid
|
12
|
+
JOIN pg_catalog.pg_locks kl
|
13
|
+
JOIN pg_catalog.pg_stat_activity ka
|
14
|
+
ON kl.pid = ka.pid
|
15
|
+
ON bl.transactionid = kl.transactionid AND bl.pid != kl.pid
|
16
|
+
WHERE NOT bl.granted;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/* Index and table hit rate */
|
2
|
+
|
3
|
+
SELECT
|
4
|
+
'index hit rate' AS name,
|
5
|
+
(sum(idx_blks_hit)) / nullif(sum(idx_blks_hit + idx_blks_read),0) AS ratio
|
6
|
+
FROM pg_statio_user_indexes
|
7
|
+
UNION ALL
|
8
|
+
SELECT
|
9
|
+
'table hit rate' AS name,
|
10
|
+
sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read),0) AS ratio
|
11
|
+
FROM pg_statio_user_tables;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/* The size of indexes, descending by size */
|
2
|
+
|
3
|
+
SELECT c.relname AS name,
|
4
|
+
pg_size_pretty(sum(c.relpages::bigint*8192)::bigint) AS size
|
5
|
+
FROM pg_class c
|
6
|
+
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
|
7
|
+
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
|
8
|
+
AND n.nspname !~ '^pg_toast'
|
9
|
+
AND c.relkind='i'
|
10
|
+
GROUP BY c.relname
|
11
|
+
ORDER BY sum(c.relpages) DESC;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
/* Index hit rate (effective databases are at 99% and up) */
|
2
|
+
|
3
|
+
SELECT relname,
|
4
|
+
CASE idx_scan
|
5
|
+
WHEN 0 THEN 'Insufficient data'
|
6
|
+
ELSE (100 * idx_scan / (seq_scan + idx_scan))::text
|
7
|
+
END percent_of_times_index_used,
|
8
|
+
n_live_tup rows_in_table
|
9
|
+
FROM
|
10
|
+
pg_stat_user_tables
|
11
|
+
ORDER BY
|
12
|
+
n_live_tup DESC;
|
data/queries/locks.sql
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
/* Queries with active locks */
|
2
|
+
|
3
|
+
SELECT
|
4
|
+
pg_stat_activity.pid,
|
5
|
+
pg_class.relname,
|
6
|
+
pg_locks.transactionid,
|
7
|
+
pg_locks.granted,
|
8
|
+
pg_locks.mode,
|
9
|
+
pg_stat_activity.query AS query_snippet,
|
10
|
+
age(now(),pg_stat_activity.query_start) AS "age"
|
11
|
+
FROM pg_stat_activity,pg_locks left
|
12
|
+
OUTER JOIN pg_class
|
13
|
+
ON (pg_locks.relation = pg_class.oid)
|
14
|
+
WHERE pg_stat_activity.query <> '<insufficient privilege>'
|
15
|
+
AND pg_locks.pid = pg_stat_activity.pid
|
16
|
+
AND pg_stat_activity.pid <> pg_backend_pid() order by query_start;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/* All queries longer than 1 minute by descending duration */
|
2
|
+
|
3
|
+
SELECT
|
4
|
+
pid,
|
5
|
+
now() - pg_stat_activity.query_start AS duration,
|
6
|
+
query AS query
|
7
|
+
FROM
|
8
|
+
pg_stat_activity
|
9
|
+
WHERE
|
10
|
+
pg_stat_activity.query <> ''::text
|
11
|
+
AND state <> 'idle'
|
12
|
+
AND now() - pg_stat_activity.query_start > interval '1 minute'
|
13
|
+
ORDER BY
|
14
|
+
now() - pg_stat_activity.query_start DESC;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/* 10 queries that have longest execution time in aggregate */
|
2
|
+
|
3
|
+
SELECT interval '1 millisecond' * total_time AS total_exec_time,
|
4
|
+
to_char((total_time/sum(total_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
|
5
|
+
to_char(calls, 'FM999G999G999G990') AS ncalls,
|
6
|
+
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time,
|
7
|
+
query AS query
|
8
|
+
FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
|
9
|
+
ORDER BY total_time DESC
|
10
|
+
LIMIT 10;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* 10 queries that have longest execution time in aggregate */
|
2
|
+
|
3
|
+
SELECT query AS qry,
|
4
|
+
interval '1 millisecond' * total_time AS exec_time,
|
5
|
+
to_char((total_time/sum(total_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
|
6
|
+
to_char(calls, 'FM999G999G990') AS ncalls,
|
7
|
+
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time
|
8
|
+
FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
|
9
|
+
ORDER BY calls DESC LIMIT 10;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/* Total size of all the indexes on each table, descending by size */
|
2
|
+
|
3
|
+
SELECT c.relname AS table,
|
4
|
+
pg_size_pretty(pg_indexes_size(c.oid)) AS index_size
|
5
|
+
FROM pg_class c
|
6
|
+
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
|
7
|
+
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
|
8
|
+
AND n.nspname !~ '^pg_toast'
|
9
|
+
AND c.relkind='r'
|
10
|
+
ORDER BY pg_indexes_size(c.oid) DESC;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/* Size of the tables (excluding indexes), descending by size */
|
2
|
+
|
3
|
+
SELECT c.relname AS name,
|
4
|
+
pg_size_pretty(pg_table_size(c.oid)) AS size
|
5
|
+
FROM pg_class c
|
6
|
+
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
|
7
|
+
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
|
8
|
+
AND n.nspname !~ '^pg_toast'
|
9
|
+
AND c.relkind='r'
|
10
|
+
ORDER BY pg_table_size(c.oid) DESC;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
/* Total size of all indexes in MB */
|
2
|
+
|
3
|
+
SELECT pg_size_pretty(sum(c.relpages::bigint*8192)::bigint) AS size
|
4
|
+
FROM pg_class c
|
5
|
+
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
|
6
|
+
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
|
7
|
+
AND n.nspname !~ '^pg_toast'
|
8
|
+
AND c.relkind='i';
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/* Size of the tables (including indexes), descending by size */
|
2
|
+
|
3
|
+
SELECT c.relname AS name,
|
4
|
+
pg_size_pretty(pg_total_relation_size(c.oid)) AS size
|
5
|
+
FROM pg_class c
|
6
|
+
LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
|
7
|
+
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
|
8
|
+
AND n.nspname !~ '^pg_toast'
|
9
|
+
AND c.relkind='r'
|
10
|
+
ORDER BY pg_total_relation_size(c.oid) DESC;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/* Unused and almost unused indexes */
|
2
|
+
/* Ordered by their size relative to the number of index scans.
|
3
|
+
Exclude indexes of very small tables (less than 5 pages),
|
4
|
+
where the planner will almost invariably select a sequential scan,
|
5
|
+
but may not in the future as the table grows */
|
6
|
+
|
7
|
+
SELECT
|
8
|
+
schemaname || '.' || relname AS table,
|
9
|
+
indexrelname AS index,
|
10
|
+
pg_size_pretty(pg_relation_size(i.indexrelid)) AS index_size,
|
11
|
+
idx_scan as index_scans
|
12
|
+
FROM pg_stat_user_indexes ui
|
13
|
+
JOIN pg_index i ON ui.indexrelid = i.indexrelid
|
14
|
+
WHERE NOT indisunique AND idx_scan < 50 AND pg_relation_size(relid) > 5 * 8192
|
15
|
+
ORDER BY pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST,
|
16
|
+
pg_relation_size(i.indexrelid) DESC;
|
data/queries/vacuum.sql
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
/* Dead rows and whether an automatic vacuum is expected to be triggered */
|
2
|
+
|
3
|
+
WITH table_opts AS (
|
4
|
+
SELECT
|
5
|
+
pg_class.oid, relname, nspname, array_to_string(reloptions, '') AS relopts
|
6
|
+
FROM
|
7
|
+
pg_class INNER JOIN pg_namespace ns ON relnamespace = ns.oid
|
8
|
+
), vacuum_settings AS (
|
9
|
+
SELECT
|
10
|
+
oid, relname, nspname,
|
11
|
+
CASE
|
12
|
+
WHEN relopts LIKE '%autovacuum_vacuum_threshold%'
|
13
|
+
THEN substring(relopts, '.*autovacuum_vacuum_threshold=([0-9.]+).*')::integer
|
14
|
+
ELSE current_setting('autovacuum_vacuum_threshold')::integer
|
15
|
+
END AS autovacuum_vacuum_threshold,
|
16
|
+
CASE
|
17
|
+
WHEN relopts LIKE '%autovacuum_vacuum_scale_factor%'
|
18
|
+
THEN substring(relopts, '.*autovacuum_vacuum_scale_factor=([0-9.]+).*')::real
|
19
|
+
ELSE current_setting('autovacuum_vacuum_scale_factor')::real
|
20
|
+
END AS autovacuum_vacuum_scale_factor
|
21
|
+
FROM
|
22
|
+
table_opts
|
23
|
+
)
|
24
|
+
SELECT
|
25
|
+
vacuum_settings.nspname AS schema,
|
26
|
+
vacuum_settings.relname AS table,
|
27
|
+
to_char(psut.last_vacuum, 'YYYY-MM-DD HH24:MI') AS last_vacuum,
|
28
|
+
to_char(psut.last_autovacuum, 'YYYY-MM-DD HH24:MI') AS last_autovacuum,
|
29
|
+
to_char(pg_class.reltuples, '9G999G999G999') AS rowcount,
|
30
|
+
to_char(psut.n_dead_tup, '9G999G999G999') AS dead_rowcount,
|
31
|
+
to_char(autovacuum_vacuum_threshold
|
32
|
+
+ (autovacuum_vacuum_scale_factor::numeric * pg_class.reltuples), '9G999G999G999') AS autovacuum_threshold,
|
33
|
+
CASE
|
34
|
+
WHEN autovacuum_vacuum_threshold + (autovacuum_vacuum_scale_factor::numeric * pg_class.reltuples) < psut.n_dead_tup
|
35
|
+
THEN 'yes'
|
36
|
+
END AS expect_autovacuum
|
37
|
+
FROM
|
38
|
+
pg_stat_user_tables psut INNER JOIN pg_class ON psut.relid = pg_class.oid
|
39
|
+
INNER JOIN vacuum_settings ON pg_class.oid = vacuum_settings.oid
|
40
|
+
ORDER BY 1;
|
data/scripts/bloat.sh
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Blocking Queries"
|
9
|
+
echo "= = ="
|
10
|
+
echo "Queries holding locks which other queries are waiting to be released"
|
11
|
+
echo
|
12
|
+
|
13
|
+
run blocking-queries.sql
|
data/scripts/locks.sh
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Long-Running Queries"
|
9
|
+
echo "= = ="
|
10
|
+
echo "All queries longer than 1 minute by descending duration"
|
11
|
+
echo
|
12
|
+
|
13
|
+
run long-running-queries.sql
|
data/scripts/outliers.sh
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Outliers"
|
9
|
+
echo "= = ="
|
10
|
+
echo "10 queries that have longest execution time in aggregate"
|
11
|
+
echo
|
12
|
+
echo "NOTE: Requires the pg_stats_statement extension"
|
13
|
+
echo "https://www.postgresql.org/docs/current/pgstatstatements.html"
|
14
|
+
echo
|
15
|
+
|
16
|
+
run outliers.sql
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Records Rank"
|
9
|
+
echo "= = ="
|
10
|
+
echo "All tables and the number of rows in each ordered by number of rows descending"
|
11
|
+
echo
|
12
|
+
|
13
|
+
run records-rank.sql
|
data/scripts/run.sh
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
function run {
|
6
|
+
sql_file=$1
|
7
|
+
|
8
|
+
current_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
9
|
+
queries_dir="$current_dir/../queries"
|
10
|
+
|
11
|
+
relative_sql_file=$queries_dir/$sql_file
|
12
|
+
|
13
|
+
absolute_sql_file="$(cd "$(dirname "$relative_sql_file")"; pwd)/$(basename "$relative_sql_file")"
|
14
|
+
|
15
|
+
echo $absolute_sql_file
|
16
|
+
echo
|
17
|
+
|
18
|
+
psql -P pager=off -f $absolute_sql_file
|
19
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Slow Statements"
|
9
|
+
echo "= = ="
|
10
|
+
echo "10 queries that have longest execution time in aggregate"
|
11
|
+
echo
|
12
|
+
echo "NOTE: Requires the pg_stats_statement extension"
|
13
|
+
echo "https://www.postgresql.org/docs/current/pgstatstatements.html"
|
14
|
+
echo
|
15
|
+
|
16
|
+
run slow-statements.sql
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
echo
|
6
|
+
echo "Statements Reset"
|
7
|
+
echo "= = ="
|
8
|
+
echo "Reset statements statistics data"
|
9
|
+
echo
|
10
|
+
echo "NOTE: Requires the pg_stats_statement extension"
|
11
|
+
echo "https://www.postgresql.org/docs/current/pgstatstatements.html"
|
12
|
+
echo
|
13
|
+
|
14
|
+
psql -P pager=off -c "SELECT pg_stat_statements_reset();"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Table Indexes Size"
|
9
|
+
echo "= = ="
|
10
|
+
echo "Total size of all the indexes on each table, descending by size"
|
11
|
+
echo
|
12
|
+
|
13
|
+
run table-indexes-size.sql
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Total Table Size"
|
9
|
+
echo "= = ="
|
10
|
+
echo "Size of the tables (including indexes), descending by size"
|
11
|
+
echo
|
12
|
+
|
13
|
+
run total-table-size.sql
|
data/scripts/vacuum.sh
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/run.sh"
|
6
|
+
|
7
|
+
echo
|
8
|
+
echo "Vacuum Stats"
|
9
|
+
echo "= = ="
|
10
|
+
echo "Dead rows and whether an automatic vacuum is expected to be triggered"
|
11
|
+
echo
|
12
|
+
|
13
|
+
run vacuum.sql
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pg-stats
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- The Eventide Project
|
8
|
+
autorequire:
|
9
|
+
bindir: executables
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-09 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: " "
|
14
|
+
email: opensource@eventide-project.org
|
15
|
+
executables:
|
16
|
+
- pg-stats-table-indexes-size
|
17
|
+
- pg-stats-total-index-size
|
18
|
+
- pg-stats-records-rank
|
19
|
+
- pg-stats-locks
|
20
|
+
- pg-stats-index-usage
|
21
|
+
- pg-stats-seq-scans
|
22
|
+
- pg-stats-total-table-size
|
23
|
+
- pg-stats-bloat
|
24
|
+
- pg-stats-index-size
|
25
|
+
- pg-stats-blocking-queries
|
26
|
+
- pg-stats-unused-indexes
|
27
|
+
- pg-stats-long-running-queries
|
28
|
+
- pg-stats-extensions
|
29
|
+
- pg-stats-statements-reset
|
30
|
+
- pg-stats-outliers
|
31
|
+
- pg-stats-vacuum
|
32
|
+
- pg-stats-table-size
|
33
|
+
- pg-stats-slow-statements
|
34
|
+
- pg-stats-cache-hit-rate
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- executables/pg-stats-bloat
|
39
|
+
- executables/pg-stats-blocking-queries
|
40
|
+
- executables/pg-stats-cache-hit-rate
|
41
|
+
- executables/pg-stats-extensions
|
42
|
+
- executables/pg-stats-index-size
|
43
|
+
- executables/pg-stats-index-usage
|
44
|
+
- executables/pg-stats-locks
|
45
|
+
- executables/pg-stats-long-running-queries
|
46
|
+
- executables/pg-stats-outliers
|
47
|
+
- executables/pg-stats-records-rank
|
48
|
+
- executables/pg-stats-seq-scans
|
49
|
+
- executables/pg-stats-slow-statements
|
50
|
+
- executables/pg-stats-statements-reset
|
51
|
+
- executables/pg-stats-table-indexes-size
|
52
|
+
- executables/pg-stats-table-size
|
53
|
+
- executables/pg-stats-total-index-size
|
54
|
+
- executables/pg-stats-total-table-size
|
55
|
+
- executables/pg-stats-unused-indexes
|
56
|
+
- executables/pg-stats-vacuum
|
57
|
+
- queries/MIT-License.txt
|
58
|
+
- queries/bloat.sql
|
59
|
+
- queries/blocking-queries.sql
|
60
|
+
- queries/cache-hit-rate.sql
|
61
|
+
- queries/extensions.sql
|
62
|
+
- queries/index-size.sql
|
63
|
+
- queries/index-usage.sql
|
64
|
+
- queries/locks.sql
|
65
|
+
- queries/long-running-queries.sql
|
66
|
+
- queries/outliers.sql
|
67
|
+
- queries/records-rank.sql
|
68
|
+
- queries/seq-scans.sql
|
69
|
+
- queries/slow-statements.sql
|
70
|
+
- queries/table-indexes-size.sql
|
71
|
+
- queries/table-size.sql
|
72
|
+
- queries/total-index-size.sql
|
73
|
+
- queries/total-table-size.sql
|
74
|
+
- queries/unused-indexes.sql
|
75
|
+
- queries/vacuum.sql
|
76
|
+
- scripts/bloat.sh
|
77
|
+
- scripts/blocking-queries.sh
|
78
|
+
- scripts/cache-hit-rate.sh
|
79
|
+
- scripts/extensions.sh
|
80
|
+
- scripts/index-size.sh
|
81
|
+
- scripts/index-usage.sh
|
82
|
+
- scripts/locks.sh
|
83
|
+
- scripts/long-running-queries.sh
|
84
|
+
- scripts/outliers.sh
|
85
|
+
- scripts/records-rank.sh
|
86
|
+
- scripts/run.sh
|
87
|
+
- scripts/seq-scans.sh
|
88
|
+
- scripts/slow-statements.sh
|
89
|
+
- scripts/statements-reset.sh
|
90
|
+
- scripts/table-indexes-size.sh
|
91
|
+
- scripts/table-size.sh
|
92
|
+
- scripts/total-index-size.sh
|
93
|
+
- scripts/total-table-size.sh
|
94
|
+
- scripts/unused-indexes.sh
|
95
|
+
- scripts/vacuum.sh
|
96
|
+
homepage: https://github.com/pg-stats/pg-stats
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata: {}
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubygems_version: 3.0.1
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Database Statistics for Postgres
|
119
|
+
test_files: []
|