ruby-pg-extras 1.5.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +32 -5
- data/README.md +87 -1
- data/Rakefile +4 -0
- data/docker-compose.yml.sample +20 -1
- data/lib/ruby-pg-extras/queries/buffercache_stats.sql +13 -0
- data/lib/ruby-pg-extras/queries/buffercache_usage.sql +9 -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/db_settings.sql +9 -0
- data/lib/ruby-pg-extras/queries/duplicate_indexes.sql +11 -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/lib/ruby-pg-extras.rb +18 -2
- data/spec/smoke_spec.rb +6 -3
- data/spec/spec_helper.rb +13 -1
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a88ff7e79fc4b77781012f9ee52afeee2462dcc46177d6bec8d24885c9822526
|
4
|
+
data.tar.gz: 9befdd7dd6f98195391fe323f5fabf0d74a6bb9bb0d717f7cf74c30219f91462
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c5df44798b60ae20ad1d8bb395cce56d92e89ddde8912d0a747fcf7e695c74ea3f9a58fa71b7d570a956d908ef3261bfc776c8feb23b21a7f61c595bc3a0855
|
7
|
+
data.tar.gz: d8d2ddcc09c7127ff75b8897bbef5a4ad98f057c80e836bcf8849833c0580914bfd1fd3a435cce34ef4124458dcf0fb12b3dcdb1d78b6932bd629f0ddb90a2f5
|
data/.circleci/config.yml
CHANGED
@@ -6,6 +6,22 @@ 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
|
10
|
+
name: postgres11
|
11
|
+
environment:
|
12
|
+
POSTGRES_USER: postgres
|
13
|
+
POSTGRES_DB: ruby-pg-extras-test
|
14
|
+
POSTGRES_PASSWORD: secret
|
15
|
+
- image: circleci/postgres:12.7
|
16
|
+
command: postgres -c shared_preload_libraries=pg_stat_statements
|
17
|
+
name: postgres12
|
18
|
+
environment:
|
19
|
+
POSTGRES_USER: postgres
|
20
|
+
POSTGRES_DB: ruby-pg-extras-test
|
21
|
+
POSTGRES_PASSWORD: secret
|
22
|
+
- image: circleci/postgres:13.3
|
23
|
+
command: postgres -c shared_preload_libraries=pg_stat_statements
|
24
|
+
name: postgres13
|
9
25
|
environment:
|
10
26
|
POSTGRES_USER: postgres
|
11
27
|
POSTGRES_DB: ruby-pg-extras-test
|
@@ -16,13 +32,24 @@ jobs:
|
|
16
32
|
- run: gem update --system
|
17
33
|
- run: gem install bundler
|
18
34
|
- run: bundle install --path vendor/bundle
|
19
|
-
- run: sudo apt-get update
|
35
|
+
- run: sudo apt-get update --allow-releaseinfo-change
|
20
36
|
- run: sudo apt install postgresql-client-11
|
21
|
-
- run: dockerize -wait tcp://
|
37
|
+
- run: dockerize -wait tcp://postgres11:5432 -timeout 1m
|
38
|
+
- run:
|
39
|
+
name: Run specs for PG 11
|
40
|
+
environment:
|
41
|
+
DATABASE_URL: postgresql://postgres:secret@postgres11:5432/ruby-pg-extras-test
|
42
|
+
command: bundle exec rspec spec/
|
43
|
+
- run:
|
44
|
+
name: Run specs for PG 12
|
45
|
+
environment:
|
46
|
+
DATABASE_URL: postgresql://postgres:secret@postgres12:5432/ruby-pg-extras-test
|
47
|
+
command: bundle exec rspec spec/
|
22
48
|
- run:
|
23
|
-
name: Run specs
|
24
|
-
|
25
|
-
|
49
|
+
name: Run specs for PG 13
|
50
|
+
environment:
|
51
|
+
DATABASE_URL: postgresql://postgres:secret@postgres13:5432/ruby-pg-extras-test
|
52
|
+
command: bundle exec rspec spec/
|
26
53
|
workflows:
|
27
54
|
version: 2
|
28
55
|
test:
|
data/README.md
CHANGED
@@ -109,6 +109,8 @@ RubyPGExtras.cache_hit
|
|
109
109
|
|
110
110
|
This command provides information on the efficiency of the buffer cache, for both index reads (`index hit rate`) as well as table reads (`table hit rate`). A low buffer cache hit ratio can be a sign that the Postgres instance is too small for the workload.
|
111
111
|
|
112
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
|
113
|
+
|
112
114
|
### `index_cache_hit`
|
113
115
|
|
114
116
|
```ruby
|
@@ -125,6 +127,8 @@ RubyPGExtras.index_cache_hit
|
|
125
127
|
|
126
128
|
The same as `cache_hit` with each table's indexes cache hit info displayed separately.
|
127
129
|
|
130
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
|
131
|
+
|
128
132
|
### `table_cache_hit`
|
129
133
|
|
130
134
|
```ruby
|
@@ -141,6 +145,28 @@ RubyPGExtras.table_cache_hit
|
|
141
145
|
|
142
146
|
The same as `cache_hit` with each table's cache hit info displayed seperately.
|
143
147
|
|
148
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
|
149
|
+
|
150
|
+
### `db_settings`
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
|
154
|
+
RubyPGExtras.db_settings
|
155
|
+
|
156
|
+
name | setting | unit |
|
157
|
+
------------------------------+---------+------+
|
158
|
+
checkpoint_completion_target | 0.7 | |
|
159
|
+
default_statistics_target | 100 | |
|
160
|
+
effective_cache_size | 1350000 | 8kB |
|
161
|
+
effective_io_concurrency | 1 | |
|
162
|
+
(truncated results for brevity)
|
163
|
+
|
164
|
+
```
|
165
|
+
|
166
|
+
This method displays values for selected PostgreSQL settings. You can compare them with settings recommended by [PGTune](https://pgtune.leopard.in.ua/#/) and tweak values to improve performance.
|
167
|
+
|
168
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
|
169
|
+
|
144
170
|
### `index_usage`
|
145
171
|
|
146
172
|
```ruby
|
@@ -178,6 +204,8 @@ RubyPGExtras.locks
|
|
178
204
|
|
179
205
|
This command displays queries that have taken out an exclusive lock on a relation. Exclusive locks typically prevent other operations on that relation from taking place, and can be a cause of "hung" queries that are waiting for a lock to be granted.
|
180
206
|
|
207
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#deadlocks)
|
208
|
+
|
181
209
|
### `all_locks`
|
182
210
|
|
183
211
|
```ruby
|
@@ -210,6 +238,8 @@ This command displays statements, obtained from `pg_stat_statements`, ordered by
|
|
210
238
|
|
211
239
|
Typically, an efficient query will have an appropriate ratio of calls to total execution time, with as little time spent on I/O as possible. Queries that have a high total execution time but low call count should be investigated to improve their performance. Queries that have a high proportion of execution time being spent on synchronous I/O should also be investigated.
|
212
240
|
|
241
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
|
242
|
+
|
213
243
|
### `calls`
|
214
244
|
|
215
245
|
```ruby
|
@@ -230,6 +260,8 @@ RubyPGExtras.calls(args: { limit: 10 })
|
|
230
260
|
|
231
261
|
This command is much like `pg:outliers`, but ordered by the number of times a statement has been called.
|
232
262
|
|
263
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
|
264
|
+
|
233
265
|
### `blocking`
|
234
266
|
|
235
267
|
```ruby
|
@@ -244,6 +276,8 @@ RubyPGExtras.blocking
|
|
244
276
|
|
245
277
|
This command displays statements that are currently holding locks that other statements are waiting to be released. This can be used in conjunction with `pg:locks` to determine which statements need to be terminated in order to resolve lock contention.
|
246
278
|
|
279
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#deadlocks)
|
280
|
+
|
247
281
|
### `total_index_size`
|
248
282
|
|
249
283
|
```ruby
|
@@ -351,6 +385,21 @@ RubyPGExtras.unused_indexes(args: { min_scans: 20 })
|
|
351
385
|
|
352
386
|
This command displays indexes that have < 50 scans recorded against them, and are greater than 5 pages in size, ordered by size relative to the number of index scans. This command is generally useful for eliminating indexes that are unused, which can impact write performance, as well as read performance should they occupy space in memory.
|
353
387
|
|
388
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#unused-indexes)
|
389
|
+
|
390
|
+
### `duplicate_indexes`
|
391
|
+
|
392
|
+
```ruby
|
393
|
+
|
394
|
+
RubyPGExtras.duplicate_indexes
|
395
|
+
|
396
|
+
| size | idx1 | idx2 | idx3 | idx4 |
|
397
|
+
+------------+--------------+----------------+----------+-----------+
|
398
|
+
| 128 k | users_pkey | index_users_id | | |
|
399
|
+
```
|
400
|
+
|
401
|
+
This command displays multiple indexes that have the same set of columns, same opclass, expression and predicate - which make them equivalent. Usually it's safe to drop one of them.
|
402
|
+
|
354
403
|
### `null_indexes`
|
355
404
|
|
356
405
|
```ruby
|
@@ -365,7 +414,9 @@ RubyPGExtras.null_indexes(args: { min_relation_size_mb: 10 })
|
|
365
414
|
|
366
415
|
```
|
367
416
|
|
368
|
-
This
|
417
|
+
This command displays indexes that contain `NULL` values. A high ratio of `NULL` values means that using a partial index excluding them will be beneficial in case they are not used for searching.
|
418
|
+
|
419
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#null-indexes)
|
369
420
|
|
370
421
|
### `seq_scans`
|
371
422
|
|
@@ -389,6 +440,8 @@ RubyPGExtras.seq_scans
|
|
389
440
|
|
390
441
|
This command displays the number of sequential scans recorded against all tables, descending by count of sequential scans. Tables that have very high numbers of sequential scans may be under-indexed, and it may be worth investigating queries that read from these tables.
|
391
442
|
|
443
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#missing-indexes)
|
444
|
+
|
392
445
|
### `long_running_queries`
|
393
446
|
|
394
447
|
```ruby
|
@@ -444,6 +497,8 @@ RubyPGExtras.bloat
|
|
444
497
|
|
445
498
|
This command displays an estimation of table "bloat" – space allocated to a relation that is full of dead tuples, that has yet to be reclaimed. Tables that have a high bloat ratio, typically 10 or greater, should be investigated to see if vacuuming is aggressive enough, and can be a sign of high table churn.
|
446
499
|
|
500
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#bloat)
|
501
|
+
|
447
502
|
### `vacuum_stats`
|
448
503
|
|
449
504
|
```ruby
|
@@ -472,6 +527,22 @@ RubyPGExtras.kill_all
|
|
472
527
|
|
473
528
|
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.
|
474
529
|
|
530
|
+
### `buffercache_stats`
|
531
|
+
|
532
|
+
```ruby
|
533
|
+
RubyPGExtras.buffercache_stats(args: { limit: 10 })
|
534
|
+
```
|
535
|
+
|
536
|
+
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.
|
537
|
+
|
538
|
+
### `buffercache_usage`
|
539
|
+
|
540
|
+
```ruby
|
541
|
+
RubyPGExtras.buffercache_usage(args: { limit: 20 })
|
542
|
+
```
|
543
|
+
|
544
|
+
This command calculates how many blocks from which table are currently cached.
|
545
|
+
|
475
546
|
### `extensions`
|
476
547
|
|
477
548
|
```ruby
|
@@ -491,3 +562,18 @@ RubyPGExtras.mandelbrot
|
|
491
562
|
```
|
492
563
|
|
493
564
|
This command outputs the Mandelbrot set, calculated through SQL.
|
565
|
+
|
566
|
+
## Testing
|
567
|
+
|
568
|
+
```bash
|
569
|
+
cp docker-compose.yml.sample docker-compose.yml
|
570
|
+
docker compose up -d
|
571
|
+
rake test_all
|
572
|
+
```
|
573
|
+
|
574
|
+
## Query sources
|
575
|
+
|
576
|
+
- [https://github.com/heroku/heroku-pg-extras](https://github.com/heroku/heroku-pg-extras)
|
577
|
+
- [https://hakibenita.com/postgresql-unused-index-size](https://hakibenita.com/postgresql-unused-index-size)
|
578
|
+
- [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)
|
579
|
+
- [https://wiki.postgresql.org/wiki/Index_Maintenance](https://wiki.postgresql.org/wiki/Index_Maintenance)
|
data/Rakefile
CHANGED
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
|
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
|
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
|
25
|
+
environment:
|
26
|
+
POSTGRES_USER: postgres
|
27
|
+
POSTGRES_DB: ruby-pg-extras-test
|
28
|
+
POSTGRES_PASSWORD: secret
|
29
|
+
ports:
|
30
|
+
- '5434:5432'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/* Calculates percentages of relations buffered in database share buffer */
|
2
|
+
|
3
|
+
SELECT
|
4
|
+
c.relname,
|
5
|
+
pg_size_pretty(count(*) * 8192) AS buffered,
|
6
|
+
round(100.0 * count(*) / (SELECT setting FROM pg_settings WHERE name = 'shared_buffers')::integer, 1) AS buffer_percent,
|
7
|
+
round(100.0 * count(*) * 8192 / pg_table_size(c.oid), 1) AS percent_of_relation
|
8
|
+
FROM pg_class c
|
9
|
+
INNER JOIN pg_buffercache b ON b.relfilenode = c.relfilenode
|
10
|
+
INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database())
|
11
|
+
GROUP BY c.oid,c.relname
|
12
|
+
ORDER BY 3 DESC
|
13
|
+
LIMIT %{limit};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* Calculate how many blocks from which table are currently cached */
|
2
|
+
|
3
|
+
SELECT c.relname, count(*) AS buffers
|
4
|
+
FROM pg_class c
|
5
|
+
INNER JOIN pg_buffercache b ON b.relfilenode = c.relfilenode
|
6
|
+
INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database())
|
7
|
+
GROUP BY c.relname
|
8
|
+
ORDER BY 2 DESC
|
9
|
+
LIMIT %{limit};
|
@@ -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};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/* Values of selected PostgreSQL settings */
|
2
|
+
|
3
|
+
SELECT name, setting, unit, short_desc FROM pg_settings
|
4
|
+
WHERE name IN (
|
5
|
+
'max_connections', 'shared_buffers', 'effective_cache_size',
|
6
|
+
'maintenance_work_mem', 'checkpoint_completion_target', 'wal_buffers',
|
7
|
+
'default_statistics_target', 'random_page_cost', 'effective_io_concurrency',
|
8
|
+
'work_mem', 'min_wal_size', 'max_wal_size'
|
9
|
+
);
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/* Multiple indexes that have the same set of columns, same opclass, expression and predicate -- which make them equivalent. */
|
2
|
+
|
3
|
+
SELECT pg_size_pretty(sum(pg_relation_size(idx))::bigint) as size,
|
4
|
+
(array_agg(idx))[1] as idx1, (array_agg(idx))[2] as idx2,
|
5
|
+
(array_agg(idx))[3] as idx3, (array_agg(idx))[4] as idx4
|
6
|
+
FROM (
|
7
|
+
SELECT indexrelid::regclass as idx, (indrelid::text ||E'\n'|| indclass::text ||E'\n'|| indkey::text ||E'\n'||
|
8
|
+
coalesce(indexprs::text,'')||E'\n' || coalesce(indpred::text,'')) as key
|
9
|
+
FROM pg_index) sub
|
10
|
+
GROUP BY key HAVING count(*)>1
|
11
|
+
ORDER BY sum(pg_relation_size(idx)) DESC;
|
@@ -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/lib/ruby-pg-extras.rb
CHANGED
@@ -6,21 +6,27 @@ 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
|
-
bloat blocking cache_hit
|
12
|
+
bloat blocking cache_hit db_settings
|
12
13
|
calls extensions table_cache_hit index_cache_hit
|
13
14
|
index_size index_usage null_indexes locks all_locks
|
14
15
|
long_running_queries mandelbrot outliers
|
15
16
|
records_rank seq_scans table_indexes_size
|
16
17
|
table_size total_index_size total_table_size
|
17
|
-
unused_indexes vacuum_stats kill_all
|
18
|
+
unused_indexes duplicate_indexes vacuum_stats kill_all
|
19
|
+
buffercache_stats buffercache_usage
|
18
20
|
)
|
19
21
|
|
20
22
|
DEFAULT_ARGS = Hash.new({}).merge({
|
21
23
|
calls: { limit: 10 },
|
24
|
+
calls_legacy: { limit: 10 },
|
22
25
|
long_running_queries: { threshold: "500 milliseconds" },
|
23
26
|
outliers: { limit: 10 },
|
27
|
+
outliers_legacy: { limit: 10 },
|
28
|
+
buffercache_stats: { limit: 10 },
|
29
|
+
buffercache_usage: { limit: 20 },
|
24
30
|
unused_indexes: { min_scans: 50 },
|
25
31
|
null_indexes: { min_relation_size_mb: 10 }
|
26
32
|
})
|
@@ -36,6 +42,16 @@ module RubyPGExtras
|
|
36
42
|
end
|
37
43
|
|
38
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
|
+
|
39
55
|
sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
|
40
56
|
sql_for(query_name: query_name) % custom_args
|
41
57
|
else
|
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: 1.
|
4
|
+
version: 2.1.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-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -86,8 +86,13 @@ files:
|
|
86
86
|
- lib/ruby-pg-extras/queries/all_locks.sql
|
87
87
|
- lib/ruby-pg-extras/queries/bloat.sql
|
88
88
|
- lib/ruby-pg-extras/queries/blocking.sql
|
89
|
+
- lib/ruby-pg-extras/queries/buffercache_stats.sql
|
90
|
+
- lib/ruby-pg-extras/queries/buffercache_usage.sql
|
89
91
|
- lib/ruby-pg-extras/queries/cache_hit.sql
|
90
92
|
- lib/ruby-pg-extras/queries/calls.sql
|
93
|
+
- lib/ruby-pg-extras/queries/calls_legacy.sql
|
94
|
+
- lib/ruby-pg-extras/queries/db_settings.sql
|
95
|
+
- lib/ruby-pg-extras/queries/duplicate_indexes.sql
|
91
96
|
- lib/ruby-pg-extras/queries/extensions.sql
|
92
97
|
- lib/ruby-pg-extras/queries/index_cache_hit.sql
|
93
98
|
- lib/ruby-pg-extras/queries/index_size.sql
|
@@ -98,6 +103,7 @@ files:
|
|
98
103
|
- lib/ruby-pg-extras/queries/mandelbrot.sql
|
99
104
|
- lib/ruby-pg-extras/queries/null_indexes.sql
|
100
105
|
- lib/ruby-pg-extras/queries/outliers.sql
|
106
|
+
- lib/ruby-pg-extras/queries/outliers_legacy.sql
|
101
107
|
- lib/ruby-pg-extras/queries/records_rank.sql
|
102
108
|
- lib/ruby-pg-extras/queries/seq_scans.sql
|
103
109
|
- lib/ruby-pg-extras/queries/table_cache_hit.sql
|
@@ -130,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
136
|
- !ruby/object:Gem::Version
|
131
137
|
version: '0'
|
132
138
|
requirements: []
|
133
|
-
rubygems_version: 3.1.
|
139
|
+
rubygems_version: 3.1.6
|
134
140
|
signing_key:
|
135
141
|
specification_version: 4
|
136
142
|
summary: Ruby PostgreSQL performance database insights
|