Skip to content
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

adding new mysql shell backup engine #16295

Merged
merged 44 commits into from
Sep 24, 2024
Merged

Conversation

rvrangel
Copy link
Contributor

@rvrangel rvrangel commented Jun 28, 2024

Description

This is a PR that implements a new backup engine for use with MySQL Shell, which is mentioned in the feature request here: #16294

It works a bit differently than the existing engines in vitess in which it only stores the metadata of how the backup was created (location + parameters used) and during the restore uses the location plus other parameters (mysql shell are different if you are doing a dump vs a restore, so we can't use exactly the same ones)

Related Issue(s)

Fixes #16294

Checklist

  • "Backport to:" labels have been added if this change should be back-ported to release branches
  • If this change is to be back-ported to previous releases, a justification is included in the PR description
  • Tests were added or are not required
  • Did the new or modified tests pass consistently locally and on CI?
  • Documentation was added or is not required

Deployment Notes

Copy link
Contributor

vitess-bot bot commented Jun 28, 2024

Review Checklist

Hello reviewers! 👋 Please follow this checklist when reviewing this Pull Request.

General

  • Ensure that the Pull Request has a descriptive title.
  • Ensure there is a link to an issue (except for internal cleanup and flaky test fixes), new features should have an RFC that documents use cases and test cases.

Tests

  • Bug fixes should have at least one unit or end-to-end test, enhancement and new features should have a sufficient number of tests.

Documentation

  • Apply the release notes (needs details) label if users need to know about this change.
  • New features should be documented.
  • There should be some code comments as to why things are implemented the way they are.
  • There should be a comment at the top of each new or modified test to explain what the test does.

New flags

  • Is this flag really necessary?
  • Flag names must be clear and intuitive, use dashes (-), and have a clear help text.

If a workflow is added or modified:

  • Each item in Jobs should be named in order to mark it as required.
  • If the workflow needs to be marked as required, the maintainer team must be notified.

Backward compatibility

  • Protobuf changes should be wire-compatible.
  • Changes to _vt tables and RPCs need to be backward compatible.
  • RPC changes should be compatible with vitess-operator
  • If a flag is removed, then it should also be removed from vitess-operator and arewefastyet, if used there.
  • vtctl command output order should be stable and awk-able.

@vitess-bot vitess-bot bot added NeedsBackportReason If backport labels have been applied to a PR, a justification is required NeedsDescriptionUpdate The description is not clear or comprehensive enough, and needs work NeedsIssue A linked issue is missing for this Pull Request NeedsWebsiteDocsUpdate What it says labels Jun 28, 2024
@github-actions github-actions bot added this to the v21.0.0 milestone Jun 28, 2024
Copy link

codecov bot commented Jun 28, 2024

Codecov Report

Attention: Patch coverage is 25.07740% with 242 lines in your changes missing coverage. Please review.

Project coverage is 69.43%. Comparing base (6d43afc) to head (bc2cff2).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
go/vt/mysqlctl/mysqlshellbackupengine.go 24.10% 211 Missing ⚠️
go/vt/mysqlctl/query.go 0.00% 21 Missing ⚠️
go/vt/mysqlctl/fakemysqldaemon.go 33.33% 4 Missing ⚠️
go/vt/mysqlctl/backup.go 83.33% 2 Missing ⚠️
go/vt/mysqlctl/builtinbackupengine.go 0.00% 2 Missing ⚠️
go/vt/mysqlctl/xtrabackupengine.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #16295      +/-   ##
==========================================
- Coverage   69.51%   69.43%   -0.08%     
==========================================
  Files        1569     1570       +1     
  Lines      202529   202945     +416     
==========================================
+ Hits       140784   140913     +129     
- Misses      61745    62032     +287     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@rvrangel rvrangel marked this pull request as ready for review July 11, 2024 14:17
@deepthi deepthi added Component: Backup and Restore Type: Feature and removed NeedsDescriptionUpdate The description is not clear or comprehensive enough, and needs work NeedsIssue A linked issue is missing for this Pull Request NeedsBackportReason If backport labels have been applied to a PR, a justification is required labels Jul 11, 2024
Copy link
Contributor

@shlomi-noach shlomi-noach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this submission! Some initial general thoughts, before a deeper code review. PErhaps these questions are more appropriate on #16294 but I did not want to then split the discussion so let's keep it here.

I have not used MySQL Shell backups before. Some questions and notes:

  • This PR adds dependencies on mysqlsh and mysqlshell binaries. This is just an observation, but points for consideration are:

    • Neither are included in a standard MySQL build. What are version dependencies between mysqlsh/mysqlshell and the MySQL server?
    • Neither are included in the MySQL docker images, to the best of my understanding. This means this backup method will not be available on kubernetes deployments via vitess-operator.
  • Re: GTID not being available in the manifest file, this means we will not be able to run point in time recoveries with a mysqlshell-based full backup. Point in time recoveries require GTID information. As mentioned in Feature Request: MySQL Shell Logical Backups #16294 (comment), the mysqlshell method is the first and only (thus far) logical backup solution, so it's unfortunate that this solution will not support logical point in time recoveries.
    Is it not possible to read the gtidExecuted field from the @.json dump file immediately after the backup is complete, and update the manifest file? E.g. if the dump is into a directory, isn't that directory available for us to read?

// This is usually run in a background goroutine, so there's no point
// returning an error. Just log it.
logger.Warningf("error scanning lines from %s: %v", prefix, err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice we do not have a unit test for this function. Having moved it around, perhaps now is a good opportunity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I can probably add it there 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unit test added for this function

@rvrangel
Copy link
Contributor Author

These are good questions, thanks Shlomi!

  • I wasn't sure, but checking the officila mysql docker images, it seems to be included actually:

    $ docker run -it mysql:8.0 mysqlsh --version
    Cannot set LC_ALL to locale en_US.UTF-8: No such file or directory
    mysqlsh   Ver 8.0.38 for Linux on x86_64 - for MySQL 8.0.38 (MySQL Community Server (GPL))
    

    In relation to the version dependency, my understanding is that MySQL Shell needs to be at least the same version of the MySQL Server, but it can be newer. we have successfully been using MySQL Shell 8.4 with Percona Server 8.0 releases.

    We don't use vitess-operator so for us it would mean we need to make sure required binaries are installed anyway (like mysqld, xtrabackup). But I imagine it being included in the official docker images means it will be less of an issue?

  • Thats a good point I didn't realise. While it is possible to read the @.json file from a directory when it is completed (if we are writing to disk), it is less straight forward when we are storing the backups on an object store. Because mysqlsh doesn't work the same way (it doesn't provide you with a single stream that can be cleanly uplodad to whatever storage engine we are using), the thought was to bypass the storage engine in vitess (except for the MANIFEST which we still write using it) and just use this metadata to help the engine locate and restore the backup instead. If this was only saving to disk, it is much easier but also very limiting.

    If we were to do this, we would need to write code that would need to fetch the @.json from the supported object stores where there is a support overlap between mysqlsh and vitess (S3, Azure, GCP, etc) and some might be missing. Perhaps a better idea would be to include this backup engine without support for PITR in the beginning and file an upstream feature request that would print or save a copy of the executed GTID once the backup is done, which we could capture in an easier way (similar to the xtrabackup engine)?

    For additional context, as proposed on select backup engine in Backup() and ignore engines in RestoreFromBackup() #16428 and described in the use case, we plan to use this mostly to keep two backup types around for each shard, but always restoring by default from xtrabackup unless we require the logical backups for a specific reason.

    We also considered mysqldump which to be honest would fit the vitess backup engine workflow a lot better, but it was just too slow. This benchmark from Percona also highlights the same thing, and for use backing up/restoring was so slow it didn't make sense.

Signed-off-by: Renan Rangel <[email protected]>
Signed-off-by: Renan Rangel <[email protected]>
Copy link
Member

@frouioui frouioui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, thank you for this contribution.

Since we have not fully finished the deletion of mysqld in the vitess/lite Docker Images, the mysqlsh binary will have to be included in the vitess/lite image regardless if it's included in the official MySQL Docker Images or not. Since we are letting people choose between using an official MySQL image or the vitess/lite image for their Docker/K8S deployment we must have the binary in both.

Regarding vitess-operator, a follow-up PR is needed on the vitess-operator to allow this new backup engine. In our CRDs we have an enumeration that restrict what backup engines are allowed, we just need to add a new entry in the enumeration. This can be done here.

FYI, I can handle the vitess-operator changes.

@shlomi-noach
Copy link
Contributor

shlomi-noach commented Jul 22, 2024

We also considered mysqldump which to be honest would fit the vitess backup engine workflow a lot better, but it was just too slow.

Have you looked at mysqlpump? (Next gen mysqldump, included in standard builds).

@shlomi-noach
Copy link
Contributor

shlomi-noach commented Jul 22, 2024

I wasn't sure, but checking the officila mysql docker images, it seems to be included actually:

Oh, that's nice! The reason I thought it wasn't included is that mysqlsh/mysqlshell is not included in the standard MySQL build.

Thats a good point I didn't realise. While it is possible to read the @.json file from a directory when it is completed (if we are writing to disk), it is less straight forward when we are storing the backups on an object store.

I feel like it's OK to have some solution "with limitations". We should strive to support as much functionality as possible though. So IMHO we should strive to include the GTID when the backup goes into a directory. This should be possible to do, which then means the backup should fail if for some reason we can't fetch the GTID or validate it (correct GTID form). i.e. return BackupUnusable if unable to fetch and validate the GTID entry.

I'd like @deepthi to weigh in her opinion.

Assuming we do decide to move forward, then I'd next expect a CI/endtoend test please, as follows:

When these are all added, a new CI job will run to test mysqlshell-based backup, restores, and point-in-time recoveries. These can (and should) use the directory-based backup configuration, one which does make the GTID available.

If this test passes, then you will have validated the full cycle of backup and resotre, as well as correctness of the captured GTID.

Edit: since mysqlshell does not come bundled in the mysql distribution, we'd need to further download/install mysqlshell in the GitHub workflow file.

S3, Azure, GCP can be left without GTID support for now.

We'd need a documentation PR that clearly indicates the limitations of this method.

Comment on lines 23 to 38
var (
// location to store the mysql shell backup
mysqlShellBackupLocation = ""
// flags passed to the mysql shell utility, used both on dump/restore
mysqlShellFlags = "--defaults-file=/dev/null --js -h localhost"
// flags passed to the Dump command, as a JSON string
mysqlShellDumpFlags = `{"threads": 2}`
// flags passed to the Load command, as a JSON string
mysqlShellLoadFlags = `{"threads": 4, "updateGtidSet": "replace", "skipBinlog": true, "progressFile": ""}`
// drain a tablet when taking a backup
mysqlShellBackupShouldDrain = false
// disable redo logging and double write buffer
mysqlShellSpeedUpRestore = false

MySQLShellPreCheckError = errors.New("MySQLShellPreCheckError")
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have correctly followed the existing design. I'm just taking the opportunity to say at some point we will want to move away from these global variables.

go/vt/mysqlctl/mysqlshellbackupengine.go Show resolved Hide resolved
// flags passed to the mysql shell utility, used both on dump/restore
mysqlShellFlags = "--defaults-file=/dev/null --js -h localhost"
// flags passed to the Dump command, as a JSON string
mysqlShellDumpFlags = `{"threads": 2}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason to choose 2 rather than something based on runtime.NumCPU()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say because MySQL Shell backups can be a bit more intensive - we are requesting a bunch of data off MySQL which needs to be fetched, parsed and compressed - and in our particular use case we were taking backups online so we didn't wan't it to cause that much disruption. It is also part of the reason why I made sure ShouldDrainForBackup() was configurable in case it is more suitable for the use case.

I am fine with changing the default to runtime.NumCPU() though since it is configurable and leave this up to the user to decide based on their environment requirements, although I am also conscious that it might cause some issues in Kube where it will show the number of CPUs of the underlying node despite the pod being possibly limited on how much CPU it can use.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we already have a --concurrency flag for the Backup command. Should we reuse that flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so looking this up again today, the default in MySQL Shell if not passed is 4. what I have been considering is that if we do something like:

mysqlShellDumpFlags = fmt.Sprintf("{\"threads\": %d}", runtime.NumCPU())

it might give the user the wrong impression that this is the default for MySQL Shell and that if they use the flag to change other settings and they don't add thread to it, they will use all CPUs by default.

so perhaps we should just set it to {"threads": 4} instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might give the user the wrong impression that this is the default for MySQL Shell and that if they use the flag to change other settings and they don't add thread to it, they will use all CPUs by default.

This is a documentation concern. We can't expect any user expectation. I can say that I would not assume as much.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still, we can try to make it more difficult for users to do the wrong thing. perhaps we can remove threads from the default value and leave it up to the user to modify it if the desire so?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps we can remove threads from the default value and leave it up to the user to modify it if the desire so?

Would that mean mysql shell would then use 4? I think this is fine. So you'd give the user the option for setting "threads", but that option is by default empty? I like it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that's correct. the docs mention the default is 4

fs.StringVar(&mysqlShellFlags, "mysql_shell_flags", mysqlShellFlags, "execution flags to pass to mysqlsh binary to be used during dump/load")
fs.StringVar(&mysqlShellDumpFlags, "mysql_shell_dump_flags", mysqlShellDumpFlags, "flags to pass to mysql shell dump utility. This should be a JSON string and will be saved in the MANIFEST")
fs.StringVar(&mysqlShellLoadFlags, "mysql_shell_load_flags", mysqlShellLoadFlags, "flags to pass to mysql shell load utility. This should be a JSON string")
fs.BoolVar(&mysqlShellBackupShouldDrain, "mysql_shell_should_drain", mysqlShellBackupShouldDrain, "decide if we should drain while taking a backup or continue to serving traffic")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing the choice of draining vs not draining is due to the increased workload on the server?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, exactly. in fact I have been meaning to propose this to be modifiable for the xtrabackup engine as well, so a tablet won't be service traffic when it is taking a backup

fs.StringVar(&mysqlShellDumpFlags, "mysql_shell_dump_flags", mysqlShellDumpFlags, "flags to pass to mysql shell dump utility. This should be a JSON string and will be saved in the MANIFEST")
fs.StringVar(&mysqlShellLoadFlags, "mysql_shell_load_flags", mysqlShellLoadFlags, "flags to pass to mysql shell load utility. This should be a JSON string")
fs.BoolVar(&mysqlShellBackupShouldDrain, "mysql_shell_should_drain", mysqlShellBackupShouldDrain, "decide if we should drain while taking a backup or continue to serving traffic")
fs.BoolVar(&mysqlShellSpeedUpRestore, "mysql_shell_speedup_restore", mysqlShellSpeedUpRestore, "speed up restore by disabling redo logging and double write buffer during the restore process")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels risky. Please indicate caveats in this flag's description. Otherwise this looks "too good", why wouldn't anyone want to speed up the restore?

Copy link
Contributor Author

@rvrangel rvrangel Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless you need the redo log/double write buffer to be disable once the instance has completed the restore, there shouldn't be much risk in enabling this. for some setups there might be an interest in disabling this (I can see as a possible case, somebody running on zfs and wanting to keep the double write buffer disabled), so I didn't want to force it if the user has a similar scenario

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so for the duration of the restore this is fine, because who cares, the server is not serving, it's just being restored, right? But then, at the end of the process, as we mentioned elsewhere, these settings must return to "persistent" values, or else the backup should fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exactly, most users will only want to run with these settings during the restore and go back to the having redo log/doublewrite buffer enabled before the tablets starts serving. This is the use case described in the MySQL docs:

As of MySQL 8.0.21, you can disable redo logging using the ALTER INSTANCE DISABLE INNODB REDO_LOG statement. This functionality is intended for loading data into a new MySQL instance. Disabling redo logging speeds up data loading by avoiding redo log writes and doublewrite buffering.
Warning

This feature is intended only for loading data into a new MySQL instance. Do not disable redo logging on a production system.

One thing that I realise now is that this will likely fail if the user is running <8.0.21. Is this something we should validate in case this flag is set or do we already have a minimum version for MySQL with Vitess? In any case, it would just cause the backup to fail and the user would have to disable passing this flag.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that I realise now is that this will likely fail if the user is running <8.0.21. Is this something we should validate in case this flag is set or do we already have a minimum version for MySQL with Vitess?

We should validate that based on the actual MySQL connection. This is an already recognized "capability" in

DisableRedoLogFlavorCapability // supported in MySQL 8.0.21 and above: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-21.html

Here is an example usage:

capableOf := mysql.ServerVersionCapableOf(conn.ServerVersion)
capable, err := capableOf(capabilities.PerformanceSchemaDataLocksTableCapability)

We should fail the operation if the flags are set and the MySQL server versions is "incapable of" the functionality. Ideally, as close as possible to the flag parsing, but also just fine if just as part of the restore process, but do try to move that up as much as possible, and before doing actual substantial resotre work (e.g. before destorying the existing data...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has been added on 6e59215

go/vt/mysqlctl/mysqlshellbackupengine.go Outdated Show resolved Hide resolved
args = append(args, strings.Fields(mysqlShellFlags)...)
}

args = append(args, "-e", fmt.Sprintf("util.dumpSchemas([\"vt_%s\"], %q, %s)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the keyspace/schema names be escaped here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean escape like in MySQL as `vt_keyspace`? I am not sure MySQL Shell supports or expects it, I will verify that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't assume that the database name is vt_keyspace. It is determined by the --init_db_name_override flag.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This brings up another point. Typically when we do the regular kind of backup we also backup the sidecar db, which defaults to _vt. Does the mysqlshell backup specifically backup only the actual keyspace/database? What are the implications of this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, it is possible to backup multiple db/schemas, we just need to specify them. is this the right place to get the name of the sidecar db?

const (
DefaultName = "_vt"
)

also, I am curious what are the consequences if _vt is not in place, we tried some of these restores without any issues but maybe we are losing some metadata?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shlomi-noach would it make sense to do it in a separate PR though, so it is easier to revert if needed? I would hate for us to have to revert this PR once merged in case it causes any side effects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeleteBeforeRestore aside, would you all be comfortable with the idea adding a flag that lets makes us run DELETE USER on all users except the current one and than letting the user define loadUsers on the mysql shell restore flags on their own so these are reloaded as appropriate if they rely on replication for propagating the grants?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to just get rid of DeleteBeforeRestore if not being used, rather than having the backup engines ignore the intended value.

I interpreted that in the sense that you prefer to remove the variable in this PR. It's fine if we did that on another PR.

Copy link
Member

@frouioui frouioui Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to do it in a separate PR though

One thing to take into account is that if we do it in a separate PR, after merging this current PR the new engine won't work on vitess-operator (the restore part only). I don't mind waiting for the second PR to be ready/merged in order to merge the vitess-operator one. But, I think it would be nice to flag it somewhere, either in this PR description or else, that this engine is only available if not using vitess-operator, in the event we do two PRs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, lets do it in this PR then to avoid the admin work of having it separate and putting up notices, I will push a change later today

defer func() { // re-enable once we are done with the restore.
err := params.Mysqld.ExecuteSuperQueryList(ctx, []string{"ALTER INSTANCE ENABLE INNODB REDO_LOG"})
if err != nil {
params.Logger.Errorf("unable to re-enable REDO_LOG: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we fail the restore process? I'm not sure if I have a good answer here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a good question. the original intention here is, since we were able to successfully disable Redo logs/double write buffer, it would be better to fail the restore than potentially put it in service with a potentially dangerous configuration without the user realising it.

if the user wishes to run with redo log/double write disabled buffer they can avoid setting --mysql_shell_speedup_restore and handle it outside of vitess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, we should fail the restore when these flags are provided and if the above errors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just verifying that this is still to be addressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there something you still wanted me to address? currently we will only attempt to disable/enable if the flags are passed, otherwise there is no change in behaviour and if we can't run the ALTER INSTANCE we will fail the backup

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently we will only attempt to disable/enable if the flags are passed, otherwise there is no change in behaviour and if we can't run the ALTER INSTANCE we will fail the backup

All right! Then there is nothing else to be addressed.

@rvrangel
Copy link
Contributor Author

rvrangel commented Jul 22, 2024

@shlomi-noach yeah, we looked into mysqlpump, but it has been deprecated (the page you linked also has a notice) and it is still slower than MySQL Shell. but since it is likely going to be removed in a future MySQL version, we though it would be better not to introduce a new feature using it :)

I think the proposal to have the GTID read when backing up to a directory while not when using an object store is fair, let me look into it and make the necessary changes. If all looks good I will proceed with working on the CI/endtoend tests, I just wanted to get some initial feedback before doing so. Also curious what @deepthi thinks about this approach.

Edit: since mysqlshell does not come bundled in the mysql distribution, we'd need to further download/install mysqlshell in the GitHub workflow file.

Is that something that needs to happen as part of this PR or something separate?

@frouioui
Copy link
Member

@rvrangel, the latest changes look good to me, and the vtop tests are all passing!
However, we should add the grant in examples/compose/config/init_db.sql and go/test/endtoend/vreplication/testdata/config/init_testserver_db.sql

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's think about marking this new workflow as required when merging the PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. We'll give it a couple weeks until all open PRs are in sync, then we'll make it Required.

changelog/21.0/21.0.0/summary.md Outdated Show resolved Hide resolved
We are introducing a the backup engine supporting logical backups starting on v21 to support use cases that require something else besides physical backups. This is experimental and is based on the
[MySQL Shell](https://dev.mysql.com/doc/mysql-shell/8.0/en/).

The new engine is enabled by using `--backup_engine_implementation=mysqlshell`. There are other options that are required, so check the docs on which options are required and how to use it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a link to the docs would be useful here.

@@ -179,6 +179,7 @@ func (p *RestoreParams) IsIncrementalRecovery() bool {
// Returns the manifest of a backup if successful, otherwise returns an error
type RestoreEngine interface {
ExecuteRestore(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (*BackupManifest, error)
ShouldStartMySQLAfterRestore() bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻

go/vt/mysqlctl/mysqlshellbackupengine.go Show resolved Hide resolved
go/vt/mysqlctl/mysqlshellbackupengine.go Outdated Show resolved Hide resolved
@shlomi-noach shlomi-noach removed the NeedsWebsiteDocsUpdate What it says label Sep 22, 2024
Copy link
Contributor

@shlomi-noach shlomi-noach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on my side, pending final comments from @frouioui

@shlomi-noach
Copy link
Contributor

shlomi-noach commented Sep 23, 2024

Merged main and pushed, having merged #16807, and to get latest fixes to unit test issues.

Signed-off-by: Shlomi Noach <[email protected]>
@frouioui frouioui removed the release notes (needs details) This PR needs to be listed in the release notes in a dedicated section (deprecation notice, etc...) label Sep 24, 2024
Copy link
Member

@frouioui frouioui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good to me besides #16295 (comment).

The vitess-operator PR also looks good to me and is ready to go.

Signed-off-by: Renan Rangel <[email protected]>
@rvrangel
Copy link
Contributor Author

@frouioui thanks, I missed that comment. I have added the GRANT on those files now!

Copy link
Member

@frouioui frouioui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working with us through this big change! I don't think any of us anticipated the amount of work related to adding a new backup engine.

Vitess-operator, Docker, and the Vitess parts look good to me!

@frouioui frouioui merged commit 969e018 into vitessio:main Sep 24, 2024
98 checks passed
@rvrangel
Copy link
Contributor Author

Thanks everyone for the support, it was a long PR but it definitely looks a much better solution than when it started! I appreciate all the suggestions feedback provided and great to see it finally merged 🎉

tanjinx pushed a commit to slackhq/vitess that referenced this pull request Oct 30, 2024
Signed-off-by: Renan Rangel <[email protected]>
Signed-off-by: Shlomi Noach <[email protected]>
Co-authored-by: Shlomi Noach <[email protected]>
tanjinx pushed a commit to slackhq/vitess that referenced this pull request Nov 14, 2024
Signed-off-by: Renan Rangel <[email protected]>
Signed-off-by: Shlomi Noach <[email protected]>
Co-authored-by: Shlomi Noach <[email protected]>
tanjinx added a commit to slackhq/vitess that referenced this pull request Nov 18, 2024
* adding new mysql shell backup engine (vitessio#16295)

Signed-off-by: Renan Rangel <[email protected]>
Signed-off-by: Shlomi Noach <[email protected]>
Co-authored-by: Shlomi Noach <[email protected]>

---------

Signed-off-by: Renan Rangel <[email protected]>
Signed-off-by: Shlomi Noach <[email protected]>
Co-authored-by: Renan Rangel <[email protected]>
Co-authored-by: Shlomi Noach <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: MySQL Shell Logical Backups
5 participants