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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '039398a75ef2c3ce82ef8760784fc14d4d05496f590d64374a6863a4eb200b08'
4
- data.tar.gz: 82d2d82c66aed09fff9276cf76a28ecb994175257ce9c0857cc5b3fd59d4b81e
3
+ metadata.gz: 50ec4785963ebe2582c746a07b4837bc7111057bfb968d97d55b9ffeaeba5fd5
4
+ data.tar.gz: c5468e40d1ffcebe54d9993a85fa5197a54c1e23fc6a103d47475571c21fb311
5
5
  SHA512:
6
- metadata.gz: 25305f71d527acb17f81b8e9e9f8c2b1420f7e07d8a43924eb69043f9be63ea578482e63c68a2800f6adf8b00d53472895ee8a0897a26a7ec0ec750b5250b94e
7
- data.tar.gz: 4d6f3706e52305a885da9351b5e752cffadef0a074bf1139d362622adb37baa0409e103f59458141811e875a01581560fdce6702884cfbffeda88da70f98ec35
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://localhost:5432 -timeout 1m
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
- command: |
25
- bundle exec rspec spec/
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 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).
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
- RubyPGExtras.outliers(args: { limit: 20 })
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
- RubyPGExtras.calls(args: { limit: 10 })
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
- RubyPGExtras.blocking
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
- RubyPGExtras.total_index_size
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
- RubyPGExtras.index_size
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
- RubyPGExtras.table_size
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
- RubyPGExtras.table_indexes_size
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
- RubyPGExtras.total_table_size
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
- RubyPGExtras.unused_indexes(args: { min_scans: 20 })
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
- RubyPGExtras.seq_scans
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
- RubyPGExtras.long_running_queries(args: { threshold: "200 milliseconds" })
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
- RubyPGExtras.records_rank
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
- RubyPGExtras.bloat
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
- RubyPGExtras.vacuum_stats
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
@@ -3,3 +3,8 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
+ desc 'Test all PG versions'
7
+ task :test_all do
8
+ system("PG_VERSION=11 bundle exec rspec spec/ && PG_VERSION=12 bundle exec rspec spec/ && PG_VERSION=13 bundle exec rspec spec/")
9
+ end
10
+
@@ -1,12 +1,30 @@
1
1
  version: '3'
2
2
 
3
3
  services:
4
- postgres:
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'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsPGExtras
4
- VERSION = "1.5.3"
4
+ VERSION = "2.2.0"
5
5
  end
@@ -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
- PG_STATS_DEPENDENT_QUERIES = %i(calls outliers)
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
- (RailsPGExtras::QUERIES - PG_STATS_DEPENDENT_QUERIES).each do |query_name|
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["DATABASE_URL"] ||= "postgresql://postgres:secret@localhost:5432/rails-pg-extras-test"
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: 1.5.3
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-02-16 00:00:00.000000000 Z
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: 1.5.3
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: 1.5.3
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.4
112
+ rubygems_version: 3.1.6
112
113
  signing_key:
113
114
  specification_version: 4
114
115
  summary: Rails PostgreSQL performance database insights