-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
[tm_state] updateLocked should re-populate local metadata tables to reflect promotion rule changes #8107
[tm_state] updateLocked should re-populate local metadata tables to reflect promotion rule changes #8107
Conversation
7881b90
to
9953560
Compare
85e47b9
to
217fd18
Compare
@@ -229,12 +229,21 @@ func (ts *tmState) updateLocked(ctx context.Context) { | |||
return | |||
} | |||
|
|||
populateMetadata := func() { |
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.
Populate metadata does some extra work that only makes sense when the tablet is bootstrapping (like creating the metadata table). All the instructions are idempotent, but I think it will be clearer/cleaner to explicitly add a method to only update the metadata
Ugh, I've fixed (mostly, there are some flaky tests) all the unit tests, but this is very much breaking the faketablet/fakesqldb invariants expected by the legacy workflow tests, and I'm not sure how to best tackle that |
At last!! Only the true failures:
Looks like I will need to some additional plumbing of state through to tell whether we're initializing or going through a state transition, which will also help incorporating your suggestion @rafael simpler. |
1824722
to
765346d
Compare
…eflect promotion rule changes Signed-off-by: Andrew Mason <amason@slack-corp.com>
If we're enabling the queryservice, wait until afterwards to populate the metadata. On the other hand, if we're disabling the queryservice, then populate the metadata just before shutting down the queryservice. Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
…ate_metadata` flag Signed-off-by: Andrew Mason <amason@slack-corp.com>
Signed-off-by: Andrew Mason <amason@slack-corp.com>
…ator func Also, track if we've previously called PopulateMetadataTables, and if so, only do the Upsert rather than Create+Upsert Signed-off-by: Andrew Mason <amason@slack-corp.com>
765346d
to
cf15b31
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.
@ajm188 nice work and thank you for the contribution! Code looks good, I do wish to reduce some confusion about function names and visibility of functions, please see inline comments.
// _vt.shard_metadata is a replicated table with per-shard information, but it's | ||
// created here to make it easier to create it on databases that were running | ||
// old version of Vitess, or databases that are getting converted to run under | ||
// Vitess. | ||
func PopulateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string, dbName string) error { | ||
log.Infof("Populating _vt.local_metadata table...") | ||
func CreateMetadataTables(mysqld MysqlDaemon, dbName string) error { |
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.
It seems like this function is only called locally, rename it to createMetadataTables()
?
return createMetadataTables(conn, dbName) | ||
} | ||
|
||
func createMetadataTables(conn *dbconnpool.DBConnection, dbName string) error { |
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.
... following up on my previous comment, we now have one method CreateMetadataTables
, one function CreateMetadataTables
, one function createMetadataTables
. Let's try and make these less ambiguous by renaming the latter two?
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.
Yeah, how about this:
MetadataManager
has public methods:{Create,Populate}MetadataTables
andUpsertMetadataTables
- The main reason I did this "public function and also public method on struct" thing was to reduce the number of changes I needed to do (because otherwise I would have to update everyone that called
mysqlctl.PopulateMetadataTables
.... which now that i look is just two places inmysqlctl/backup.go
so maybe I should just change them 🤔 ) - The other reason for the public/private with the same name was to allow code reuse without having to get new dba connections for each stage, so in
Populate
, we first get a connection, and then call privatecreate
and privateupsert
, whereas if we called publicCreate
and publicUpsert
then we would get a new connection for each of those.
Then, we do:
type MetadataManager struct {}
func (m *MetadataManager) PopulateMetadataTables(mysqld MysqldDaemon, dbName string) error {
log.Infof("....")
conn, err := mysqld.GetDbaConnection(...)
if err != nil {
return err
}
defer conn.Close()
return m.populateMetadataTablesWithConn(conn, dbName)
}
func PopulateMetadataTables(mysqld MysqldDaemon, localMetadata map[string]string, dbName string) error {
m := &MetadataManager{}
return m.PopulateMetadataTables(mysqld, localMetadata, dbName)
}
and then the private function does all the logic, and has a slightly cleaner naming (due to the "WithConn" suffix, or at least that's my goal!). And if we want, I can update those last few callsites and remove the package-level public function as well.
What do you think?
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.
Sounds good. We can do so iteratively in followup PRs.
// Callers are responsible for ensuring the _vt.local_metadata table exists | ||
// before calling this function, usually by calling CreateMetadataTables at | ||
// least once prior. | ||
func UpsertLocalMetadata(mysqld MysqlDaemon, localMetadata map[string]string, dbName string) error { |
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.
this function is only called locally, reduce its visibility by lowercasing it?
return upsertLocalMetadata(conn, localMetadata, dbName) | ||
} | ||
|
||
func upsertLocalMetadata(conn *dbconnpool.DBConnection, localMetadata map[string]string, dbName string) error { |
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.
similarly, we have three different functions now called upsertLocalMetadata
with different capitalization. Let's change names to avoid confusion.
Signed-off-by: Andrew Mason amason@slack-corp.com
Description
TODO.
This means we call
PopulateMetadataTables
on:(*tmState).ChangeTabletType
(*tmState).RefreshFromTopoInfo
(*tmState).RefreshFromTopo
(viaRefreshFromTopoInfo
)(*tmState).Open
See it in action
Related Issue(s)
Checklist
Deployment Notes