Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Postgres reconnection on failover for RDS

I have a Rails application with a Postgres database under AWS RDS with multi-az architecture. The HA architecture used by RDS is master/slave and they provide the service with a single endpoint that points to the current master.

Whenever there's a database failover, Active Record will continue to try to connect to the same server, instead of retrying the connection in order to pick up the new IP for the master.

Is there a way to create a "global" rescue for the ActiveRecord::StatementInvalid: PG::ConnectionBad: PQsocket() can't get socket descriptor error that simply runs ActiveRecord::Base.connection_pool.disconnect! that will make the next query to work?

like image 683
hernandes Avatar asked Apr 12 '16 19:04

hernandes


1 Answers

I was able to make Active Record reconnect after the failover event by applying a monkey patch to postgres_adapter.

lib/core_ext/active_record/postgresql_adapter.rb:

require 'active_record/connection_adapters/postgresql_adapter'

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
  private
  def exec_no_cache(sql, name, binds)
    log(sql, name, binds) { @connection.async_exec(sql, []) }
  rescue ActiveRecord::StatementInvalid => e
    if e.to_s.include?('PG::ConnectionBad')
      ActiveRecord::Base.connection_pool.disconnect!
    end
    raise e
  end
end
like image 127
hernandes Avatar answered Oct 20 '22 10:10

hernandes