1. 程式人生 > >Docker環境下的前後端分離專案部署與運維(六)搭建MySQL叢集

Docker環境下的前後端分離專案部署與運維(六)搭建MySQL叢集

單節點資料庫的弊病

  • 大型網際網路程式使用者群體龐大,所以架構必須要特殊設計
  • 單節點的資料庫無法滿足效能上的要求
  • 單節點的資料庫沒有冗餘設計,無法滿足高可用

單節點MySQL的效能瓶領頸

2016年春節微信紅包巨大業務量,資料庫承受巨大負載

常見MySQL叢集方案

  mysql 叢集方案介紹,建議使用pxc,因為弱一致性會有問題,比如說a節點資料庫顯示我購買成功,b 節點資料庫顯示沒有成功,這就麻煩了,pxc 方案是在全部節點都寫入成功之後才會告訴你成功,是可讀可寫雙向同步的,但是replication是單向的,不同節點的資料庫之間都會開放埠進行通訊,如果從防火牆的這個埠關閉,pxc就不會同步成功,也不會返給你成功了。

Replication

  • 速度快,但僅能保證弱一致性,適用於儲存價值不高的資料,比如日誌、帖子、新聞等。
  • 採用master-slave結構,在master寫入會同步到slave,能從slave讀出;但在slave寫入無法同步到master。
  • 採用非同步複製,master寫入成功就向客戶端返回成功,但是同步slave可能失敗,會造成無法從slave讀出的結果。

     

PXC (Percona XtraDB Cluster)

  • 速度慢,但能保證強一致性,適用於儲存價值較高的資料,比如訂單、客戶、支付等。
  • 資料同步是雙向的,在任一節點寫入資料,都會同步到其他所有節點,在任何節點上都能同時讀寫。
  • 採用同步複製,向任一節點寫入資料,只有所有節點都同步成功後,才會向客戶端返回成功。事務在所有節點要麼同時提交,要麼不提交。

建議PXC使用PerconaServer (MySQL改進版,效能提升很大)

PXC的資料強一致性

  • 同步複製,事務在所有叢集節點要麼同時提交,要麼不提交
  • Replication採用非同步複製,無法保證資料的一致性

 

PXC叢集安裝介紹

在Docker中安裝PXC叢集,使用Docker倉庫中的PXC官方映象:https://hub.docker.com/r/percona/percona-xtradb-cluster

  1. 從docker官方倉庫中拉下PXC映象:
    docker pull percona/percona-xtradb-cluster

    或者本地安裝

    docker load < /home/soft/pxc.tar.gz

    安裝完成:

    [root@localhost ~]# docker pull percona/percona-xtradb-cluster
    Using default tag: latest
    Trying to pull repository docker.io/percona/percona-xtradb-cluster ... 
    latest: Pulling from docker.io/percona/percona-xtradb-cluster
    ff144d3c0ab1: Pull complete 
    eafdff1524b5: Pull complete 
    c281665399a2: Pull complete 
    c27d896755b2: Pull complete 
    c43c51f1cccf: Pull complete 
    6eb96f41c54d: Pull complete 
    4966940ec632: Pull complete 
    2bafadcea292: Pull complete 
    3c2c0e21b695: Pull complete 
    52a8c2e9228e: Pull complete 
    f3f28eb1ce04: Pull complete 
    d301ece75f56: Pull complete 
    3d24904bec3c: Pull complete 
    1053c2982c37: Pull complete 
    Digest: sha256:17c64dacbb9b62bd0904b4ff80dd5973b2d2d931ede2474170cbd642601383bd
    Status: Downloaded newer image for docker.io/percona/percona-xtradb-cluster:latest
    [root@localhost ~]# docker images
    REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
    docker.io/percona/percona-xtradb-cluster   latest              70b3670450ef        2 months ago        408 MB
    View Code
  2. 重新命名映象:(名稱太長,重新命名一下)
    docker tag percona/percona-xtradb-cluster:latest pxc

    然後原來的映象就可以刪除掉了

    [root@localhost ~]# docker images
    REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
    docker.io/percona/percona-xtradb-cluster   latest              70b3670450ef        2 months ago        408 MB
    pxc                                        latest              70b3670450ef        2 months ago        408 MB
    docker.io/java                             latest              d23bdf5b1b1b        2 years ago         643 MB
    [root@localhost ~]# docker rmi docker.io/percona/percona-xtradb-cluster
    Untagged: docker.io/percona/percona-xtradb-cluster:latest
    Untagged: docker.io/percona/percona-xtradb-cluster@sha256:17c64dacbb9b62bd0904b4ff80dd5973b2d2d931ede2474170cbd642601383bd
    [root@localhost ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    pxc                 latest              70b3670450ef        2 months ago        408 MB
    docker.io/java      latest              d23bdf5b1b1b        2 years ago         643 MB
    View Code
  3. 出於安全考慮,給PXC叢集建立Docker內部網路
    # 建立網段
    docker network create --subnet=172.18.0.0/24 net1
    # 檢視網段
    docker network inspect net1
    # 刪除網段
    # docker network rm net1
  4. 建立Docker卷:
    使用Docker時,業務資料應儲存在宿主機中,採用目錄對映,這樣可以使資料與容器獨立。但是容器中的PXC無法直接使用對映目錄,解決辦法是採用Docker捲來對映
    # 建立名稱為v1的資料卷,--name可以省略
    docker volume create --name v1

    檢視資料卷

    docker inspect v1

    結果:

    [root@localhost ~]# docker inspect v1
    [
        {
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/v1/_data",#這裡是在宿主機的儲存位置
            "Name": "v1",
            "Options": {},
            "Scope": "local"
        }
    ]

    刪除資料卷

    docker volume rm v1

    建立5個數據卷

    # 建立5個數據卷
    docker volume create --name v1
    docker volume create --name v2
    docker volume create --name v3
    docker volume create --name v4
    docker volume create --name v5
  5. 建立5個PXC容器:
    # 建立5個PXC容器構成叢集
    # 第一個節點
    docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql --name=node1 --network=net1 --ip 172.18.0.2 pxc
    # 在第一個節點啟動後要等待一段時間,等候mysql啟動完成。
    
    # 第二個節點
    docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v2:/var/lib/mysql --name=node2 --net=net1 --ip 172.18.0.3 pxc
    # 第三個節點
    docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v3:/var/lib/mysql --name=node3 --net=net1 --ip 172.18.0.4 pxc
    # 第四個節點
    docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v4:/var/lib/mysql --name=node4 --net=net1 --ip 172.18.0.5 pxc
    # 第五個節點
    docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v5:/var/lib/mysql --name=node5 --net=net1 --ip 172.18.0.6 pxc

    檢視:

    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                                   NAMES
    f4708ce32209        pxc                 "/entrypoint.sh "   About a minute ago   Up About a minute   4567-4568/tcp, 0.0.0.0:3309->3306/tcp   node4
    bf612f9586bc        pxc                 "/entrypoint.sh "   17 minutes ago       Up 17 minutes       4567-4568/tcp, 0.0.0.0:3310->3306/tcp   node5
    9fdde5e6becd        pxc                 "/entrypoint.sh "   17 minutes ago       Up 17 minutes       4567-4568/tcp, 0.0.0.0:3308->3306/tcp   node3
    edd5794175b6        pxc                 "/entrypoint.sh "   18 minutes ago       Up 18 minutes       4567-4568/tcp, 0.0.0.0:3307->3306/tcp   node2
    33d842de7f42        pxc                 "/entrypoint.sh "   21 minutes ago       Up 21 minutes       0.0.0.0:3306->3306/tcp, 4567-4568/tcp   node1

資料庫負載均衡的必要性

雖然搭建了叢集,但是不使用資料庫負載均衡,單節點處理所有請求,負載高,效能差

將請求均勻地傳送給叢集中的每一個節點。

  • 所有請求傳送給單一節點,其負載過高,效能很低,而其他節點卻很空閒。
  • 使用Haproxy做負載均衡,可以將請求均勻地傳送給每個節點,單節點負載低,效能好

負載均衡中介軟體對比

  負載均衡首先是資料庫的叢集,加入5個叢集,每次請求都是第一個的話,有可能第一個資料庫就掛掉了,所以更優的方案是對不同的節點都進行請求,這就需要有中介軟體進行轉發,比較好的中介軟體有nginx,haproxy等,因nginx 支援外掛,但是剛剛支援了tcp/ip 協議,haproxy 是一個老牌的中間轉發件。如果要用haproxy的話,可以從官方下載映象,然後呢對映象進行配置(自己寫好配置檔案,因為這個映象是沒有配置檔案的,配置好之後再執行映象的時候進行資料夾的對映,配置檔案開放3306(資料庫請求,然後根據check心跳檢測訪問不同的資料庫,8888 對資料庫叢集進行監控))。配置檔案裡面設定使用者(使用者在資料庫進行心跳檢測,判斷哪個資料庫節點是空閒的,然後對空閒的進行訪問),還有各種演算法(比如輪訓),最大連線數,時間等,還有對叢集的監控。配置檔案寫好以後執行這個映象,映象執行成功後進入容器啟動配置檔案 。其實haprocy返回的也是一個數據庫例項(但是並不儲存任何的資料,只是轉發請求),這個例項用來check其他節點。

安裝Haproxy

  1. 從Docker倉庫拉取haproxy映象:https://hub.docker.com/_/haproxy

    docker pull haproxy
    [root@localhost ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    docker.io/haproxy   latest              11fa4d7ff427        11 days ago         72.2 MB
    View Code
  2. 建立Haproxy配置檔案。供Haproxy容器使用(docker中未生成配置檔案,我們需要在宿主機中自己建立配置檔案)
    配置檔案詳情參考:https://www.cnblogs.com/wyt007/p/10829184.html

    # 啟動容器時使用目錄對映技術使容器讀取該配置檔案
    touch /home/soft/haproxy/haproxy.cfg

    haproxy.cfg

    # haproxy.cfg
    global
        #工作目錄
        chroot /usr/local/etc/haproxy
        #日誌檔案,使用rsyslog服務中local5日誌裝置(/var/log/local5),等級info
        log 127.0.0.1 local5 info
        #守護程序執行
        daemon
    
    defaults
        log    global
        mode    http
        #日誌格式
        option    httplog
        #日誌中不記錄負載均衡的心跳檢測記錄
        option    dontlognull
        #連線超時(毫秒)
        timeout connect 5000
        #客戶端超時(毫秒)
        timeout client  50000
        #伺服器超時(毫秒)
        timeout server  50000
    
    #監控介面    
    listen  admin_stats
        #監控介面的訪問的IP和埠
        bind  0.0.0.0:8888
        #訪問協議
        mode        http
        #URI相對地址
        stats uri   /dbs
        #統計報告格式
        stats realm     Global\ statistics
        #登陸帳戶資訊
        stats auth  admin:abc123456
    #資料庫負載均衡
    listen  proxy-mysql
        #訪問的IP和埠
        bind  0.0.0.0:3306  
        #網路協議
        mode  tcp
        #負載均衡演算法(輪詢演算法)
        #輪詢演算法:roundrobin
        #權重演算法:static-rr
        #最少連線演算法:leastconn
        #請求源IP演算法:source 
        balance  roundrobin
        #日誌格式
        option  tcplog
        #在MySQL中建立一個沒有許可權的haproxy使用者,密碼為空。Haproxy使用這個賬戶對MySQL資料庫心跳檢測
        option  mysql-check user haproxy
        server  MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000  
        server  MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000  
        server  MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000 
        server  MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
        server  MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
        #使用keepalive檢測死鏈
        option  tcpka  

     

  3. 在資料庫叢集中建立空密碼、無許可權使用者haproxy,來供Haproxy對MySQL資料庫進行心跳檢測
    create user 'haproxy'@'%' identified by '';
  4. 建立Haproxy容器(name=h1的原因是為了高可用)
    # 這裡要加 --privileged
    docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h1 --net=net1 --ip 172.18.0.7 --privileged haproxy
  5. 進入容器
    docker exec -it h1 bash
  6. 在容器bash中啟動Haproxy
    haproxy -f /usr/local/etc/haproxy/haproxy.cfg
  7. 接下來便可以在瀏覽器中開啟Haproxy監控介面,埠4001,在配置檔案中定義有使用者名稱admin,密碼abc123456。
    我這邊訪問的是http://192.168.63.144:4001/dbs,並且要使用使用者名稱密碼進行登入(小插曲,使用的是Basic登入,我的Chrome不知為何被遮蔽了,我最後用的火狐)

    這時候我們手動掛掉一個Docker節點,看一下變化(我們會發現已經顯示掛掉了)

  8. Haproxy不儲存資料,只轉發資料。可以在資料庫中建立Haproxy的連線,埠4002,使用者名稱和密碼為資料庫叢集的使用者名稱和密碼

為什麼要採用雙機熱備

  單節點Haproxy不具備高可用,必須要有冗餘設計

  雙機就是兩個請求處理程式,比如兩個haproxy,當一個掛掉的時候,另外 一個可以頂上。熱備我理解就是keepalive。在haproxy 容器中安裝keepalive。

虛擬IP地址

  linux系統可以在一個網絡卡中定義多個IP地址,把這些地址分配給多個應用程式,這些地址就是虛擬IP,Haproxy的雙機熱備方案最關鍵的技術就是虛擬IP。

  關鍵就是虛擬ip,定義一個虛擬ip,然後比如兩個haproxy分別安裝keepalive映象,因為haproxy是ubuntu系統的,所以安裝用apt-get,keepalive是作用是搶佔虛擬ip,搶到的就是主伺服器,沒有搶到的就是備用伺服器,然後兩個keepalive進行心跳檢測(就是建立一個使用者到對方那裡試探,看是否還活著,mysql的叢集之間也是心跳檢測),如果 掛掉搶佔ip。所以在啟動keepalive 之前首先要編輯好他的配置檔案,怎麼搶佔,權重是什麼,虛擬ip是什麼,建立的使用者交什麼。配置完啟動完以後可以ping一下看是否正確,然後將虛擬ip對映到區域網的ip

利用Keepalived實現雙機熱備

  • 定義虛擬IP
  • 在Docker中啟動兩個Haproxy容器,每個容器中還需要安裝Keepalived程式(以下簡稱KA)
  • 兩個KA會爭搶虛擬IP,一個搶到後,另一個沒搶到就會等待,搶到的作為主伺服器,沒搶到的作為備用伺服器
  • 兩個KA之間會進行心跳檢測,如果備用伺服器沒有受到主伺服器的心跳響應,說明主伺服器發生故障,那麼備用伺服器就可以爭搶虛擬IP,繼續工作
  • 我們向虛擬IP傳送資料庫請求,一個Haproxy掛掉,可以有另一個接替工作

Нaproxy雙機熱備方案

  • Docker中建立兩個Haproxy,並通過Keepalived搶佔Docker內地虛擬IP
  • Docker內的虛擬IP不能被外網,所以需要藉助宿主機Keepalived對映成外網可以訪問地虛擬IP

安裝Keepalived

  1. 進入Haproxy容器,安裝Keepalived:
    $ docker exec -it h1 bash
    apt-get update
    apt-get install keepalived
  2. Keepalived配置檔案(Keepalived.conf):
    Keepalived的配置檔案是/etc/keepalived/keepalived.conf
    # vim /etc/keepalived/keepalived.conf
    vrrp_instance  VI_1 {
        state  MASTER  # Keepalived的身份(MASTER主服務要搶佔IP,BACKUP備伺服器不會搶佔IP)。
        interface  eth0    # docker網絡卡裝置,虛擬IP所在
        virtual_router_id  51  # 虛擬路由標識,MASTER和BACKUP的虛擬路由標識必須一致。從0~255
        priority  100  # MASTER權重要高於BACKUP數字越大優先順序越高
        advert_int  1  # MASTER和BACKUP節點同步檢查的時間間隔,單位為秒,主備之間必須一致
        authentication {  # 主從伺服器驗證方式。主備必須使用相同的密碼才能正常通訊
            auth_type  PASS
            auth_pass  123456
        }
        virtual_ipaddress {  # 虛擬IP。可以設定多個虛擬IP地址,每行一個
            172.18.0.201
        }
    }
  3. 啟動Keepalived
    service keepalived start
    啟動成功後,通過 ip a 可以檢視網絡卡中虛擬IP是否成功,另外可以在宿主機中ping成功虛擬IP  172.18.0.201 
  4. 可以按照以上步驟,再另外建立一個Haproxy容器,注意對映的宿主機埠不能重複,Haproxy配置一樣。然後在容器中安裝Keepalived,配置也基本一樣(可以修改優先權重)。這樣便基本實現了Haproxy雙機熱備方案
    命令如下:

    建立Haproxy容器(name=h2的原因是為了高可用)

    # 這裡要加 --privileged
    docker run -it -d -p 4003:8888 -p 4004:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h2 --net=net1 --ip 172.18.0.8 --privileged haproxy

    進入容器

    docker exec -it h2 bash

    在容器bash中啟動Haproxy

    haproxy -f /usr/local/etc/haproxy/haproxy.cfg

    接下來便可以在瀏覽器中開啟Haproxy監控介面,埠4003,在配置檔案中定義有使用者名稱admin,密碼abc123456。
    我這邊訪問的是http://192.168.63.144:4003/dbs,並且要使用使用者名稱密碼進行登入(小插曲,使用的是Basic登入,我的Chrome不知為何被遮蔽了,我最後用的火狐)

    安裝Keepalived:
    apt-get update
    apt-get install keepalived

    Keepalived配置檔案(Keepalived.conf):
    Keepalived的配置檔案是/etc/keepalived/keepalived.conf

    # vim /etc/keepalived/keepalived.conf
    vrrp_instance  VI_1 {
        state  MASTER  # Keepalived的身份(MASTER主服務要搶佔IP,BACKUP備伺服器不會搶佔IP)。
        interface  eth0    # docker網絡卡裝置,虛擬IP所在
        virtual_router_id  51  # 虛擬路由標識,MASTER和BACKUP的虛擬路由標識必須一致。從0~255
        priority  100  # MASTER權重要高於BACKUP數字越大優先順序越高
        advert_int  1  # MASTER和BACKUP節點同步檢查的時間間隔,單位為秒,主備之間必須一致
        authentication {  # 主從伺服器驗證方式。主備必須使用相同的密碼才能正常通訊
            auth_type  PASS
            auth_pass  123456
        }
        virtual_ipaddress {  # 虛擬IP。可以設定多個虛擬IP地址,每行一個
            172.18.0.201
        }
    }

    啟動Keepalived

    service keepalived start

    啟動成功後,通過 ip a 可以檢視網絡卡中虛擬IP是否成功,另外可以在宿主機中ping成功虛擬IP 172.18.0.201 

實現外網訪問虛擬IP

檢視當前區域網IP分配情況:

yum install nmap -y
nmap -sP 192.168.1.0/24
  1. 在宿主機中安裝Keepalived
    yum install keepalived
  2. 宿主機Keepalived配置如下(/etc/keepalived/keepalived.conf):
    vrrp_instance VI_1 {
        state MASTER
    #這裡是宿主機的網絡卡,可以通過ip a檢視當前自己電腦上用的網絡卡名是哪個
        interface ens33
        virtual_router_id 100
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
    #這裡是指定的一個宿主機上的虛擬ip,一定要和宿主機網絡卡在同一個網段,
    #我的宿主機網絡卡ip是192.168.63.144,所以指定虛擬ip是160
               192.168.63.160
        }
    }
     
    #接受監聽資料來源的埠,網頁入口使用
    virtual_server 192.168.63.160 8888 {
        delay_loop 3
        lb_algo rr 
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
    #把接受到的資料轉發給docker服務的網段及埠,由於是發給docker服務,所以和docker服務資料要一致
        real_server 172.18.0.201 8888 {
            weight 1
        }
    }
     
    #接受資料庫資料埠,宿主機資料庫埠是3306,所以這裡也要和宿主機資料接受埠一致
    virtual_server 192.168.63.160 3306 {
        delay_loop 3
        lb_algo rr 
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
    #同理轉發資料庫給服務的埠和ip要求和docker服務中的資料一致
        real_server 172.18.0.201 3306 {
            weight 1
        }
    }
  3. 啟動Keepalived服務
    service keepalived start
    #service keepalived status
    #service keepalived stop
    之後其他電腦便可以通過虛擬IP 192.168.63.160 的8888和3306埠來訪問宿主機Docker中的 172.18.0.201 的相應埠。

暫停PXC叢集的辦法

vi /etc/sysctl.conf
#檔案中新增net.ipv4.ip_forward=1這個配置
systemctl restart network

然後把虛擬機器掛起

熱備份資料

冷備份

  • 冷備份是關閉資料庫時候的備份方式,通常做法是拷貝資料檔案
  • 是簡單安全的一種備份方式,不能在資料庫執行時備份。
  • 大型網站無法做到關閉業務備份資料,所以冷備份不是最佳選擇

熱備份

熱備份是在系統執行狀態下備份資料
MySQL常見的熱備份有LVM和XtraBackup兩種方案

  • LVM:linux的分割槽備份命令,可以備份任何資料庫;但是會對資料庫加鎖,只能讀取;而且命令複雜
  • XtraBackup:不需要鎖表,而且免費

XtraBackup

XtraBackup是一款基於InnoDB的線上熱備工具,具有開源免費,支援線上熱備,佔用磁碟空間小,能夠非常快速地備份與恢復mysql資料庫

  • 備份過程中不鎖表,快速可靠
  • 備份過程中不會打斷正在執行地事務
  • 備份資料經過壓縮,佔用磁碟空間小

全量備份和增量備份

  • 全量備份:備份全部資料。備份過程時間長,佔用空間大。第一次備份要使用全量備份
  • 增量備份: 只備份變化的那部分資料。備份的時間短,佔用空間小。第二次以後使用增量備份

PXC全量備份

  1. 備份要在某個PXC節點的容器內進行,但應該把備份資料儲存到宿主機內。所以採用目錄對映技術。先新建Docker卷:
    docker volume create backup
  2. 挑選一個PXC節點node1,將其容器停止並刪除,然後重新建立一個增加了backup目錄對映的node1容器

    docker stop node1
    docker rm node1    # 資料庫資料儲存在Docker卷v1中,不會丟失
    # 引數改變:
    # 1. -e CLUSTER_JOIN=node2;原來其他節點是通過node1加入叢集的,現在node1重新建立,需要選擇一個其他節點加入叢集
    # 2. -v backup:/data;將Docker卷backup對映到容器的/data目錄
    docker run -d -u root -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node2 -v v1:/var/lib/mysql -v backup:/data --network=net1 --ip 172.18.0.2 --name=node1 pxc
  3. 在node1容器中安裝 percona-xtrabackup-24

    docker exec -it node1 bash
    apt-get update
    apt-get install percona-xtrabackup-24

    之後便可以執行如下命令進行全量備份,備份後的資料會儲存在 /data/backup/full 目錄下:

    mkdir /data/backup
    mkdir /data/backup/full
    #不建議,已過時 innobackupex --backup -u root -p abc123456 --target-dir=/data/backup/full
    xtrabackup --backup -uroot -pabc123456 --target-dir=/data/backup/full

    官方文件已經不推薦使用 innobackupex,而推薦使用 xtrabackup 命令

PXC全量還原

資料庫可以熱備份,但是不能熱還原,否則會造成業務資料和還原資料的衝突。

對於PXC叢集為了避免還原過程中各節點資料同步衝突的問題,我們要先解散原來的叢集,刪除節點。然後新建節點空白資料庫,執行還原,最後再建立起其他叢集節點。

還原前還要將熱備份儲存的未提交的事務回滾,還原之後重啟MySQL

  1. 停止並刪除PXC叢集所有節點
    docker stop node1 node2 node3 node4 node5
    docker rm node1 node2 node3 node4 node5
    docker volume rm v1 v2 v3 v4 v5
  2. 按照之前的步驟重新建立node1容器,並進入容器,執行冷還原

    # 建立卷
    docker volume create v1
    # 建立容器
    docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup:/data --name=node1 --network=net1 --ip 172.18.0.2 pxc
    # 以root身份進入容器
    docker exec -it -uroot node1 bash
    # 刪除資料
    rm -rf /var/lib/mysql/*
    # 準備階段
    xtrabackup --prepare --target-dir=/data/backup/full/
    # 執行冷還原
    xtrabackup --copy-back --target-dir=/data/backup/full/
    # 更改還原後的資料庫檔案屬主
    chown -R mysql:mysql /var/lib/mysql
    # 退出容器後,重啟容器
    docker stop node1
    docker start node1