Skip to content

Commit 858245d

Browse files
authored
Fix the concurrent statement timeout (#3781)
- Fix the 20240314131908_add_user_guid_to_jobs_table migration (don't use 'with_concurrent_timeout' in a block - e.g. alter_table {}). - Also fix migration_concurrent_statement_timeout_spec (be less specific about the original timeout). - Also fix the concurrent_timeout_in_milliseconds calculation.
1 parent ccfe5de commit 858245d

File tree

3 files changed

+17
-18
lines changed

3 files changed

+17
-18
lines changed

db/migrations/20240314131908_add_user_guid_to_jobs_table.rb

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@
44

55
up do
66
if database_type == :postgres
7-
db = self
8-
alter_table :jobs do
9-
add_column :user_guid, String, size: 255, if_not_exists: true
10-
VCAP::Migration.with_concurrent_timeout(db) do
11-
add_index :user_guid, name: :jobs_user_guid_index, if_not_exists: true, concurrently: true
12-
end
7+
add_column :jobs, :user_guid, String, size: 255, if_not_exists: true
8+
VCAP::Migration.with_concurrent_timeout(self) do
9+
add_index :jobs, :user_guid, name: :jobs_user_guid_index, if_not_exists: true, concurrently: true
1310
end
1411

1512
elsif database_type == :mysql
@@ -24,13 +21,10 @@
2421

2522
down do
2623
if database_type == :postgres
27-
db = self
28-
alter_table :jobs do
29-
VCAP::Migration.with_concurrent_timeout(db) do
30-
drop_index :user_guid, name: :jobs_user_guid_index, if_exists: true, concurrently: true
31-
end
32-
drop_column :user_guid, if_exists: true
24+
VCAP::Migration.with_concurrent_timeout(self) do
25+
drop_index :jobs, :user_guid, name: :jobs_user_guid_index, if_exists: true, concurrently: true
3326
end
27+
drop_column :jobs, :user_guid, if_exists: true
3428
end
3529

3630
if database_type == :mysql

lib/cloud_controller/db.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,15 +224,20 @@ def self.uuid_function(migration)
224224
# Concurrent migrations can take a long time to run, so this helper can be used to override 'max_migration_statement_runtime_in_seconds' for a specific migration.
225225
# REF: https://www.postgresql.org/docs/current/sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY
226226
def self.with_concurrent_timeout(db, &block)
227-
concurrent_timeout_seconds = VCAP::CloudController::Config.config&.get(:migration_psql_concurrent_statement_timeout_in_seconds) || PSQL_DEFAULT_STATEMENT_TIMEOUT
228-
229-
if concurrent_timeout_seconds && db.database_type == :postgres
227+
concurrent_timeout_in_seconds = VCAP::CloudController::Config.config&.get(:migration_psql_concurrent_statement_timeout_in_seconds)
228+
concurrent_timeout_in_milliseconds = if concurrent_timeout_in_seconds.nil? || concurrent_timeout_in_seconds <= 0
229+
PSQL_DEFAULT_STATEMENT_TIMEOUT
230+
else
231+
concurrent_timeout_in_seconds * 1000
232+
end
233+
234+
if db.database_type == :postgres
230235
original_timeout = db.fetch("select setting from pg_settings where name = 'statement_timeout'").first[:setting]
231-
db.run("SET statement_timeout TO #{concurrent_timeout_seconds * 1000}")
236+
db.run("SET statement_timeout TO #{concurrent_timeout_in_milliseconds}")
232237
end
233238
block.call
234239
ensure
235-
db.run("SET statement_timeout TO #{original_timeout}") if original_timeout && db.database_type == :postgres
240+
db.run("SET statement_timeout TO #{original_timeout}") if original_timeout
236241
end
237242

238243
def self.logger

spec/migrations/migration_concurrent_statement_timeout_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
skip if db.database_type != :postgres
3434
expect { Sequel::Migrator.run(db, tmp_migrations_dir, allow_missing_migration_files: true) }.not_to raise_error
3535
expect(db).to have_received(:run).exactly(2).times
36+
expect(db).to have_received(:run).with(/SET statement_timeout TO \d+/).twice
3637
expect(db).to have_received(:run).with('SET statement_timeout TO 1899000').once
37-
expect(db).to have_received(:run).with('SET statement_timeout TO 30000').once
3838
end
3939
end

0 commit comments

Comments
 (0)