Kubernetes集群部署之MySql8.0


部署前先考慮mysql在Kubernetes中需要的過程細節

 

維持MySql主從集群狀態需要依賴ip,而且配置好后是固定的,但是,在Kubernetes中pod重啟后ip就變了,而實時監控po ip又很困難。可不可以利用類似動態dns那種ip與域名自動映射,到時候直接用固定域名訪問不是就可以解決。所以可以借助COREDNS的能力。因為換了概念,把主從配置的ip換成域名。那么域名就需要是固定。

集群搭建,我需要對外提供四層服務那么就需要NodePort Service。而維持集群狀態,我需要集群發現功能。目的是把域名給我解析成地址,那么就要Headless Service

因為集群重啟有序,並且涉及數據持久化數據是獨立存儲,掛掉恢復或者重啟還能自動連接。那么結合最上面一條綜合考慮,滿足這些需求的就只剩sts(sts控制的pod與容器名字剛好就是sts.name + 編號)。因為deploy創建的pod名字與容器內名字不固定(命名規則:deploy.name+rs.name+hash)重啟po ip也會變,並且持久化也會因為重啟而且不能自動恢復,最嚴重啟動無序導致集群混亂異常。而恰恰這些原因都是部署集群最關注的地方。

 

 

 

組件縮寫:

 

deploy: Deployment

sts: StatefulSet

po: Pod

cm: ConfigMap

sc: StorageClass

pv: PersistentVolume

pvc: PersistentVolumeClaim

 

 

 

 

 

1、部署需求

 

1). 是主從復制集群

2). 有1個或者多個節點(本例單主)

3). 從節點可以橫向擴縮

4). 所有寫操作只能在主節點,讀在所有節點都可讀取

5). 如果MySql容器進程掛掉或主從異常能重啟自動恢復

6). 主節點掛掉能自動恢復

 

 

 

 

 

 

 

Master: write

Slave: read

Master index = 0

Slave index = 1 or 2

index根據hostname抓取后面的id取值即可,因為sts的pod內容器命名規則是sts name+id形成,id就可以作為索引。因為sts中pod啟動順序是有序的,所以不怕混亂,掛掉恢復也會保持。

 

 

Xtrabackup

 

 

注:都知道這個是mysql備份工具,有一點要注意,8.0版本不能備份之前版本的mysql,只能備份8.0以上的mysql數據庫

 

Xtrabackup備份后會生成一些文件

 

 

1)、 xtrabackup開頭的都是

[root@master mysql-statefulset-pod]# kubectl exec -it pod/mysql-0 -n mysql -c mysql -- bash root@mysql-1:/var/lib/mysql# ls
'#innodb_temp'   ca-key.pem                  ib_logfile0          mysql-0-bin.index private_key.pem undo_002 xtrabackup_master_key_id auto.cnf ca.pem ib_logfile1 mysql-1-relay-bin.000001 public_key.pem xtrabackup_backupfiles xtrabackup_slave_info backup-my.cnf   change_master_to.sql.orig   ibdata1              mysql-1-relay-bin.000002   server-cert.pem xtrabackup_binlog_info xtrabackup_tablespaces binlog.000001   client-cert.pem             ibtmp1               mysql-1-relay-bin.index    server-key.pem xtrabackup_checkpoints binlog.000002   client-key.pem mysql mysql.ibd sys xtrabackup_info binlog.index ib_buffer_pool mysql-0-bin.000004 performance_schema undo_001 xtrabackup_logfile root@mysql-1:/var/lib/mysql# 

 

 

2)、 備份的信息

root@mysql-1:/var/lib/mysql# cat xtrabackup_info uuid = 1668c169-a3d1-11eb-a3a8-72033cfab7a8 name = tool_name = xtrabackup tool_command = --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root tool_version = 8.0.9 ibbackup_version = 8.0.9 server_version = 8.0.19 start_time = 2021-04-23 01:13:12 end_time = 2021-04-23 01:13:18 lock_time = 0 binlog_pos = filename 'mysql-0-bin.000004', position '155' innodb_from_lsn = 0 innodb_to_lsn = 31267893 partial = N incremental = N format = xbstream compressed = N encrypted = N

 

 

3)、 主從CHANGE MASTER TO中的MASTER_LOG_FILE與MASTER_LOG_POS的信息就在這取

root@mysql-1:/var/lib/mysql# cat xtrabackup_binlog_info mysql-0-bin.000004      155

 

 

4)、 這個文件在恢復數據時會先檢查它,如果沒有就報錯。同樣這個在用xtrabackup增量備份的時候會檢查,其中的LAST_LSN如果大於這個值就開始增量備份

root@mysql-1:/var/lib/mysql# cat xtrabackup_checkpoints backup_type = full-prepared from_lsn = 0 to_lsn = 31267404 last_lsn = 31267414 flushed_lsn = 0

 

 

5)、 這個文件是空的,可以在后面判斷是主從復制時使用。是從主節點來的數據,還是從從節點來的數據。主節點過來的數據,雖然有這個文件但是文件是空的,而從節點過來的是有數據的。

root@mysql-1:/var/lib/mysql# cat xtrabackup_slave_info root@mysql-1:/var/lib/mysql# 

 

 

正文:

 

Kubernetes跑Mysql自動主從流程

 

 

1、 先從xtrabackup中截取MASTER_LOG_FILE and MASTER_LOG_POS

 

2、 判斷機器索引是否為0,如果是那么為0,那么就是主節點,跳過。否則就是從節點,那么就需要執行CHANGE MASTER TO配置。

 

3、啟動從節點

 

4、加入其他從節點

 

 

目前涉及有三個點:

 

 

1、主節點與從節點my.cnf配置不同需要區分開

 

2、節點之間需要傳輸數據

 

3、從節點第一次執行需要一些初始設定,而且重啟需要防止第一個從節點二次初始化。(例如:CHANGE MASTER TO)

 

 

 

 

 

先解決第一個問題

 

1)、 配置文件不同,那就在一個cm下以不同的key,定義不同的配置。然后根據判斷index后copy過去,可以用initcontainer搞這個事情

 

 

 

