pg_easy_replicate 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +20 -18
- data/README.md +5 -5
- data/lib/pg_easy_replicate/version.rb +1 -1
- data/lib/pg_easy_replicate.rb +4 -12
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d45fb127cf497feec36832e91ca67a54878d9fcf783cab3059aad366b0e99026
|
4
|
+
data.tar.gz: 989e3900bebfb04cb9af6037bf849da4f2ea9c6da9a9c6899d64a193ab507b93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5e5a55884a847b5bcfbaee5252704a60e2969c7dba7813fd35e875b2e381c65a7be5088c3042d4473acde9205b0423c59d22e0c9792178c9fd2e49e86b4ef4d
|
7
|
+
data.tar.gz: 17af5a3e97dc562970e3f84f1aa2eb4878159cf5bf8f4d1d7cccd3948ded00c7f2c2f003024281409e07a2d9e19bee1eab8aa7c9a5959eb7ebdc8d9c1da75f33
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.1.10] - 2023-12-12
|
2
|
+
|
3
|
+
- Reference the passed in URL and use source db url - #74
|
4
|
+
|
5
|
+
## [0.1.9] - 2023-08-01
|
6
|
+
|
7
|
+
- Exclude views, temporary tables and foreign tables from #list_all_tables - #39
|
8
|
+
- Add quote_identifier helper for SQL identifiers. - #40
|
9
|
+
- Escape db user name in queries - #42
|
10
|
+
- Require english lib so that $CHILD_STATUS is loaded - #43
|
11
|
+
- Bump rubocop from 1.54.2 to 1.55.0 - #37
|
12
|
+
- Bump rubocop-rspec from 2.22.0 to 2.23.0 - #36
|
13
|
+
- Quote indent username, dbname and schema in all places - #44
|
14
|
+
|
1
15
|
## [0.1.8] - 2023-07-23
|
2
16
|
|
3
17
|
- Introduce --copy_schema via pg_dump - #35
|
data/Gemfile.lock
CHANGED
@@ -1,42 +1,43 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pg_easy_replicate (0.1.
|
4
|
+
pg_easy_replicate (0.1.10)
|
5
5
|
ougai (~> 2.0.0)
|
6
6
|
pg (~> 1.5.3)
|
7
|
-
sequel (>= 5.69, < 5.
|
7
|
+
sequel (>= 5.69, < 5.76)
|
8
8
|
thor (~> 1.2.2)
|
9
9
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
13
|
ast (2.4.2)
|
14
|
+
bigdecimal (3.1.4)
|
14
15
|
coderay (1.1.3)
|
15
16
|
diff-lcs (1.5.0)
|
16
17
|
haml (6.1.1)
|
17
18
|
temple (>= 0.8.2)
|
18
19
|
thor
|
19
20
|
tilt
|
20
|
-
json (2.
|
21
|
+
json (2.7.0)
|
21
22
|
language_server-protocol (3.17.0.3)
|
22
23
|
method_source (1.0.0)
|
23
24
|
oj (3.14.3)
|
24
25
|
ougai (2.0.0)
|
25
26
|
oj (~> 3.10)
|
26
27
|
parallel (1.23.0)
|
27
|
-
parser (3.2.2.
|
28
|
+
parser (3.2.2.4)
|
28
29
|
ast (~> 2.4.1)
|
29
30
|
racc
|
30
|
-
pg (1.5.
|
31
|
+
pg (1.5.4)
|
31
32
|
prettier_print (1.2.1)
|
32
33
|
pry (0.14.2)
|
33
34
|
coderay (~> 1.1)
|
34
35
|
method_source (~> 1.0)
|
35
|
-
racc (1.7.
|
36
|
+
racc (1.7.3)
|
36
37
|
rainbow (3.1.1)
|
37
38
|
rake (13.0.6)
|
38
39
|
rbs (3.1.0)
|
39
|
-
regexp_parser (2.8.
|
40
|
+
regexp_parser (2.8.2)
|
40
41
|
rexml (3.2.6)
|
41
42
|
rspec (3.12.0)
|
42
43
|
rspec-core (~> 3.12.0)
|
@@ -51,37 +52,38 @@ GEM
|
|
51
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
52
53
|
rspec-support (~> 3.12.0)
|
53
54
|
rspec-support (3.12.0)
|
54
|
-
rubocop (1.
|
55
|
+
rubocop (1.58.0)
|
55
56
|
json (~> 2.3)
|
56
57
|
language_server-protocol (>= 3.17.0)
|
57
58
|
parallel (~> 1.10)
|
58
|
-
parser (>= 3.2.2.
|
59
|
+
parser (>= 3.2.2.4)
|
59
60
|
rainbow (>= 2.2.2, < 4.0)
|
60
61
|
regexp_parser (>= 1.8, < 3.0)
|
61
62
|
rexml (>= 3.2.5, < 4.0)
|
62
|
-
rubocop-ast (>= 1.
|
63
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
63
64
|
ruby-progressbar (~> 1.7)
|
64
65
|
unicode-display_width (>= 2.4.0, < 3.0)
|
65
|
-
rubocop-ast (1.
|
66
|
+
rubocop-ast (1.30.0)
|
66
67
|
parser (>= 3.2.1.0)
|
67
|
-
rubocop-capybara (2.
|
68
|
+
rubocop-capybara (2.19.0)
|
68
69
|
rubocop (~> 1.41)
|
69
|
-
rubocop-factory_bot (2.
|
70
|
+
rubocop-factory_bot (2.24.0)
|
70
71
|
rubocop (~> 1.33)
|
71
72
|
rubocop-packaging (0.5.2)
|
72
73
|
rubocop (>= 1.33, < 2.0)
|
73
|
-
rubocop-performance (1.
|
74
|
+
rubocop-performance (1.19.1)
|
74
75
|
rubocop (>= 1.7.0, < 2.0)
|
75
76
|
rubocop-ast (>= 0.4.0)
|
76
77
|
rubocop-rake (0.6.0)
|
77
78
|
rubocop (~> 1.0)
|
78
|
-
rubocop-rspec (2.
|
79
|
+
rubocop-rspec (2.24.1)
|
79
80
|
rubocop (~> 1.33)
|
80
81
|
rubocop-capybara (~> 2.17)
|
81
82
|
rubocop-factory_bot (~> 2.22)
|
82
83
|
ruby-progressbar (1.13.0)
|
83
|
-
sequel (5.
|
84
|
-
|
84
|
+
sequel (5.75.0)
|
85
|
+
bigdecimal
|
86
|
+
syntax_tree (6.2.0)
|
85
87
|
prettier_print (>= 1.2.0)
|
86
88
|
syntax_tree-haml (4.0.3)
|
87
89
|
haml (>= 5.2)
|
@@ -94,7 +96,7 @@ GEM
|
|
94
96
|
temple (0.10.1)
|
95
97
|
thor (1.2.2)
|
96
98
|
tilt (2.1.0)
|
97
|
-
unicode-display_width (2.
|
99
|
+
unicode-display_width (2.5.0)
|
98
100
|
|
99
101
|
PLATFORMS
|
100
102
|
arm64-darwin-22
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Smoke spec](https://github.com/shayonj/pg_easy_replicate/actions/workflows/smoke.yaml/badge.svg?branch=main)](https://github.com/shayonj/pg_easy_replicate/actions/workflows/ci.yaml)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/pg_easy_replicate.svg?2)](https://badge.fury.io/rb/pg_easy_replicate)
|
6
6
|
|
7
|
-
`pg_easy_replicate` is a CLI orchestrator tool that simplifies the process of setting up [logical replication](https://www.postgresql.org/docs/current/logical-replication.html) between two PostgreSQL databases. `pg_easy_replicate` also supports switchover. After the source (primary database) is fully
|
7
|
+
`pg_easy_replicate` is a CLI orchestrator tool that simplifies the process of setting up [logical replication](https://www.postgresql.org/docs/current/logical-replication.html) between two PostgreSQL databases. `pg_easy_replicate` also supports switchover. After the source (primary database) is fully replicated, `pg_easy_replicate` puts it into read-only mode and via logical replication flushes all data to the new target database. This ensures zero data loss and minimal downtime for the application. This method can be useful for performing minimal downtime (up to <1min, depending) major version upgrades between two PostgreSQL databases, load testing with blue/green database setup and other similar use cases.
|
8
8
|
|
9
9
|
Battle tested in production at [Tines](https://www.tines.com/) 🚀
|
10
10
|
|
@@ -58,7 +58,7 @@ https://hub.docker.com/r/shayonj/pg_easy_replicate
|
|
58
58
|
|
59
59
|
- PostgreSQL 10 and later
|
60
60
|
- Ruby 2.7 and later
|
61
|
-
- Database
|
61
|
+
- Database users should have `SUPERUSER` permissions, or pass in a special user with privileges to create the needed role, schema, publication and subscription on both databases. More on `--special-user-role` section below.
|
62
62
|
|
63
63
|
## Limits
|
64
64
|
|
@@ -160,7 +160,7 @@ $ pg_easy_replicate start_sync --group-name database-cluster-1
|
|
160
160
|
|
161
161
|
### Stats
|
162
162
|
|
163
|
-
You can inspect or watch stats any time during the sync process. The stats give you
|
163
|
+
You can inspect or watch stats any time during the sync process. The stats give you an idea of when the sync started, current flush/write lag, how many tables are in `replicating`, `copying` or other stages, and more.
|
164
164
|
|
165
165
|
You can poll these stats to perform any other after the switchover is done. The stats include a `switchover_completed_at` which is updated once the switch over is complete.
|
166
166
|
|
@@ -203,7 +203,7 @@ $ pg_easy_replicate stats --group-name database-cluster-1
|
|
203
203
|
|
204
204
|
`switchover` will wait until all tables in the group are replicating and the delta for lag is <200kb (by calculating the `pg_wal_lsn_diff` between `sent_lsn` and `write_lsn`) and then perform the switch.
|
205
205
|
|
206
|
-
The switch is made by putting the user on the source database in `READ ONLY` mode, so that it is not accepting any more writes and waits for the flush lag to be `0`. It
|
206
|
+
The switch is made by putting the user on the source database in `READ ONLY` mode, so that it is not accepting any more writes and waits for the flush lag to be `0`. It’s up to the user to kick off a rolling restart of your application containers or failover DNS (more on these below in strategies) after the switchover is complete, so that your application isn't sending any read/write requests to the old/source database.
|
207
207
|
|
208
208
|
```bash
|
209
209
|
$ pg_easy_replicate switchover --group-name database-cluster-1
|
@@ -252,7 +252,7 @@ Next, you can set up a program that watches the `stats` and waits until `switcho
|
|
252
252
|
|
253
253
|
### Adding internal user to pgBouncer `userlist`
|
254
254
|
|
255
|
-
`pg_easy_replicate` creates a special user to orchestrate the replication. If you
|
255
|
+
`pg_easy_replicate` creates a special user to orchestrate the replication. If you use pgBouncer, you may need to allow `pger_su_h1a4fb` as a user that can perform login by adding it to the `userlist`.
|
256
256
|
|
257
257
|
## Contributing
|
258
258
|
|
data/lib/pg_easy_replicate.rb
CHANGED
@@ -100,7 +100,6 @@ module PgEasyReplicate
|
|
100
100
|
logger.info("Setting up replication user on source database")
|
101
101
|
create_user(
|
102
102
|
conn_string: source_db_url,
|
103
|
-
group_name: options[:group_name],
|
104
103
|
special_user_role: options[:special_user_role],
|
105
104
|
grant_permissions_on_schema: true,
|
106
105
|
)
|
@@ -108,7 +107,6 @@ module PgEasyReplicate
|
|
108
107
|
logger.info("Setting up replication user on target database")
|
109
108
|
create_user(
|
110
109
|
conn_string: target_db_url,
|
111
|
-
group_name: options[:group_name],
|
112
110
|
special_user_role: options[:special_user_role],
|
113
111
|
)
|
114
112
|
|
@@ -157,7 +155,7 @@ module PgEasyReplicate
|
|
157
155
|
"DROP SCHEMA IF EXISTS #{quote_ident(internal_schema_name)} CASCADE",
|
158
156
|
connection_url: source_db_url,
|
159
157
|
schema: internal_schema_name,
|
160
|
-
user: db_user(
|
158
|
+
user: db_user(source_db_url),
|
161
159
|
)
|
162
160
|
rescue => e
|
163
161
|
raise "Unable to drop schema: #{e.message}"
|
@@ -174,7 +172,7 @@ module PgEasyReplicate
|
|
174
172
|
query: sql,
|
175
173
|
connection_url: source_db_url,
|
176
174
|
schema: internal_schema_name,
|
177
|
-
user: db_user(
|
175
|
+
user: db_user(source_db_url),
|
178
176
|
)
|
179
177
|
rescue => e
|
180
178
|
raise "Unable to setup schema: #{e.message}"
|
@@ -243,12 +241,7 @@ module PgEasyReplicate
|
|
243
241
|
ORDER BY 1;
|
244
242
|
SQL
|
245
243
|
|
246
|
-
r =
|
247
|
-
Query.run(
|
248
|
-
query: sql,
|
249
|
-
connection_url: url,
|
250
|
-
user: db_user(target_db_url),
|
251
|
-
)
|
244
|
+
r = Query.run(query: sql, connection_url: url, user: db_user(url))
|
252
245
|
# If special_user_role is passed just ensure the url in conn_string has been granted
|
253
246
|
# the special_user_role
|
254
247
|
r.any? { |q| q[:role] == special_user_role }
|
@@ -258,7 +251,7 @@ module PgEasyReplicate
|
|
258
251
|
query:
|
259
252
|
"SELECT rolname, rolsuper FROM pg_roles where rolname = '#{db_user(url)}';",
|
260
253
|
connection_url: url,
|
261
|
-
user: db_user(
|
254
|
+
user: db_user(url),
|
262
255
|
)
|
263
256
|
r.any? { |q| q[:rolsuper] }
|
264
257
|
end
|
@@ -268,7 +261,6 @@ module PgEasyReplicate
|
|
268
261
|
|
269
262
|
def create_user(
|
270
263
|
conn_string:,
|
271
|
-
group_name:,
|
272
264
|
special_user_role: nil,
|
273
265
|
grant_permissions_on_schema: false
|
274
266
|
)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_easy_replicate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shayon Mukherjee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ougai
|
@@ -47,7 +47,7 @@ dependencies:
|
|
47
47
|
version: '5.69'
|
48
48
|
- - "<"
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: '5.
|
50
|
+
version: '5.76'
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -57,7 +57,7 @@ dependencies:
|
|
57
57
|
version: '5.69'
|
58
58
|
- - "<"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '5.
|
60
|
+
version: '5.76'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: thor
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|