Skip to content

Commit 6621a02

Browse files
committed
*: support backup/restore with NFS #148
1 parent 2d61f59 commit 6621a02

25 files changed

+417
-25
lines changed

api/v1alpha1/backup_types.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ type BackupSpec struct {
3535
Image string `json:"image"`
3636

3737
// HostName represents the host for which to take backup
38-
HostName string `json:"hostname"`
38+
// If is empty, is use leader HostName
39+
HostName string `json:"hostname,omitempty"`
40+
41+
// Represents the name of backup to NFS
42+
// +optional
43+
BackupToNFS string `json:"BackupToNFS,omitempty"`
3944

4045
// Cluster represents the cluster name to backup
4146
ClusterName string `json:"clustname"`

api/v1alpha1/cluster_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ type ClusterSpec struct {
8181
// Represents the name of the cluster restore from backup path
8282
// +optional
8383
RestoreFrom string `json:"restoreFrom,omitempty"`
84+
85+
// Represents the name of the cluster restore from NFS
86+
// +optional
87+
RestoreFromNFS string `json:"restoreFromNFS,omitempty"`
8488
}
8589

8690
// MysqlOpts defines the options of MySQL container.

backup/backup.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ func (b *Backup) GetNameForJob() string {
4949
return fmt.Sprintf("%s-backup", b.Name)
5050
}
5151

52-
// Create the backup Domain Name.
53-
func (b *Backup) GetBackupURL(cluster_name string, hostname string) string {
54-
return fmt.Sprintf("%s.%s-mysql.%s:%v", hostname, cluster_name, b.Namespace, utils.XBackupPort)
52+
// Create the backup Domain Name or leader DNS.
53+
func (b *Backup) GetBackupURL(clusterName string, hostname string) string {
54+
if len(hostname) != 0 {
55+
return fmt.Sprintf("%s.%s-mysql.%s:%v", hostname, clusterName, b.Namespace, utils.XBackupPort)
56+
} else {
57+
return fmt.Sprintf("%s-leader.%s:%v", clusterName, b.Namespace, utils.XBackupPort)
58+
}
5559
}

backup/syncer/job.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,41 @@ func (s *jobSyncer) ensurePodSpec(in corev1.PodSpec) corev1.PodSpec {
115115
sctName := fmt.Sprintf("%s-secret", s.backup.Spec.ClusterName)
116116
in.Containers[0].Name = utils.ContainerBackupName
117117
in.Containers[0].Image = s.backup.Spec.Image
118-
in.Containers[0].Args = []string{
119-
"request_a_backup",
120-
s.backup.GetBackupURL(s.backup.Spec.ClusterName, s.backup.Spec.HostName),
118+
119+
if len(s.backup.Spec.BackupToNFS) != 0 {
120+
// add volumn about pvc
121+
in.Volumes = []corev1.Volume{
122+
{
123+
Name: utils.XtrabackupPV,
124+
VolumeSource: corev1.VolumeSource{
125+
NFS: &corev1.NFSVolumeSource{
126+
Server: s.backup.Spec.BackupToNFS,
127+
Path: "/",
128+
},
129+
},
130+
},
131+
}
132+
//"rm -rf /backup/*;curl --user sys_backups:sys_backups sample-mysql-0.sample-mysql.default:8082/download|xbstream -x -C /backup"
133+
in.Containers[0].Command = []string{
134+
"/bin/bash", "-c", "--",
135+
}
136+
var backupToDir string = utils.BuildBackupName()
137+
in.Containers[0].Args = []string{
138+
fmt.Sprintf("mkdir -p /backup/%s;curl --user $BACKUP_USER:$BACKUP_PASSWORD %s/download|xbstream -x -C /backup/%s; exit ${PIPESTATUS[0]}",
139+
backupToDir, s.backup.GetBackupURL(s.backup.Spec.ClusterName, s.backup.Spec.HostName), backupToDir),
140+
}
141+
in.Containers[0].VolumeMounts = []corev1.VolumeMount{
142+
{
143+
Name: utils.XtrabackupPV,
144+
MountPath: utils.XtrabckupLocal,
145+
},
146+
}
147+
} else {
148+
// in.Containers[0].ImagePullPolicy = s.opt.ImagePullPolicy
149+
in.Containers[0].Args = []string{
150+
"request_a_backup",
151+
s.backup.GetBackupURL(s.backup.Spec.ClusterName, s.backup.Spec.HostName),
152+
}
121153
}
122154
var optTrue bool = true
123155
in.Containers[0].Env = []corev1.EnvVar{

charts/mysql-operator/crds/mysql.radondb.com_backups.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ spec:
3636
spec:
3737
description: BackupSpec defines the desired state of Backup
3838
properties:
39+
BackupToNFS:
40+
description: Represents the name of backup to NFS
41+
type: string
3942
clustname:
4043
description: Cluster represents the cluster name to backup
4144
type: string
@@ -46,14 +49,14 @@ spec:
4649
type: integer
4750
hostname:
4851
description: HostName represents the host for which to take backup
52+
If is empty, is use leader HostName
4953
type: string
5054
image:
5155
default: radondb/mysql-sidecar:latest
5256
description: To specify the image that will be used for sidecar container.
5357
type: string
5458
required:
5559
- clustname
56-
- hostname
5760
type: object
5861
status:
5962
description: BackupStatus defines the observed state of Backup

charts/mysql-operator/crds/mysql.radondb.com_clusters.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,9 @@ spec:
12431243
description: Represents the name of the cluster restore from backup
12441244
path
12451245
type: string
1246+
restoreFromNFS:
1247+
description: Represents the name of the cluster restore from NFS
1248+
type: string
12461249
xenonOpts:
12471250
default:
12481251
admitDefeatHearbeatCount: 5

cluster/cluster.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,18 @@ func (c *Cluster) EnsureVolumes() []corev1.Volume {
213213
},
214214
},
215215
)
216-
216+
// add the nfs volumn mount
217+
if len(c.Spec.RestoreFromNFS) != 0 {
218+
volumes = append(volumes, corev1.Volume{
219+
Name: utils.XtrabackupPV,
220+
VolumeSource: corev1.VolumeSource{
221+
NFS: &corev1.NFSVolumeSource{
222+
Server: c.Spec.RestoreFromNFS,
223+
Path: "/",
224+
},
225+
},
226+
})
227+
}
217228
return volumes
218229
}
219230

cluster/container/init_sidecar.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ func (c *initSidecar) getEnvVars() []corev1.EnvVar {
9999
Name: "RESTORE_FROM",
100100
Value: c.Spec.RestoreFrom,
101101
},
102-
102+
{
103+
Name: "CLUSTER_NAME",
104+
Value: c.Name,
105+
},
103106
getEnvVarFromSecret(sctName, "MYSQL_ROOT_PASSWORD", "root-password", false),
104107
getEnvVarFromSecret(sctName, "MYSQL_DATABASE", "mysql-database", true),
105108
getEnvVarFromSecret(sctName, "MYSQL_USER", "mysql-user", true),
@@ -124,7 +127,12 @@ func (c *initSidecar) getEnvVars() []corev1.EnvVar {
124127
getEnvVarFromSecret(sctNamebackup, "S3_BUCKET", "s3-bucket", true),
125128
)
126129
}
127-
130+
if len(c.Spec.RestoreFromNFS) != 0 {
131+
envs = append(envs, corev1.EnvVar{
132+
Name: "RESTORE_FROM_NFS",
133+
Value: c.Spec.RestoreFromNFS,
134+
})
135+
}
128136
if c.Spec.MysqlOpts.InitTokuDB {
129137
envs = append(envs, corev1.EnvVar{
130138
Name: "INIT_TOKUDB",
@@ -194,6 +202,15 @@ func (c *initSidecar) getVolumeMounts() []corev1.VolumeMount {
194202
)
195203
}
196204

205+
if len(c.Spec.RestoreFromNFS) != 0 {
206+
volumeMounts = append(volumeMounts,
207+
corev1.VolumeMount{
208+
Name: utils.XtrabackupPV,
209+
MountPath: utils.XtrabckupLocal,
210+
},
211+
)
212+
}
213+
197214
if c.Spec.Persistence.Enabled {
198215
volumeMounts = append(volumeMounts,
199216
corev1.VolumeMount{

cluster/syncer/follower_service.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,17 @@ func NewFollowerSVCSyncer(cli client.Client, c *cluster.Cluster) syncer.Interfac
5151
service.Spec.Selector["role"] = "follower"
5252
service.Spec.Selector["healthy"] = "yes"
5353

54-
if len(service.Spec.Ports) != 1 {
55-
service.Spec.Ports = make([]corev1.ServicePort, 1)
54+
if len(service.Spec.Ports) != 2 {
55+
service.Spec.Ports = make([]corev1.ServicePort, 2)
5656
}
5757

5858
service.Spec.Ports[0].Name = utils.MysqlPortName
5959
service.Spec.Ports[0].Port = utils.MysqlPort
6060
service.Spec.Ports[0].TargetPort = intstr.FromInt(utils.MysqlPort)
61+
// xtrabackup
62+
service.Spec.Ports[1].Name = utils.XBackupPortName
63+
service.Spec.Ports[1].Port = utils.XBackupPort
64+
service.Spec.Ports[1].TargetPort = intstr.FromInt(utils.XBackupPort)
6165
return nil
6266
})
6367
}

cluster/syncer/leader_service.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,18 @@ func NewLeaderSVCSyncer(cli client.Client, c *cluster.Cluster) syncer.Interface
5050
service.Spec.Selector = c.GetSelectorLabels()
5151
service.Spec.Selector["role"] = "leader"
5252

53-
if len(service.Spec.Ports) != 1 {
54-
service.Spec.Ports = make([]corev1.ServicePort, 1)
53+
if len(service.Spec.Ports) != 2 {
54+
service.Spec.Ports = make([]corev1.ServicePort, 2)
5555
}
5656

5757
service.Spec.Ports[0].Name = utils.MysqlPortName
5858
service.Spec.Ports[0].Port = utils.MysqlPort
5959
service.Spec.Ports[0].TargetPort = intstr.FromInt(utils.MysqlPort)
60+
61+
// xtrabackup
62+
service.Spec.Ports[1].Name = utils.XBackupPortName
63+
service.Spec.Ports[1].Port = utils.XBackupPort
64+
service.Spec.Ports[1].TargetPort = intstr.FromInt(utils.XBackupPort)
6065
return nil
6166
})
6267
}

0 commit comments

Comments
 (0)