pg_online_schema_change 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 839fe414842291d9118a4115a56e06f1e0308ab3b7a740cafd9994314ded2d76
4
- data.tar.gz: 22e9639093bf386f8a1e554e15e8d83df5e3c6de340c372f181fa3b280aee98d
3
+ metadata.gz: e1838409c592e1497790a6e02f883b857851450181854baf660b9b7ee3664c6e
4
+ data.tar.gz: 4f7e58eeafb2413ec774988b3190391033e819a444a25da3b1ff0fcbf6bf64e4
5
5
  SHA512:
6
- metadata.gz: a160d19b3f1cb6655f70e0481b3293110deaee04d7a017ff9fe0c2b4d6100fd7d475520092db1b3bb5e068df5cb70243a00397a5cb1c2c259f2fe5b776b7e405
7
- data.tar.gz: 9e4543fde48359fdc12046ff019420aafe51732f5cd1332285b3762fac3dcb198acc7be4f5fc6f6f90b910532758eb4a5752a8c9835d1f394774e6f77eda3898
6
+ metadata.gz: c769f18ab1815fa543246fd18bb3157add074894f15371abb88e1af61e9381eade6850e4fba3a7d6d3701711594ed10a9018c7fe1c45a5ffdaf501891bf7e548
7
+ data.tar.gz: 84667ac77dab1d97478d51d9635dfcacd38e23ffe59ef6171863ca52d69294af19672bd89dba49a6d325b1c64c4e76a5dc8c57bf3dfee1120e2bd4bec1ca9e21
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [0.9.6] - 2023-11-04
2
+
3
+ - Fix and add links to caveats section in #130
4
+ - Refresh views across all schemas post swap in #134
5
+
1
6
  ## [0.9.5] - 2023-10-15
2
7
 
3
8
  - Validate one constraint at a time in #124
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pg_online_schema_change (0.9.6)
4
+ pg_online_schema_change (0.9.7)
5
5
  ougai (~> 2.0.0)
6
6
  pg (>= 1.3.2, < 1.6.0)
7
7
  pg_query (>= 2.1.3, < 4.3.0)
@@ -11,9 +11,11 @@ GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
13
  ast (2.4.2)
14
+ bigdecimal (3.1.5)
14
15
  coderay (1.1.3)
15
16
  diff-lcs (1.5.0)
16
- google-protobuf (3.25.0-arm64-darwin)
17
+ google-protobuf (3.25.2-arm64-darwin)
18
+ google-protobuf (3.25.2-x86_64-linux)
17
19
  haml (6.1.1)
18
20
  temple (>= 0.8.2)
19
21
  thor
@@ -21,7 +23,8 @@ GEM
21
23
  json (2.6.3)
22
24
  language_server-protocol (3.17.0.3)
23
25
  method_source (1.0.0)
24
- oj (3.16.1)
26
+ oj (3.16.3)
27
+ bigdecimal (>= 3.0)
25
28
  ougai (2.0.0)
26
29
  oj (~> 3.10)
27
30
  parallel (1.23.0)
