使用local-pvc部署mysql主从数据库

使用local-storage来部署mysql

先创建local-storageclass,需要现在对应的机器上创建对应的目录 {1883F049-2684-4B45-A56B-AA1CD5EAD716}.png 注意这里一个是local-storageclass,是需要先创建好的,另外一个就是hostpath,也要存在并且手动创建好。

接下来是mysql-statefulsettest这个文件,这个文件就是创建mysql主从列表

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
cat mysql-statefulset.yml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: mysql-new
  labels:
    app: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 2
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
        - name: init-mysql
          image: www.harbortest.mobi/mysql/mysql:8.0.26
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
          command:
            - bash
            - "-c"
            - |
              set -ex
              # 从 Pod 的序号,生成 server-id
              [[ $(hostname) =~ -([0-9]+)$ ]] || exit 1
              ordinal=${BASH_REMATCH[1]}
              echo [mysqld] > /mnt/conf.d/server-id.cnf
              # 由于 server-id 不能为 0,因此给 ID 加 100 来避开它
              echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
              # 如果 Pod 的序号为 0,说明它是 Master 节点,从 ConfigMap 里把 Master 的配置文件拷贝到 /mnt/conf.d 目录下
              # 否则,拷贝 ConfigMap 里的 Slave 的配置文件
              if [[ ${ordinal} -eq 0 ]]; then
                cp /mnt/config-map/master.cnf /mnt/conf.d
              else
                cp /mnt/config-map/slave.cnf /mnt/conf.d
              fi              
          volumeMounts:
            - name: conf
              mountPath: /mnt/conf.d
            - name: config-map
              mountPath: /mnt/config-map
        - name: clone-mysql
          image: www.harbortest.mobi/mysql/xtrabackup:8.0.29
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
          command:
            - bash
            - "-c"
            - |
              set -ex
              # 拷贝操作只需要在第一次启动时进行,所以数据已经存在则跳过
              [[ -d /var/lib/mysql/mysql ]] && exit 0
              # Master 节点(序号为 0)不需要这个操作
              [[ $(hostname) =~ -([0-9]+)$ ]] || exit 1
              ordinal=${BASH_REMATCH[1]}
              [[ $ordinal == 0 ]] && exit 0
              # 使用 ncat 指令,远程地从前一个节点拷贝数据到本地
              ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
              # 执行 --prepare,这样拷贝来的数据就可以用作恢复了
              xtrabackup --prepare --target-dir=/var/lib/mysql              
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
              subPath: mysql
            - name: conf
              mountPath: /etc/mysql/conf.d
      containers:
        - name: mysql
          image: www.harbortest.mobi/mysql/mysql:8.0.26
          args: ["--default-authentication-plugin=mysql_native_password"]
          env:
            - name: MYSQL_ALLOW_EMPTY_PASSWORD
              value: "1"
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
          ports:
            - name: mysql
              containerPort: 3306
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
              subPath: mysql
            - name: conf
              mountPath: /etc/mysql/conf.d
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
            limits:
              cpu: 500m
              memory: 1Gi
          livenessProbe: #存活探针健康检测
            exec:
              command:
                - /bin/sh
                - "-c"
                - MYSQL_PWD="${MYSQL_ROOT_PASSWORD}"
                - mysqladmin ping
            #tcpSocket:
            #port: 3306
            initialDelaySeconds: 30
            periodSeconds: 10
            timeoutSeconds: 5
          readinessProbe: #就绪探针健康检测
            exec:
              command:
                - /bin/sh
                - "-c"
                - MYSQL_PWD="${MYSQL_ROOT_PASSWORD}"
                - mysql -h 127.0.0.1 -u root -e "SELECT 1"
            #tcpSocket:
            # port: 3306
            initialDelaySeconds: 5
            periodSeconds: 2
            timeoutSeconds: 1
        - name: xtrabackup
          image: www.harbortest.mobi/mysql/xtrabackup:8.0.29
          ports:
            - name: xtrabackup
              containerPort: 3307
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
          command:
            - bash
            - "-c"
            - |
              set -ex
              cd /var/lib/mysql
              # 从备份信息文件里读取 MASTER_LOG_FILE 和 MASTER_LOG_POS 这 2 个字段的值,用来拼装集群初始化 SQL
              if [[ -f xtrabackup_slave_info ]]; then
                # 如果 xtrabackup_slave_info 文件存在,说明这个备份数据来自于另一个 Slave 节点
                # 这种情况下,XtraBackup 工具在备份的时候,就已经在这个文件里自动生成了 "CHANGE MASTER TO" SQL 语句
                # 所以,只需要把这个文件重命名为 change_master_to.sql.in,后面直接使用即可
                mv xtrabackup_slave_info change_master_to.sql.in
                # 所以,也就用不着 xtrabackup_binlog_info 了
                rm -f xtrabackup_binlog_info
              elif [[ -f xtrabackup_binlog_info ]]; then
                # 如果只是存在 xtrabackup_binlog_info 文件,说明备份来自于 Master 节点,就需要解析这个备份信息文件,读取所需的两个字段的值
                [[ $(cat xtrabackup_binlog_info) =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
                rm xtrabackup_binlog_info
                # 把两个字段的值拼装成 SQL,写入 change_master_to.sql.in 文件
                echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
                      MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
              fi
              # 如果存在 change_master_to.sql.in,就意味着需要做集群初始化工作
              if [[ -f change_master_to.sql.in ]]; then
                # 但一定要先等 MySQL 容器启动之后才能进行下一步连接 MySQL 的操作
                echo "Waiting for mysqld to be ready(accepting connections)"
                until mysql -h 127.0.0.1 -uroot -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"; do sleep 1; done
                echo "Initializing replication from clone position"
                # 将文件 change_master_to.sql.in 改个名字
                # 防止这个 Container 重启的时候,因为又找到了 change_master_to.sql.in,从而重复执行一遍初始化流程
                mv change_master_to.sql.in change_master_to.sql.orig
                # 使用 change_master_to.sql.orig 的内容,也就是前面拼装的 SQL,组成一个完整的初始化和启动 Slave 的 SQL 语句
                mysql -h 127.0.0.1 -uroot -p${MYSQL_ROOT_PASSWORD} << EOF
              $(< change_master_to.sql.orig),
                MASTER_HOST='mysql-0.mysql.mysql',
                MASTER_USER='root',
                MASTER_PASSWORD='${MYSQL_ROOT_PASSWORD}',
                MASTER_CONNECT_RETRY=10;
              START SLAVE;
              EOF
              fi
              # 使用 ncat 监听 3307 端口。
              # 它的作用是,在收到传输请求的时候,直接执行 xtrabackup --backup 命令,备份 MySQL 的数据并发送给请求者
              exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
                "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=${MYSQL_ROOT_PASSWORD}"              
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
              subPath: mysql
            - name: conf
              mountPath: /etc/mysql/conf.d
      volumes:
        - name: conf
          emptyDir: {}
        - name: config-map
          configMap:
            name: mysql
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
          - "ReadWriteMany"
        storageClassName: local-storage
        resources:
          requests:
            storage: 5Gi

注意1:storageclassName、注意2 storage大小这里需要和声明的pv的大小是一样的 另外要注意到两个文件: configmap的配置文件,这个文件里面放的是主从的配置文件,在部署过程中会采用configmap来对应的文件的方式。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  namespace: mysql-new
  labels:
    app: mysql
data:
  master.cnf: |
    # Master配置
    [mysqld]
    log-bin
    bind-address=0.0.0.0    
  slave.cnf: |
    # Slave配置
    [mysqld]
    super-read-only
    bind-address=0.0.0.0    

配置mysql的用户名和密码,是使用的secret的方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  namespace: mysql-new
  labels:
    app: mysql
type: Opaque
data:
  password: ********** 

这个password是用base64编码的方式提供的。 接下来需要对mysql进行测试: 先查看主库master image.png

1
change master to master_host='mysql-0.mysql',master_user='root',master_password='12345678',master_log_file='mysql-0-bin.000001',master_log_pos=156,master_port=3306;

输入这命令后,start slave 来启动同步,输入show slave status,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: mysql-0.mysql
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-0-bin.000001
          Read_Master_Log_Pos: 156
               Relay_Log_File: mysql-1-relay-bin.000002
                Relay_Log_Pos: 326
        Relay_Master_Log_File: mysql-0-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 156
              Relay_Log_Space: 537
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 100
                  Master_UUID: ec2184fc-f280-11ef-b428-eedb23c7dcf5
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)
1
pt-heartbeat h='10.7.20.199',u='root',p='123456',P=30316   -D test --create-table --update  --daemonize

从库测试

1
bin/pt-heartbeat h='10.7.20.199',u='pt_checksum',p='123456',P=30316 -D test --table=heartbeat --monitor --master-server-id=100 --frames=1m,2m,3m,4m

注意查看server-id {022798CC-AE99-4BBA-8546-3C4A96963077}.png 从库看实验输出如下所示: {DF3E003C-817E-4505-AF98-1AED87F25405}.png 查看 ps -ef|grep heartbeat`,可以看到pt-heatbeat。 可以看到主从延迟0ms。

Licensed under CC BY-NC-SA 4.0
最后更新于 Apr 11, 2025 07:19 UTC
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计
Caret Up