You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Patch ActiveRecord::Base.clear_query_caches_for_current_thread to restore underlying database
Otherwise it's possible for a Mysql2Adapter instance's database to be changed out from under it during an operation (e.g. insert, update, delete, truncate, etc).
CONTEXT OF THE ISSUE
This issue presented itself with a combination of using active_record_shards and active_record_host_pool. It was representing the sharded and unsharded database connections within the same connection pool. This problem did not manifest itself until Rails 6 when cache clearing for cache dirtying operations—e.g. insert, update, truncate, delete, etc—was updated to loop over the app's connection handlers, connection pools to search for currently active connections.
This happens mid-operation (inside of ActiveRecord::ConnectionAdapters::Mysql2Adapter instance) just before the operation is carried out. The result was that referencing the connection was changing the currently selected database and it was not being restored. This led to issues where the operation would try to be carried out on a different database that did not have the same tables/columns.
It is important to note that this issue existed in active_record_host_pool for years, but no code paths exercised it. The assumption that connections would not be re-referenced from within an operation on a connection was safe for years until ActiveRecord 6.
WHY THIS FIX
The active_record_host_pool library is optimized to reduce the number of database connections by pooling them by host/port/socket/user/slave. This means that different databases on the same host will use the same connection pool. This requires that this library provide a mechanism for selecting the correct database when executing queries.
This fix maintains that optimization and fixes the currently known problematic code path introduced in ActiveRecord 6.
BENEFITS OF THIS CHANGE
Preserves host pool optimization.
CONSEQUENCES OF THIS CHANGE
This does not fix the issue, it just fixes the one spot where we know ActiveRecord 6.0 can expose it.
REFERENCES
The problematic line that causes the database to switch is: https://github.com/zendesk/active_record_host_pool/blob/981fdeb8dfa52f390bd91471adc19049283c6fb8/lib/active_record_host_pool/connection_proxy.rb#L16
The change in Rails 6 that exercised a code path to expose this surface the issue: https://github.com/rails/rails/pull/35089/files#diff-193e6e4a86bf5d360a5001bce59334cbR180-R186
For an alternate solution see: #60
0 commit comments