apiVersion: v1 kind: ConfigMap metadata: name: mysql namespace: mysql labels: app: mysql data: master.cnf: | [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [mysqld] log-bin binlog_expire_logs_seconds=2592000 max_connections=1000000 binlog_format=MIXED default-time-zone='+8:00' character-set-client-handshake=FALSE character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci' slave.cnf: | [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [mysqld] super-read-only max_connections=1000000 binlog_format=MIXED

  # 下面三條結尾介紹配置原因 relay_log_info_repository
=table master_info_repository=table relay_log_recovery = 1 default-time-zone='+8:00' character-set-client-handshake=FALSE character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'

 

 

判斷索引

initContainers:
- name: init-mysql
image: mysql:
8.0.19
imagePullPolicy: IfNotPresent
command:
- bash
- "-c"
- |
set
-ex

# 從hostname中去index,例子:mysql-0去的就是后邊的0。 [[ `
hostname` =~ -([0-9]+)$ ]] || exit 1

# BASH_REMATCH[x]取組,配合shell中的( )使用,匹配的括號內正則匹配的值。

# 取值賦給myinde變量,如果嚴格來寫,記得變量大寫。我比較懶,都小寫了。 myindex
=${BASH_REMATCH[1]}
      
echo [mysqld] > /mnt/conf.d/server-id.cnf

  
echo server-id=$((100 + ${myindex})) >> /mnt/conf.d/server-id.cnf

  
if [[ ${myindex} -eq 0 ]]; then
cp /mnt/config-map/master.cnf /mnt/conf.d/

else
cp /mnt/config-map/slave.cnf /mnt/conf.d/
fi

 

 

2)、 傳輸文件可以用ncat來進行

 

只接受文件,但是這個實際還有一層意思。是向mysql-[id] 3307發送請求。initcontainer下的clone-mysql

ncat --recv-only mysql-$((${myindex}-1)).mysql 3307

 

 

監聽3307端口,收到請求,只發送數據。container下的xtrabackup

 

exec ncat --listen --keep-open --send-only --max-conns=1 3307

 

 

3)、 從節點第一次執行需要一些初始設定,並防止重啟或恢復后二次初始化主從配置。(例如:CHANGE MASTER TO)

 

 

containers: - name: xtrabackup image: mzmuer/xtrabackup:1.0 imagePullPolicy: IfNotPresent ports: - name: xtrabackup containerPort: 3307 command: - bash - "-c"

  - | set -ex   

  # 進入數據目錄(或者說要備份或恢復的目錄) cd
/var/lib/mysql
  # 如果這個文件有數據,證明,這是從從節點傳輸過來的。(-s)如果有數據就成立

  # 如果沒有數據有xtrabackup_binlog_info,就會認為是從主節點過來的,但是若不是,會因為判斷錯誤導致change_master_to.sql.in再次被重寫,影響后續第一個從節點之后所有以后節點的主從配置(因為第二次copy的binlog中是slave的binlog信息與偏移量)

  # 所以xtrabackup_binlog_info這個存在會影響判斷變更結果,所以需要刪除。
if [[ -s xtrabackup_slave_info ]]; then

   # 直接改名 mv xtrabackup_slave_info change_master_to.sql.in
   # 如果不刪除會繼續下面elif的判斷,不刪除的條件成立會繼續執行導致文件變更。 rm -f xtrabackup_binlog_info    
   # 如果這個文件存在,證明數據是從主節點傳輸過來的。
elif [[ -f xtrabackup_binlog_info ]]; then
   # 那么,取其中值因為中間是空格分割所以用了[[:space:]]配合兩端()用BASH_REMATCH取值。 [[ `
cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1

   # 取到的值以換行回車方式存儲到change_master_to.sql.in echo -e "CHANGE MASTER TO\nMASTER_LOG_FILE='${BASH_REMATCH[1]}',\nMASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
   # 刪除為了如果容器重啟第一個從節點二次初始化。 rm -f xtrabackup_binlog_info fi if [[ -f change_master_to.sql.in ]]; then echo "Waiting for mysqld to be ready (accepting connections)" until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done echo "Initializing replication from clone position" mv change_master_to.sql.in change_master_to.sql.orig mysql -h 127.0.0.1 <<EOF $(<change_master_to.sql.orig), MASTER_HOST='mysql-0.mysql', MASTER_USER='repl', MASTER_PASSWORD='repl123.', MASTER_CONNECT_RETRY=10; START SLAVE; EOF echo "master slave config ok" fi

 

 

 

配置對外提供四層服務與維持集群狀態的Service(兩個)

 

 

apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: mysql
labels:
app: mysql
spec:
selector:
app: mysql
ports:
- name: mysql
port:
3306
clusterIP: None --- apiVersion: v1
kind: Service
metadata:
name: mysql
-read
namespace: mysql
labels:
app: mysql
spec:
selector:
app: mysql
ports:
- name: mysql
port:
3306

 

 

先寫主題框架:

 

 

 

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: mysql
spec:
replicas:
3
selector:
matchLabels:
app: mysql
serviceName: mysql
template:
metadata:
labels:
app: mysql
spec:

   # 初始化容器 initContainers:

   # 初始化master或slave配置文件用
- name: init-mysql
image: mysql:
8.0.19
   
   # 本地有鏡像就直接用沒有才下載 imagePullPolicy: IfNotPresent

   # 從節點復制備份文件用
- name: clone-mysql
image: mzmuer
/xtrabackup:1.0
imagePullPolicy: IfNotPresent
containers:

   # 主要服務容器
- name: mysql
image: mysql:
8.0.19
imagePullPolicy: IfNotPresent
ports:
   
   # 容器接口
- name: mysql
containerPort:
3306

   # master or slave初始化主從配置 - name: xtrabackup
image: mzmuer
/xtrabackup:1.0
imagePullPolicy: IfNotPresent
ports:
- name: xtrabackup
containerPort:
3307

   # 初始化配置文件所有的共享存儲 volumes:
- name: conf
emptyDir: {}
   
   # 數據文件存儲
- name: config-map
configMap:
   # cm的名字 name: mysql

# 創建pvc使用這個模板 volumeClaimTemplates:
- metadata:
name: data
spec:
   
   # 存儲類名字sc名 storageClassName:
"managed-nfs-storage"

   # 匹配pv的一個參數,讀寫權限 accessModes: [
"ReadWriteMany"]
resources:
requests:
     
     # 匹配pv的指標容量 storage: 10Gi

 

 

 

填寫初始化配置文件容器:

 

 

 

initContainers:
- name: init-mysql
image: mysql:
8.0.19
imagePullPolicy: IfNotPresent
command:
- bash
- "-c"
- |
set
-ex
[[ `
hostname` =~ -([0-9]+)$ ]] || exit 1
myindex=${BASH_REMATCH[1]}

  # 兩個細節兩個配置文件,第一個server-id.cnf里面記錄的是集群內的成員id用來區分實例。
echo [mysqld] > /mnt/conf.d/server-id.cnf

  # 向剛剛的server-id.cnf中寫入server-id=100+id。
echo server-id=$((100 + ${myindex})) >> /mnt/conf.d/server-id.cnf

  # 如果index為0,那么就拷貝cm中的master配置過去,其他就拷貝slave配置過去
if [[ ${myindex} -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

 

 

 

注:所有MySQL實例都要配置一個獨一無二的server-id。默認值為0,當server-id=0時,雖然會記錄二進制日志,如果在主節點,會拒絕所有的從節點連接。如果是從節點,會拒絕鏈接其他實例

server_id不能相同,因為用來決定是否執行event,相同就不執行

 

 

 

填寫初始化復制文件容器:

 

 

 

initContainers: - name: clone-mysql image: mzmuer/xtrabackup:1.0 imagePullPolicy: IfNotPresent command: - bash - "-c"

  - | set -ex   # 如果目錄存在證明已經有數據了,退出。否則執行下一個判斷。 [[ -d /var/lib/mysql/mysql ]] && exit 0   # 右側正則表達式如果不成立退出 [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 
  # 取上面正則表達式匹配的值 myindex
=${BASH_REMATCH[1]}   # 如果索引等於0是是主節點,退出 [[ ${myindex} -eq 0 ]] && exit 0   # 向mysql-[id] 3307 發起請求並只接受數據,且解壓數據到/var/lib/mysql中(x解壓C指定目錄) ncat --recv-only mysql-$((${myindex}-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
  # 恢復數據 xtrabackup
--prepare --target-dir=/var/lib/mysql # --redo-only 加了會導致未提交的事務不回滾 volumeMounts: - name: data mountPath: /var/lib/mysql subPath: mysql - name: conf mountPath: /etc/mysql/conf.d

 

 

填寫主服務容器:

 

 

 

containers: - name: mysql image: mysql:8.0.19 imagePullPolicy: IfNotPresent args: ["--default-authentication-plugin=mysql_native_password"] env: - name: MYSQL_ALLOW_EMPTY_PASSWORD value: "1" ports: - name: mysql containerPort: 3306 volumeMounts: - name: data mountPath: /var/lib/mysql subPath: mysql - name: conf mountPath: /etc/mysql/conf.d resources: requests: cpu: 250m memory: 256Mi limits: cpu: 500m memory: 512Mi livenessProbe: exec: command: ["mysqladmin", "ping"] initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: exec: command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"] initialDelaySeconds: 5 periodSeconds: 2 timeoutSeconds: 1

 

 

 

填寫初始化配置容器:

 

 

 

containers: - name: xtrabackup image: mzmuer/xtrabackup:1.0 imagePullPolicy: IfNotPresent ports: - name: xtrabackup containerPort: 3307 command: - bash - "-c"

    - | set -ex    # 進入數據目錄(或者說要備份或恢復的目錄) cd /var/lib/mysql
  

   # 如果這個文件有數據,證明,這是從從節點傳輸過來的。(-s)如果有數據就成立

 
         

   # 如果沒有數據有xtrabackup_binlog_info,就會認為是從主節點過來的,但是若不是,會因為判斷錯誤導致change_master_to.sql.in再次被重寫,影響后續第一個從節點之后所有以后節點的主從配置(因為第二次copy的binlog中是slave的binlog信息與偏移量)

 
         

   # 所以xtrabackup_binlog_info這個存在會影響判斷變更結果,所以需要刪除。

 if [[ -s xtrabackup_slave_info ]]; then
   # 直接改名 mv xtrabackup_slave_info change_master_to.sql.in
   # 如果不刪除會繼續下面elif的判斷,不刪除的條件成立會繼續執行導致文件變更。 rm -f xtrabackup_binlog_info
  # 如果這個文件存在,證明數據是從主節點傳輸過來的。
elif [[ -f xtrabackup_binlog_info ]]; then
   # 那么,取其中值因為中間是空格分割所以用了[[:space:]]配合兩端()用BASH_REMATCH取值。 [[ `
cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1

   # 取到的值以換行回車方式存儲到change_master_to.sql.in echo -e "CHANGE MASTER TO\nMASTER_LOG_FILE='${BASH_REMATCH[1]}',\nMASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
   # 刪除為了如果容器重啟第一個從節點二次重寫change_master_to.sql.in執行后續初始化 rm -f xtrabackup_binlog_info fi if [[ -f change_master_to.sql.in ]]; then echo "Waiting for mysqld to be ready (accepting connections)"
   # 檢測服務是否啟動 until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done echo "Initializing replication from clone position"   


   # 重命名防止重啟在此檢測初始化 mv change_master_to.sql.in change_master_to.sql.orig
   # 初始化主從配置 mysql
-h 127.0.0.1 <<EOF $(<change_master_to.sql.orig), MASTER_HOST='mysql-0.mysql', MASTER_USER='repl', MASTER_PASSWORD='repl123.', MASTER_CONNECT_RETRY=10; START SLAVE; EOF echo "master slave config ok" fi [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 myindex=${BASH_REMATCH[1]}
  # 如果是主節點配置主從同步賬戶
if [[ ${myindex} -eq 0 ]]; then mysql -h 127.0.0.1 <<EOF use mysql; delete from user where user='repl' and host='%';flush privileges; CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl123.'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';flush privileges; SELECT Host, User, plugin from mysql.user; EOF else
   # 獲取主從健康狀態 Slave_healthy
=`mysql -h 127.0.0.1 -e 'show slave status\G' 2> /dev/null |grep -E "Slave_IO_Running|Slave_SQL_Running"|awk '{print $2}'|grep -c Yes` if [[ ${Slave_healthy} -eq 2 ]]; then echo "master slave healthy ok"

   # 主從運行中需要停止刷新reloy_log然后開啟從節點 elif [[ ${Slave_healthy} -eq 1 ]]; then echo "master slave healthy no" mysql -h 127.0.0.1 <<EOF stop slave; reset slave; start slave; EOF echo "master slave healthy revert"
   # 主從為啟動可能是reloy_log還是上一個節點信息導致,直接刷新開啟從節點 elif [[ ${Slave_healthy} -eq 0 ]]; then echo "master slave healthy no" mysql -h 127.0.0.1 <<EOF reset slave; start slave; EOF echo "master slave healthy revert" fi fi
  # 監聽 3307 端口,如果收到請求。只發送備份數據。 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" volumeMounts: - name: data mountPath: /var/lib/mysql subPath: mysql - name: conf mountPath: /etc/mysql/conf.d resources: requests: cpu: 100m memory: 100Mi limits: cpu: 200m memory: 200Mi 

 

 

存儲用的nfs,但是安裝了插件使用了儲存類,如果出異常,排錯方法如下:

 

1、現在nfs服務端查看/etc/exports配置文件,沒有配置加配置

2、查看nfs服務狀態,如果正常。使用exportfs -v查看信息

3、如果nfs服務狀態異常,重啟服務記得先啟動rpcbind后啟動nfs

4、上述正常,在其他設備上showmount -e [nfs ip]查看nfs可用掛載目錄信息

 

都正常后,安裝rbac deployment 與 class待sc出現即可使用nfs存儲類

 

到此整體部署結束。

 

注:每次尾從節點有一個大坑。

 

 

如果CM配置文件slave.cnf部分沒有relay_log_info_repository=table、master_info_repository=table和relay_log_recovery=1那么最后一個從節點,始終不會正常,原因我說在下面。

 

 

 

 1 [root@master ~]# kubectl logs pod/mysql-2 -n mysql -c mysql  2 2021-04-23 08:53:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started.  3 2021-04-23 08:53:50+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
 4 2021-04-23 08:53:50+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started.  5 2021-04-23T08:53:50.504572Z 0 [Warning] [MY-000081] [Server] option 'max_connections': unsigned value 1000000 adjusted to 100000.  6 2021-04-23T08:53:50.969604Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.  7 2021-04-23T08:53:50.969742Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19) starting as process 1
 8 2021-04-23T08:53:52.853035Z 0 [System] [MY-010229] [Server] Starting XA crash recovery...  9 2021-04-23T08:53:52.867197Z 0 [System] [MY-010232] [Server] XA crash recovery finished. 10 2021-04-23T08:53:52.937037Z 0 [Warning] [MY-010075] [Server] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 6dda8985-a411-11eb-9ed4-f223f4afe76a. 11 2021-04-23T08:53:53.754834Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed. 12 2021-04-23T08:53:53.964524Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory. 13 2021-04-23T08:53:54.042613Z 0 [Warning] [MY-010604] [Repl] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=mysql-2-relay-bin' to avoid this problem. 14 2021-04-23T08:53:54.106498Z 0 [ERROR] [MY-010544] [Repl] Failed to open the relay log './mysql-1-relay-bin.000002' (relay_log_pos 204). 15 2021-04-23T08:53:54.106684Z 0 [ERROR] [MY-011059] [Repl] Could not find target log file mentioned in relay log info in the index file './mysql-2-relay-bin.index' during relay log initialization. 16 2021-04-23T08:53:54.111596Z 0 [ERROR] [MY-010426] [Repl] Slave: Failed to initialize the master info structure for channel ''; its record may still be present in 'mysql.slave_master_info' table, consider deleting it. 17 2021-04-23T08:53:54.111764Z 0 [ERROR] [MY-010529] [Repl] Failed to create or recover replication info repositories. 18 2021-04-23T08:53:54.114091Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.19'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL. 19 2021-04-23T08:53:54.177303Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
20 2021-04-23T08:53:54.449627Z 9 [System] [MY-010597] [Repl] 'CHANGE MASTER TO FOR CHANNEL '' executed'. Previous state master_host='mysql-0.mysql', master_port= 3306, master_log_file='mysql-0-bin.000004', master_log_pos= 155, master_bind=''. New state master_host='mysql-0.mysql', master_port= 3306, master_log_file='mysql-0-bin.000004', master_log_pos= 155, master_bind=''.

 

 

標注部分提示找不到mysql-2-relay-bin.index文件。不是沒有,但是不是在這個節點,是在上一個節點。因為是冷備文件恢復,所以導致Relay_log內容還是上一個節點的Relay_log,所以啟動必報錯。

而mysql-1-relay-bin.000002就是第一個從節點的Relay_log_name

 

1、relay log 文件:由IO thread線程從主庫讀取的二進制日志事件組成,該日志被Slave上的SQL thread線程執行,從而實現數據的復制。

 

2、master info log:該文件保存slave連接master的狀態以及配置信息。在my.cnf 配置master-info-repository=table使用。這些信息會被寫入slave_master_info 表中。替換早期版本的相關文件。

 

3、relay log info log:該文件保存slave上relay log的執行位置。在my.cnf中配置 relay-log-info-repository=table使用。用slave_relay_log_info表替換早期版本的相關文件。當slave上執行start slave時,就會讀取表中的位置信息。

 

使用表替換原來的文件,是為了崩潰后的安全復制。大大提高意外情況下從庫的可靠性。

 

 

reset slave作用:

 

 

1、刪除slave_master_info ,slave_relay_log_info兩個表中數據。


2、刪除所有relay log文件,並重新創建新的relay log文件。


3、不會改變gtid_executed 或者 gtid_purged的值。

 

 

 

relay_log_recovery

 

 

打開該參數,在數據庫啟動后立即啟動自動relay log恢復。在恢復過程中,創建一個新的relay log文件。將sql線程的位置初始化到新的relay log,並將i/o線程初始化到sql線程位置。

 

mysql在運行過程中,從庫上可能會出現以外宕機的情況,那么在從庫啟動后,必須能夠恢復到停止之前的狀態。i/o線程必須恢復到接受事務的位置,sql線程必須恢復到一直執行事務的位置。

 

用表來存儲這些信息,並且把這些表設置為innodb引擎,通過使用事務性存儲引擎,總能夠恢復這個信息。可以配置參數master_info_repository=table和relay_log_info_repository=table使從庫信息存儲到表中。從庫如何從宕機狀態恢復到正確狀態,取決與從庫是單線程還是多線程,relay_log_recover參數值,以及master_auto_position的使用方式。

 

 

 

1,單線程模式的復制

 

 

當基於gtid模式復制的時候,並且設置了master_auto_posion參數和relay_log_recover=0,使用該設置,其中relay_log_info_repository和其他變量的設置都不會影響恢復。

 

當基於傳統模式復制的情況下,需要設置relay_log_recovery=1和relay_log_info_repository=table。

 

 

2,多線程模式的復制

 

 

當基於gtid模式復制的時候,並且設置了master_auto_position和relay_log_recover=0,使用該配置,其relay_log_info_repository和其他變量的設置都會影響恢復。

 

當基於傳統模式復制的時候,請設置relay_log_recover=1,sync_relay_log=1和relay_log_info_repository=table。

 

 

 

現在從節點查看slave_relay_log_info然后做記錄。

 

[root@master ~]# kubectl exec -it pod/mysql-1 -n mysql -c mysql -- bash

 

 1 mysql> select * from slave_relay_log_info\G  2 *************************** 1. row ***************************
 3           Number_of_lines: 11
 4            Relay_log_name: ./mysql-1-relay-bin.000002
 5             Relay_log_pos: 204
 6           Master_log_name: mysql-0-bin.000004
 7            Master_log_pos: 155
 8                 Sql_delay: 0
 9         Number_of_workers: 0
10                        Id: 1
11  Channel_name: 12 Privilege_checks_username: NULL 13 Privilege_checks_hostname: NULL 14        Require_row_format: 0
15 1 row in set (0.00 sec)

 

 

查看尾從節點的slave_relay_log_info然后再次做記錄。

 

 

[root@master ~]# kubectl exec -it pod/mysql-2 -n mysql -c mysql -- bash

 

 1 mysql> select * from slave_relay_log_info\G  2 *************************** 1. row ***************************
 3           Number_of_lines: 11
 4            Relay_log_name: ./mysql-1-relay-bin.000002
 5             Relay_log_pos: 204
 6           Master_log_name: mysql-0-bin.000004
 7            Master_log_pos: 155
 8                 Sql_delay: 0
 9         Number_of_workers: 0
10                        Id: 1
11  Channel_name: 12 Privilege_checks_username: NULL 13 Privilege_checks_hostname: NULL 14        Require_row_format: 0
15 1 row in set (0.00 sec)

 

 

 

查看正常之后的。

 

 

[root@master ~]# kubectl exec -it pod/mysql-2 -n mysql -c mysql -- bash

 

 1 mysql> select * from slave_relay_log_info\G  2 *************************** 1. row ***************************
 3           Number_of_lines: 11
 4            Relay_log_name: ./mysql-2-relay-bin.000007
 5             Relay_log_pos: 373
 6           Master_log_name: mysql-0-bin.000004
 7            Master_log_pos: 155
 8                 Sql_delay: 0
 9         Number_of_workers: 0
10                        Id: 1
11  Channel_name: 12 Privilege_checks_username: NULL 13 Privilege_checks_hostname: NULL 14        Require_row_format: 0
15 1 row in set (0.00 sec)

 

 

附上sts完整yaml代碼

 

 1 apiVersion: apps/v1  2 kind: StatefulSet  3 metadata:  4  name: mysql  5  namespace: mysql  6 spec:  7   replicas: 3
 8  selector:  9  matchLabels:  10  app: mysql  11  serviceName: mysql  12  template:  13  metadata:  14  labels:  15  app: mysql  16  spec:  17  initContainers:  18       - name: init-mysql  19         image: mysql:8.0.19
 20  imagePullPolicy: IfNotPresent  21  command:  22         - bash  23         - "-c"
 24         - | 
 25           set -ex  26           [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
 27           myindex=${BASH_REMATCH[1]}  28           echo [mysqld] > /mnt/conf.d/server-id.cnf  29           echo server-id=$((100 + ${myindex})) >> /mnt/conf.d/server-id.cnf  30           if [[ ${myindex} -eq 0 ]]; then
 31             cp /mnt/config-map/master.cnf /mnt/conf.d/
 32           else
 33             cp /mnt/config-map/slave.cnf /mnt/conf.d/
 34           fi
 35  volumeMounts:  36         - name: conf  37           mountPath: /mnt/conf.d  38         - name: config-map  39           mountPath: /mnt/config-map  40       - name: clone-mysql  41         image: mzmuer/xtrabackup:1.0
 42  imagePullPolicy: IfNotPresent  43  command:  44         - bash  45         - "-c"
 46         - |
 47           set -ex  48           [[ -d /var/lib/mysql/mysql ]] && exit 0
 49           [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
 50           myindex=${BASH_REMATCH[1]}  51           [[ ${myindex} -eq 0 ]] && exit 0
 52           ncat --recv-only mysql-$((${myindex}-1)).mysql 3307 | xbstream -x -C /var/lib/mysql  53           xtrabackup --prepare --target-dir=/var/lib/mysql  54           # --redo-only 加了會導致為提交的事務不回滾  55  volumeMounts:  56         - name: data  57           mountPath: /var/lib/mysql  58  subPath: mysql  59         - name: conf  60           mountPath: /etc/mysql/conf.d  61  containers:  62       - name: mysql  63         image: mysql:8.0.19
 64  imagePullPolicy: IfNotPresent  65         args: ["--default-authentication-plugin=mysql_native_password"]  66         env:  67         - name: MYSQL_ALLOW_EMPTY_PASSWORD  68           value: "1"
 69  ports:  70         - name: mysql  71           containerPort: 3306
 72  volumeMounts:  73         - name: data  74           mountPath: /var/lib/mysql  75  subPath: mysql  76         - name: conf  77           mountPath: /etc/mysql/conf.d  78  resources:  79  requests:  80  cpu: 250m  81  memory: 256Mi  82  limits:  83  cpu: 500m  84  memory: 512Mi  85  livenessProbe:  86  exec:  87             command: ["mysqladmin", "ping"]  88           initialDelaySeconds: 30
 89           periodSeconds: 10
 90           timeoutSeconds: 5
 91  readinessProbe:  92  exec:  93             command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]  94           initialDelaySeconds: 5
 95           periodSeconds: 2
 96           timeoutSeconds: 1
 97       - name: xtrabackup  98         image: mzmuer/xtrabackup:1.0
 99  imagePullPolicy: IfNotPresent 100  ports: 101         - name: xtrabackup 102           containerPort: 3307
103  command: 104         - bash 105         - "-c"
106         - |
107           set -ex 108           mkdir /test 109           cd /var/lib/mysql 110           if [[ -s xtrabackup_slave_info ]]; then
111             mv xtrabackup_slave_info change_master_to.sql.in
112             rm -f xtrabackup_binlog_info 113           elif [[ -f xtrabackup_binlog_info ]]; then
114             [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
115             echo -e "CHANGE MASTER TO\nMASTER_LOG_FILE='${BASH_REMATCH[1]}',\nMASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
116             rm -f xtrabackup_binlog_info 117           fi
118           if [[ -f change_master_to.sql.in ]]; then
119             echo "Waiting for mysqld to be ready (accepting connections)"
120             until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
121             echo "Initializing replication from clone position"
122             mv change_master_to.sql.in change_master_to.sql.orig 123             mysql -h 127.0.0.1 <<EOF 124             $(<change_master_to.sql.orig), 125             MASTER_HOST='mysql-0.mysql', 126             MASTER_USER='repl', 127             MASTER_PASSWORD='repl123.', 128             MASTER_CONNECT_RETRY=10; 129  START SLAVE; 130  EOF 131           echo "master slave config ok"
132           fi
133           [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
134           myindex=${BASH_REMATCH[1]} 135           if [[ ${myindex} -eq 0 ]]; then
136             mysql -h 127.0.0.1 <<EOF 137  use mysql; 138             delete from user where user='repl' and host='%';flush privileges; 139             CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl123.'; 140             GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';flush privileges; 141  SELECT Host, User, plugin from mysql.user; 142  EOF 143           else
144             Slave_healthy=`mysql -h 127.0.0.1 -e 'show slave status\G' 2> /dev/null |grep -E "Slave_IO_Running|Slave_SQL_Running"|awk '{print $2}'|grep -c Yes` 145             if [[ ${Slave_healthy} -eq 2 ]]; then
146               echo "master slave healthy ok"
147             elif [[ ${Slave_healthy} -eq 1 ]]; then
148               echo "master slave healthy no"
149               mysql -h 127.0.0.1 <<EOF 150  stop slave; 151  reset slave; 152  start slave; 153  EOF 154               echo "master slave healthy revert"
155             elif [[ ${Slave_healthy} -eq 0 ]]; then
156               echo "master slave healthy no"
157               mysql -h 127.0.0.1 <<EOF 158  reset slave; 159  start slave; 160  EOF 161               echo "master slave healthy revert"
162             fi
163           fi
164           exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \ 165             "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
166  volumeMounts: 167         - name: data 168           mountPath: /var/lib/mysql 169  subPath: mysql 170         - name: conf 171           mountPath: /etc/mysql/conf.d 172  resources: 173  requests: 174  cpu: 100m 175  memory: 100Mi 176  limits: 177  cpu: 200m 178  memory: 200Mi 179  volumes: 180       - name: conf 181  emptyDir: {} 182       - name: config-map 183  configMap: 184  name: mysql 185  volumeClaimTemplates: 186   - metadata: 187  name: data 188  spec: 189       storageClassName: "managed-nfs-storage"
190       accessModes: ["ReadWriteMany"] 191  resources: 192  requests: 193           storage: 10Gi
View Code

 

 

作者:K&

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM