ruby-pg-extras 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a09437b758895b5a7dcb519cd1659c5afb0ae11d9fa3e79b73ddac88cd689c8
4
- data.tar.gz: addcfb85c1f3a73731cbd34670ed984d8677954563980cf4e9b3317fcc329ce8
3
+ metadata.gz: 5d6fbc5ab6b75d6afab360ce585c6b99da6f7c7622da5c7d41ef5c9a352cf1d0
4
+ data.tar.gz: d6065e2b079138d523ea47dd5855793e6c53d45d7d0f59f6035a3f0cc22e97d1
5
5
  SHA512:
6
- metadata.gz: 62cdf41039cd544cc02467606282bca0ecf990b0d65eeaf51803e356b702eba719ee4f861318fef7a225834c0afa85b0ed4f5cd652e604b9c9c6f5f0057e5f7f
7
- data.tar.gz: '081df083c1f33c94883eb0fff10ad32b6ca28629f39b07ca704879a45c7945b7c67706bd27107fcfff8001ba4d78924ff1f4810ff7fdab312748ef9bedbbbce1'
6
+ metadata.gz: 06235baa16b1433f94c6df83cdd764792ab85217ea0dae0880fedf981f84e7e4a12748e267462bc99a69096dd7706cf6893680d24f7b1e7da5fc8c502e4bc9fb
7
+ data.tar.gz: 0cce03aa9d5e05cc826c4d4835fc4fc8c3d50f3d062dfbdd7deec85d4b51366de68e264d3e3023f509464144ab80ae983975cecb50aaf3d333b1a8e0962df878
@@ -16,7 +16,8 @@ jobs:
16
16
  - run: gem update --system
17
17
  - run: gem install bundler
18
18
  - run: bundle install --path vendor/bundle
19
- - run: sudo apt install postgresql-client
19
+ - run: sudo apt-get update
20
+ - run: sudo apt install postgresql-client-11
20
21
  - run: dockerize -wait tcp://localhost:5432 -timeout 1m
21
22
  - run:
22
23
  name: Run specs
