From fc5f9fcf60db81d3767f52c9365ecc2423ba4543 Mon Sep 17 00:00:00 2001 From: ris <79858083+RidRisR@users.noreply.github.com> Date: Mon, 13 Jan 2025 09:38:07 +0800 Subject: [PATCH] br: add a new CRD for compact backup (#5822) --- docs/api-references/docs.md | 16 +-- .../pingcap/v1alpha1/openapi_generated.go | 2 +- pkg/apis/pingcap/v1alpha1/types.go | 4 - .../backupschedule/backup_schedule_manager.go | 124 +++++++++--------- 4 files changed, 67 insertions(+), 79 deletions(-) diff --git a/docs/api-references/docs.md b/docs/api-references/docs.md index 5e43336ba9..be862212fe 100644 --- a/docs/api-references/docs.md +++ b/docs/api-references/docs.md @@ -5601,9 +5601,7 @@ StorageProvider

(Members of StorageProvider are embedded into this type.)

-

StorageProvider configures where and how backups should be stored. -*** Note: This field should generally not be left empty, unless you are certain the storage provider -*** can be obtained from another source, such as a schedule CR.

+

StorageProvider configures where and how backups should be stored.

@@ -5681,9 +5679,7 @@ BRConfig -

BRConfig is the configs for BR -*** Note: This field should generally not be left empty, unless you are certain the BR config -*** can be obtained from another source, such as a schedule CR.

+

BRConfig is the configs for BR

@@ -5942,9 +5938,7 @@ StorageProvider

(Members of StorageProvider are embedded into this type.)

-

StorageProvider configures where and how backups should be stored. -*** Note: This field should generally not be left empty, unless you are certain the storage provider -*** can be obtained from another source, such as a schedule CR.

+

StorageProvider configures where and how backups should be stored.

@@ -6022,9 +6016,7 @@ BRConfig -

BRConfig is the configs for BR -*** Note: This field should generally not be left empty, unless you are certain the BR config -*** can be obtained from another source, such as a schedule CR.

+

BRConfig is the configs for BR

diff --git a/pkg/apis/pingcap/v1alpha1/openapi_generated.go b/pkg/apis/pingcap/v1alpha1/openapi_generated.go index a7b74920de..4f38fa8279 100644 --- a/pkg/apis/pingcap/v1alpha1/openapi_generated.go +++ b/pkg/apis/pingcap/v1alpha1/openapi_generated.go @@ -1832,7 +1832,7 @@ func schema_pkg_apis_pingcap_v1alpha1_CompactSpec(ref common.ReferenceCallback) }, "br": { SchemaProps: spec.SchemaProps{ - Description: "BRConfig is the configs for BR *** Note: This field should generally not be left empty, unless you are certain the BR config *** can be obtained from another source, such as a schedule CR.", + Description: "BRConfig is the configs for BR", Ref: ref("github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.BRConfig"), }, }, diff --git a/pkg/apis/pingcap/v1alpha1/types.go b/pkg/apis/pingcap/v1alpha1/types.go index d8f01e5f35..28967fa42c 100644 --- a/pkg/apis/pingcap/v1alpha1/types.go +++ b/pkg/apis/pingcap/v1alpha1/types.go @@ -3523,8 +3523,6 @@ type CompactSpec struct { // +optional Env []corev1.EnvVar `json:"env,omitempty"` // StorageProvider configures where and how backups should be stored. - // *** Note: This field should generally not be left empty, unless you are certain the storage provider - // *** can be obtained from another source, such as a schedule CR. StorageProvider `json:",inline"` // StartTs is the start ts of the compact backup. // Format supports TSO or datetime, e.g. '400036290571534337', '2018-05-11 01:42:23'. @@ -3546,8 +3544,6 @@ type CompactSpec struct { // +optional ToolImage string `json:"toolImage,omitempty"` // BRConfig is the configs for BR - // *** Note: This field should generally not be left empty, unless you are certain the BR config - // *** can be obtained from another source, such as a schedule CR. BR *BRConfig `json:"br,omitempty"` // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images. // +optional diff --git a/pkg/backup/backupschedule/backup_schedule_manager.go b/pkg/backup/backupschedule/backup_schedule_manager.go index 6bba1496fe..0960863143 100644 --- a/pkg/backup/backupschedule/backup_schedule_manager.go +++ b/pkg/backup/backupschedule/backup_schedule_manager.go @@ -292,36 +292,36 @@ func (bm *backupScheduleManager) deleteLastcompactJob(bs *v1alpha1.BackupSchedul // It returns a controller.RequeueError if the backup is still running, // otherwise it updates the LastCompactTime or returns any encountered error. func (bm *backupScheduleManager) handleLastCompact(ns, bsName, lastCompact string, bs *v1alpha1.BackupSchedule) error { - if lastCompact == "" { - return nil - } - - compact, err := bm.deps.CompactBackupLister.CompactBackups(ns).Get(lastCompact) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return fmt.Errorf("backup schedule %s/%s: get compact backup %s failed: %w", ns, bsName, lastCompact, err) - } - - var timestamp string - switch compact.Status.State { - case string(v1alpha1.BackupComplete): - timestamp = compact.Spec.EndTs - case string(v1alpha1.BackupFailed): - timestamp = compact.Spec.StartTs - default: - return controller.RequeueErrorf("backup schedule %s/%s: compact backup %s is still running", ns, bsName, lastCompact) - } - - t, err := config.ParseTSStringToGoTime(timestamp) - if err != nil { - return perrors.AddStack(err) - } - - if err := bm.deps.CompactControl.DeleteCompactBackup(compact); err != nil { - return fmt.Errorf("backup schedule %s/%s: delete compact backup %s failed: %w", ns, bsName, lastCompact, err) - } + if lastCompact == "" { + return nil + } + + compact, err := bm.deps.CompactBackupLister.CompactBackups(ns).Get(lastCompact) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return fmt.Errorf("backup schedule %s/%s: get compact backup %s failed: %w", ns, bsName, lastCompact, err) + } + + var timestamp string + switch compact.Status.State { + case string(v1alpha1.BackupComplete): + timestamp = compact.Spec.EndTs + case string(v1alpha1.BackupFailed): + timestamp = compact.Spec.StartTs + default: + return controller.RequeueErrorf("backup schedule %s/%s: compact backup %s is still running", ns, bsName, lastCompact) + } + + t, err := config.ParseTSStringToGoTime(timestamp) + if err != nil { + return perrors.AddStack(err) + } + + if err := bm.deps.CompactControl.DeleteCompactBackup(compact); err != nil { + return fmt.Errorf("backup schedule %s/%s: delete compact backup %s failed: %w", ns, bsName, lastCompact, err) + } if !t.IsZero() && t.Before(bs.Status.LogBackupStartTs.Time) { return fmt.Errorf("backupSchedule %s/%s last compact time can't rollback (from %v to %v)", bs.GetNamespace(), bs.GetName(), bs.Status.LogBackupStartTs, t) @@ -330,46 +330,46 @@ func (bm *backupScheduleManager) handleLastCompact(ns, bsName, lastCompact strin return fmt.Errorf("backupSchedule %s/%s last compact time can't rollback (from %v to %v)", bs.GetNamespace(), bs.GetName(), bs.Status.LastCompactTime, t) } bs.Status.LastCompactTime = &metav1.Time{Time: t} - return nil + return nil } func (bm *backupScheduleManager) canPerformNextCompact(bs *v1alpha1.BackupSchedule) error { - ns := bs.GetNamespace() - bsName := bs.GetName() + ns := bs.GetNamespace() + bsName := bs.GetName() if bs.Status.LogBackupStartTs == nil { return nil } - // Determine if the backup schedule is part of a group - bsGroupName := bs.GetLabels()[label.BackupScheduleGroupLabelKey] - if bsGroupName == "" { - return bm.handleLastCompact(ns, bsName, bs.Status.LastCompact, bs) - } - - backupScheduleGroupLabels := label.NewBackupScheduleGroup(bsGroupName) - selector, err := backupScheduleGroupLabels.Selector() - if err != nil { - return fmt.Errorf("generate backup schedule group %s label selector failed: %w", bsGroupName, err) - } - - bss, err := bm.deps.BackupScheduleLister.BackupSchedules(ns).List(selector) - if err != nil { - return fmt.Errorf("backup schedule %s/%s: list backup schedules failed: %w", ns, bsName, err) - } - - for _, bsMember := range bss { - if err := bm.handleLastCompact(ns, bsName, bsMember.Status.LastCompact, bsMember); err != nil { - // If it's a requeue error, propagate it - if controller.IsRequeueError(err) { - return err - } - // For other errors, return immediately - return fmt.Errorf("backup schedule %s/%s: processing compact failed: %w", ns, bsName, err) - } - } - - return nil + // Determine if the backup schedule is part of a group + bsGroupName := bs.GetLabels()[label.BackupScheduleGroupLabelKey] + if bsGroupName == "" { + return bm.handleLastCompact(ns, bsName, bs.Status.LastCompact, bs) + } + + backupScheduleGroupLabels := label.NewBackupScheduleGroup(bsGroupName) + selector, err := backupScheduleGroupLabels.Selector() + if err != nil { + return fmt.Errorf("generate backup schedule group %s label selector failed: %w", bsGroupName, err) + } + + bss, err := bm.deps.BackupScheduleLister.BackupSchedules(ns).List(selector) + if err != nil { + return fmt.Errorf("backup schedule %s/%s: list backup schedules failed: %w", ns, bsName, err) + } + + for _, bsMember := range bss { + if err := bm.handleLastCompact(ns, bsName, bsMember.Status.LastCompact, bsMember); err != nil { + // If it's a requeue error, propagate it + if controller.IsRequeueError(err) { + return err + } + // For other errors, return immediately + return fmt.Errorf("backup schedule %s/%s: processing compact failed: %w", ns, bsName, err) + } + } + + return nil } func (bm *backupScheduleManager) performLogBackupIfNeeded(bs *v1alpha1.BackupSchedule) error {