Skip to content

Commit 4813032

Browse files
authored
feat: set lock_timeout to 0 for index create/drop (#30)
1 parent 53e30c3 commit 4813032

File tree

7 files changed

+27
-45
lines changed

7 files changed

+27
-45
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,7 @@ So you can actually check that the `CREATE INDEX` statement will be performed co
206206
```ruby
207207
SafePgMigrations.config.safe_timeout = 5.seconds # Lock and statement timeout used for all DDL operations except from CREATE / DROP INDEX
208208

209-
SafePgMigrations.config.index_lock_timeout = 30.seconds # Lock timeout used for CREATE / DROP INDEX
210-
211-
SafePgMigrations.config.blocking_activity_logger_margin = 1.second # Delay to output blocking queries before timeout. Must be smaller than safe_timeout and index_lock_timeout
209+
SafePgMigrations.config.blocking_activity_logger_margin = 1.second # Delay to output blocking queries before timeout. Must be shorter than safe_timeout
212210

213211
SafePgMigrations.config.batch_size = 1000 # Size of the batches used for backfilling when adding a column with a default value pre-PG11
214212

lib/safe-pg-migrations/configuration.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
module SafePgMigrations
66
class Configuration
77
attr_accessor :safe_timeout
8-
attr_accessor :index_lock_timeout
98
attr_accessor :blocking_activity_logger_margin
109
attr_accessor :batch_size
1110
attr_accessor :retry_delay
1211
attr_accessor :max_tries
1312

1413
def initialize
1514
self.safe_timeout = 5.seconds
16-
self.index_lock_timeout = 30.seconds
1715
self.blocking_activity_logger_margin = 1.second
1816
self.batch_size = 1000
1917
self.retry_delay = 1.minute
@@ -24,10 +22,6 @@ def pg_safe_timeout
2422
pg_duration(safe_timeout)
2523
end
2624

27-
def pg_index_lock_timeout
28-
pg_duration(index_lock_timeout)
29-
end
30-
3125
def pg_duration(duration)
3226
value, unit = duration.integer? ? [duration, 's'] : [(duration * 1000).to_i, 'ms']
3327
"#{value}#{unit}"

lib/safe-pg-migrations/plugins/blocking_activity_logger.rb

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,22 @@ module BlockingActivityLogger
2525
SQL
2626

2727
%i[
28-
add_column remove_column add_foreign_key remove_foreign_key change_column_default
29-
change_column_null create_table add_index remove_index
28+
add_column remove_column add_foreign_key remove_foreign_key change_column_default change_column_null create_table
3029
].each do |method|
3130
define_method method do |*args, &block|
32-
log_blocking_queries(method) { super(*args, &block) }
31+
log_blocking_queries { super(*args, &block) }
3332
end
3433
end
3534

3635
private
3736

38-
def delay_before_logging(method)
39-
timeout_delay =
40-
if %i[add_index remove_index].include?(method)
41-
SafePgMigrations.config.index_lock_timeout
42-
else
43-
SafePgMigrations.config.safe_timeout
44-
end
45-
46-
timeout_delay - SafePgMigrations.config.blocking_activity_logger_margin
47-
end
37+
def log_blocking_queries
38+
delay_before_logging =
39+
SafePgMigrations.config.safe_timeout - SafePgMigrations.config.blocking_activity_logger_margin
4840

49-
def log_blocking_queries(method)
5041
blocking_queries_retriever_thread =
5142
Thread.new do
52-
sleep delay_before_logging(method)
43+
sleep delay_before_logging
5344
SafePgMigrations.alternate_connection.query(SELECT_BLOCKING_QUERIES_SQL % raw_connection.backend_pid)
5445
end
5546

lib/safe-pg-migrations/plugins/statement_insurer.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ def add_index(table_name, column_name, **options)
5050
options[:algorithm] = :concurrently
5151
SafePgMigrations.say_method_call(:add_index, table_name, column_name, options)
5252

53-
with_index_timeouts { super }
53+
without_timeout { super }
5454
end
5555

5656
def remove_index(table_name, options = {})
5757
options = { column: options } unless options.is_a?(Hash)
5858
options[:algorithm] = :concurrently
5959
SafePgMigrations.say_method_call(:remove_index, table_name, options)
6060

61-
with_index_timeouts { super }
61+
without_timeout { super }
6262
end
6363

6464
def backfill_column_default(table_name, column_name)
@@ -99,12 +99,12 @@ def without_statement_timeout
9999
with_setting(:statement_timeout, 0) { yield }
100100
end
101101

102-
def with_index_timeouts
103-
without_statement_timeout do
104-
with_setting(:lock_timeout, SafePgMigrations.config.pg_index_lock_timeout) do
105-
yield
106-
end
107-
end
102+
def without_lock_timeout
103+
with_setting(:lock_timeout, 0) { yield }
104+
end
105+
106+
def without_timeout
107+
without_statement_timeout { without_lock_timeout { yield } }
108108
end
109109
end
110110
end

lib/safe-pg-migrations/plugins/statement_retrier.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
module SafePgMigrations
44
module StatementRetrier
55
RETRIABLE_SCHEMA_STATEMENTS = %i[
6-
add_column add_foreign_key remove_foreign_key change_column_default
7-
change_column_null add_index remove_index remove_column
6+
add_column add_foreign_key remove_foreign_key change_column_default change_column_null remove_column
87
].freeze
98

109
RETRIABLE_SCHEMA_STATEMENTS.each do |method|

test/create_table_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def change
4343

4444
# Create the index.
4545
'SET statement_timeout TO 0',
46-
"SET lock_timeout TO '30s'",
46+
'SET lock_timeout TO 0',
4747
'CREATE INDEX CONCURRENTLY "index_users_on_user_id" ON "users" ("user_id")',
4848
"SET lock_timeout TO '5s'",
4949
"SET statement_timeout TO '5s'",
@@ -82,11 +82,11 @@ def change
8282
assert_calls [
8383
"SET statement_timeout TO '5s'",
8484
'SET statement_timeout TO 0',
85-
"SET lock_timeout TO '30s'",
85+
'SET lock_timeout TO 0',
8686
"SET lock_timeout TO '5s'",
8787
"SET statement_timeout TO '5s'",
8888
'SET statement_timeout TO 0',
89-
"SET lock_timeout TO '30s'",
89+
'SET lock_timeout TO 0',
9090
'CREATE INDEX CONCURRENTLY "index_users_on_email" ON "users" ("email")',
9191
"SET lock_timeout TO '5s'",
9292
"SET statement_timeout TO '5s'",

test/safe_pg_migrations_test.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def change
309309

310310
# An index is created because of the column reference.
311311
'SET statement_timeout TO 0',
312-
"SET lock_timeout TO '30s'",
312+
'SET lock_timeout TO 0',
313313
'CREATE INDEX CONCURRENTLY "index_users_on_user_id" ON "users" ("user_id")',
314314
"SET lock_timeout TO '5s'",
315315
"SET statement_timeout TO '70s'",
@@ -332,7 +332,7 @@ def change
332332
calls = record_calls(@connection, :execute) { run_migration }
333333
assert_calls [
334334
'SET statement_timeout TO 0',
335-
"SET lock_timeout TO '30s'",
335+
'SET lock_timeout TO 0',
336336
'CREATE INDEX CONCURRENTLY "index_users_on_email" ON "users" ("email")',
337337
"SET lock_timeout TO '5s'",
338338
"SET statement_timeout TO '70s'",
@@ -355,12 +355,12 @@ def change
355355

356356
assert_calls [
357357
'SET statement_timeout TO 0',
358-
"SET lock_timeout TO '30s'",
358+
'SET lock_timeout TO 0',
359359
'CREATE INDEX CONCURRENTLY "my_custom_index_name" ON "users" ("email") WHERE email IS NOT NULL',
360360
"SET lock_timeout TO '5s'",
361361
"SET statement_timeout TO '70s'",
362362
'SET statement_timeout TO 0',
363-
"SET lock_timeout TO '30s'",
363+
'SET lock_timeout TO 0',
364364
"SET lock_timeout TO '5s'",
365365
"SET statement_timeout TO '70s'",
366366
], calls
@@ -398,12 +398,12 @@ def change
398398
calls = record_calls(@connection, :execute) { run_migration }
399399
assert_calls [
400400
'SET statement_timeout TO 0',
401-
"SET lock_timeout TO '30s'",
401+
'SET lock_timeout TO 0',
402402

403403
'SET statement_timeout TO 0',
404-
"SET lock_timeout TO '30s'",
404+
'SET lock_timeout TO 0',
405405
'DROP INDEX CONCURRENTLY "index_users_on_email"',
406-
"SET lock_timeout TO '30s'",
406+
"SET lock_timeout TO '0'",
407407
"SET statement_timeout TO '0'",
408408

409409
'CREATE INDEX CONCURRENTLY "index_users_on_email" ON "users" ("email")',
@@ -428,7 +428,7 @@ def change
428428

429429
# The index is created concurrently.
430430
'SET statement_timeout TO 0',
431-
"SET lock_timeout TO '30s'",
431+
'SET lock_timeout TO 0',
432432
'CREATE INDEX CONCURRENTLY "index_users_on_user_id" ON "users" ("user_id")',
433433
"SET lock_timeout TO '5s'",
434434
"SET statement_timeout TO '70s'",

0 commit comments

Comments
 (0)