data/README.md CHANGED
@@ -4,7 +4,19 @@ Ruby port of [Heroku PG Extras](https://github.com/heroku/heroku-pg-extras) with
4
4
 
5
5
  Queries can be used to obtain information about a Postgres instance, that may be useful when analyzing performance issues. This includes information about locks, index usage, buffer cache hit ratios and vacuum statistics. Ruby API enables developers to easily integrate the tool into e.g. automatic monitoring tasks.
6
6
 
7
- Are you riding on Rails? Check out the [Rails version](https://github.com/pawurb/rails-pg-extras).
7
+ You can check out this blog post for detailed step by step tutorial on how to [optimize PostgreSQL using PG Extras library](https://pawelurbanek.com/postgresql-fix-performance).
8
+
9
+ Alternative versions:
10
+
11
+ - [Ruby on Rails](https://github.com/pawurb/rails-pg-extras)
12
+
13
+ - [NodeJS](https://github.com/pawurb/node-postgres-extras)
14
+
15
+ - [Elixir](https://github.com/pawurb/ecto_psql_extras)
16
+
17
+ - [Python](https://github.com/pawurb/python-pg-extras)
18
+
19
+ - [Haskell](https://github.com/pawurb/haskell-pg-extras)
8
20
 
9
21
  ## Installation
10
22
 
@@ -14,6 +26,19 @@ In your Gemfile
14
26
  gem "ruby-pg-extras"
15
27
  ```
16
28
 
29
+ Some of the queries (e.g., `calls` and `outliers`) require [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html) extension enabled.
30
+
31
+ You can check if it is enabled in your database by running:
32
+
33
+ ```ruby
34
+ RubyPGExtras.extensions
35
+ ```
36
+ You should see the similar line in the output:
37
+
38
+ ```bash
39
+ | pg_stat_statements | 1.7 | 1.7 | track execution statistics of all SQL statements executed |
40
+ ```
41
+
17
42
  ## Usage
18
43
 
19
44
  Gem expects the `ENV['DATABASE_URL']` value in the following format:
@@ -91,7 +116,7 @@ RubyPGExtras.index_cache_hit
91
116
  (truncated results for brevity)
92
117
  ```
93
118
 
94
- The same as `cache_hit` with each table's indexes cache hit info displayed seperately.
119
+ The same as `cache_hit` with each table's indexes cache hit info displayed separately.
95
120
 
96
121
  ### `table_cache_hit`
97
122
 
@@ -144,7 +169,7 @@ RubyPGExtras.locks
144
169
  (4 rows)
145
170
  ```
146
171
 
147
- This command displays queries that have taken out an exlusive 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.
172
+ 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.
148
173
 
149
174
  ### `all_locks`
150
175
 
@@ -174,7 +199,7 @@ RubyPGExtras.outliers
174
199
  (truncated results for brevity)
175
200
  ```
176
201
 
177
- This command displays statements, obtained from `pg_stat_statements`, ordered by the amount of time to execute in aggregate. This includes the statement itself, the total execution time for that statement, the proportion of total execution time for all statements that statement has taken up, the number of times that statement has been called, and the amount of time that statement spent on synchronous I/O (reading/writing from the filesystem).
202
+ This command displays statements, obtained from `pg_stat_statements`, ordered by the amount of time to execute in aggregate. This includes the statement itself, the total execution time for that statement, the proportion of total execution time for all statements that statement has taken up, the number of times that statement has been called, and the amount of time that statement spent on synchronous I/O (reading/writing from the file system).
178
203
 
179
204
  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.
180
205
 
@@ -283,7 +308,7 @@ RubyPGExtras.table_indexes_size
283
308
  (truncated results for brevity)
284
309
  ```
285
310
 
286
- This command displays the total size of indexes for each table, in MB. It is calcualtes by using the system administration function `pg_indexes_size()`.
311
+ This command displays the total size of indexes for each table and materialized view, in MB. It is calculated by using the system administration function `pg_indexes_size()`.
287
312
 
288
313
  ### `total_table_size`
289
314
 
@@ -301,7 +326,7 @@ RubyPGExtras.total_table_size
301
326
  (truncated results for brevity)
302
327
  ```
303
328
 
304
- This command displays the total size of each table in the database, in MB. It is calculated by using the system administration function `pg_total_relation_size()`, which includes table size, total index size and TOAST data.
329
+ This command displays the total size of each table and materialized view in the database, in MB. It is calculated by using the system administration function `pg_total_relation_size()`, which includes table size, total index size and TOAST data.
305
330
 
306
331
  ### `unused_indexes`
307
332
 
@@ -339,7 +364,7 @@ RubyPGExtras.seq_scans
339
364
  (truncated results for brevity)
340
365
  ```
341
366
 
342
- 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 underindexed, and it may be worth investigating queries that read from these tables.
367
+ 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.
343
368
 
344
369
  ### `long_running_queries`
345
370
 
@@ -412,7 +437,7 @@ RubyPGExtras.vacuum_stats
412
437
  (truncated results for brevity)
413
438
  ```
414
439
 
415
- This command displays statistics related to vacuum operations for each table, including an estiamtion of dead rows, last autovacuum and the current autovacuum threshold. This command can be useful when determining if current vacuum thresholds require adjustments, and to determine when the table was last vacuumed.
440
+ This command displays statistics related to vacuum operations for each table, including an estimation of dead rows, last autovacuum and the current autovacuum threshold. This command can be useful when determining if current vacuum thresholds require adjustments, and to determine when the table was last vacuumed.
416
441
 
417
442
  ### `kill_all`
418
443
 
@@ -424,18 +449,22 @@ RubyPGExtras.kill_all
424
449
 
425
450
  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.
426
451
 
427
- ### `mandelbrot`
452
+ ### `extensions`
428
453
 
429
454
  ```ruby
430
455
 
431
- RubyPGExtras.mandelbrot
456
+ RubyPGExtras.extensions
432
457
 
433
458
  ```
434
459
 
435
- This command outputs the Mandelbrot set, calculated through SQL.
460
+ This command lists all the currently installed and available PostgreSQL extensions.
461
+
462
+ ### `mandelbrot`
463
+
464
+ ```ruby
436
465
 
437
- ## FAQ
466
+ RubyPGExtras.mandelbrot
438
467
 
439
- * Does is not violate the Heroku PG Extras license?
468
+ ```
440
469
 
441
- The original plugin is MIT based so it means that copying and redistribution in any format is permitted.
470
+ This command outputs the Mandelbrot set, calculated through SQL.
@@ -17,19 +17,30 @@ module RubyPGExtras
17
17
  unused_indexes vacuum_stats kill_all
18
18
  )
19
19
 
20
+ DEFAULT_ARGS = Hash.new({}).merge({
21
+ calls: { limit: 10 },
22
+ long_running_queries: { interval: '5 seconds' },
23
+ outliers: { limit: 10 },
24
+ unused_indexes: { min_scans: 50 }
25
+ })
26
+
20
27
  QUERIES.each do |query_name|
21
- define_singleton_method query_name do |options = { in_format: :display_table }|
28
+ define_singleton_method query_name do |options = {}|
22
29
  run_query(
23
30
  query_name: query_name,
24
- in_format: options.fetch(:in_format)
31
+ in_format: options.fetch(:in_format, :display_table),
32
+ args: options.fetch(:args, {})
25
33
  )
26
34
  end
27
35
  end
28
36
 
29
- def self.run_query(query_name:, in_format:)
30
- result = connection.exec(
37
+ def self.run_query(query_name:, in_format:, args: {})
38
+ sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
39
+ sql_for(query_name: query_name) % custom_args
40
+ else
31
41
  sql_for(query_name: query_name)
32
- )
42
+ end
43
+ result = connection.exec(sql)
33
44
 
34
45
  display_result(
35
46
  result,
@@ -1,9 +1,9 @@
1
- /* 10 queries that have highest frequency of execution */
1
+ /* Queries that have highest frequency of execution */
2
2
 
3
3
  SELECT query AS qry,
4
4
  interval '1 millisecond' * total_time AS exec_time,
5
- to_char((total_time/sum(total_time) OVER()) * 100, 'FM90D0') || '%' AS prop_exec_time,
5
+ to_char((total_time/sum(total_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)
9
- ORDER BY calls DESC LIMIT 10;
9
+ ORDER BY calls DESC LIMIT %{limit};
@@ -9,6 +9,6 @@ FROM
9
9
  WHERE
10
10
  pg_stat_activity.query <> ''::text
11
11
  AND state <> 'idle'
12
- AND now() - pg_stat_activity.query_start > interval '5 minutes'
12
+ AND now() - pg_stat_activity.query_start > interval '%{interval}'
13
13
  ORDER BY
14
14
  now() - pg_stat_activity.query_start DESC;
@@ -1,10 +1,10 @@
1
- /* 10 queries that have longest execution time in aggregate */
1
+ /* Queries that have longest execution time in aggregate */
2
2
 
3
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,
4
+ to_char((total_time/sum(total_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
9
  ORDER BY total_time DESC
10
- LIMIT 10;
10
+ LIMIT %{limit};
@@ -6,5 +6,5 @@ FROM pg_class c
6
6
  LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
7
7
  WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
8
8
  AND n.nspname !~ '^pg_toast'
9
- AND c.relkind='r'
9
+ AND c.relkind IN ('r', 'm')
10
10
  ORDER BY pg_indexes_size(c.oid) DESC;
@@ -6,5 +6,5 @@ FROM pg_class c
6
6
  LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace)
7
7
  WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
8
8
  AND n.nspname !~ '^pg_toast'
9
- AND c.relkind='r'
9
+ AND c.relkind IN ('r', 'm')
10
10
  ORDER BY pg_table_size(c.oid) DESC;
@@ -11,6 +11,6 @@ SELECT
11
11
  idx_scan as index_scans
12
12
  FROM pg_stat_user_indexes ui
13
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
14
+ WHERE NOT indisunique AND idx_scan < %{min_scans} AND pg_relation_size(relid) > 5 * 8192
15
15
  ORDER BY pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST,
16
16
  pg_relation_size(i.indexrelid) DESC;
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RubyPGExtras
2
- VERSION = "1.2.0"
4
+ VERSION = "1.3.0"
3
5
  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: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pawurb
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-13 00:00:00.000000000 Z
11
+ date: 2021-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -114,7 +114,7 @@ homepage: http://github.com/pawurb/ruby-pg-extras
114
114
  licenses:
115
115
  - MIT
116
116
  metadata: {}
117
- post_install_message:
117
+ post_install_message:
118
118
  rdoc_options: []
119
119
  require_paths:
120
120
  - lib
@@ -129,8 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
131
  requirements: []
132
- rubygems_version: 3.0.6
133
- signing_key:
132
+ rubygems_version: 3.1.4
133
+ signing_key:
134
134
  specification_version: 4
135
135
  summary: Ruby PostgreSQL performance database insights
136
136
  test_files: