[vtctldserver] OnlineDDL protobuf message introduction#12195
[vtctldserver] OnlineDDL protobuf message introduction#12195ajm188 wants to merge 25 commits intovitessio:mainfrom
Conversation
Review ChecklistHello reviewers! 👋 Please follow this checklist when reviewing this Pull Request. General
If a new flag is being introduced:
If a workflow is added or modified:
Bug fixes
Non-trivial changes
New/Existing features
Backward compatibility
|
d90ffd8 to
c05f69f
Compare
|
This PR is being marked as stale because it has been open for 30 days with no activity. To rectify, you may do any of the following:
If no action is taken within 7 days, this PR will be closed. |
|
This PR is being marked as stale because it has been open for 30 days with no activity. To rectify, you may do any of the following:
If no action is taken within 7 days, this PR will be closed. |
|
This PR is being marked as stale because it has been open for 30 days with no activity. To rectify, you may do any of the following:
If no action is taken within 7 days, this PR will be closed. |
|
This PR was closed because it has been stale for 7 days with no activity. |
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
…rds compat Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
65e028c to
3dbbd40
Compare
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
Signed-off-by: Andrew Mason <andrew@planetscale.com>
shlomi-noach
left a comment
There was a problem hiding this comment.
@ajm188 wow, what a massive effort! 🙇 I've left several comments throughout the PR. But, I would also like to carefully question a basic premise here. I'm not in on the many intricates of vtctld and you would know better than me; also, you seem to already have a plan for OnlineDDL commands which we haven't discussed, so I definitely might just miss something.
This change is so massive first and foremost due to moving OnlineDDL to proto. The question being: why do we need OnlineDDL to be in proto? While I don't have a clear grasp of how I'd like to see vtctldclient OnlineDDL commands implemented, I am not sure I see the need for OnlineDDL to pass as a message, in either direction. All I think is needed are a command ("cancel", "complete", "show") and a UUID/"all", for most cases. I don't see that the state of an OnlineDDL struct should pass back or forth?
Basically, the entire existence of the OnlineDDL command was made as a convenience. Most of the commands can be applied via ApplySchema anyway. So it's mostly syntactic sugar. It was created at a time where we envisioned VExec to be a new mechanism with which to control all-things-internal, but we've moved away from that idea. But the command vtctl OnlineDDL caught on, being useful, and so we want to keep supporting it -- however I'd hate for this otherwise syntactic-sugar command to cause such a disruption in the code/design. In my comments below I raise a few concerns over some of the changes.
I'm happy to discuss further. This is such a tremendous work 👏 and again I might miss something very important, but I also want to be cautious and make sure we don't make changes that aren't strictly necessary 🙏
There was a problem hiding this comment.
Can you please explain what the functions in this file do? I'm a bit lost.
| ApplySchema.Flags().MarkDeprecated("--allow-long-unavailability", "") | ||
| ApplySchema.Flags().MarkDeprecated("--skip-preflight", "Deprecated. Assumed to be always 'true'") | ||
| ApplySchema.Flags().StringVar(&applySchemaOptions.DDLStrategy, "ddl-strategy", string(schema.DDLStrategyDirect), "Online DDL strategy, compatible with @@ddl_strategy session variable (examples: 'gh-ost', 'pt-osc', 'gh-ost --max-load=Threads_running=100'.") | ||
| ApplySchema.Flags().StringVar(&applySchemaOptions.DDLStrategy, "ddl-strategy", strings.ToLower(tabletmanagerdatapb.OnlineDDL_Strategy_name[int32(tabletmanagerdatapb.OnlineDDL_DIRECT)]), "Online DDL strategy, compatible with @@ddl_strategy session variable (examples: 'gh-ost', 'pt-osc', 'gh-ost --max-load=Threads_running=100'.") |
There was a problem hiding this comment.
Can we have a helper function to simplify strings.ToLower(tabletmanagerdatapb.OnlineDDL_Strategy_name[int32(...)])? This kind of logic recurs a few times in the code and I find it difficult to parse.
| testWithInitialSchema(t) | ||
| t.Run("create non_online", func(t *testing.T) { | ||
| _ = testOnlineDDLStatement(t, alterTableNormalStatement, string(schema.DDLStrategyDirect), "vtctl", "non_online", "") | ||
| _ = testOnlineDDLStatement(t, alterTableNormalStatement, "direct", "vtctl", "non_online", "") |
There was a problem hiding this comment.
Can we have a helper function that translates OnlineDDL_DIRECT to the string "direct"?
There was a problem hiding this comment.
Presumably based on tabletmanagerdatapb.OnlineDDL_Strategy_name[int32(strategy)]?
| return tabletmanagerdatapb.OnlineDDL_DIRECT, nil | ||
| } | ||
|
|
||
| lowerName := strings.ToUpper(name) |
There was a problem hiding this comment.
lowerName := strings.ToUpper(...) is contradictory is confusing. Let's do use ToLower() and look for texts like "gh-ost" instread of "GH-OST"
| lowerName := strings.ToUpper(name) | |
| lowerName := strings.ToLower(name) |
There was a problem hiding this comment.
ah it should actually be upperName because we need the ALL_CAPS to index into the enum table
| var assertion func(t assert.TestingT, value bool, msgAndArgs ...any) bool | ||
| switch direct { | ||
| case true: | ||
| assertion = assert.True | ||
| case false: | ||
| assertion = assert.False | ||
| } | ||
|
|
||
| assertion(t, NewDDLStrategySetting(strategy, "").IsDirect()) |
There was a problem hiding this comment.
I think this reads simpler:
| var assertion func(t assert.TestingT, value bool, msgAndArgs ...any) bool | |
| switch direct { | |
| case true: | |
| assertion = assert.True | |
| case false: | |
| assertion = assert.False | |
| } | |
| assertion(t, NewDDLStrategySetting(strategy, "").IsDirect()) | |
| assert.Equal(t, direct, NewDDLStrategySetting(strategy, "").IsDirect()) |
| // should use the IsReadyToComplete and MarkReadyToComplete methods to | ||
| // safely modify the value of that field rather than accessing it through | ||
| // the embedded protobuf message directly. | ||
| m sync.Mutex |
There was a problem hiding this comment.
I'm wary of adding a mutex member of OnlineDDL. Throughout the existing code we pass OnlineDDL by reference and by value, and this does not play well with mutex members as their behavior can be inconsistent. OnlineDDL was designed to be a data-only object. I'd say we can perhaps enforce users to use sync/atomic Bool or similar?
| onlineDDL := &OnlineDDL{} | ||
| err := json.Unmarshal(bytes, onlineDDL) | ||
| return onlineDDL, err | ||
| func FromJSON(data []byte) (*OnlineDDL, error) { |
There was a problem hiding this comment.
Will it not be safer to create a temporary struct in the likeness of the old OnlineDDL struct, read the JSON into that struct, then copy over the results to the "new" OnlineDDL fields?
| onlineDDL.m.Lock() | ||
| defer onlineDDL.m.Unlock() | ||
|
|
||
| return onlineDDL.ReadyToComplete, onlineDDL.OnlineDDL.WasReadyToComplete |
There was a problem hiding this comment.
Can we use sync/atomic here instead of using a Mutex?
| // safely modify the value of that field rather than accessing it through | ||
| // the embedded protobuf message directly. | ||
| m sync.Mutex | ||
| *tabletmanagerdatapb.OnlineDDL |
There was a problem hiding this comment.
Should we use tabletmanagerdatapb.OnlineDDL by value and not by pointer? This will be more inline with the current usage. Again, I'm concerned about copying OnlineDDL values: with *tabletmanagerdatapb.OnlineDDL we risk two instances of OnlineDDL sharing data. Maybe there's nothing in the code to worry about, and if all the tests pass then I guess everything's fine. But the original design was to share nothing, and I'm concerned we might miss a leak.
shlomi-noach
left a comment
There was a problem hiding this comment.
@ajm188 wow, what a massive effort! 🙇 I've left several comments throughout the PR. But, I would also like to carefully question a basic premise here. I'm not in on the many intricates of vtctld and you would know better than me; also, you seem to already have a plan for OnlineDDL commands which we haven't discussed, so I definitely might just miss something.
This change is so massive first and foremost due to moving OnlineDDL to proto. The question being: why do we need OnlineDDL to be in proto? While I don't have a clear grasp of how I'd like to see vtctldclient OnlineDDL commands implemented, I am not sure I see the need for OnlineDDL to pass as a message, in either direction. All I think is needed are a command ("cancel", "complete", "show") and a UUID/"all", for most cases. I don't see that the state of an OnlineDDL struct should pass back or forth?
Basically, the entire existence of the OnlineDDL command was made as a convenience. Most of the commands can be applied via ApplySchema anyway. So it's mostly syntactic sugar. It was created at a time where we envisioned VExec to be a new mechanism with which to control all-things-internal, but we've moved away from that idea. But the command vtctl OnlineDDL caught on, being useful, and so we want to keep supporting it -- however I'd hate for this otherwise syntactic-sugar command to cause such a disruption in the code/design. In my comments below I raise a few concerns over some of the changes.
I'm happy to discuss further. This is such a tremendous work 👏 and again I might miss something very important, but I also want to be cautious and make sure we don't make changes that aren't strictly necessary 🙏
|
(No idea why the review comment submitted twice). Just a bit more context: the I think the closes to exposing |
|
@shlomi-noach yep, you are exactly correct (regarding "wait, hang on, do we need this?") and i came to the same realization yesterday when I started on Wish I had gone with the whole-hog approach rather than this way as I would have realized that sooner, but c'est la vie! I've got the protobuf working in another branch which I'll open shortly, I have some open questions about exactly how much we want to be showing |
|
we don't need this, instead see #13738 |
Description
Introducing a formal protobuf type for
OnlineDDLtypes to use across the existing onlineddl code,vtctldserver(and client), and eventually vtadmin.This is a prerequisite to moving any of the command functionality, as it will help us ensure we're maintaining compatibility if both the new and old code is using the same underlying types.
In order to do this I needed to slightly change some of the field names, which I've (attempted) to do in a backwards-compatible way, issuing deprecation warnings anywhere we parse in an "old" way.
Related Issue(s)
Closes #13713
Checklist
Deployment Notes