don't bother unnecessarily setting max_update_limit

avoids 1 to 3 extra db round trips if we're already doing batches
of 1000

Change-Id: I0b17a1072ad0a54c01ba0b9778f94bf3255ef014
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/338146
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Jacob Burroughs <jburroughs@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
Migration-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2024-01-19 08:40:41 -07:00
parent b6a6938539
commit d5c60665b1
4 changed files with 20 additions and 5 deletions

View File

@ -23,6 +23,14 @@ class QuotedValue < String
end end
module PostgreSQLAdapterExtensions module PostgreSQLAdapterExtensions
# when changing this, you need to re-apply the latest migration creating the guard_excessive_updates function
DEFAULT_MAX_UPDATE_LIMIT = 1000
def initialize(*)
super
@max_update_limit = DEFAULT_MAX_UPDATE_LIMIT
end
def configure_connection def configure_connection
super super
@ -258,6 +266,11 @@ module PostgreSQLAdapterExtensions
end end
def with_max_update_limit(limit) def with_max_update_limit(limit)
return yield if limit == @max_update_limit
old_limit = @max_update_limit
@max_update_limit = limit
if transaction_open? if transaction_open?
execute("SET LOCAL inst.max_update_limit = #{limit}") execute("SET LOCAL inst.max_update_limit = #{limit}")
ret = yield ret = yield
@ -269,6 +282,8 @@ module PostgreSQLAdapterExtensions
end end
end end
ret ret
ensure
@max_update_limit = old_limit if old_limit
end end
def quote(*args) def quote(*args)

View File

@ -55,7 +55,7 @@ class GuardExcessiveUpdates < ActiveRecord::Migration[7.0]
max_record_count integer; max_record_count integer;
BEGIN BEGIN
SELECT count(*) FROM oldtbl INTO record_count; SELECT count(*) FROM oldtbl INTO record_count;
max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '1000'); max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '#{PostgreSQLAdapterExtensions::DEFAULT_MAX_UPDATE_LIMIT}');
IF record_count > max_record_count THEN IF record_count > max_record_count THEN
IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN
RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed. Would update % records but max is %', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME, record_count, max_record_count; RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed. Would update % records but max is %', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME, record_count, max_record_count;

View File

@ -29,7 +29,7 @@ class BetterGuardLogs < ActiveRecord::Migration[7.0]
max_record_count integer; max_record_count integer;
BEGIN BEGIN
SELECT count(*) FROM oldtbl INTO record_count; SELECT count(*) FROM oldtbl INTO record_count;
max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '1000'); max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '#{PostgreSQLAdapterExtensions::DEFAULT_MAX_UPDATE_LIMIT}');
IF record_count > max_record_count THEN IF record_count > max_record_count THEN
IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN
RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME USING DETAIL = 'Would update ' || record_count || ' records but max is ' || max_record_count; RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME USING DETAIL = 'Would update ' || record_count || ' records but max is ' || max_record_count;
@ -52,7 +52,7 @@ class BetterGuardLogs < ActiveRecord::Migration[7.0]
max_record_count integer; max_record_count integer;
BEGIN BEGIN
SELECT count(*) FROM oldtbl INTO record_count; SELECT count(*) FROM oldtbl INTO record_count;
max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '1000'); max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '#{PostgreSQLAdapterExtensions::DEFAULT_MAX_UPDATE_LIMIT}');
IF record_count > max_record_count THEN IF record_count > max_record_count THEN
IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN
RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed. Would update % records but max is %', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME, record_count, max_record_count; RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed. Would update % records but max is %', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME, record_count, max_record_count;

View File

@ -29,7 +29,7 @@ class EvenBetterGuardLogs < ActiveRecord::Migration[7.0]
max_record_count integer; max_record_count integer;
BEGIN BEGIN
SELECT count(*) FROM oldtbl INTO record_count; SELECT count(*) FROM oldtbl INTO record_count;
max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '1000'); max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '#{PostgreSQLAdapterExtensions::DEFAULT_MAX_UPDATE_LIMIT}');
IF record_count > max_record_count THEN IF record_count > max_record_count THEN
IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN
RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME USING DETAIL = 'Would update ' || record_count || ' records but max is ' || max_record_count || ', orig query: ' || current_query(); RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME USING DETAIL = 'Would update ' || record_count || ' records but max is ' || max_record_count || ', orig query: ' || current_query();
@ -52,7 +52,7 @@ class EvenBetterGuardLogs < ActiveRecord::Migration[7.0]
max_record_count integer; max_record_count integer;
BEGIN BEGIN
SELECT count(*) FROM oldtbl INTO record_count; SELECT count(*) FROM oldtbl INTO record_count;
max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '1000'); max_record_count := COALESCE(setting_as_int('inst.max_update_limit.' || TG_TABLE_NAME), setting_as_int('inst.max_update_limit'), '#{PostgreSQLAdapterExtensions::DEFAULT_MAX_UPDATE_LIMIT}');
IF record_count > max_record_count THEN IF record_count > max_record_count THEN
IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN IF current_setting('inst.max_update_fail', true) IS NOT DISTINCT FROM 'true' THEN
RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME USING DETAIL = 'Would update ' || record_count || ' records but max is ' || max_record_count; RAISE EXCEPTION 'guard_excessive_updates: % to %.% failed', TG_OP, TG_TABLE_SCHEMA, TG_TABLE_NAME USING DETAIL = 'Would update ' || record_count || ' records but max is ' || max_record_count;