ruby-pg-extras 1.6.0 → 2.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 +4 -4
- data/.circleci/config.yml +1 -0
- data/README.md +20 -14
- data/docker-compose.yml.sample +20 -1
- data/lib/ruby-pg-extras.rb +13 -0
- data/lib/ruby-pg-extras/queries/calls.sql +2 -2
- data/lib/ruby-pg-extras/queries/calls_legacy.sql +9 -0
- data/lib/ruby-pg-extras/queries/outliers.sql +3 -3
- data/lib/ruby-pg-extras/queries/outliers_legacy.sql +10 -0
- data/lib/ruby-pg-extras/version.rb +1 -1
- data/spec/smoke_spec.rb +6 -3
- data/spec/spec_helper.rb +13 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d71c264c67135e083a2072dfa8248ff46210ae386c813f23417b70c6084d01c2
|
4
|
+
data.tar.gz: 8749efb98e35fb17443f16a1e9a06cd8ce4e70d87f32aef4a20f21b22bfd56b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f31780c4436d533a80fd1b73c4470a09276330ef6a07b8e453807a4b12c4595c05c0dce82ef85d400d4615e9d384b6df25f4f84442007e40d187212e52b33618
|
7
|
+
data.tar.gz: 4de7b1452cea8ef0df3d9f6d3c4c71de7476c6cf2cedb43bdbdff8e4d5f5732890b3251938ab9a811f74e64d4b24c4d325b32a4d5511b072fe152b1b836e98ca
|
data/.circleci/config.yml
CHANGED
@@ -6,6 +6,7 @@ jobs:
|
|
6
6
|
environment:
|
7
7
|
DATABASE_URL: postgresql://postgres:secret@localhost:5432/ruby-pg-extras-test
|
8
8
|
- image: circleci/postgres:11.5
|
9
|
+
command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c max_connections=200
|
9
10
|
environment:
|
10
11
|
POSTGRES_USER: postgres
|
11
12
|
POSTGRES_DB: ruby-pg-extras-test
|
data/README.md
CHANGED
@@ -514,6 +514,22 @@ RubyPGExtras.kill_all
|
|
514
514
|
|
515
515
|
This commands kills all the currently active connections to the database. It can be useful as a last resort when your database is stuck in a deadlock.
|
516
516
|
|
517
|
+
### `buffercache_stats`
|
518
|
+
|
519
|
+
```ruby
|
520
|
+
RubyPGExtras.buffercache_stats(args: { limit: 10 })
|
521
|
+
```
|
522
|
+
|
523
|
+
This command shows the relations buffered in database share buffer, ordered by percentage taken. It also shows that how much of the whole relation is buffered.
|
524
|
+
|
525
|
+
### `buffercache_usage`
|
526
|
+
|
527
|
+
```ruby
|
528
|
+
RubyPGExtras.buffercache_usage(args: { limit: 20 })
|
529
|
+
```
|
530
|
+
|
531
|
+
This command calculates how many blocks from which table are currently cached.
|
532
|
+
|
517
533
|
### `extensions`
|
518
534
|
|
519
535
|
```ruby
|
@@ -534,18 +550,8 @@ RubyPGExtras.mandelbrot
|
|
534
550
|
|
535
551
|
This command outputs the Mandelbrot set, calculated through SQL.
|
536
552
|
|
537
|
-
|
538
|
-
|
539
|
-
This command shows the relations buffered in database share buffer, ordered by percentage taken. It also shows that how much of the whole relation is buffered.
|
540
|
-
|
541
|
-
```ruby
|
542
|
-
RubyPGExtras.buffercache_stats(args: { limit: 10 })
|
543
|
-
```
|
553
|
+
## Query sources
|
544
554
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
```ruby
|
550
|
-
RubyPGExtras.buffercache_usage(args: { limit: 20 })
|
551
|
-
```
|
555
|
+
- [https://github.com/heroku/heroku-pg-extras](https://github.com/heroku/heroku-pg-extras)
|
556
|
+
- [https://hakibenita.com/postgresql-unused-index-size](https://hakibenita.com/postgresql-unused-index-size)
|
557
|
+
- [https://sites.google.com/site/itmyshare/database-tips-and-examples/postgres/useful-sqls-to-check-contents-of-postgresql-shared_buffer](https://sites.google.com/site/itmyshare/database-tips-and-examples/postgres/useful-sqls-to-check-contents-of-postgresql-shared_buffer)
|
data/docker-compose.yml.sample
CHANGED
@@ -1,11 +1,30 @@
|
|
1
1
|
version: '3'
|
2
2
|
|
3
3
|
services:
|
4
|
-
|
4
|
+
postgres11:
|
5
5
|
image: postgres:11.5-alpine
|
6
|
+
command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c max_connections=200
|
6
7
|
environment:
|
7
8
|
POSTGRES_USER: postgres
|
8
9
|
POSTGRES_DB: ruby-pg-extras-test
|
9
10
|
POSTGRES_PASSWORD: secret
|
10
11
|
ports:
|
11
12
|
- '5432:5432'
|
13
|
+
postgres12:
|
14
|
+
image: postgres:12.7-alpine
|
15
|
+
command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c max_connections=200
|
16
|
+
environment:
|
17
|
+
POSTGRES_USER: postgres
|
18
|
+
POSTGRES_DB: ruby-pg-extras-test
|
19
|
+
POSTGRES_PASSWORD: secret
|
20
|
+
ports:
|
21
|
+
- '5433:5432'
|
22
|
+
postgres13:
|
23
|
+
image: postgres:13.3-alpine
|
24
|
+
command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c max_connections=200
|
25
|
+
environment:
|
26
|
+
POSTGRES_USER: postgres
|
27
|
+
POSTGRES_DB: ruby-pg-extras-test
|
28
|
+
POSTGRES_PASSWORD: secret
|
29
|
+
ports:
|
30
|
+
- '5434:5432'
|
data/lib/ruby-pg-extras.rb
CHANGED
@@ -6,6 +6,7 @@ require 'pg'
|
|
6
6
|
|
7
7
|
module RubyPGExtras
|
8
8
|
@@database_url = nil
|
9
|
+
NEW_PG_STAT_STATEMENTS = "1.8"
|
9
10
|
|
10
11
|
QUERIES = %i(
|
11
12
|
bloat blocking cache_hit db_settings
|
@@ -20,8 +21,10 @@ module RubyPGExtras
|
|
20
21
|
|
21
22
|
DEFAULT_ARGS = Hash.new({}).merge({
|
22
23
|
calls: { limit: 10 },
|
24
|
+
calls_legacy: { limit: 10 },
|
23
25
|
long_running_queries: { threshold: "500 milliseconds" },
|
24
26
|
outliers: { limit: 10 },
|
27
|
+
outliers_legacy: { limit: 10 },
|
25
28
|
buffercache_stats: { limit: 10 },
|
26
29
|
buffercache_usage: { limit: 20 },
|
27
30
|
unused_indexes: { min_scans: 50 },
|
@@ -39,6 +42,16 @@ module RubyPGExtras
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def self.run_query(query_name:, in_format:, args: {})
|
45
|
+
if %i(calls outliers).include?(query_name)
|
46
|
+
pg_stat_statements_ver = RubyPGExtras.connection.exec("select installed_version from pg_available_extensions where name='pg_stat_statements'")
|
47
|
+
.to_a[0].fetch("installed_version", nil)
|
48
|
+
if pg_stat_statements_ver != nil
|
49
|
+
if Gem::Version.new(pg_stat_statements_ver) < Gem::Version.new(NEW_PG_STAT_STATEMENTS)
|
50
|
+
query_name = "#{query_name}_legacy".to_sym
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
42
55
|
sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
|
43
56
|
sql_for(query_name: query_name) % custom_args
|
44
57
|
else
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/* Queries that have highest frequency of execution */
|
2
2
|
|
3
3
|
SELECT query AS qry,
|
4
|
-
interval '1 millisecond' *
|
5
|
-
to_char((
|
4
|
+
interval '1 millisecond' * total_exec_time AS exec_time,
|
5
|
+
to_char((total_exec_time/sum(total_exec_time) OVER()) * 100, 'FM90D0') || '%%' AS prop_exec_time,
|
6
6
|
to_char(calls, 'FM999G999G990') AS ncalls,
|
7
7
|
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time
|
8
8
|
FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* Queries that have highest frequency of execution */
|
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 %{limit};
|
@@ -1,10 +1,10 @@
|
|
1
1
|
/* Queries that have longest execution time in aggregate */
|
2
2
|
|
3
|
-
SELECT interval '1 millisecond' *
|
4
|
-
to_char((
|
3
|
+
SELECT interval '1 millisecond' * total_exec_time AS total_exec_time,
|
4
|
+
to_char((total_exec_time/sum(total_exec_time) OVER()) * 100, 'FM90D0') || '%%' AS prop_exec_time,
|
5
5
|
to_char(calls, 'FM999G999G999G990') AS ncalls,
|
6
6
|
interval '1 millisecond' * (blk_read_time + blk_write_time) AS sync_io_time,
|
7
7
|
query AS query
|
8
8
|
FROM pg_stat_statements WHERE userid = (SELECT usesysid FROM pg_user WHERE usename = current_user LIMIT 1)
|
9
|
-
ORDER BY
|
9
|
+
ORDER BY total_exec_time DESC
|
10
10
|
LIMIT %{limit};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/* 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 %{limit};
|
data/spec/smoke_spec.rb
CHANGED
@@ -3,6 +3,11 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe RubyPGExtras do
|
6
|
+
before(:all) do
|
7
|
+
RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_buffercache;")
|
8
|
+
RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_stat_statements;")
|
9
|
+
end
|
10
|
+
|
6
11
|
RubyPGExtras::QUERIES.each do |query_name|
|
7
12
|
it "#{query_name} description can be read" do
|
8
13
|
expect do
|
@@ -13,9 +18,7 @@ describe RubyPGExtras do
|
|
13
18
|
end
|
14
19
|
end
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
(RubyPGExtras::QUERIES - PG_STATS_DEPENDENT_QUERIES).each do |query_name|
|
21
|
+
RubyPGExtras::QUERIES.each do |query_name|
|
19
22
|
it "#{query_name} query can be executed" do
|
20
23
|
expect do
|
21
24
|
RubyPGExtras.run_query(
|
data/spec/spec_helper.rb
CHANGED
@@ -4,4 +4,16 @@ require 'rubygems'
|
|
4
4
|
require 'bundler/setup'
|
5
5
|
require_relative '../lib/ruby-pg-extras'
|
6
6
|
|
7
|
-
ENV["
|
7
|
+
pg_version = ENV["PG_VERSION"]
|
8
|
+
|
9
|
+
port = if pg_version == "11"
|
10
|
+
"5432"
|
11
|
+
elsif pg_version == "12"
|
12
|
+
"5433"
|
13
|
+
elsif pg_version == "13"
|
14
|
+
"5434"
|
15
|
+
else
|
16
|
+
"5432"
|
17
|
+
end
|
18
|
+
|
19
|
+
ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/ruby-pg-extras-test"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-pg-extras
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pawurb
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/ruby-pg-extras/queries/buffercache_usage.sql
|
91
91
|
- lib/ruby-pg-extras/queries/cache_hit.sql
|
92
92
|
- lib/ruby-pg-extras/queries/calls.sql
|
93
|
+
- lib/ruby-pg-extras/queries/calls_legacy.sql
|
93
94
|
- lib/ruby-pg-extras/queries/db_settings.sql
|
94
95
|
- lib/ruby-pg-extras/queries/extensions.sql
|
95
96
|
- lib/ruby-pg-extras/queries/index_cache_hit.sql
|
@@ -101,6 +102,7 @@ files:
|
|
101
102
|
- lib/ruby-pg-extras/queries/mandelbrot.sql
|
102
103
|
- lib/ruby-pg-extras/queries/null_indexes.sql
|
103
104
|
- lib/ruby-pg-extras/queries/outliers.sql
|
105
|
+
- lib/ruby-pg-extras/queries/outliers_legacy.sql
|
104
106
|
- lib/ruby-pg-extras/queries/records_rank.sql
|
105
107
|
- lib/ruby-pg-extras/queries/seq_scans.sql
|
106
108
|
- lib/ruby-pg-extras/queries/table_cache_hit.sql
|
@@ -133,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
135
|
- !ruby/object:Gem::Version
|
134
136
|
version: '0'
|
135
137
|
requirements: []
|
136
|
-
rubygems_version: 3.1.
|
138
|
+
rubygems_version: 3.1.6
|
137
139
|
signing_key:
|
138
140
|
specification_version: 4
|
139
141
|
summary: Ruby PostgreSQL performance database insights
|