ruby-pg-extras 3.3.0 → 4.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 +1 -1
- data/README.md +42 -42
- data/lib/{ruby-pg-extras → ruby_pg_extras}/diagnose_data.rb +2 -2
- data/lib/{ruby-pg-extras → ruby_pg_extras}/diagnose_print.rb +1 -1
- data/lib/{ruby-pg-extras → ruby_pg_extras}/index_info.rb +2 -2
- data/lib/{ruby-pg-extras → ruby_pg_extras}/index_info_print.rb +1 -1
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/add_extensions.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/all_locks.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/bloat.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/blocking.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/buffercache_stats.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/buffercache_usage.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/cache_hit.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/calls.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/calls_legacy.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/db_settings.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/duplicate_indexes.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/extensions.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/index_cache_hit.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/index_scans.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/index_size.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/index_usage.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/indexes.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/kill_all.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/locks.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/long_running_queries.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/mandelbrot.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/null_indexes.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/outliers.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/outliers_legacy.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/pg_stat_statements_reset.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/records_rank.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/seq_scans.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/ssl_used.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/table_cache_hit.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/table_index_scans.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/table_indexes_size.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/table_size.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/tables.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/total_index_size.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/total_table_size.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/unused_indexes.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/queries/vacuum_stats.sql +0 -0
- data/lib/{ruby-pg-extras → ruby_pg_extras}/table_info.rb +2 -2
- data/lib/{ruby-pg-extras → ruby_pg_extras}/table_info_print.rb +1 -1
- data/lib/ruby_pg_extras/version.rb +5 -0
- data/lib/{ruby-pg-extras.rb → ruby_pg_extras.rb} +16 -16
- data/ruby-pg-extras.gemspec +2 -2
- data/spec/diagnose_data_spec.rb +9 -9
- data/spec/diagnose_print_spec.rb +2 -2
- data/spec/index_info_spec.rb +8 -8
- data/spec/smoke_spec.rb +7 -7
- data/spec/spec_helper.rb +4 -4
- data/spec/table_info_spec.rb +11 -11
- metadata +47 -47
- data/lib/ruby-pg-extras/version.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff41e99e61ffb824563514d242ede3943cf075cf615f00c9ae7f10adb270b20e
|
4
|
+
data.tar.gz: 0d273ed6c798109a6b1b96a6a0de6860ddb185e21d1bc94510c75f48a83837dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9624e0c2972f933bf2157b0df43f3ba0a1e078e57a61aa5c700023335a3c7f1ec36e4358bd22c8f6d0c1dcc97ebcffe250a7e88ff56edb67100677e02fd4f557
|
7
|
+
data.tar.gz: 308c3623ceeeb79815af005e2e857a8b4ae477a93c95491916c26ee9766de6937f9abeebfc66e268d324d933537b1f640715fca531f5805d416c8bdb88e6654a
|
data/.circleci/config.yml
CHANGED
data/README.md
CHANGED
@@ -23,7 +23,7 @@ Alternative versions:
|
|
23
23
|
In your Gemfile
|
24
24
|
|
25
25
|
```ruby
|
26
|
-
gem "ruby-pg-extras"
|
26
|
+
gem "ruby-pg-extras", require: "ruby_pg_extras"
|
27
27
|
```
|
28
28
|
|
29
29
|
`calls` and `outliers` queries require [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html) extension.
|
@@ -31,7 +31,7 @@ gem "ruby-pg-extras"
|
|
31
31
|
You can check if it is enabled in your database by running:
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
|
34
|
+
RubyPgExtras.extensions
|
35
35
|
```
|
36
36
|
You should see the similar line in the output:
|
37
37
|
|
@@ -42,7 +42,7 @@ You should see the similar line in the output:
|
|
42
42
|
`ssl_used` requires `sslinfo` extension, and `buffercache_usage`/`buffercache_usage` queries need `pg_buffercache`. You can enable them all by running:
|
43
43
|
|
44
44
|
```ruby
|
45
|
-
|
45
|
+
RubyPgExtras.add_extensions
|
46
46
|
```
|
47
47
|
|
48
48
|
## Usage
|
@@ -56,13 +56,13 @@ ENV["DATABASE_URL"] = "postgresql://postgres:secret@localhost:5432/database_name
|
|
56
56
|
Alternatively you can set it using the module class method:
|
57
57
|
|
58
58
|
```ruby
|
59
|
-
|
59
|
+
RubyPgExtras.database_url = "postgresql://postgres:secret@localhost:5432/database_name"
|
60
60
|
```
|
61
61
|
|
62
62
|
You can run queries using a simple Ruby API:
|
63
63
|
|
64
64
|
```ruby
|
65
|
-
|
65
|
+
RubyPgExtras.cache_hit
|
66
66
|
```
|
67
67
|
```bash
|
68
68
|
+----------------+------------------------+
|
@@ -78,15 +78,15 @@ RubyPGExtras.cache_hit
|
|
78
78
|
By default the ASCII table is displayed, to change to format you need to specify the `in_format` parameter (`[:display_table, :hash, :array, :raw]` options are available):
|
79
79
|
|
80
80
|
```ruby
|
81
|
-
|
81
|
+
RubyPgExtras.cache_hit(in_format: :hash) =>
|
82
82
|
|
83
83
|
[{"name"=>"index hit rate", "ratio"=>"0.97796610169491525424"}, {"name"=>"table hit rate", "ratio"=>"0.96724294813466787989"}]
|
84
84
|
|
85
|
-
|
85
|
+
RubyPgExtras.cache_hit(in_format: :array) =>
|
86
86
|
|
87
87
|
[["index hit rate", "0.97796610169491525424"], ["table hit rate", "0.96724294813466787989"]]
|
88
88
|
|
89
|
-
|
89
|
+
RubyPgExtras.cache_hit(in_format: :raw) =>
|
90
90
|
|
91
91
|
#<PG::Result:0x00007f75777f7328 status=PGRES_TUPLES_OK ntuples=2 nfields=2 cmd_tuples=2>
|
92
92
|
```
|
@@ -94,7 +94,7 @@ RubyPGExtras.cache_hit(in_format: :raw) =>
|
|
94
94
|
Some methods accept an optional `args` param allowing you to customize queries:
|
95
95
|
|
96
96
|
```ruby
|
97
|
-
|
97
|
+
RubyPgExtras.long_running_queries(args: { threshold: "200 milliseconds" })
|
98
98
|
|
99
99
|
```
|
100
100
|
|
@@ -103,7 +103,7 @@ RubyPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
|
|
103
103
|
The simplest way to start using pg-extras is to execute a `diagnose` method. It runs a set of checks and prints out a report highlighting areas that may require additional investigation:
|
104
104
|
|
105
105
|
```ruby
|
106
|
-
|
106
|
+
RubyPgExtras.diagnose
|
107
107
|
```
|
108
108
|
|
109
109
|
![Diagnose report](https://github.com/pawurb/ruby-pg-extras/raw/master/ruby-pg-extras-diagnose.png)
|
@@ -117,7 +117,7 @@ Keep reading to learn about methods that `diagnose` uses under the hood.
|
|
117
117
|
This method displays metadata metrics for all or a selected table. You can use it to check the table's size, its cache hit metrics, and whether it is correctly indexed. Many sequential scans or no index scans are potential indicators of misconfigured indexes. This method aggregates data provided by other methods in an easy to analyze summary format.
|
118
118
|
|
119
119
|
```ruby
|
120
|
-
|
120
|
+
RubyPgExtras.table_info(args: { table_name: "users" })
|
121
121
|
|
122
122
|
| Table name | Table size | Table cache hit | Indexes cache hit | Estimated rows | Sequential scans | Indexes scans |
|
123
123
|
+------------+------------+-------------------+--------------------+----------------+------------------+---------------+
|
@@ -131,7 +131,7 @@ This method returns summary info about database indexes. You can check index siz
|
|
131
131
|
|
132
132
|
```ruby
|
133
133
|
|
134
|
-
|
134
|
+
RubyPgExtras.index_info(args: { table_name: "users" })
|
135
135
|
|
136
136
|
| Index name | Table name | Columns | Index size | Index scans | Null frac |
|
137
137
|
+-------------------------------+------------+----------------+------------+-------------+-----------+
|
@@ -148,7 +148,7 @@ RubyPGExtras.index_info(args: { table_name: "users" })
|
|
148
148
|
|
149
149
|
```ruby
|
150
150
|
|
151
|
-
|
151
|
+
RubyPgExtras.cache_hit
|
152
152
|
|
153
153
|
name | ratio
|
154
154
|
----------------+------------------------
|
@@ -165,7 +165,7 @@ This command provides information on the efficiency of the buffer cache, for bot
|
|
165
165
|
|
166
166
|
```ruby
|
167
167
|
|
168
|
-
|
168
|
+
RubyPgExtras.index_cache_hit
|
169
169
|
|
170
170
|
| name | buffer_hits | block_reads | total_read | ratio |
|
171
171
|
+-----------------------+-------------+-------------+------------+-------------------+
|
@@ -183,7 +183,7 @@ The same as `cache_hit` with each table's indexes cache hit info displayed separ
|
|
183
183
|
|
184
184
|
```ruby
|
185
185
|
|
186
|
-
|
186
|
+
RubyPgExtras.table_cache_hit
|
187
187
|
|
188
188
|
| name | buffer_hits | block_reads | total_read | ratio |
|
189
189
|
+-----------------------+-------------+-------------+------------+-------------------+
|
@@ -201,7 +201,7 @@ The same as `cache_hit` with each table's cache hit info displayed seperately.
|
|
201
201
|
|
202
202
|
```ruby
|
203
203
|
|
204
|
-
|
204
|
+
RubyPgExtras.db_settings
|
205
205
|
|
206
206
|
name | setting | unit |
|
207
207
|
------------------------------+---------+------+
|
@@ -221,7 +221,7 @@ This method displays values for selected PostgreSQL settings. You can compare th
|
|
221
221
|
|
222
222
|
```ruby
|
223
223
|
|
224
|
-
|
224
|
+
RubyPgExtras.ssl_used
|
225
225
|
|
226
226
|
| ssl_is_used |
|
227
227
|
+---------------------------------+
|
@@ -235,7 +235,7 @@ Returns boolean indicating if an encrypted SSL is currently used. Connecting to
|
|
235
235
|
|
236
236
|
```ruby
|
237
237
|
|
238
|
-
|
238
|
+
RubyPgExtras.index_usage
|
239
239
|
|
240
240
|
relname | percent_of_times_index_used | rows_in_table
|
241
241
|
---------------------+-----------------------------+---------------
|
@@ -253,7 +253,7 @@ This command provides information on the efficiency of indexes, represented as w
|
|
253
253
|
|
254
254
|
```ruby
|
255
255
|
|
256
|
-
|
256
|
+
RubyPgExtras.locks
|
257
257
|
|
258
258
|
procpid | relname | transactionid | granted | query_snippet | mode | age
|
259
259
|
---------+---------+---------------+---------+-----------------------+-------------------------------------
|
@@ -274,7 +274,7 @@ This command displays queries that have taken out an exclusive lock on a relatio
|
|
274
274
|
|
275
275
|
```ruby
|
276
276
|
|
277
|
-
|
277
|
+
RubyPgExtras.all_locks
|
278
278
|
|
279
279
|
```
|
280
280
|
|
@@ -284,7 +284,7 @@ This command displays all the current locks, regardless of their type.
|
|
284
284
|
|
285
285
|
```ruby
|
286
286
|
|
287
|
-
|
287
|
+
RubyPgExtras.outliers(args: { limit: 20 })
|
288
288
|
|
289
289
|
query | exec_time | prop_exec_time | ncalls | sync_io_time
|
290
290
|
-----------------------------------------+------------------+----------------+-------------+--------------
|
@@ -308,7 +308,7 @@ Typically, an efficient query will have an appropriate ratio of calls to total e
|
|
308
308
|
|
309
309
|
```ruby
|
310
310
|
|
311
|
-
|
311
|
+
RubyPgExtras.calls(args: { limit: 10 })
|
312
312
|
|
313
313
|
qry | exec_time | prop_exec_time | ncalls | sync_io_time
|
314
314
|
-----------------------------------------+------------------+----------------+-------------+--------------
|
@@ -330,7 +330,7 @@ This command is much like `pg:outliers`, but ordered by the number of times a st
|
|
330
330
|
|
331
331
|
```ruby
|
332
332
|
|
333
|
-
|
333
|
+
RubyPgExtras.blocking
|
334
334
|
|
335
335
|
blocked_pid | blocking_statement | blocking_duration | blocking_pid | blocked_statement | blocked_duration
|
336
336
|
-------------+--------------------------+-------------------+--------------+------------------------------------------------------------------------------------+------------------
|
@@ -346,7 +346,7 @@ This command displays statements that are currently holding locks that other sta
|
|
346
346
|
|
347
347
|
```ruby
|
348
348
|
|
349
|
-
|
349
|
+
RubyPgExtras.total_index_size
|
350
350
|
|
351
351
|
size
|
352
352
|
-------
|
@@ -360,7 +360,7 @@ This command displays the total size of all indexes on the database, in MB. It i
|
|
360
360
|
|
361
361
|
```ruby
|
362
362
|
|
363
|
-
|
363
|
+
RubyPgExtras.index_size
|
364
364
|
|
365
365
|
name | size
|
366
366
|
---------------------------------------------------------------+---------
|
@@ -383,7 +383,7 @@ This command displays the size of each each index in the database, in MB. It is
|
|
383
383
|
|
384
384
|
```ruby
|
385
385
|
|
386
|
-
|
386
|
+
RubyPgExtras.table_size
|
387
387
|
|
388
388
|
name | size
|
389
389
|
---------------------------------------------------------------+---------
|
@@ -401,7 +401,7 @@ This command displays the size of each table and materialized view in the databa
|
|
401
401
|
|
402
402
|
```ruby
|
403
403
|
|
404
|
-
|
404
|
+
RubyPgExtras.table_indexes_size
|
405
405
|
|
406
406
|
table | indexes_size
|
407
407
|
---------------------------------------------------------------+--------------
|
@@ -419,7 +419,7 @@ This command displays the total size of indexes for each table and materialized
|
|
419
419
|
|
420
420
|
```ruby
|
421
421
|
|
422
|
-
|
422
|
+
RubyPgExtras.total_table_size
|
423
423
|
|
424
424
|
name | size
|
425
425
|
---------------------------------------------------------------+---------
|
@@ -437,7 +437,7 @@ This command displays the total size of each table and materialized view in the
|
|
437
437
|
|
438
438
|
```ruby
|
439
439
|
|
440
|
-
|
440
|
+
RubyPgExtras.unused_indexes(args: { max_scans: 20 })
|
441
441
|
|
442
442
|
table | index | index_size | index_scans
|
443
443
|
---------------------+--------------------------------------------+------------+-------------
|
@@ -455,7 +455,7 @@ This command displays indexes that have < 50 scans recorded against them, and ar
|
|
455
455
|
|
456
456
|
```ruby
|
457
457
|
|
458
|
-
|
458
|
+
RubyPgExtras.duplicate_indexes
|
459
459
|
|
460
460
|
| size | idx1 | idx2 | idx3 | idx4 |
|
461
461
|
+------------+--------------+----------------+----------+-----------+
|
@@ -468,7 +468,7 @@ This command displays multiple indexes that have the same set of columns, same o
|
|
468
468
|
|
469
469
|
```ruby
|
470
470
|
|
471
|
-
|
471
|
+
RubyPgExtras.null_indexes(args: { min_relation_size_mb: 10 })
|
472
472
|
|
473
473
|
oid | index | index_size | unique | indexed_column | null_frac | expected_saving
|
474
474
|
---------+--------------------+------------+--------+----------------+-----------+-----------------
|
@@ -486,7 +486,7 @@ This command displays indexes that contain `NULL` values. A high ratio of `NULL`
|
|
486
486
|
|
487
487
|
```ruby
|
488
488
|
|
489
|
-
|
489
|
+
RubyPgExtras.seq_scans
|
490
490
|
|
491
491
|
|
492
492
|
name | count
|
@@ -510,7 +510,7 @@ This command displays the number of sequential scans recorded against all tables
|
|
510
510
|
|
511
511
|
```ruby
|
512
512
|
|
513
|
-
|
513
|
+
RubyPgExtras.long_running_queries(args: { threshold: "200 milliseconds" })
|
514
514
|
|
515
515
|
|
516
516
|
pid | duration | query
|
@@ -527,7 +527,7 @@ This command displays currently running queries, that have been running for long
|
|
527
527
|
|
528
528
|
```ruby
|
529
529
|
|
530
|
-
|
530
|
+
RubyPgExtras.records_rank
|
531
531
|
|
532
532
|
name | estimated_count
|
533
533
|
-----------------------------------+-----------------
|
@@ -546,7 +546,7 @@ This command displays an estimated count of rows per table, descending by estima
|
|
546
546
|
|
547
547
|
```ruby
|
548
548
|
|
549
|
-
|
549
|
+
RubyPgExtras.bloat
|
550
550
|
|
551
551
|
|
552
552
|
type | schemaname | object_name | bloat | waste
|
@@ -567,7 +567,7 @@ This command displays an estimation of table "bloat" – space allocated to a re
|
|
567
567
|
|
568
568
|
```ruby
|
569
569
|
|
570
|
-
|
570
|
+
RubyPgExtras.vacuum_stats
|
571
571
|
|
572
572
|
schema | table | last_vacuum | last_autovacuum | rowcount | dead_rowcount | autovacuum_threshold | expect_autovacuum
|
573
573
|
--------+-----------------------+-------------+------------------+----------------+----------------+----------------------+-------------------
|
@@ -585,7 +585,7 @@ This command displays statistics related to vacuum operations for each table, in
|
|
585
585
|
|
586
586
|
```ruby
|
587
587
|
|
588
|
-
|
588
|
+
RubyPgExtras.kill_all
|
589
589
|
|
590
590
|
```
|
591
591
|
|
@@ -594,7 +594,7 @@ This commands kills all the currently active connections to the database. It can
|
|
594
594
|
### `pg_stat_statements_reset`
|
595
595
|
|
596
596
|
```ruby
|
597
|
-
|
597
|
+
RubyPgExtras.pg_stat_statements_reset
|
598
598
|
```
|
599
599
|
|
600
600
|
This command discards all statistics gathered so far by pg_stat_statements.
|
@@ -602,7 +602,7 @@ This command discards all statistics gathered so far by pg_stat_statements.
|
|
602
602
|
### `buffercache_stats`
|
603
603
|
|
604
604
|
```ruby
|
605
|
-
|
605
|
+
RubyPgExtras.buffercache_stats(args: { limit: 10 })
|
606
606
|
```
|
607
607
|
|
608
608
|
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.
|
@@ -610,7 +610,7 @@ This command shows the relations buffered in database share buffer, ordered by p
|
|
610
610
|
### `buffercache_usage`
|
611
611
|
|
612
612
|
```ruby
|
613
|
-
|
613
|
+
RubyPgExtras.buffercache_usage(args: { limit: 20 })
|
614
614
|
```
|
615
615
|
|
616
616
|
This command calculates how many blocks from which table are currently cached.
|
@@ -619,7 +619,7 @@ This command calculates how many blocks from which table are currently cached.
|
|
619
619
|
|
620
620
|
```ruby
|
621
621
|
|
622
|
-
|
622
|
+
RubyPgExtras.extensions
|
623
623
|
|
624
624
|
```
|
625
625
|
|
@@ -629,7 +629,7 @@ This command lists all the currently installed and available PostgreSQL extensio
|
|
629
629
|
|
630
630
|
```ruby
|
631
631
|
|
632
|
-
|
632
|
+
RubyPgExtras.mandelbrot
|
633
633
|
|
634
634
|
```
|
635
635
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'filesize'
|
4
4
|
|
5
|
-
module
|
5
|
+
module RubyPgExtras
|
6
6
|
class DiagnoseData
|
7
7
|
PG_EXTRAS_TABLE_CACHE_HIT_MIN_EXPECTED = "0.985"
|
8
8
|
PG_EXTRAS_INDEX_CACHE_HIT_MIN_EXPECTED = "0.985"
|
@@ -52,7 +52,7 @@ module RubyPGExtras
|
|
52
52
|
private
|
53
53
|
|
54
54
|
def query_module
|
55
|
-
|
55
|
+
RubyPgExtras
|
56
56
|
end
|
57
57
|
|
58
58
|
def table_cache_hit
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -3,14 +3,14 @@
|
|
3
3
|
require 'terminal-table'
|
4
4
|
require 'uri'
|
5
5
|
require 'pg'
|
6
|
-
require '
|
7
|
-
require '
|
8
|
-
require '
|
9
|
-
require '
|
10
|
-
require '
|
11
|
-
require '
|
12
|
-
|
13
|
-
module
|
6
|
+
require 'ruby_pg_extras/diagnose_data'
|
7
|
+
require 'ruby_pg_extras/diagnose_print'
|
8
|
+
require 'ruby_pg_extras/index_info'
|
9
|
+
require 'ruby_pg_extras/index_info_print'
|
10
|
+
require 'ruby_pg_extras/table_info'
|
11
|
+
require 'ruby_pg_extras/table_info_print'
|
12
|
+
|
13
|
+
module RubyPgExtras
|
14
14
|
@@database_url = nil
|
15
15
|
NEW_PG_STAT_STATEMENTS = "1.8"
|
16
16
|
|
@@ -50,7 +50,7 @@ module RubyPGExtras
|
|
50
50
|
|
51
51
|
def self.run_query(query_name:, in_format:, args: {})
|
52
52
|
if %i(calls outliers).include?(query_name)
|
53
|
-
pg_stat_statements_ver =
|
53
|
+
pg_stat_statements_ver = RubyPgExtras.connection.exec("select installed_version from pg_available_extensions where name='pg_stat_statements'")
|
54
54
|
.to_a[0].fetch("installed_version", nil)
|
55
55
|
if pg_stat_statements_ver != nil
|
56
56
|
if Gem::Version.new(pg_stat_statements_ver) < Gem::Version.new(NEW_PG_STAT_STATEMENTS)
|
@@ -74,10 +74,10 @@ module RubyPGExtras
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def self.diagnose(in_format: :display_table)
|
77
|
-
data =
|
77
|
+
data = RubyPgExtras::DiagnoseData.call
|
78
78
|
|
79
79
|
if in_format == :display_table
|
80
|
-
|
80
|
+
RubyPgExtras::DiagnosePrint.call(data)
|
81
81
|
elsif in_format == :hash
|
82
82
|
data
|
83
83
|
elsif in_format == :array
|
@@ -88,10 +88,10 @@ module RubyPGExtras
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def self.index_info(args: {}, in_format: :display_table)
|
91
|
-
data =
|
91
|
+
data = RubyPgExtras::IndexInfo.call(args[:table_name])
|
92
92
|
|
93
93
|
if in_format == :display_table
|
94
|
-
|
94
|
+
RubyPgExtras::IndexInfoPrint.call(data)
|
95
95
|
elsif in_format == :hash
|
96
96
|
data
|
97
97
|
elsif in_format == :array
|
@@ -102,10 +102,10 @@ module RubyPGExtras
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def self.table_info(args: {}, in_format: :display_table)
|
105
|
-
data =
|
105
|
+
data = RubyPgExtras::TableInfo.call(args[:table_name])
|
106
106
|
|
107
107
|
if in_format == :display_table
|
108
|
-
|
108
|
+
RubyPgExtras::TableInfoPrint.call(data)
|
109
109
|
elsif in_format == :hash
|
110
110
|
data
|
111
111
|
elsif in_format == :array
|
@@ -155,7 +155,7 @@ module RubyPGExtras
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def self.sql_path_for(query_name:)
|
158
|
-
File.join(File.dirname(__FILE__), "/
|
158
|
+
File.join(File.dirname(__FILE__), "/ruby_pg_extras/queries/#{query_name}.sql")
|
159
159
|
end
|
160
160
|
|
161
161
|
def self.connection
|
data/ruby-pg-extras.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require '
|
4
|
+
require 'ruby_pg_extras/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "ruby-pg-extras"
|
8
|
-
s.version =
|
8
|
+
s.version = RubyPgExtras::VERSION
|
9
9
|
s.authors = ["pawurb"]
|
10
10
|
s.email = ["contact@pawelurbanek.com"]
|
11
11
|
s.summary = %q{ Ruby PostgreSQL performance database insights }
|
data/spec/diagnose_data_spec.rb
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe RubyPgExtras::DiagnoseData do
|
6
6
|
subject(:result) do
|
7
|
-
|
7
|
+
RubyPgExtras::DiagnoseData.call
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "call" do
|
11
11
|
context "stubbed cases" do
|
12
12
|
before do
|
13
|
-
expect(
|
13
|
+
expect(RubyPgExtras).to receive(:unused_indexes) {
|
14
14
|
[
|
15
15
|
{ "table" => "public.plans", "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "index_scans" => 0 },
|
16
16
|
{ "table" => "public.feedbacks", "index" => "index_feedbacks_on_target_id", "index_size" => "111180 bytes", "index_scans" => 1 },
|
@@ -18,7 +18,7 @@ describe RubyPGExtras::DiagnoseData do
|
|
18
18
|
]
|
19
19
|
}
|
20
20
|
|
21
|
-
expect(
|
21
|
+
expect(RubyPgExtras).to receive(:null_indexes) {
|
22
22
|
[
|
23
23
|
{ "oid" => 123, "index" => "index_plans_on_payer_id", "index_size" => "16 MB", "unique" => true, "null_frac" => "00.00%", "expected_saving" => "0 kb" },
|
24
24
|
{ "oid" => 321, "index" => "index_feedbacks_on_target_id", "index_size" => "80 kB", "unique" => true, "null_frac" => "97.00%", "expected_saving" => "77 kb" },
|
@@ -26,7 +26,7 @@ describe RubyPGExtras::DiagnoseData do
|
|
26
26
|
]
|
27
27
|
}
|
28
28
|
|
29
|
-
expect(
|
29
|
+
expect(RubyPgExtras).to receive(:bloat) {
|
30
30
|
[
|
31
31
|
{ "type" => "table", "schemaname" => "public", "object_name" => "bloated_table_1", "bloat" => 8, "waste" => "0 kb" },
|
32
32
|
{ "type" => "table", "schemaname" => "public", "object_name" => "bloated_table_2", "bloat" => 8, "waste" => "77 kb" },
|
@@ -34,13 +34,13 @@ describe RubyPGExtras::DiagnoseData do
|
|
34
34
|
]
|
35
35
|
}
|
36
36
|
|
37
|
-
expect(
|
37
|
+
expect(RubyPgExtras).to receive(:duplicate_indexes) {
|
38
38
|
[
|
39
39
|
{ "size" => "128 kb", "idx1" => "users_pkey", "idx2" => "index_users_id" }
|
40
40
|
]
|
41
41
|
}
|
42
42
|
|
43
|
-
expect(
|
43
|
+
expect(RubyPgExtras).to receive(:outliers) {
|
44
44
|
[
|
45
45
|
{ "query" => "SELECT * FROM users WHERE users.age > 20 AND users.height > 160", "exec_time" => "154:39:26.431466", "prop_exec_time" => "72.2%", "ncalls" => "34,211,877", "sync_io_time" => "00:34:19.784318" }
|
46
46
|
]
|
@@ -49,7 +49,7 @@ describe RubyPGExtras::DiagnoseData do
|
|
49
49
|
|
50
50
|
it "works" do
|
51
51
|
expect {
|
52
|
-
|
52
|
+
RubyPgExtras::DiagnosePrint.call(result)
|
53
53
|
}.not_to raise_error
|
54
54
|
end
|
55
55
|
end
|
@@ -57,7 +57,7 @@ describe RubyPGExtras::DiagnoseData do
|
|
57
57
|
context "real database data" do
|
58
58
|
it "works" do
|
59
59
|
expect {
|
60
|
-
|
60
|
+
RubyPgExtras::DiagnosePrint.call(result)
|
61
61
|
}.not_to raise_error
|
62
62
|
end
|
63
63
|
end
|
data/spec/diagnose_print_spec.rb
CHANGED
data/spec/index_info_spec.rb
CHANGED
@@ -2,35 +2,35 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe RubyPgExtras::IndexInfo do
|
6
6
|
subject(:result) do
|
7
|
-
|
7
|
+
RubyPgExtras::IndexInfo.call
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "call" do
|
11
11
|
context "stubbed cases" do
|
12
12
|
before do
|
13
|
-
expect(
|
13
|
+
expect(RubyPgExtras).to receive(:indexes) {
|
14
14
|
[
|
15
15
|
{ "schemaname" => "public", "indexname" => "index_users_on_api_auth_token", "tablename" => "users", "columns" => "api_auth_token, column2" },
|
16
16
|
{"schemaname" => "public", "indexname" => "index_teams_on_slack_id", "tablename" => "teams", "columns" => "slack_id" },
|
17
17
|
]
|
18
18
|
}
|
19
19
|
|
20
|
-
expect(
|
20
|
+
expect(RubyPgExtras).to receive(:index_size) {
|
21
21
|
[
|
22
22
|
{ "name" => "index_users_on_api_auth_token", "size" => "1744 kB" },
|
23
23
|
{"name" => "index_teams_on_slack_id", "size" => "500 kB"},
|
24
24
|
]
|
25
25
|
}
|
26
26
|
|
27
|
-
expect(
|
27
|
+
expect(RubyPgExtras).to receive(:null_indexes) {
|
28
28
|
[
|
29
29
|
{ "oid" => 16803, "index" => "index_users_on_api_auth_token", "index_size" => "1744 kB", "unique"=>true, "indexed_column" => "api_auth_token", "null_frac" => "25.00%", "expected_saving" => "300 kB" }
|
30
30
|
]
|
31
31
|
}
|
32
32
|
|
33
|
-
expect(
|
33
|
+
expect(RubyPgExtras).to receive(:index_scans) {
|
34
34
|
[
|
35
35
|
{ "schemaname" => "public", "table" => "users", "index" => "index_users_on_api_auth_token", "index_size" => "1744 kB", "index_scans"=> 0 },
|
36
36
|
{ "schemaname" => "public", "table" => "teams", "index" => "index_teams_on_slack_id", "index_size" => "500 kB", "index_scans"=> 0 }
|
@@ -40,7 +40,7 @@ describe RubyPGExtras::IndexInfo do
|
|
40
40
|
|
41
41
|
it "works" do
|
42
42
|
expect {
|
43
|
-
|
43
|
+
RubyPgExtras::IndexInfoPrint.call(result)
|
44
44
|
}.not_to raise_error
|
45
45
|
end
|
46
46
|
end
|
@@ -48,7 +48,7 @@ describe RubyPGExtras::IndexInfo do
|
|
48
48
|
context "real data" do
|
49
49
|
it "works" do
|
50
50
|
expect {
|
51
|
-
|
51
|
+
RubyPgExtras::IndexInfoPrint.call(result)
|
52
52
|
}.not_to raise_error
|
53
53
|
end
|
54
54
|
end
|
data/spec/smoke_spec.rb
CHANGED
@@ -2,21 +2,21 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
6
|
-
|
5
|
+
describe RubyPgExtras do
|
6
|
+
RubyPgExtras::QUERIES.each do |query_name|
|
7
7
|
it "#{query_name} description can be read" do
|
8
8
|
expect do
|
9
|
-
|
9
|
+
RubyPgExtras.description_for(
|
10
10
|
query_name: query_name
|
11
11
|
)
|
12
12
|
end.not_to raise_error
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
RubyPgExtras::QUERIES.each do |query_name|
|
17
17
|
it "#{query_name} query can be executed" do
|
18
18
|
expect do
|
19
|
-
|
19
|
+
RubyPgExtras.run_query(
|
20
20
|
query_name: query_name,
|
21
21
|
in_format: :hash
|
22
22
|
)
|
@@ -26,9 +26,9 @@ describe RubyPGExtras do
|
|
26
26
|
|
27
27
|
describe "#database_url=" do
|
28
28
|
it "setting custom database URL works" do
|
29
|
-
|
29
|
+
RubyPgExtras.database_url = ENV.fetch("DATABASE_URL")
|
30
30
|
expect do
|
31
|
-
|
31
|
+
RubyPgExtras.bloat(in_format: :hash)
|
32
32
|
end.not_to raise_error
|
33
33
|
end
|
34
34
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'bundler/setup'
|
5
|
-
require_relative '../lib/
|
5
|
+
require_relative '../lib/ruby_pg_extras'
|
6
6
|
|
7
7
|
pg_version = ENV["PG_VERSION"]
|
8
8
|
|
@@ -20,8 +20,8 @@ ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/ruby-pg-
|
|
20
20
|
|
21
21
|
RSpec.configure do |config|
|
22
22
|
config.before(:suite) do
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
RubyPgExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_stat_statements;")
|
24
|
+
RubyPgExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_buffercache;")
|
25
|
+
RubyPgExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS sslinfo;")
|
26
26
|
end
|
27
27
|
end
|
data/spec/table_info_spec.rb
CHANGED
@@ -2,57 +2,57 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe RubyPgExtras::TableInfo do
|
6
6
|
subject(:result) do
|
7
|
-
|
7
|
+
RubyPgExtras::TableInfo.call
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "call" do
|
11
11
|
context "stubbed cases" do
|
12
12
|
before do
|
13
|
-
expect(
|
13
|
+
expect(RubyPgExtras).to receive(:tables) {
|
14
14
|
[
|
15
15
|
{ "schemaname" => "public", "tablename" => "users" },
|
16
16
|
{ "schemaname" => "public", "tablename" => "teams" }
|
17
17
|
]
|
18
18
|
}
|
19
19
|
|
20
|
-
expect(
|
20
|
+
expect(RubyPgExtras).to receive(:table_size) {
|
21
21
|
[
|
22
22
|
{ "name" => "teams", "size" => "25 MB" },
|
23
23
|
{"name" => "users", "size" => "250 MB"},
|
24
24
|
]
|
25
25
|
}
|
26
26
|
|
27
|
-
expect(
|
27
|
+
expect(RubyPgExtras).to receive(:index_cache_hit) {
|
28
28
|
[
|
29
29
|
{ "name" => "teams", "ratio" => "0.98" },
|
30
30
|
{ "name" => "users", "ratio" => "0.999" },
|
31
31
|
]
|
32
32
|
}
|
33
33
|
|
34
|
-
expect(
|
34
|
+
expect(RubyPgExtras).to receive(:table_cache_hit) {
|
35
35
|
[
|
36
36
|
{ "name" => "teams", "ratio" => "0.88" },
|
37
37
|
{ "name" => "users", "ratio" => "0.899" },
|
38
38
|
]
|
39
39
|
}
|
40
40
|
|
41
|
-
expect(
|
41
|
+
expect(RubyPgExtras).to receive(:records_rank) {
|
42
42
|
[
|
43
43
|
{ "name" => "teams", "estimated_count" => "358" },
|
44
44
|
{ "name" => "users", "estimated_count" => "8973" },
|
45
45
|
]
|
46
46
|
}
|
47
47
|
|
48
|
-
expect(
|
48
|
+
expect(RubyPgExtras).to receive(:seq_scans) {
|
49
49
|
[
|
50
50
|
{ "name" => "teams", "count" => "0" },
|
51
51
|
{ "name" => "users", "count" => "409328" },
|
52
52
|
]
|
53
53
|
}
|
54
54
|
|
55
|
-
expect(
|
55
|
+
expect(RubyPgExtras).to receive(:table_index_scans) {
|
56
56
|
[
|
57
57
|
{ "name" => "teams", "count" => "8579" },
|
58
58
|
{ "name" => "users", "count" => "0" },
|
@@ -62,7 +62,7 @@ describe RubyPGExtras::TableInfo do
|
|
62
62
|
|
63
63
|
it "works" do
|
64
64
|
expect {
|
65
|
-
|
65
|
+
RubyPgExtras::TableInfoPrint.call(result)
|
66
66
|
}.not_to raise_error
|
67
67
|
end
|
68
68
|
end
|
@@ -70,7 +70,7 @@ describe RubyPGExtras::TableInfo do
|
|
70
70
|
context "real data" do
|
71
71
|
it "works" do
|
72
72
|
expect {
|
73
|
-
|
73
|
+
RubyPgExtras::TableInfoPrint.call(result)
|
74
74
|
}.not_to raise_error
|
75
75
|
end
|
76
76
|
end
|
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: 4.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: 2022-
|
11
|
+
date: 2022-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -96,51 +96,51 @@ files:
|
|
96
96
|
- README.md
|
97
97
|
- Rakefile
|
98
98
|
- docker-compose.yml.sample
|
99
|
-
- lib/
|
100
|
-
- lib/
|
101
|
-
- lib/
|
102
|
-
- lib/
|
103
|
-
- lib/
|
104
|
-
- lib/
|
105
|
-
- lib/
|
106
|
-
- lib/
|
107
|
-
- lib/
|
108
|
-
- lib/
|
109
|
-
- lib/
|
110
|
-
- lib/
|
111
|
-
- lib/
|
112
|
-
- lib/
|
113
|
-
- lib/
|
114
|
-
- lib/
|
115
|
-
- lib/
|
116
|
-
- lib/
|
117
|
-
- lib/
|
118
|
-
- lib/
|
119
|
-
- lib/
|
120
|
-
- lib/
|
121
|
-
- lib/
|
122
|
-
- lib/
|
123
|
-
- lib/
|
124
|
-
- lib/
|
125
|
-
- lib/
|
126
|
-
- lib/
|
127
|
-
- lib/
|
128
|
-
- lib/
|
129
|
-
- lib/
|
130
|
-
- lib/
|
131
|
-
- lib/
|
132
|
-
- lib/
|
133
|
-
- lib/
|
134
|
-
- lib/
|
135
|
-
- lib/
|
136
|
-
- lib/
|
137
|
-
- lib/
|
138
|
-
- lib/
|
139
|
-
- lib/
|
140
|
-
- lib/
|
141
|
-
- lib/
|
142
|
-
- lib/
|
143
|
-
- lib/
|
99
|
+
- lib/ruby_pg_extras.rb
|
100
|
+
- lib/ruby_pg_extras/diagnose_data.rb
|
101
|
+
- lib/ruby_pg_extras/diagnose_print.rb
|
102
|
+
- lib/ruby_pg_extras/index_info.rb
|
103
|
+
- lib/ruby_pg_extras/index_info_print.rb
|
104
|
+
- lib/ruby_pg_extras/queries/add_extensions.sql
|
105
|
+
- lib/ruby_pg_extras/queries/all_locks.sql
|
106
|
+
- lib/ruby_pg_extras/queries/bloat.sql
|
107
|
+
- lib/ruby_pg_extras/queries/blocking.sql
|
108
|
+
- lib/ruby_pg_extras/queries/buffercache_stats.sql
|
109
|
+
- lib/ruby_pg_extras/queries/buffercache_usage.sql
|
110
|
+
- lib/ruby_pg_extras/queries/cache_hit.sql
|
111
|
+
- lib/ruby_pg_extras/queries/calls.sql
|
112
|
+
- lib/ruby_pg_extras/queries/calls_legacy.sql
|
113
|
+
- lib/ruby_pg_extras/queries/db_settings.sql
|
114
|
+
- lib/ruby_pg_extras/queries/duplicate_indexes.sql
|
115
|
+
- lib/ruby_pg_extras/queries/extensions.sql
|
116
|
+
- lib/ruby_pg_extras/queries/index_cache_hit.sql
|
117
|
+
- lib/ruby_pg_extras/queries/index_scans.sql
|
118
|
+
- lib/ruby_pg_extras/queries/index_size.sql
|
119
|
+
- lib/ruby_pg_extras/queries/index_usage.sql
|
120
|
+
- lib/ruby_pg_extras/queries/indexes.sql
|
121
|
+
- lib/ruby_pg_extras/queries/kill_all.sql
|
122
|
+
- lib/ruby_pg_extras/queries/locks.sql
|
123
|
+
- lib/ruby_pg_extras/queries/long_running_queries.sql
|
124
|
+
- lib/ruby_pg_extras/queries/mandelbrot.sql
|
125
|
+
- lib/ruby_pg_extras/queries/null_indexes.sql
|
126
|
+
- lib/ruby_pg_extras/queries/outliers.sql
|
127
|
+
- lib/ruby_pg_extras/queries/outliers_legacy.sql
|
128
|
+
- lib/ruby_pg_extras/queries/pg_stat_statements_reset.sql
|
129
|
+
- lib/ruby_pg_extras/queries/records_rank.sql
|
130
|
+
- lib/ruby_pg_extras/queries/seq_scans.sql
|
131
|
+
- lib/ruby_pg_extras/queries/ssl_used.sql
|
132
|
+
- lib/ruby_pg_extras/queries/table_cache_hit.sql
|
133
|
+
- lib/ruby_pg_extras/queries/table_index_scans.sql
|
134
|
+
- lib/ruby_pg_extras/queries/table_indexes_size.sql
|
135
|
+
- lib/ruby_pg_extras/queries/table_size.sql
|
136
|
+
- lib/ruby_pg_extras/queries/tables.sql
|
137
|
+
- lib/ruby_pg_extras/queries/total_index_size.sql
|
138
|
+
- lib/ruby_pg_extras/queries/total_table_size.sql
|
139
|
+
- lib/ruby_pg_extras/queries/unused_indexes.sql
|
140
|
+
- lib/ruby_pg_extras/queries/vacuum_stats.sql
|
141
|
+
- lib/ruby_pg_extras/table_info.rb
|
142
|
+
- lib/ruby_pg_extras/table_info_print.rb
|
143
|
+
- lib/ruby_pg_extras/version.rb
|
144
144
|
- ruby-pg-extras-diagnose.png
|
145
145
|
- ruby-pg-extras.gemspec
|
146
146
|
- spec/diagnose_data_spec.rb
|