Skip to content

Commit 4e26d8e

Browse files
committed
Minor Edits
1 parent 363ff3c commit 4e26d8e

1 file changed

Lines changed: 55 additions & 52 deletions

File tree

  • docs/guides/databases/mysql/cross-site-replication-of-mysql-db-on-lke

docs/guides/databases/mysql/cross-site-replication-of-mysql-db-on-lke/index.md

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ external_resources:
1515

1616
Cross-site replication is a database pattern where changes written to a primary database in one location are copied to one or more replica databases in another location. In MySQL, this is commonly used to maintain a remote read-only copy of production data for disaster recovery testing, reporting, analytics, or standby capacity.
1717

18-
This guide uses Skupper to provide cross-site connectivity across Linode Kubernetes Engine (LKE) clusters in different regions. Skupper creates a secure application network between Kubernetes clusters. It allows workloads in one cluster to reach selected services in another cluster without requiring direct Pod-to-Pod networking or a custom VPN. In this guide, Skupper exposes the writable MySQL primary in `site-1` to the MySQL Pods in `site-2` by using a shared service name.
18+
This guide uses Skupper to connect Linode Kubernetes Engine (LKE) clusters in different regions. Skupper creates a secure application network between Kubernetes clusters. It allows workloads in one cluster to reach selected services in another cluster without requiring direct Pod-to-Pod networking or a custom VPN. In this guide, Skupper exposes the writable MySQL primary in `site-1` to the MySQL Pods in `site-2` by using a shared service name.
1919

2020
This solves a specific problem for MySQL deployed across LKE regions. The source and destination databases live in separate Kubernetes clusters with separate internal networks. The approach in this guide combines Skupper for connectivity, the MySQL Clone plugin for initial seeding, and GTID-based replication for ongoing change streaming.
2121

@@ -47,7 +47,7 @@ This guide demonstrates a one-way replication setup from site-1 to site-2. It do
4747

4848
### Placeholders
4949

50-
This tutorial contains a number of placeholders that are intended to be replaced by values from your own environment. The table below lists these placeholders, what they represent, and the example values used in this guide:
50+
Replace the following placeholders with values from your own environment:
5151

5252
| Placeholder | Description | Example |
5353
| -- | -- | -- |
@@ -68,7 +68,7 @@ Additionally, this guide uses the following fixed example values consistently th
6868

6969
### Configure `kubectl` Contexts
7070

71-
If you followed the guides linked above, you should have already installed `kubectl` and set up kubeconfig. For simplicity, rename these contexts to `site-1` and `site-2`, respectively.
71+
If you followed the guides linked above, you should already have `kubectl` installed and both cluster contexts available in your local kubeconfig. For simplicity, rename these contexts to `site-1` and `site-2`, respectively.
7272

7373
1. Use `kubectl` to list your context names:
7474

@@ -139,13 +139,13 @@ This tutorial uses Skupper v2. The commands in this section are not compatible w
139139
```
140140

141141
```output
142-
COMPONENT VERSION
143-
router 3.4.2
144-
controller 2.1.3
145-
network-observer 2.1.3
146-
cli 2.1.3
147-
prometheus v2.42.0
148-
origin-oauth-proxy 4.14.0
142+
COMPONENT VERSION
143+
router 3.4.2
144+
controller 2.1.3
145+
network-observer 2.1.3
146+
cli 2.1.3
147+
prometheus v2.42.0
148+
origin-oauth-proxy 4.14.0
149149
```
150150

151151
{{< note >}}
@@ -214,7 +214,7 @@ If you are using a Cloud Firewall, ensure that site-1 allows inbound TCP port `9
214214
```output
215215
Waiting for token status ...
216216
217-
Grant "site-1-a4c9d2f3-7b81-4e6a-9d2f-3c7b8e1a6f40" is ready
217+
Grant "<grant-id>" is ready
218218
Token file ~/site1.token created
219219
220220
Transfer this file to a remote site. At the remote site,
@@ -233,7 +233,7 @@ If you are using a Cloud Firewall, ensure that site-1 allows inbound TCP port `9
233233

