-
Notifications
You must be signed in to change notification settings - Fork 821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NEW Allow database read-only replicas #11379
base: 6
Are you sure you want to change the base?
Conversation
4554d2e
to
a734683
Compare
4015f1a
to
4e739a4
Compare
src/Control/Director.php
Outdated
* List of rules that must only use the primary database and not a replica | ||
*/ | ||
private static array $must_use_primary_db_rules = [ | ||
'Security' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm enforcing must_use_primary on anything "Security" related - i.e. any url that matches /Security, any DataObject under the Security namespace, to prevent any weird issues that could happen when a replica is out of sync with the primary
For instance a password is changed, the user logs out, but cannot log back in because the replica isn't synced up yet.
Having replicas be slightly out of sync is one of the trade-offs for using replicas, though for anything security related it introduces risk so it's disallowed
bc7692c
to
2d388e9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't tested locally yet but here's some requested changes based on reviewing the code
cli-script.php
Outdated
// CLI scripts must only use the primary database connection and not replicas | ||
DB::setMustUsePrimary(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to make sure this gets carried over to the new sake somehow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on which PR gets merged first, I'd expect it to create merge conflict in the 2nd PR as the cli-script.php was deleted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fingers crossed whoever deals with the conflict things to check what changed and doesn't just go "it was deleted so we don't need it 😅
e57f963
to
2d41361
Compare
*/ | ||
public static function getMustUsePrimary(): bool | ||
{ | ||
return DB::$mustUsePrimary; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return DB::$mustUsePrimary; | |
return DB::$mustUsePrimary || DB::$withPrimaryCount > 0; |
In both of these scenarios, the primary must be used. It doesn't matter why the primary must be used, just that it must.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this since it's named as a getting.
What I'll do instead is create a new method to 'willUsePrimary()' and add in the check for replica config, i.e. I'll extract the logic from the top of DB::getDefaultConnectionName()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh okay. My intention was always for this to be the "tell me if I am using the primary" method, not the "Get that property's value" method.
Probably not worth having a getter just for this property on its own, that'll just be confusing I think especially when there's also a willUsePrimary
.
IMO remove this getter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
* | ||
* Prior to CMS 5.4 when replica connections were introduced, the 'default' connection | ||
* was not dynamic and instead represented what the 'primary' connection is now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* | |
* Prior to CMS 5.4 when replica connections were introduced, the 'default' connection | |
* was not dynamic and instead represented what the 'primary' connection is now |
We don't tend to keep historical information in PHPDocs - that's probably something for the changelog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to keep this one inline because 'default' is a poor way to describe 'either primary or replica if configured' i.e. it doesn't do what it sounds like it should do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have reworded a little now that I've changed the const to DB::CONN_DYNAMIC
src/ORM/DB.php
Outdated
return DB::get_conn()->query($sql, $errorLevel); | ||
$name = DB::getDefaultConnectionName($sql); | ||
return DB::get_conn($name)->query($sql, $errorLevel); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it would go to this
public static function query($sql, $errorLevel = E_USER_ERROR)
{
// ...
updateConnectionIfNeeded($sql);
$name = DB::getDefaultConnectionName();
return DB::get_conn($name)->query($sql, $errorLevel);
I guess part of the problem is just naming because for backwards compatibility we have to use 'default' instead of 'dynamic'
We could move this to CMS 6 and rename it if you like. Or deprecate "default" now, and have the const set to "dynamic" - and if "default" is passed in, throw a deprecation warning and set it to "dynamic".
That would probably resolve this problem for me, since a "dynamic connection" could dynamically change based on sql whereas a "default connection" feels like it should have been determined already.
75f7c5c
to
d66c230
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- NEW Allow database read-only replicas #11379 (comment) still hasn't been addressed
- New comment in NEW Allow database read-only replicas #11379 (comment) (sorry, forgot to start review)
*/ | ||
public static function getMustUsePrimary(): bool | ||
{ | ||
return DB::$mustUsePrimary; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh okay. My intention was always for this to be the "tell me if I am using the primary" method, not the "Get that property's value" method.
Probably not worth having a getter just for this property on its own, that'll just be confusing I think especially when there's also a willUsePrimary
.
IMO remove this getter
d66c230
to
af8c2ac
Compare
Issue #11352