rails-pg-extras 1.5.3 → 2.2.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 +81 -15
- data/Rakefile +5 -0
- data/docker-compose.yml.sample +20 -2
- data/lib/rails-pg-extras/version.rb +1 -1
- data/lib/rails-pg-extras.rb +11 -2
- data/rails-pg-extras-web.png +0 -0
- data/spec/smoke_spec.rb +5 -2
- data/spec/spec_helper.rb +13 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50ec4785963ebe2582c746a07b4837bc7111057bfb968d97d55b9ffeaeba5fd5
|
4
|
+
data.tar.gz: c5468e40d1ffcebe54d9993a85fa5197a54c1e23fc6a103d47475571c21fb311
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fd7ea62b34b1c9a3fcc090bcfb6f5df17223f5208b10bd848ad4bc04e0a2ef8772467edc16cff15dd070a63e5cd23466b334bec9b877efcb033ebe19dec2a77
|
7
|
+
data.tar.gz: 6cbf078dd0a56f9a9cdfac8bac27557b2192f29df9f491807f6e66e994e256fe710df061500198efffcb6bb1f847899a11bd166b73f643b73a55cda7b8675dac
|
data/.circleci/config.yml
CHANGED
@@ -6,6 +6,22 @@ jobs:
|
|
6
6
|
environment:
|
7
7
|
DATABASE_URL: postgresql://postgres:secret@localhost:5432/rails-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: rails-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: rails-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: rails-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
|
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/rails-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/rails-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/rails-pg-extras-test
|
52
|
+
command: bundle exec rspec spec/
|
26
53
|
workflows:
|
27
54
|
version: 2
|
28
55
|
test:
|
data/README.md
CHANGED
@@ -4,7 +4,13 @@ Rails port of [Heroku PG Extras](https://github.com/heroku/heroku-pg-extras) wit
|
|
4
4
|
|
5
5
|
Included rake tasks and Ruby methods 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
|
-
You can
|
7
|
+
You can read 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
|
+
**Shameless plug:** rails-pg-extras is one of the tools that I use when conducting Rails performance audits. [Check out my offer](https://pawelurbanek.com/#rails-performance-tuning) if you need help with fine-tuning your app.
|
10
|
+
|
11
|
+
Use [rails-pg-extras-web](https://github.com/defkode/rails-pg-extras-web) if you want to see SQL metrics in the UI instead of a command line interface.
|
12
|
+
|
13
|
+
![Web interface](https://github.com/pawurb/rails-pg-extras/raw/master/rails-pg-extras-web.png)
|
8
14
|
|
9
15
|
Alternative versions:
|
10
16
|
|
@@ -165,6 +171,22 @@ $ rake pg_extras:db_settings
|
|
165
171
|
|
166
172
|
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
173
|
|
174
|
+
[More info](https://pawelurbanek.com/postgresql-fix-performance#cache-hit)
|
175
|
+
|
176
|
+
### 'ssl_used'
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
|
180
|
+
RailsPGExtras.ssl_used
|
181
|
+
|
182
|
+
| ssl_is_used |
|
183
|
+
+---------------------------------+
|
184
|
+
| t |
|
185
|
+
|
186
|
+
```
|
187
|
+
|
188
|
+
Returns boolean indicating if an encrypted SSL is currently used. Connecting to the database via an unencrypted connection is a critical security risk.
|
189
|
+
|
168
190
|
### `index_usage`
|
169
191
|
|
170
192
|
```ruby
|
@@ -219,7 +241,7 @@ This command displays all the current locks, regardless of their type.
|
|
219
241
|
### `outliers`
|
220
242
|
|
221
243
|
```ruby
|
222
|
-
|
244
|
+
RailsPGExtras.outliers(args: { limit: 20 })
|
223
245
|
|
224
246
|
$ rake pg_extras:outliers
|
225
247
|
|
@@ -243,7 +265,7 @@ Typically, an efficient query will have an appropriate ratio of calls to total e
|
|
243
265
|
### `calls`
|
244
266
|
|
245
267
|
```ruby
|
246
|
-
|
268
|
+
RailsPGExtras.calls(args: { limit: 10 })
|
247
269
|
|
248
270
|
$ rake pg_extras:calls
|
249
271
|
|
@@ -264,7 +286,7 @@ This command is much like `pg:outliers`, but ordered by the number of times a st
|
|
264
286
|
### `blocking`
|
265
287
|
|
266
288
|
```ruby
|
267
|
-
|
289
|
+
RailsPGExtras.blocking
|
268
290
|
|
269
291
|
$ rake pg_extras:blocking
|
270
292
|
|
@@ -281,7 +303,7 @@ This command displays statements that are currently holding locks that other sta
|
|
281
303
|
### `total_index_size`
|
282
304
|
|
283
305
|
```ruby
|
284
|
-
|
306
|
+
RailsPGExtras.total_index_size
|
285
307
|
|
286
308
|
$ rake pg_extras:total_index_size
|
287
309
|
|
@@ -296,7 +318,7 @@ This command displays the total size of all indexes on the database, in MB. It i
|
|
296
318
|
### `index_size`
|
297
319
|
|
298
320
|
```ruby
|
299
|
-
|
321
|
+
RailsPGExtras.index_size
|
300
322
|
|
301
323
|
$ rake pg_extras:index_size
|
302
324
|
name | size
|
@@ -319,7 +341,7 @@ This command displays the size of each each index in the database, in MB. It is
|
|
319
341
|
### `table_size`
|
320
342
|
|
321
343
|
```ruby
|
322
|
-
|
344
|
+
RailsPGExtras.table_size
|
323
345
|
|
324
346
|
$ rake pg_extras:table_size
|
325
347
|
|
@@ -338,7 +360,7 @@ This command displays the size of each table and materialized view in the databa
|
|
338
360
|
### `table_indexes_size`
|
339
361
|
|
340
362
|
```ruby
|
341
|
-
|
363
|
+
RailsPGExtras.table_indexes_size
|
342
364
|
|
343
365
|
$ rake pg_extras:table_indexes_size
|
344
366
|
|
@@ -357,7 +379,7 @@ This command displays the total size of indexes for each table and materialized
|
|
357
379
|
### `total_table_size`
|
358
380
|
|
359
381
|
```ruby
|
360
|
-
|
382
|
+
RailsPGExtras.total_table_size
|
361
383
|
|
362
384
|
$ rake pg_extras:total_table_size
|
363
385
|
|
@@ -376,7 +398,7 @@ This command displays the total size of each table and materialized view in the
|
|
376
398
|
### `unused_indexes`
|
377
399
|
|
378
400
|
```ruby
|
379
|
-
|
401
|
+
RailsPGExtras.unused_indexes(args: { min_scans: 20 })
|
380
402
|
|
381
403
|
$ rake pg_extras:unused_indexes
|
382
404
|
|
@@ -392,6 +414,19 @@ This command displays indexes that have < 50 scans recorded against them, and ar
|
|
392
414
|
|
393
415
|
[More info](https://pawelurbanek.com/postgresql-fix-performance#unused-indexes)
|
394
416
|
|
417
|
+
### `duplicate_indexes`
|
418
|
+
|
419
|
+
```ruby
|
420
|
+
|
421
|
+
RailsPGExtras.duplicate_indexes
|
422
|
+
|
423
|
+
| size | idx1 | idx2 | idx3 | idx4 |
|
424
|
+
+------------+--------------+----------------+----------+-----------+
|
425
|
+
| 128 k | users_pkey | index_users_id | | |
|
426
|
+
```
|
427
|
+
|
428
|
+
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.
|
429
|
+
|
395
430
|
### `null_indexes`
|
396
431
|
|
397
432
|
```ruby
|
@@ -415,7 +450,7 @@ This command displays indexes that contain `NULL` values. A high ratio of `NULL`
|
|
415
450
|
### `seq_scans`
|
416
451
|
|
417
452
|
```ruby
|
418
|
-
|
453
|
+
RailsPGExtras.seq_scans
|
419
454
|
|
420
455
|
$ rake pg_extras:seq_scans
|
421
456
|
|
@@ -439,7 +474,7 @@ This command displays the number of sequential scans recorded against all tables
|
|
439
474
|
### `long_running_queries`
|
440
475
|
|
441
476
|
```ruby
|
442
|
-
|
477
|
+
RailsPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
|
443
478
|
|
444
479
|
$ rake pg_extras:long_running_queries
|
445
480
|
|
@@ -456,7 +491,7 @@ This command displays currently running queries, that have been running for long
|
|
456
491
|
### `records_rank`
|
457
492
|
|
458
493
|
```ruby
|
459
|
-
|
494
|
+
RailsPGExtras.records_rank
|
460
495
|
|
461
496
|
$ rake pg_extras:records_rank
|
462
497
|
|
@@ -476,7 +511,7 @@ This command displays an estimated count of rows per table, descending by estima
|
|
476
511
|
### `bloat`
|
477
512
|
|
478
513
|
```ruby
|
479
|
-
|
514
|
+
RailsPGExtras.bloat
|
480
515
|
|
481
516
|
$ rake pg_extras:bloat
|
482
517
|
|
@@ -497,7 +532,7 @@ This command displays an estimation of table "bloat" – space allocated to a re
|
|
497
532
|
### `vacuum_stats`
|
498
533
|
|
499
534
|
```ruby
|
500
|
-
|
535
|
+
RailsPGExtras.vacuum_stats
|
501
536
|
|
502
537
|
$ rake pg_extras:vacuum_stats
|
503
538
|
|
@@ -522,6 +557,22 @@ RailsPGExtras.kill_all
|
|
522
557
|
|
523
558
|
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.
|
524
559
|
|
560
|
+
### `buffercache_stats`
|
561
|
+
|
562
|
+
```ruby
|
563
|
+
RailsPGExtras.buffercache_stats(args: { limit: 10 })
|
564
|
+
```
|
565
|
+
|
566
|
+
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.
|
567
|
+
|
568
|
+
### `buffercache_usage`
|
569
|
+
|
570
|
+
```ruby
|
571
|
+
RailsPGExtras.buffercache_usage(args: { limit: 20 })
|
572
|
+
```
|
573
|
+
|
574
|
+
This command calculates how many blocks from which table are currently cached.
|
575
|
+
|
525
576
|
### `extensions`
|
526
577
|
|
527
578
|
```ruby
|
@@ -546,3 +597,18 @@ $ rake pg_extras:mandelbrot
|
|
546
597
|
```
|
547
598
|
|
548
599
|
This command outputs the Mandelbrot set, calculated through SQL.
|
600
|
+
|
601
|
+
## Testing
|
602
|
+
|
603
|
+
```bash
|
604
|
+
cp docker-compose.yml.sample docker-compose.yml
|
605
|
+
docker compose up -d
|
606
|
+
rake test_all
|
607
|
+
```
|
608
|
+
|
609
|
+
## Query sources
|
610
|
+
|
611
|
+
- [https://github.com/heroku/heroku-pg-extras](https://github.com/heroku/heroku-pg-extras)
|
612
|
+
- [https://hakibenita.com/postgresql-unused-index-size](https://hakibenita.com/postgresql-unused-index-size)
|
613
|
+
- [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)
|
614
|
+
- [https://wiki.postgresql.org/wiki/Index_Maintenance](https://wiki.postgresql.org/wiki/Index_Maintenance)
|
data/Rakefile
CHANGED
data/docker-compose.yml.sample
CHANGED
@@ -1,12 +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: rails-pg-extras-test
|
9
10
|
POSTGRES_PASSWORD: secret
|
10
11
|
ports:
|
11
12
|
- '5432:5432'
|
12
|
-
|
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: rails-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: rails-pg-extras-test
|
28
|
+
POSTGRES_PASSWORD: secret
|
29
|
+
ports:
|
30
|
+
- '5434:5432'
|
data/lib/rails-pg-extras.rb
CHANGED
@@ -6,6 +6,7 @@ require 'ruby-pg-extras'
|
|
6
6
|
module RailsPGExtras
|
7
7
|
QUERIES = RubyPGExtras::QUERIES
|
8
8
|
DEFAULT_ARGS = RubyPGExtras::DEFAULT_ARGS
|
9
|
+
NEW_PG_STAT_STATEMENTS = RubyPGExtras::NEW_PG_STAT_STATEMENTS
|
9
10
|
|
10
11
|
QUERIES.each do |query_name|
|
11
12
|
define_singleton_method query_name do |options = {}|
|
@@ -18,6 +19,16 @@ module RailsPGExtras
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def self.run_query(query_name:, in_format:, args: {})
|
22
|
+
if %i(calls outliers).include?(query_name)
|
23
|
+
pg_stat_statements_ver = RailsPGExtras.connection.execute("select installed_version from pg_available_extensions where name='pg_stat_statements'")
|
24
|
+
.to_a[0].fetch("installed_version", nil)
|
25
|
+
if pg_stat_statements_ver != nil
|
26
|
+
if Gem::Version.new(pg_stat_statements_ver) < Gem::Version.new(NEW_PG_STAT_STATEMENTS)
|
27
|
+
query_name = "#{query_name}_legacy".to_sym
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
21
32
|
sql = if (custom_args = DEFAULT_ARGS[query_name].merge(args)) != {}
|
22
33
|
RubyPGExtras.sql_for(query_name: query_name) % custom_args
|
23
34
|
else
|
@@ -36,8 +47,6 @@ module RailsPGExtras
|
|
36
47
|
def self.connection
|
37
48
|
ActiveRecord::Base.connection
|
38
49
|
end
|
39
|
-
|
40
|
-
private_class_method :connection
|
41
50
|
end
|
42
51
|
|
43
52
|
require 'rails-pg-extras/railtie' if defined?(Rails)
|
Binary file
|
data/spec/smoke_spec.rb
CHANGED
@@ -3,9 +3,12 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe RailsPGExtras do
|
6
|
-
|
6
|
+
before(:all) do
|
7
|
+
RailsPGExtras.connection.execute("CREATE EXTENSION IF NOT EXISTS pg_buffercache;")
|
8
|
+
RubyPGExtras.connection.exec("CREATE EXTENSION IF NOT EXISTS pg_stat_statements;")
|
9
|
+
end
|
7
10
|
|
8
|
-
|
11
|
+
RailsPGExtras::QUERIES.each do |query_name|
|
9
12
|
it "#{query_name} query can be executed" do
|
10
13
|
expect do
|
11
14
|
RailsPGExtras.run_query(
|
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,19 @@ require 'bundler/setup'
|
|
5
5
|
require 'active_record'
|
6
6
|
require_relative '../lib/rails-pg-extras'
|
7
7
|
|
8
|
-
ENV["
|
8
|
+
pg_version = ENV["PG_VERSION"]
|
9
|
+
|
10
|
+
port = if pg_version == "11"
|
11
|
+
"5432"
|
12
|
+
elsif pg_version == "12"
|
13
|
+
"5433"
|
14
|
+
elsif pg_version == "13"
|
15
|
+
"5434"
|
16
|
+
else
|
17
|
+
"5432"
|
18
|
+
end
|
19
|
+
|
20
|
+
ENV["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:#{port}/rails-pg-extras-test"
|
9
21
|
|
10
22
|
RSpec.configure do |config|
|
11
23
|
config.before :suite do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-pg-extras
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.2.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-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-pg-extras
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/rails-pg-extras/railtie.rb
|
87
87
|
- lib/rails-pg-extras/tasks/all.rake
|
88
88
|
- lib/rails-pg-extras/version.rb
|
89
|
+
- rails-pg-extras-web.png
|
89
90
|
- rails-pg-extras.gemspec
|
90
91
|
- spec/smoke_spec.rb
|
91
92
|
- spec/spec_helper.rb
|
@@ -108,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
109
|
- !ruby/object:Gem::Version
|
109
110
|
version: '0'
|
110
111
|
requirements: []
|
111
|
-
rubygems_version: 3.1.
|
112
|
+
rubygems_version: 3.1.6
|
112
113
|
signing_key:
|
113
114
|
specification_version: 4
|
114
115
|
summary: Rails PostgreSQL performance database insights
|