Figure out how we would actually adjust the PHP code to use different DB groups depending on the situation; how much code would need to be adjusted; etc.
Description
| Status | Subtype | Assigned | Task | ||
|---|---|---|---|---|---|
| Resolved | Addshore | T246415 Investigate a different db load groups for wikidata / wikibase | |||
| Resolved | Lucas_Werkmeister_WMDE | T262924 Investigate how to implement different DB load groups in Wikibase |
Event Timeline
I looked a bit into this so I guess I should claim it.
As far as I can tell, there’s no “silver bullet” that will let us implement this easily. The DB load group is specified when calling getConnection() or getConnectionRef() on an ILoadBalancer, and currently a lot of places in our code directly call those methods, and (as far as I can tell) always with the default group. Some classes extend the DBAccessBase class, which has special support for defaulting to a certain database domain, but not to a certain database group:
protected function getConnection( $id, array $groups = [] ) { return $this->getLoadBalancer()->getConnectionRef( $id, $groups, $this->dbDomain ); }
The LoadBalancer and LBFactory classes have a defaultGroup parameter that can be set at construction time, but there’s no provision for changing this parameter later. I also couldn’t find any way to get an “alternative version” of a load balancer (factory), so the idea of “let’s create a copy of the main load balancer, but with a different defaultGroup parameter, and inject that into various services” also falls flat.
So I suspect the solution to implementing custom DB load groups will be tedious but straightforward: add an optional $databaseGroups = [] parameter to various services that take an ILoadBalancer, similar to how some of them already take a $databaseDomain = false parameter (e. g. DatabaseMatchingTermsLookup). I haven’t found any better way.
The parent ticket T246415 talks about that a split into load groups for clients/repo could be difficult as both are using code in lib/ for some of their requests. Did you encounter places in lib/ that create/get a global ILoadBalancer instance themselves without it being injected? And if so, do you have an intuition for how much effort it would be to refactor them?
As far as I can tell, everything in Lib gets an ILoadBalancer or ILBFactory injected. (In one case it’s an LBFactory without I, fixed in https://gerrit.wikimedia.org/r/c/mediawiki/extensions/Wikibase/+/630563.)
I just discovered some changes by @Addshore: Introduce DomainDB and ReplicationWaiter and follow-ups. It sounds like a default DB load group could also be added to this DomainDB abstraction, if we went ahead with it.
I'm not sure if this can be figured out any more other than starting to do this in some cases and see what it looks like? It seems a general approach other than find all getConnectionRef, getConnection and figure out what group should go in there is not applicable.