Skip to content

Commit

Permalink
*: add backup gtid and fix some bugs radondb#698
Browse files Browse the repository at this point in the history
  • Loading branch information
acekingke committed Aug 14, 2023
1 parent a64d2af commit c924410
Show file tree
Hide file tree
Showing 11 changed files with 1,814 additions and 7 deletions.
2 changes: 2 additions & 0 deletions api/v1alpha1/backup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ type BackupStatus struct {
BackupDate string `json:"backupDate,omitempty"`
// Get the backup Type
BackupType string `json:"backupType,omitempty"`
// Get the Gtid
Gtid string `json:"gtid,omitempty"`
// Conditions represents the backup resource conditions list.
Conditions []BackupCondition `json:"conditions,omitempty"`
}
Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha1/mysqlcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,9 @@ type MysqlClusterStatus struct {
ReadyNodes int `json:"readyNodes,omitempty"`
// State
State ClusterState `json:"state,omitempty"`
// LastBackup
LastBackup string `json:"lastbackup,omitempty"`
LastBackupGtid string `json:"lastbackupGtid,omitempty"`
// Conditions contains the list of the cluster conditions fulfilled.
Conditions []ClusterCondition `json:"conditions,omitempty"`
// Nodes contains the list of the node status fulfilled.
Expand Down
18 changes: 14 additions & 4 deletions backup/cronbackup.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,22 @@ func (j *CronJob) scheduledBackupsRunningCount() int {
backupsList := &apiv1alpha1.BackupList{}
// select all backups with labels recurrent=true and and not completed of the cluster
selector := j.backupSelector()
client.MatchingFields{"status.completed": "false"}.ApplyToList(selector)
// Because k8s do not support fieldSelector with custom resources
// https://github.com/kubernetes/kubernetes/issues/51046
// So this cannot use fields selector.
// client.MatchingFields{"status.completed": "false"}.ApplyToList(selector)

if err := j.Client.List(context.TODO(), backupsList, selector); err != nil {
if err := j.Client.List(context.TODO(), backupsList); err != nil {
log.Error(err, "failed getting backups", "selector", selector)
return 0
}

return len(backupsList.Items)
var rest []apiv1alpha1.Backup
for _, b := range backupsList.Items {
if !b.Status.Completed {
rest = append(rest, b)
}
}
return len(rest)
}

func (j *CronJob) backupSelector() *client.ListOptions {
Expand Down Expand Up @@ -151,10 +159,12 @@ func (j *CronJob) createBackup() (*apiv1alpha1.Backup, error) {
//RemoteDeletePolicy: j.BackupRemoteDeletePolicy,
HostName: fmt.Sprintf("%s-mysql-0", j.ClusterName),
},
Status: apiv1alpha1.BackupStatus{Completed: false},
}
if len(j.NFSServerAddress) > 0 {
backup.Spec.NFSServerAddress = j.NFSServerAddress
}

return backup, j.Client.Create(context.TODO(), backup)
}

Expand Down
10 changes: 8 additions & 2 deletions backup/syncer/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

v1alpha1 "github.com/radondb/radondb-mysql-kubernetes/api/v1alpha1"
"github.com/radondb/radondb-mysql-kubernetes/backup"
Expand Down Expand Up @@ -101,6 +102,9 @@ func (s *jobSyncer) updateStatus(job *batchv1.Job) {
if backType := s.job.Annotations[utils.JobAnonationType]; backType != "" {
s.backup.Status.BackupType = backType
}
if gtid := s.job.Annotations[utils.JobAnonationGtid]; gtid != "" {
s.backup.Status.Gtid = gtid
}
}

// check for failed condition
Expand Down Expand Up @@ -154,10 +158,12 @@ func (s *jobSyncer) ensurePodSpec(in corev1.PodSpec) corev1.PodSpec {
"/bin/bash", "-c", "--",
}
backupToDir, DateTime := utils.BuildBackupName(s.backup.Spec.ClusterName)
// add the gtid script
strAnnonations := fmt.Sprintf(`curl -X PATCH -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" -H "Content-Type: application/json-patch+json" \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/apis/batch/v1/namespaces/%s/jobs/%s \
-d '[{"op": "add", "path": "/metadata/annotations/backupName", "value": "%s"}, {"op": "add", "path": "/metadata/annotations/backupDate", "value": "%s"}, {"op": "add", "path": "/metadata/annotations/backupType", "value": "NFS"}]';`,
s.backup.Namespace, s.backup.GetNameForJob(), backupToDir, DateTime)
-d "[{\"op\": \"add\", \"path\": \"/metadata/annotations/backupName\", \"value\": \"%s\"}, {\"op\": \"add\", \"path\": \"/metadata/annotations/backupDate\", \"value\": \"%s\"},{\"op\": \"add\", \"path\": \"/metadata/annotations/gtid\", \"value\": \"$( cat /backup/%s/xtrabackup_binlog_info|awk '{print $3}')\"}, {\"op\": \"add\", \"path\": \"/metadata/annotations/backupType\", \"value\": \"NFS\"}]";`,
s.backup.Namespace, s.backup.GetNameForJob(), backupToDir, DateTime, backupToDir)
log.Log.Info(strAnnonations)
// Add the check DiskUsage
// use expr because shell cannot compare float number
checkUsage := `[ $(echo "$(df /backup|awk 'NR>1 {print $4}') > $(du /backup |awk 'END {if (NR > 1) {print $1 /(NR-1)} else print 0}')"|bc) -eq '1' ] || { echo disk available may be too small; exit 1;};`
Expand Down
144 changes: 144 additions & 0 deletions charts/mysql-operator/crds/mysql.radondb.com_backups.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.1
creationTimestamp: null
name: backups.mysql.radondb.com
spec:
group: mysql.radondb.com
names:
kind: Backup
listKind: BackupList
plural: backups
singular: backup
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: The Backup name
jsonPath: .status.backupName
name: BackupName
type: string
- description: The Backup Date time
jsonPath: .status.backupDate
name: BackupDate
type: string
- description: The Backup Type
jsonPath: .status.backupType
name: Type
type: string
- description: Whether the backup Success?
jsonPath: .status.conditions[?(@.type=="Complete")].status
name: Success
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: Backup is the Schema for the backups API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: This is the backup Job CRD. BackupSpec defines the desired
state of Backup
properties:
clusterName:
description: ClusterName represents the cluster name to backup
type: string
historyLimit:
default: 3
description: History Limit of job
format: int32
type: integer
hostName:
description: HostName represents the host for which to take backup
If is empty, is use leader HostName
type: string
image:
default: radondb/mysql57-sidecar:v2.3.0
description: To specify the image that will be used for sidecar container.
type: string
nfsServerAddress:
description: Represents the ip address of the nfs server.
type: string
required:
- clusterName
type: object
status:
description: BackupStatus defines the observed state of Backup
properties:
backupDate:
description: Get the backup Date
type: string
backupName:
description: Get the backup path.
type: string
backupType:
description: Get the backup Type
type: string
completed:
default: false
description: Completed indicates whether the backup is in a final
state, no matter whether its' corresponding job failed or succeeded
type: boolean
conditions:
description: Conditions represents the backup resource conditions
list.
items:
description: BackupCondition defines condition struct for backup
resource
properties:
lastTransitionTime:
description: LastTransitionTime
format: date-time
type: string
message:
description: Message
type: string
reason:
description: Reason
type: string
status:
description: Status of the condition, one of (\"True\", \"False\",
\"Unknown\")
type: string
type:
description: type of cluster condition, values in (\"Ready\")
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
gtid:
description: Get the Gtid
type: string
required:
- completed
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
Loading

0 comments on commit c924410

Please sign in to comment.