data/README.md CHANGED
@@ -107,9 +107,9 @@ print the version
107
107
  - `pg-osc` acquires minimal locks throughout the process (read more below on the [caveats](#few-things-to-keep-in-mind)).
108
108
  - Copies over indexes and Foreign keys.
109
109
  - Optionally drop or retain old tables in the end.
110
+ - Reduce bloat (since pg-osc creates a new table and drops the old one post swap).
110
111
  - Tune how slow or fast should replays be from the audit/log table ([Replaying larger workloads](#replaying-larger-workloads)).
111
112
  - Backfill old/new columns as data is copied from primary table to shadow table, and then perform the swap. [Example](#backfill-data)
112
- - **TBD**: Ability to reverse the change with no data loss. [tracking issue](https://github.com/shayonj/pg-osc/issues/14)
113
113
 
114
114
  ## Load test
115
115
 
@@ -67,5 +67,9 @@ module PgOnlineSchemaChange
67
67
 
68
68
  @copy_statement = File.binread(file_path)
69
69
  end
70
+
71
+ def checkout_connection
72
+ PG.connect(dbname: dbname, host: host, user: username, password: password, port: port)
73
+ end
70
74
  end
71
75
  end
@@ -5,6 +5,7 @@ require "securerandom"
5
5
  module PgOnlineSchemaChange
6
6
  class Orchestrate
7
7
  SWAP_STATEMENT_TIMEOUT = "5s"
8
+ TRACK_PROGRESS_INTERVAL = 60 # seconds
8
9
 
9
10
  extend Helper
10
11
 
@@ -58,6 +59,10 @@ module PgOnlineSchemaChange
58
59
 
59
60
  raise Error, "Parent table has no primary key, exiting..." if primary_key.nil?
60
61
 
62
+ logger.info("Performing some house keeping....")
63
+ run_analyze!
64
+ run_vacuum!
65
+
61
66
  setup_audit_table!
62
67
 
63
68
  setup_trigger!
@@ -159,6 +164,12 @@ module PgOnlineSchemaChange
159
164
  end
160
165
 
161
166
  def setup_shadow_table!
167
+ logger.info("Setting up shadow table", { shadow_table: shadow_table })
168
+ Query.run(
169
+ client.connection,
170
+ "SELECT create_table_all('#{client.table_name}', '#{shadow_table}');",
171
+ )
172
+
162
173
  # re-uses transaction with serializable
163
174
  # This ensures that all queries from here till copy_data run with serializable.
164
175
  # This is to to ensure that once the trigger is added to the primay table
@@ -168,13 +179,6 @@ module PgOnlineSchemaChange
168
179
  # adding the trigger, till the copy ends, since they all happen in the
169
180
  # same serializable transaction.
170
181
  Query.run(client.connection, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE", true)
171
- logger.info("Setting up shadow table", { shadow_table: shadow_table })
172
-
173
- Query.run(
174
- client.connection,
175
- "SELECT create_table_all('#{client.table_name}', '#{shadow_table}');",
176
- true,
177
- )
178
182
 
179
183
  # update serials
180
184
  Query.run(
@@ -208,19 +212,44 @@ module PgOnlineSchemaChange
208
212
  )
209
213
  Query.run(client.connection, "DELETE FROM #{audit_table}", true)
210
214
 
211
- logger.info(
212
- "Copying contents..",
213
- { shadow_table: shadow_table, parent_table: client.table_name },
214
- )
215
215
  if client.copy_statement
216
216
  query = format(client.copy_statement, shadow_table: shadow_table)
217
217
  return Query.run(client.connection, query, true)
218
218
  end
219
219
 
220
+ logger.info(
221
+ "Copying contents..",
222
+ { shadow_table: shadow_table, parent_table: client.table_name },
223
+ )
224
+
225
+ @copy_finished = false
226
+ log_progress
227
+
220
228
  sql = Query.copy_data_statement(client, shadow_table, true)
221
229
  Query.run(client.connection, sql, true)
222
230
  ensure
223
231
  Query.run(client.connection, "COMMIT;") # commit the serializable transaction
232
+ @copy_finished = true
233
+ end
234
+
235
+ def log_progress
236
+ new_connection = client.checkout_connection
237
+ source_table_size = Query.get_table_size(new_connection, client.schema, client.table_name)
238
+
239
+ Thread.new do
240
+ loop do
241
+ break if @copy_finished
242
+
243
+ shadow_table_size = Query.get_table_size(new_connection, client.schema, shadow_table)
244
+ progress = (shadow_table_size.to_f / source_table_size) * 100
245
+ logger.info("Estimated copy progress: #{progress.round(2)}% complete")
246
+
247
+ break if @copy_finished || progress >= 100
248
+ sleep(TRACK_PROGRESS_INTERVAL) unless ENV["CI"]
249
+ rescue StandardError => e
250
+ logger.info("Reporting progress failed: #{e.message}")
251
+ end
252
+ end
224
253
  end
225
254
 
226
255
  def replay_and_swap!
@@ -272,7 +301,13 @@ module PgOnlineSchemaChange
272
301
  def run_analyze!
273
302
  logger.info("Performing ANALYZE!")
274
303
 
275
- Query.run(client.connection, "ANALYZE VERBOSE #{client.table_name};")
304
+ client.connection.async_exec("ANALYZE VERBOSE #{client.schema}.#{client.table_name};")
305
+ end
306
+
307
+ def run_vacuum!
308
+ logger.info("Performing VACUUM!")
309
+
310
+ client.connection.async_exec("VACUUM VERBOSE #{client.schema}.#{client.table_name};")
276
311
  end
277
312
 
278
313
  def validate_constraints!
@@ -428,6 +428,15 @@ module PgOnlineSchemaChange
428
428
  SELECT setval((select pg_get_serial_sequence('#{shadow_table}', '#{primary_key}')), (SELECT max(#{primary_key}) FROM #{table}));
429
429
  SQL
430
430
  end
431
+
432
+ def get_table_size(connection, schema, table_name)
433
+ size_query = "SELECT pg_table_size('#{schema}.#{table_name}');"
434
+ result = run(connection, size_query).first
435
+ result["pg_table_size"].to_i
436
+ rescue StandardError => e
437
+ logger.error("Error getting table size: #{e.message}")
438
+ 0
439
+ end
431
440
  end
432
441
  end
433
442
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgOnlineSchemaChange
4
- VERSION = "0.9.6"
4
+ VERSION = "0.9.7"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_online_schema_change
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
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-04 00:00:00.000000000 Z
11
+ date: 2024-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ougai
@@ -311,7 +311,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
311
311
  requirements:
312
312
  - - ">="
313
313
  - !ruby/object:Gem::Version
314
- version: 2.7.0
314
+ version: 3.0.0
315
315
  required_rubygems_version: !ruby/object:Gem::Requirement
316
316
  requirements:
317
317
  - - ">="