Skip to content

Commit 6e7beba

Browse files
committed
add the disaster function code
1 parent 2e20c17 commit 6e7beba

19 files changed

+529
-21
lines changed

api/v1alpha1/mysqlcluster_types.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ type MysqlClusterSpec struct {
117117
// Bootstraping from remote data source
118118
// +optional
119119
SourceConfig *corev1.SecretProjection `json:"sourceConfig,omitempty"`
120-
120+
// remote replica source
121+
RemoteCluster *RemoteSourceStruct `json:"remoteCluster,omitempty"`
121122
// Leader as follower represents if make leader use as follower to read
122123
// +optional
123124
// +kubebuilder:default:=false
@@ -140,6 +141,11 @@ type ReadOnlyType struct {
140141
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
141142
}
142143

144+
type RemoteSourceStruct struct {
145+
Name string `json:"name"`
146+
NameSpace string `json:"namespace"`
147+
}
148+
143149
// MysqlOpts defines the options of MySQL container.
144150
type MysqlOpts struct {
145151
// Specifies mysql image to use.
@@ -366,7 +372,18 @@ const (
366372

367373
// ClusterConditionType defines type for cluster condition type.
368374
type ClusterConditionType string
375+
type ClusterConditionsIndex uint8
369376

377+
const (
378+
ClIndexInit ClusterConditionsIndex = iota
379+
ClIndexUpdate
380+
ClIndexReady
381+
ClIndexClose
382+
ClIndexError
383+
ClIndexScaleIn
384+
ClIndexScaleOut
385+
ClIndexRemoteSlave
386+
)
370387
const (
371388
// ConditionInit indicates whether the cluster is initializing.
372389
ConditionInit ClusterConditionType = "Initializing"
@@ -382,6 +399,8 @@ const (
382399
ConditionScaleIn ClusterConditionType = "ScaleIn"
383400
// ConditionScaleOut indicates whether the cluster replicas is increasing.
384401
ConditionScaleOut ClusterConditionType = "ScaleOut"
402+
// is it a slave for Remote cluster?
403+
ConditionRemoteSlave ClusterConditionType = "RemoteSlave"
385404
)
386405

387406
// ClusterCondition defines type for cluster conditions.

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta1/mysqlcluster_conversion.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ func Convert_v1alpha1_MysqlClusterSpec_To_v1beta1_MysqlClusterSpec(in *v1alpha1.
9898
if in.SourceConfig != nil {
9999
out.DataSource.Remote.SourceConfig = in.SourceConfig
100100
}
101+
if in.RemoteCluster != nil {
102+
out.DataSource.Remote.RemoteCluster = (*RemoteSourceStruct)(in.RemoteCluster)
103+
}
101104
if len(in.NFSServerAddress) != 0 {
102105
ipStr := strings.Split(in.NFSServerAddress, ":")
103106
out.DataSource.RestorePoint = in.RestorePoint
@@ -165,6 +168,9 @@ func Convert_v1beta1_MysqlClusterSpec_To_v1alpha1_MysqlClusterSpec(in *MysqlClus
165168
if in.DataSource.Remote.SourceConfig != nil {
166169
out.SourceConfig = in.DataSource.Remote.SourceConfig
167170
}
171+
if in.DataSource.Remote.RemoteCluster != nil {
172+
out.RemoteCluster = (*v1alpha1.RemoteSourceStruct)(in.DataSource.Remote.RemoteCluster)
173+
}
168174
if len(in.DataSource.S3Backup.Name) != 0 {
169175
out.RestoreFrom = in.DataSource.S3Backup.Name
170176
out.BackupSecretName = in.DataSource.S3Backup.SecretName

api/v1beta1/mysqlcluster_types.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ const (
276276
ConditionScaleIn ClusterConditionType = "ScaleIn"
277277
// ConditionScaleOut indicates whether the cluster replicas is increasing.
278278
ConditionScaleOut ClusterConditionType = "ScaleOut"
279+
280+
// is it a slave for Remote cluster?
281+
ConditionRemoteSlave ClusterConditionType = "RemoteSlave"
279282
)
280283

281284
// ClusterCondition defines type for cluster conditions.
@@ -438,10 +441,15 @@ type DataSource struct {
438441
// +optional
439442
RestorePoint string `json:"restorePoint"`
440443
}
441-
444+
type RemoteSourceStruct struct {
445+
Name string `json:"name"`
446+
NameSpace string `json:"namespace"`
447+
}
442448
type RemoteDataSource struct {
443-
//
449+
// xtrabackup remote source
444450
SourceConfig *corev1.SecretProjection `json:"sourceConfig,omitempty"`
451+
// remote replica source
452+
RemoteCluster *RemoteSourceStruct `json:"remoteCluster,omitempty"`
445453
}
446454

447455
type S3BackupDataSource struct {

api/v1beta1/zz_generated.conversion.go

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/mysql.radondb.com_mysqlclusters.yaml

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,6 +2246,17 @@ spec:
22462246
required:
22472247
- num
22482248
type: object
2249+
remoteCluster:
2250+
description: remote replica source
2251+
properties:
2252+
name:
2253+
type: string
2254+
namespace:
2255+
type: string
2256+
required:
2257+
- name
2258+
- namespace
2259+
type: object
22492260
replicas:
22502261
default: 3
22512262
description: Replicas is the number of pods.
@@ -3503,12 +3514,19 @@ spec:
35033514
remote:
35043515
description: Bootstraping from remote data source
35053516
properties:
3517+
remoteCluster:
3518+
description: remote replica source
3519+
properties:
3520+
name:
3521+
type: string
3522+
namespace:
3523+
type: string
3524+
required:
3525+
- name
3526+
- namespace
3527+
type: object
35063528
sourceConfig:
3507-
description: "Adapts a secret into a projected volume. \n
3508-
The contents of the target Secret's Data field will be presented
3509-
in a projected volume as files using the keys in the Data
3510-
field as the file names. Note that this is identical to
3511-
a secret volume source without the default mode."
3529+
description: xtrabackup remote source
35123530
properties:
35133531
items:
35143532
description: If unspecified, each key-value pair in the

controllers/mysqlcluster_controller.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ func (r *MysqlClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request
164164
clustersyncer.NewXenonCMSyncer(r.Client, instance),
165165
)
166166
}
167+
168+
if instance.Spec.RemoteCluster != nil {
169+
syncers = append(syncers, clustersyncer.NewRemoteClusterCMSyncer(r.Client, instance))
170+
}
167171
if instance.Spec.MetricsOpts.Enabled {
168172
syncers = append(syncers, clustersyncer.NewMetricsSVCSyncer(r.Client, instance))
169173
}

internal/sql_runner.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ type sqlRunner struct {
117117
type SQLRunner interface {
118118
QueryExec(query Query) error
119119
QueryRow(query Query, dest ...interface{}) error
120+
QueryRowContext(ctx context.Context, query Query, dest ...interface{}) error
120121
QueryRows(query Query) (*sql.Rows, error)
122+
QueryRowsContext(ctx context.Context, query Query) (*sql.Rows, error)
121123
}
122124

123125
type closeFunc func()
@@ -168,10 +170,24 @@ func (s sqlRunner) QueryExec(query Query) error {
168170
return nil
169171
}
170172

173+
// QueryExec used to run the query with args.
174+
func (s sqlRunner) ExecContext(ctx context.Context, query Query) error {
175+
if _, err := s.db.ExecContext(ctx, query.String(), query.args...); err != nil {
176+
return err
177+
}
178+
179+
return nil
180+
}
181+
171182
func (s sqlRunner) QueryRow(query Query, dest ...interface{}) error {
172183
return s.db.QueryRow(query.escapedQuery, query.args...).Scan(dest...)
173184
}
174185

186+
// QueryExec used to run the query with args.
187+
func (s sqlRunner) QueryRowContext(ctx context.Context, query Query, dest ...interface{}) error {
188+
return s.db.QueryRowContext(ctx, query.String(), query.args...).Scan(dest...)
189+
}
190+
175191
func (s sqlRunner) QueryRows(query Query) (*sql.Rows, error) {
176192
rows, err := s.db.Query(query.escapedQuery, query.args...)
177193
if err != nil {
@@ -181,6 +197,15 @@ func (s sqlRunner) QueryRows(query Query) (*sql.Rows, error) {
181197
return rows, rows.Err()
182198
}
183199

200+
func (s sqlRunner) QueryRowsContext(ctx context.Context, query Query) (*sql.Rows, error) {
201+
rows, err := s.db.QueryContext(ctx, query.escapedQuery, query.args...)
202+
if err != nil {
203+
return nil, err
204+
}
205+
206+
return rows, rows.Err()
207+
}
208+
184209
// CheckSlaveStatusWithRetry check the slave status with retry time.
185210
func CheckSlaveStatusWithRetry(sqlRunner SQLRunner, retry uint32, replicaLag *int32) (isLagged, isReplicating corev1.ConditionStatus, err error) {
186211
for {
@@ -202,8 +227,11 @@ func CheckSlaveStatusWithRetry(sqlRunner SQLRunner, retry uint32, replicaLag *in
202227
// CheckSlaveStatus check the slave status.
203228
func CheckSlaveStatus(sqlRunner SQLRunner, ReplicaLag *int32) (isLagged, isReplicating corev1.ConditionStatus, err error) {
204229
var rows *sql.Rows
230+
231+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
232+
defer cancel()
205233
isLagged, isReplicating = corev1.ConditionUnknown, corev1.ConditionUnknown
206-
rows, err = sqlRunner.QueryRows(NewQuery("show slave status;"))
234+
rows, err = sqlRunner.QueryRowsContext(ctx, NewQuery("show slave status;"))
207235
if err != nil {
208236
return
209237
}
@@ -287,12 +315,16 @@ func CheckReadOnly(sqlRunner SQLRunner) (corev1.ConditionStatus, error) {
287315

288316
// GetGlobalVariable used to get the global variable by param.
289317
func GetGlobalVariable(sqlRunner SQLRunner, param string, val interface{}) error {
290-
return sqlRunner.QueryRow(NewQuery("select @@global.?", param), val)
318+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
319+
defer cancel()
320+
return sqlRunner.QueryRowContext(ctx, NewQuery("select @@global.?", param), val)
291321
}
292322

293323
func CheckProcesslist(sqlRunner SQLRunner) (bool, error) {
324+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
325+
defer cancel()
294326
var rows *sql.Rows
295-
rows, err := sqlRunner.QueryRows(NewQuery("show processlist;"))
327+
rows, err := sqlRunner.QueryRowsContext(ctx, NewQuery("show processlist;"))
296328
if err != nil {
297329
return false, err
298330
}

mysqlcluster/container/init_sidecar.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,18 @@ func (c *initSidecar) getEnvVars() []corev1.EnvVar {
153153
Value: "1",
154154
})
155155
}
156+
157+
if c.Spec.RemoteCluster != nil {
158+
envs = append(envs, corev1.EnvVar{
159+
Name: "REMOTE_CLUSTER_NAME",
160+
Value: c.Spec.RemoteCluster.Name,
161+
}, corev1.EnvVar{
162+
Name: "REMOTE_CLUSTER_NAMESPACE",
163+
Value: c.Spec.RemoteCluster.NameSpace,
164+
})
165+
166+
}
167+
156168
return envs
157169
}
158170

@@ -264,5 +276,12 @@ func (c *initSidecar) getVolumeMounts() []corev1.VolumeMount {
264276
MountPath: utils.RemoteSourcePath,
265277
})
266278
}
279+
if c.Spec.RemoteCluster != nil {
280+
volumeMounts = append(volumeMounts,
281+
corev1.VolumeMount{
282+
Name: utils.RemoteClusterCMVolumeName,
283+
MountPath: utils.RemoteClusterCMMountPath,
284+
})
285+
}
267286
return volumeMounts
268287
}

0 commit comments

Comments
 (0)