Implement uncached behavior for multiple databases
What does this MR do and why?
Related to #350191 (closed)
Adds Gitlab::Database.all_uncached
, which works similar to ActiveRecord::Base.uncached
, but for multiple database connections.
The method is only used in one location in the code right now, so it could be fixed at that spot, but it has somewhat surprising behavior due how it interacts with the load balancer. Since ActiveRecord::Base.uncached
only disables the query cache for the current connection, if the load balancer swaps connections underneath, the query cache can be silently reenabled.
To work around that, we set the current session to only use the primary database from the point of calling uncached
, to keep the connection consistent.
How to set up and validate locally
Rails implements SQL caching around controller actions, so we won't be able to test directly in the rails console.
- First setup your data for multiple databases according to nhttps://docs.gitlab.com/ee/development/database/multiple_databases.html#development-setup
- In the
ProjectsController#show
method add the following snippet before therespond_to
block:logger.info "******************* testing cache ***************************" Project.first Project.first Ci::Pipeline.first Ci::Pipeline.first
- Tail the logs with something like
tail -f log/development.log | grep -A 10 'testing cache'
- Go to the show page for a project, and look at the log output. You should see this for the queries, indicating the second run came from the cache:
Project Load (1.0ms) SELECT "projects"."id" ... CACHE Project Load (0.0ms) SELECT "projects"."id" ... Ci::Pipeline Load (4.1ms) SELECT "ci_pipelines".* ... CACHE Ci::Pipeline Load (0.0ms) SELECT "ci_pipelines".*
- Now, wrap the entire snippet we added earlier in a
Gitlab::Database.all_uncached
block:Gitlab::Database.all_uncached do # earlier snippet end
- Reload the page, and look at the log output, which should now show the absence of cached queries:
Project Load (5.2ms) SELECT "projects"."id" ... Project Load (0.7ms) SELECT "projects"."id" ... Ci::Pipeline Load (2.3ms) SELECT "ci_pipelines".* ... Ci::Pipeline Load (0.4ms) SELECT "ci_pipelines".* ...
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.