DEV: Remove cache PG connection type map freedom patch (#26153)
Why this change? Previously, we identified that ActiveRecord's PostgreSQL adapter executes 3 db queries each time a new connection is created. The 3 db queries was identified when we looked at the `pg_stats_statement` table on one of our multisite production cluster. At that time, the hypothesis is that because we were agressively reaping and creating connections, the db queries executed each time a connection is created is wasting resources on our database servers. However, we didn't see any the needle move much on our servers after deploying the patch so we have decided to drop this patch as it makes it harder for us to upgrade ActiveRecord in the future.
This commit is contained in:
parent
e7f539df10
commit
1f71db426e
|
@ -1,50 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This patch has been added to address the problems identified in https://github.com/rails/rails/issues/35311. For every,
|
||||
# new connection created using the PostgreSQL adapter, 3 queries are executed to fetch the type map adding about 1ms overhead
|
||||
# to every connection creation. In multisite clusters where connections are reaped more aggressively, the 3 queries executed
|
||||
# accounts for a significant portion of CPU usage on the PostgreSQL cluster. This patch works around the problem by
|
||||
# caching the type map in a class level attribute to reuse across connections.
|
||||
#
|
||||
# The latest attempt to fix the problem in Rails is in https://github.com/rails/rails/pull/46409 but it has gone stale.
|
||||
module FreedomPatches
|
||||
module PostgreSQLAdapter
|
||||
# Definition as of writing: https://github.com/rails/rails/blob/5bf5344521a6f305ca17e0004273322a0a26f50a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L316
|
||||
def reload_type_map
|
||||
self.class.type_map = nil
|
||||
super
|
||||
end
|
||||
|
||||
# Definition as of writing: https://github.com/rails/rails/blob/5bf5344521a6f305ca17e0004273322a0a26f50a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L614
|
||||
def initialize_type_map(m = type_map)
|
||||
if !self.class.type_map.nil?
|
||||
@type_map = self.class.type_map
|
||||
else
|
||||
super.tap { self.class.type_map = @type_map }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module PostgreSQLAdapterClassMethods
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
@type_map_mutex = Mutex.new
|
||||
@type_map = nil
|
||||
|
||||
def self.type_map
|
||||
@type_map_mutex.synchronize { @type_map }
|
||||
end
|
||||
|
||||
def self.type_map=(type_map)
|
||||
@type_map_mutex.synchronize { @type_map = type_map }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(FreedomPatches::PostgreSQLAdapter)
|
||||
|
||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(
|
||||
FreedomPatches::PostgreSQLAdapterClassMethods,
|
||||
)
|
||||
end
|
|
@ -1,24 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "Caching PostgreSQL connection type map" do
|
||||
it "caches the type map and avoid querying the database for type map information on every new connection" do
|
||||
expect(ActiveRecord::Base.connection.class.type_map).to be_present
|
||||
|
||||
pg_type_queries = []
|
||||
|
||||
subscriber =
|
||||
ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
|
||||
if payload[:name] == "SCHEMA"
|
||||
sql = payload[:sql]
|
||||
pg_type_queries.push(sql) if sql.include?("pg_type")
|
||||
end
|
||||
end
|
||||
|
||||
expect do
|
||||
ActiveRecord::Base.clear_active_connections!
|
||||
ActiveRecord::Base.establish_connection
|
||||
end.to change { pg_type_queries.length }.by(1) # There is some default pg_type query but if stuff was not cached, we would see 4 queries here
|
||||
ensure
|
||||
ActiveSupport::Notifications.unsubscribe(subscriber)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue