-
Notifications
You must be signed in to change notification settings - Fork 202
K8SPXC-1144: mark backups as PITR unready in the storage #2261
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
Changes from 6 commits
8422839
f3bb732
6106de6
572c84d
d221e0d
2229b85
ecacfcb
65dc354
2f47d22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| apiVersion: pxc.percona.com/v1 | ||
| kind: PerconaXtraDBClusterRestore | ||
| metadata: | ||
| name: restore-on-pitr-minio-gap-bs | ||
| spec: | ||
| pxcCluster: pitr-gap-errors | ||
| pitr: | ||
| type: latest | ||
| backupSource: | ||
| storageName: "minio-binlogs" | ||
| backupSource: | ||
| destination: #destination | ||
| s3: | ||
| bucket: operator-testing | ||
| credentialsSecret: minio-secret | ||
| endpointUrl: https://minio-service.#namespace:9000/ | ||
| region: us-east-1 | ||
| verifyTLS: false | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,11 +7,14 @@ import ( | |
| "github.com/pkg/errors" | ||
| batchv1 "k8s.io/api/batch/v1" | ||
| corev1 "k8s.io/api/core/v1" | ||
| "k8s.io/apimachinery/pkg/api/meta" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "k8s.io/apimachinery/pkg/types" | ||
| "sigs.k8s.io/controller-runtime/pkg/client" | ||
|
|
||
| api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" | ||
| "github.com/percona/percona-xtradb-cluster-operator/pkg/naming" | ||
| "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/backup/storage" | ||
| ) | ||
|
|
||
| func getBackup(ctx context.Context, cl client.Client, cr *api.PerconaXtraDBClusterRestore) (*api.PerconaXtraDBClusterBackup, error) { | ||
|
|
@@ -95,3 +98,32 @@ func isJobFinished(checkJob *batchv1.Job) (bool, error) { | |
| } | ||
| return false, nil | ||
| } | ||
|
|
||
| func (r *ReconcilePerconaXtraDBClusterRestore) isPITRReady(ctx context.Context, cluster *api.PerconaXtraDBCluster, bcp *api.PerconaXtraDBClusterBackup) (bool, error) { | ||
| cond := meta.FindStatusCondition(bcp.Status.Conditions, api.BackupConditionPITRReady) | ||
| if cond != nil && cond.Status == metav1.ConditionFalse { | ||
| return false, nil | ||
| } | ||
|
|
||
| opts, err := storage.GetOptionsFromBackup(ctx, r.client, cluster, bcp) | ||
| if err != nil { | ||
| return false, errors.Wrap(err, "failed to get storage options") | ||
| } | ||
|
|
||
| stg, err := r.newStorageClientFunc(ctx, opts) | ||
| if err != nil { | ||
| return false, errors.Wrap(err, "new storage") | ||
| } | ||
|
|
||
| filepath := bcp.Status.Destination.BackupName() + "." + naming.PITRNotReady | ||
| objReader, err := stg.GetObject(ctx, filepath) | ||
| if err == nil { | ||
| objReader.Close() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we handle the error this returns?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least we can log it, maybe
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We handle it below |
||
| return false, nil | ||
| } | ||
| if errors.Is(err, storage.ErrObjectNotFound) { | ||
| return true, nil | ||
| } | ||
|
|
||
| return false, errors.Wrap(err, "get pitr-not-ready file from storage") | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,9 +21,10 @@ import ( | |
| api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1" | ||
| "github.com/percona/percona-xtradb-cluster-operator/pkg/naming" | ||
| "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/app/binlogcollector" | ||
| "github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/backup/storage" | ||
| ) | ||
|
|
||
| func CheckPITRErrors(ctx context.Context, cl client.Client, clcmd *clientcmd.Client, cr *api.PerconaXtraDBCluster) error { | ||
| func CheckPITRErrors(ctx context.Context, cl client.Client, clcmd *clientcmd.Client, cr *api.PerconaXtraDBCluster, storageFunc storage.NewClientFunc) error { | ||
| log := logf.FromContext(ctx) | ||
|
|
||
| if cr.Spec.Backup == nil || !cr.Spec.Backup.PITR.Enabled { | ||
|
|
@@ -64,7 +65,7 @@ func CheckPITRErrors(ctx context.Context, cl client.Client, clcmd *clientcmd.Cli | |
| stdoutBuf := &bytes.Buffer{} | ||
| stderrBuf := &bytes.Buffer{} | ||
|
|
||
| err = clcmd.Exec(collectorPod, "pitr", []string{"/bin/bash", "-c", "cat /tmp/gap-detected || true"}, nil, stdoutBuf, stderrBuf, false) | ||
| err = clcmd.Exec(collectorPod, "pitr", []string{"/bin/bash", "-c", "cat " + naming.GapDetected + " || true"}, nil, stdoutBuf, stderrBuf, false) | ||
| if err != nil { | ||
| return errors.Wrapf(err, "exec binlog collector pod %s", collectorPod.Name) | ||
| } | ||
|
|
@@ -85,6 +86,10 @@ func CheckPITRErrors(ctx context.Context, cl client.Client, clcmd *clientcmd.Cli | |
| } | ||
| meta.SetStatusCondition(&backup.Status.Conditions, condition) | ||
|
|
||
| if err := addPitrNotReadyFileToBackup(ctx, cl, cr, backup, storageFunc); err != nil { | ||
| return errors.Wrap(err, "add pitr-not-ready file") | ||
| } | ||
|
|
||
| if err := cl.Status().Update(ctx, backup); err != nil { | ||
| return errors.Wrap(err, "update backup status") | ||
| } | ||
|
|
@@ -164,6 +169,24 @@ func UpdatePITRTimeline(ctx context.Context, cl client.Client, clcmd *clientcmd. | |
| return nil | ||
| } | ||
|
|
||
| func addPitrNotReadyFileToBackup(ctx context.Context, cl client.Client, cr *api.PerconaXtraDBCluster, backup *api.PerconaXtraDBClusterBackup, storageFunc storage.NewClientFunc) error { | ||
| opts, err := storage.GetOptionsFromBackup(ctx, cl, cr, backup) | ||
| if err != nil { | ||
| return errors.Wrap(err, "failed to get storage options") | ||
| } | ||
| scli, err := storageFunc(ctx, opts) | ||
| if err != nil { | ||
| return errors.Wrap(err, "failed to create s3 client") | ||
|
||
| } | ||
|
|
||
| filepath := backup.Status.Destination.BackupName() + "." + naming.PITRNotReady | ||
| if err = scli.PutObject(ctx, filepath, bytes.NewBuffer([]byte{}), 0); err != nil { | ||
| return errors.Wrap(err, "put pitr-not-ready object") | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| var ErrNoBackups = errors.New("No backups found") | ||
|
|
||
| func getLatestSuccessfulBackup(ctx context.Context, cl client.Client, cr *api.PerconaXtraDBCluster) (*api.PerconaXtraDBClusterBackup, 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.
will be storedThere 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.
ecacfcb