Рельсы не могут подключиться к базе данных postgres

У меня есть приложение rails (4.1.5), поддерживаемое базой данных postgres (9.2.13), использующей гем pg (0.17.1), сервер единорога (1.1.0) с двумя рабочими процессами.

Приложение rails запускает задания с использованием sidekiq (2.17.7)

В какой-то момент postgres db перешел в режим восстановления. Следующая ошибка была выдана несколькими заданиями:

PG::ConnectionBad:FATAL:  the database system is in recovery mode
FATAL:  the database system is in recovery mode

База данных восстановилась, но задания продолжали выдавать следующие две ошибки:

PG::Error:invalid encoding name: utf8
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/postgresql_adapter.rb:908:in `set_client_encoding'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/postgresql_adapter.rb:908:in `configure_connection'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/postgresql_adapter.rb:603:in `reconnect!'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract_adapter.rb:313:in `verify!'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:453:in `block in checkout_and_verify'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activesupport-4.1.5/lib/active_support/callbacks.rb:82:in `run_callbacks'

а также

ActiveRecord::ConnectionTimeoutError:could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:190:in `block in wait_poll'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:181:in `loop'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:181:in `wait_poll'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:136:in `block in poll'
/home/ruby/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:146:in `synchronize'
/home/ruby/data42/shared/bundle/ruby/2.2.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:134:in `poll'

Мне кажется, что rails замечает, что соединение не активно, и пытается сбросить соединение. В postgresql_adapter.rb активной записи вызывается следующий метод:

  # Close then reopen the connection.
  def reconnect!
    super
    @connection.reset
    configure_connection
  end

Я предполагаю, что connection.reset на самом деле не работает, поэтому, когда гем pg идет для установки кодировки (первая часть метода configure_connection), он маскирует тот факт, что соединения нет, выдавая ошибку, специфичную для кодировки.

Ниже приведен метод из pg gem (.17.1) ext/pg_connection.c/2804

/*
* call-seq:


*    conn.set_client_encoding( encoding )
 *
 * Sets the client encoding to the _encoding_ String.
 */
static VALUE
pgconn_set_client_encoding(VALUE self, VALUE str)
{
    PGconn *conn = pg_get_pgconn( self );

    Check_Type(str, T_STRING);

    if ( (PQsetClientEncoding(conn, StringValuePtr(str))) == -1 ) {
        rb_raise(rb_ePGerror, "invalid encoding name: %s",StringValuePtr(str));
    }

    return Qnil;
}

Так что, если эти предположения верны, почему не работает сброс соединения?
Перезапуск приложения восстанавливает правильное соединение с базой данных, но я надеюсь, что эта проблема будет решена не вручную.

0 ответов

Другие вопросы по тегам