Увеличьте время ожидания оператора для миграции рельсов - PullRequest
1 голос
/ 25 февраля 2020

Для моего приложения в приложении rails время ожидания оператора postgres установлено на 5 секунд. Этот тайм-аут хорошо работает для нас, помогает нам обнаруживать ошибки в работе, убивать ошибочные запросы и т. Д. c. Однако, когда мы внедряем изменение, нам иногда хочется запустить миграцию данных, которая занимает более 5 секунд и часто приводит к жестокой PG::QueryCanceled: ERROR: canceling statement due to statement timeout. Следовательно, мы ищем способ увеличить время ожидания заявления до ~ 10 минут для наших миграций. Каков наилучший способ сделать это?

Вот варианты, которые мы рассмотрели, и почему мы не довольны ни одним из них.

1) Увеличьте время ожидания утверждения в каждой отдельной миграции Вы думаете, может быть проблематично c. -> Часто разработчики забывают или имеют плохие оценки того, сколько времени это займет. Если они ошибаются, мы заканчиваем неудачным развертыванием, вишневым выбором, и т. Д. c.

2) Используйте Task.enhance для db:migrate (или другие методы), чтобы увеличить время ожидания оператора перед каждой задачей. -> Можно просто увеличить время ожидания оператора с помощью ActiveRecord::Base.connection.execute 'SET statement_timeout = 600000', но это будет применяться только к существующему соединению. Оказывается, когда вы запускаете rake db:migrate, ActiveRecord фактически открывает новое соединение с БД, которое возвращается к существующему по умолчанию.

3) Обезьяна исправляет фактический метод переноса, чтобы установить время ожидания оператора ПОСЛЕ соединения создано. -> Посмотрите код ниже, это не красиво и возиться с внутренними функциями ActiveRecord может иметь последствия, о которых мы не знаем.

* Примечание: Если вы используете гем

перенос данных , вам также необходимо указать следующее.
# Override when we are running with the data migrate gem (which we do in prod)
# https://github.com/ilyakatz/data-migrate/blob/4db2dba7d53e73cac06aa9bfab136c10aa38367b/tasks/databases.rake#L9
module OverrideDataMigrateMigration
  def self.included base
    orig_method = base.method(:run)
    base.define_singleton_method :run do |*args|
      puts '-- SET statement_timeout = 600000'
      ActiveRecord::Base.connection.execute 'SET statement_timeout = 600000' # 10 minutes should suffice, right?    
      orig_method.call *args
    end
  end
end
DataMigrate::DataMigrator.send(:include, OverrideDataMigrateMigration)
DataMigrate::SchemaMigration.send(:include, OverrideDataMigrateMigration)
...