234234
```output
235235
Waiting for token status ...
236-
Token "site-1-a4c9d2f3-7b81-4e6a-9d2f-3c7b8e1a6f40" has been redeemed
236+
Token "<grant-id>" has been redeemed
237237
```
238238

239239
1. Before deploying the MySQL replication components, verify that the Skupper link between the clusters is active:
@@ -246,7 +246,7 @@ If you are using a Cloud Firewall, ensure that site-1 allows inbound TCP port `9
246246

247247
```output
248248
NAME STATUS COST MESSAGE
249-
site-1-a4c9d2f3-7b81-4e6a-9d2f-3c7b8e1a6f40 Ready 1 OK
249+
<grant-id> Ready 1 OK
250250
```
251251

252252
## Deploy MySQL Configuration
@@ -319,7 +319,7 @@ The MySQL configuration is stored in a Kubernetes ConfigMap so that both cluster
319319
mysql 2 25s
320320
```
321321

322-
## Deploy the MySQL Services
322+
## Deploy MySQL Services
323323

324324
The MySQL Service provides the stable network identity required by the StatefulSets in each cluster. The headless `mysql` Service provides predictable DNS names for each Pod so that MySQL instances can communicate directly for replication and management tasks.
325325

@@ -382,7 +382,7 @@ The MySQL Service provides the stable network identity required by the StatefulS
382382

383383
At this point, both clusters have the same Service layout. The StatefulSets in the next steps use the headless `mysql` Service for stable Pod-to-Pod communication and replication traffic within each cluster.
384384

385-
## Deploy MySQL StatefulSet (site-1)
385+
## Deploy site-1 MySQL StatefulSet
386386

387387
Deploy the MySQL StatefulSet in site-1 to create the primary MySQL cluster. In this cluster, `mysql-0` is configured as the writable primary, while `mysql-1` and `mysql-2` are configured as replica candidates. Replication is configured in a later section after the required MySQL users are created.
388388

@@ -494,19 +494,16 @@ Deploy the MySQL StatefulSet in site-1 to create the primary MySQL cluster. In t
494494
```
495495

496496
```output
497-
NAME READY STATUS RESTARTS AGE
498-
mysql-0 1/1 Running 0 3m9s
499-
mysql-1 1/1 Running 1 (86s ago) 2m29s
500-
mysql-2 1/1 Running 1 (46s ago) 102s
501-
skupper-router-7b56568444-p6686 2/2 Running 0 9m42s
497+
NAME READY STATUS RESTARTS AGE
498+
mysql-0 1/1 Running 0 <minutes>
499+
mysql-1 1/1 Running 1 (<minutes> ago) <minutes>
500+
mysql-2 1/1 Running 1 (<minutes> ago) <minutes>
501+
skupper-router-7b56568444-p6686 2/2 Running 0 <minutes>
502502
```
503503

504504
## Create Replication and Clone Users
505505

506-
Before configuring replication between the clusters, create the MySQL accounts required for replication and cloning. This guide uses the account names `repl` and `cloner` throughout:
507-
508-
- A replication user that replicas use to read binary logs from the primary.
509-
- A clone user used by the MySQL Clone plugin when seeding replicas.
506+
Before configuring replication between the clusters, create the MySQL accounts required for replication and cloning. This guide uses the account names `repl` and `cloner` throughout.
510507

511508
These users are created on the primary database (`mysql-0`) in site-1.
512509

@@ -592,11 +589,11 @@ These users are created on the primary database (`mysql-0`) in site-1.
592589
repl %
593590
```
594591

595-
## Configure Clone Initialization (site-2)
592+
## Prepare Site-2 for Cloning
596593

597594
The site-2 Pods rely on a MySQL initialization script to install the Clone plugin and configure cloning during first startup. Because MySQL initialization scripts only run when the data directory is first created, this ConfigMap must be created before deploying the site-2 StatefulSet.
598595

