restore: Run PITR through mysqlctl#13123
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
|
a51a422 to
2f03810
Compare
When we run a retore remotely on the vttablet, we need to run the partial restore logic through mysqlctl to ensure we run it with the correct MySQL binaries. It adds additional safety checks for using `Mysqld` because it's reused between both the local MySQL interaction and `mysqlctl` but also as a remote interface used from `vttablet`. This safety check means that we should never run certain things when running remotely inside `vttablet`, which is identified by the `socketFile` being set or not. When it is set, we now panic on certain actions we know are not going to work. By adding this panic we can ensure we catch uses like the restore usage earlier since it would break if we do anything unsupported. Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
2f03810 to
8061c55
Compare
| func (c *capabilitySet) hasDisableRedoLog() bool { | ||
| return c.isMySQLLike() && c.version.atLeast(ServerVersion{Major: 8, Minor: 0, Patch: 21}) | ||
| } | ||
|
|
There was a problem hiding this comment.
I have removed this function since nothing is using atm. I'd like to reduce anything that checks capabilities to as little as possible, since this PR also further restricts that these capabilities can only be used properly inside mysqlctl and with less surface, we have less potential issues where it can be used wrong.
| if socketFile != "" { | ||
| log.Info("mysqld is remote. Skipping flavor detection") | ||
| return result | ||
| } |
There was a problem hiding this comment.
This ensures we don't set up capabilities when we can't correctly detect them.
| defer client.Close() | ||
| return client.RunMysqlUpgrade(context.TODO()) | ||
| return client.RunMysqlUpgrade(ctx) | ||
| } |
There was a problem hiding this comment.
Seems simplest to pass in the context we already have in all the callers further up in the call chain.
| // binaryPath does a limited path lookup for a command, | ||
| // searching only within sbin and bin in the given root. | ||
| func binaryPath(root, binary string) (string, error) { | ||
| noSocketFile() |
There was a problem hiding this comment.
Anywhere we're going to check if a certain binary is available, implies we need to be running inside mysqlctl. This ensures we error out hard when we try to end up calling this somewhere else.
Everything is correct here today, this is a safety mechanism so that we don't accidentally add broken usage in the future.
| res := qr.Named().Row() | ||
| version, _ := res.ToString("@@global.version") | ||
| return version | ||
| } |
There was a problem hiding this comment.
Similar to GetVersionComment, we get the version number here at runtime from the actual running MySQL instance. This ensures we get the right version and not the local binary.
| } | ||
| defer client.Close() | ||
| return client.ApplyBinlogFile(ctx, binlogFile, mysql.EncodePosition(restorePos)) | ||
| } |
There was a problem hiding this comment.
This is now part of the interface and also has a remote version so we can run this correctly for restores through mysqlctl.
| // ApplyBinlogFile extracts a binary log file and applies it to MySQL. It is the equivalent of: | ||
| // $ mysqlbinlog --include-gtids binlog.file | mysql | ||
| func (mysqld *Mysqld) applyBinlogFile(binlogFile string, includeGTIDs mysql.GTIDSet) error { | ||
| func (mysqld *Mysqld) ApplyBinlogFile(ctx context.Context, binlogFile string, restorePos mysql.Position) error { |
There was a problem hiding this comment.
Changing this to mysql.Position makes it easier to serialize / deserialize and better matches how we use a GTID position in other places here.
| BinlogRestorePosition: binlogRestorePosition, | ||
| } | ||
| return c.withRetry(ctx, func() error { | ||
| _, err := c.c.ApplyBinlogFile(ctx, req) |
There was a problem hiding this comment.
Not a fan of c.c. but unrelated to this PR
There was a problem hiding this comment.
Copied this basically from the other things we have to be consistent.
| log.Errorf("Unexpected number of rows: %v", qr.Rows) | ||
| return "" | ||
| } | ||
| res := qr.Named().Row() |
There was a problem hiding this comment.
BTW the function Row() returns nil if the number of rows != 1. So if you wanted, you could rewrite the integrity check above from if len(qr.Rows) != 1 { to (down in this line) if res == nil. Whichever you feel more comfortable with, seeing that the former is more explicit and the latter is implied.
There was a problem hiding this comment.
Same here, this is basically a copy paste of how the comment version works and mostly the same to stay consistent with that.
After the changes in vitessio#13123, I realized that there's no cases left where we actually use or depend on `MYSQL_FLAVOR`. This means we can actually remove usages of `MYSQL_FLAVOR`. It doesn't yet remove it from the artifacts we build, because we shouldn't clean that up until v18 then because users might mix versions during the upgrade and we don't want to have old code that still depends on this fail then. Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
* mysqlctl: Remove usage of MYSQL_FLAVOR After the changes in #13123, I realized that there's no cases left where we actually use or depend on `MYSQL_FLAVOR`. This means we can actually remove usages of `MYSQL_FLAVOR`. It doesn't yet remove it from the artifacts we build, because we shouldn't clean that up until v18 then because users might mix versions during the upgrade and we don't want to have old code that still depends on this fail then. Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com> * Add release note item for removed `MYSQL_FLAVOR`. Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com> --------- Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
When we run a restore remotely on the vttablet, we need to run the PITR logic through mysqlctl to ensure we run it with the correct MySQL binaries.
It adds additional safety checks for using the
Mysqldtype because it's reused between both the local MySQL interaction andmysqlctlbut also as a remote interface used fromvttablet.This safety check means that we should never run certain things when running remotely inside
vttablet, which is identified by thesocketFilebeing set or not. When it is set, we now panic on certain actions we know are not going to work.By adding this panic we can ensure we catch uses like the restore usage earlier since it would break if we do anything unsupported.
Related Issue(s)
Fixes #13124
Checklist