599-
This guide also uses the fixed listener name `mysql-primary` and the fixed clone user name `cloner` throughout the remaining sections.
596+
This guide also uses the fixed listener name `mysql-primary`.
600597

601598
1. Create a ConfigMap containing the site-2 initialization SQL (e.g., `mysql-site2-init-configmap.yaml`):
602599

@@ -625,6 +622,8 @@ This guide also uses the fixed listener name `mysql-primary` and the fixed clone
625622
FLUSH PRIVILEGES;
626623
```
627624

625+
When done, save and close the file.
626+
628627
1. Apply the site-2 initialization ConfigMap:
629628

630629
```command
@@ -635,7 +634,7 @@ This guide also uses the fixed listener name `mysql-primary` and the fixed clone
635634
configmap/mysql-site2-init created
636635
```
637636

638-
## Deploy MySQL StatefulSet (site-2)
637+
## Deploy site-2 MySQL StatefulSet
639638

640639
Deploy the MySQL StatefulSet in site-2 to create the secondary MySQL cluster. In this cluster, all three Pods are configured as replica candidates. Each Pod starts with its MySQL configuration and persistent storage in place, but replication is configured after the replica data is seeded (covered later). This StatefulSet mounts the initialization ConfigMap so that each Pod is fully prepared for cloning upon first startup.
641640

@@ -748,10 +747,10 @@ Deploy the MySQL StatefulSet in site-2 to create the secondary MySQL cluster. In
748747

749748
```output
750749
NAME READY STATUS RESTARTS AGE
751-
mysql-0 1/1 Running 0 11m
752-
mysql-1 1/1 Running 0 10m
753-
mysql-2 1/1 Running 0 9m49s
754-
skupper-router-7565975cb5-94x8b 2/2 Running 0 113m
750+
mysql-0 1/1 Running 0 <minutes>
751+
mysql-1 1/1 Running 0 <minutes>
752+
mysql-2 1/1 Running 0 <minutes>
753+
skupper-router-7565975cb5-94x8b 2/2 Running 0 <minutes>
755754
```
756755

757756
## Seed Replicas Using Clone Plugin
@@ -772,18 +771,18 @@ The MySQL Clone plugin is used to seed the site-2 Pods with data from the primar
772771
Listener "mysql-primary" is configured.
773772
```
774773

775-
1. Wait for the site-2 Pods to return to the `Running` state:
774+
1. Confirm that the site-2 Pods are in the `Running` state before cloning:
776775

777776
```command
778777
kubectl --context site-2 get pods
779778
```
780779

781780
```output
782781
NAME READY STATUS RESTARTS AGE
783-
mysql-0 1/1 Running 0 18m
784-
mysql-1 1/1 Running 0 17m
785-
mysql-2 1/1 Running 0 16m
786-
skupper-router-7565975cb5-94x8b 2/2 Running 0 120m
782+
mysql-0 1/1 Running 0 <minutes>
783+
mysql-1 1/1 Running 0 <minutes>
784+
mysql-2 1/1 Running 0 <minutes>
785+
skupper-router-7565975cb5-94x8b 2/2 Running 0 <minutes>
787786
```
788787

789788
1. Run the clone operation on one Pod first (mysql-0):
@@ -806,18 +805,18 @@ The MySQL Clone plugin is used to seed the site-2 Pods with data from the primar
806805
This is expected. The clone operation replaces the data directory and triggers a restart. In this environment, Kubernetes handles that restart instead of MySQL.
807806
{{< /note >}}
808807

809-
1. Check if `mysql-0` restarted and wait for the Pod to return to the `Running` state:
808+
1. Wait for `mysql-0` to return to the `Running` state:
810809

811810
```command
812811
kubectl --context site-2 get pods
813812
```
814813

815814
```output
816-
NAME READY STATUS RESTARTS AGE
817-
mysql-0 1/1 Running 1 (40m ago) 60m
818-
mysql-1 1/1 Running 0 59m
819-
mysql-2 1/1 Running 0 59m
820-
skupper-router-7565975cb5-94x8b 2/2 Running 0 162m
815+
NAME READY STATUS RESTARTS AGE
816+
mysql-0 1/1 Running 1 (<minutes> ago) <minutes>
817+
mysql-1 1/1 Running 0 <minutes>
818+
mysql-2 1/1 Running 0 <minutes>
819+
skupper-router-7565975cb5-94x8b 2/2 Running 0 <minutes>
821820
```
822821
1. Verify that the clone completed successfully:
823822

@@ -835,9 +834,9 @@ The MySQL Clone plugin is used to seed the site-2 Pods with data from the primar
835834
ERROR_NO: 0
836835
BINLOG_FILE: mysql-bin.000003
837836
BINLOG_POSITION: 2270
838-
GTID_EXECUTED: 77a0ed51-26fe-11f1-b19c-16978697c802:1-13
839-
BEGIN_TIME: 2026-03-23 23:17:46.604
840-
END_TIME: 2026-03-23 23:17:54.435
837+
GTID_EXECUTED: <gtid-set>
838+
BEGIN_TIME: <timestamp>
839+
END_TIME: <timestamp>
841840
user host
842841
cloner %
843842
repl %
@@ -852,7 +851,7 @@ The MySQL Clone plugin is used to seed the site-2 Pods with data from the primar
852851
"
853852
```
854853

855-
1. Check if `mysql-1` restarted and wait for `mysql-1` to return to the `Running` state.
854+
1. Wait for `mysql-1` to return to the `Running` state.
856855

857856
```command
858857
kubectl --context site-2 get pods
@@ -868,6 +867,8 @@ The MySQL Clone plugin is used to seed the site-2 Pods with data from the primar
868867
"
869868
```
870869

870+
Confirm the same values shown for `mysql-0`.
871+
871872
1. Run the clone operation on `mysql-2`:
872873

873874
```command
@@ -877,7 +878,7 @@ The MySQL Clone plugin is used to seed the site-2 Pods with data from the primar
877878
"
878879
```
879880

880-
1. Check if `mysql-2` restarted and wait for `mysql-2` to return to the `Running` state:
881+
1. Wait for `mysql-2` to return to the `Running` state:
881882

882883
```command
883884
kubectl --context site-2 get pods
@@ -893,6 +894,8 @@ The MySQL Clone plugin is used to seed the site-2 Pods with data from the primar
893894
"
894895
```
895896

897+
Confirm the same values shown for `mysql-0`.
898+
896899
Only after `mysql-0`, `mysql-1`, and `mysql-2` have each been cloned and individually verified with `performance_schema.clone_status` should you proceed to the replication section.
897900

898901
## Enable Cross-Site Replication
@@ -931,7 +934,7 @@ After cloning the site-2 Pods from the primary in site-1, configure each site-2
931934
mountPath: /mnt/config-map
932935
```
933936

934-
Save and close the file when done.
937+
When done, save and close the file.
935938

936939
1. Apply the updated StatefulSet definition:
937940

@@ -1050,9 +1053,9 @@ After cross-site replication is enabled, verify that each site-2 Pod is actively
10501053

10511054
```output
10521055
Server_Id Host Port Source_Id Replica_UUID
1053-
202 3306 100 11da6a2e-270c-11f1-984d-5a8c68140dd6
1054-
201 3306 100 fc258ddf-270b-11f1-8cc5-1a122ea3d965
1055-
200 3306 100 e603a9da-270b-11f1-a0f4-76730864de28
1056+
202 3306 100 <replica-uuid>
1057+
201 3306 100 <replica-uuid>
1058+
200 3306 100 <replica-uuid>
10561059
```
10571060

10581061
1. Create a test database and table on the primary in site-1, then insert a row:
@@ -1076,7 +1079,7 @@ After cross-site replication is enabled, verify that each site-2 Pod is actively
10761079

10771080
```output
10781081
id message
1079-
1 replication works
1082+
1 replication works
10801083
```
10811084

10821085
If site-1 reports all three replicas and the test row appears on site-2, cross-site replication is working successfully.

0 commit comments

Comments
 (0)