docker搭建數據庫高可用方案PXC

前言

本方案主要目的是學習, 該方案不太合適於企業項目html

是什麼?

白話點, 是個提供了必要環境的虛擬機(相似於java的導入部分包同樣和c++的頭文件差很少), 因此它比普通的VMWare或者VirtualBox安裝的虛擬機要java

整體來講相似於jvm那樣的存在, 只不過jvm運行的是java編譯的字節碼, docker運行的是各類組件, 好比mysql, redis, zookeeper或者咱們的項目node

有哪些關鍵的概念

  1. 鏡像

docker鏡像相似於系統安裝包ISO, 或者咱們對某個程序的備份, 將這個備份壓縮成rar壓縮包, 備份了不少程序的數據和配置, 咱們只要把這個壓縮包丟給別人, 別人解壓並使用這個程序mysql

  1. 容器

容器相似於咱們的程序(前面的鏡像是壓縮包), 能夠直接運行linux

總結
鏡像和容器的關係是 一個鏡像對應能夠多個容器(只要你建立的多)c++

怎麼用?

設置鏡像加速

建立或編輯該文件:redis

vi /etc/docker/daemon.json 在該文件中輸入以下內容:算法

{
    "registry-mirrors": [
        "https://docker.mirrors.ustc.edu.cn",
        "https://hub-mirror.c.163.com",
        "https://mirror.ccs.tencentyun.com",
        "https://registry.docker-cn.com"
    ]
}
複製代碼

docker基本指令

service docker start # 開啓docker
service docker stop # 關閉docker
service docker restart # 重啓docker
複製代碼

鏡像管理

導入導出鏡像

docker save java > /home/java.tar.gz
docker load < /home/java.tar.gz
複製代碼

鏡像查找

docker search java
複製代碼

鏡像下載

docker pull java
複製代碼

查看鏡像列表

docker images
複製代碼

查看鏡像信息

docker inspect java
複製代碼
[
    {
        "Id": "sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8",
        "RepoTags": [
            "java:latest"
        ],
        "RepoDigests": [
            "java@sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2017-01-17T00:52:54.890877145Z",
        "Container": "4b4ab1e131616e04a88f26f9811e5847dd0c3ec5f8178b634b388d3c510ee606",
        "ContainerConfig": {
            "Hostname": "33842653d6db",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "LANG=C.UTF-8",
                "JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64",
                "JAVA_VERSION=8u111",
                "JAVA_DEBIAN_VERSION=8u111-b14-2~bpo8+1",
                "CA_CERTIFICATES_JAVA_VERSION=20140324"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "/var/lib/dpkg/info/ca-certificates-java.postinst configure"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:7cfe1ce37b990ea20d6377b8901f5ffccd463ed2f965e9730d834e693b53baec",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": [],
            "Labels": {}
        },
        "DockerVersion": "1.12.3",
        "Author": "",
        "Config": {
            "Hostname": "33842653d6db",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "LANG=C.UTF-8",
                "JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64",
                "JAVA_VERSION=8u111",
                "JAVA_DEBIAN_VERSION=8u111-b14-2~bpo8+1",
                "CA_CERTIFICATES_JAVA_VERSION=20140324"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:7cfe1ce37b990ea20d6377b8901f5ffccd463ed2f965e9730d834e693b53baec",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": [],
            "Labels": {}
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 643195347,
        "VirtualSize": 643195347,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/fcdfe412499e0b1afe9cb8d6800eb56af9c578b1c49fbf0fc9f38fead4f32b2d/diff:/var/lib/docker/overlay2/5d79e6646df2342376ba59d8d21b70142d0e3fd0c9a0de2229c1cfa4c2d98e93/diff:/var/lib/docker/overlay2/47b9afdc585a2c847d112283d7d884f00140dab44c33203eeeccc4a592a23378/diff:/var/lib/docker/overlay2/9565b7df775e50948f7713b8a1b1ba6610eb055c958bbd23a7646b4414ccefab/diff:/var/lib/docker/overlay2/dd8233c055d2241a6e52a0f0acd48220f87a75e50fbe2a7355445bcc75bbfbb9/diff:/var/lib/docker/overlay2/64bb2d108355eb53a495cdb6804e602baa651888a27c10c19dfb0fa2351648b6/diff:/var/lib/docker/overlay2/3fb4d1d79e7b1966b16dfb4d7dcde2ac6ac602f932395acf2c5d3bd0573a9c67/diff",
                "MergedDir": "/var/lib/docker/overlay2/09e28e456caf00dd0ab82af1f594f248f05e0e64a4b931f69251ab2f1c9c4df3/merged",
                "UpperDir": "/var/lib/docker/overlay2/09e28e456caf00dd0ab82af1f594f248f05e0e64a4b931f69251ab2f1c9c4df3/diff",
                "WorkDir": "/var/lib/docker/overlay2/09e28e456caf00dd0ab82af1f594f248f05e0e64a4b931f69251ab2f1c9c4df3/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:a2ae92ffcd29f7ededa0320f4a4fd709a723beae9a4e681696874932db7aee2c",
                "sha256:0eb22bfb707db44a8e5ba46a21b2ac59c83dfa946228f04be511aba313bdc090",
                "sha256:30339f20ced009fc394410ac3360f387351641ed40d6b2a44b0d39098e2e2c40",
                "sha256:ce6c8756685b2bff514e0b28f78eedb671380084555af2b3833e54bb191b262a",
                "sha256:a3483ce177ce1278dd26f992b7c0cfe8b8175dd45bc28fee2628ff2cf063604c",
                "sha256:6ed1a81ba5b6811a62563b80ea12a405ed442a297574de7440beeafe8512a00a",
                "sha256:c3fe59dd955634c3fa1808b8053353f03f4399d9d071be015fdfb98b3e105709",
                "sha256:35c20f26d18852b74cc90afc4fb1995f1af45537a857eef042a227bd8d0822a3"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]
複製代碼

鏡像刪除

docker rmi java
複製代碼

容器管理

啓動鏡像(鏡像初次產生容器)

啓動鏡像會默認建立出一個容器sql

  • docker run -it --name myjava java bash 使用bash運行保持控制檯方式運行
  • docker run -it --name myjava -p 9000:8080 -p 9050:8050 java bash 以控制檯方式運行java而且映射了java的端口8080到主機的9000, 映射到java的8050到主機的9050端口
  • docker run -it -name myjava -v /home/project:/soft --privileged java bash 映射java應用的路徑/soft 到主機的/home/project路徑並使用--privileged給了修改權限
mkdir /home/project
docker run -it --name myjava -p 9000:8080 -p 9050:8050 -v /home/project:/soft --privileged java bash
複製代碼

添加[option] -d建立和之後臺方式啓動容器docker

暫停、中止和開啓容器

docker pause myjava # 能夠在另外一個控制檯暫停
docker unpause myjava # 能夠在另外一個控制檯執行
docker stop myjava # 能夠中止掉容器
docker start -i myjava
複製代碼

查看容器和查看運行中的容器

docker ps -a # 查看全部容器, 包括未運行的容器
docker ps # 查看正在運行的容器
複製代碼

刪除容器

docker rm myjava 刪除容器

建立docker內部網絡

建立docker內部網絡比較安全, 內部只要對外部提供端口即可, 通常用於集羣內部網絡時使用

docker network create net1
docker network inspect net1
docker network rm net1
複製代碼

docker network create --subnet=172.18.0.0/24 net1

建立docker卷

爲何須要數據卷?

這得從 docker 容器的文件系統提及。出於效率等一系列緣由,docker 容器的文件系統在宿主機上存在的方式很複雜,這會帶來下面幾個問題:

  • 不能在宿主機上很方便地訪問容器中的文件。
  • 沒法在多個容器之間共享數據。
  • 當容器刪除時,容器中產生的數據將丟失。

爲了解決這些問題,docker 引入了數據卷(volume) 機制。數據卷是存在於一個或多個容器中的特定文件或文件夾,這個文件或文件夾以獨立於 docker 文件系統的形式存在於宿主機中。數據卷的最大特定是:其生存週期獨立於容器的生存週期。

使用數據卷的最佳場景

  • 在多個容器之間共享數據,多個容器能夠同時以只讀或者讀寫的方式掛載同一個數據卷,從而共享數據卷中的數據。
  • 當宿主機不能保證必定存在某個目錄或一些固定路徑的文件時,使用數據卷能夠規避這種限制帶來的問題。
  • 當你想把容器中的數據存儲在宿主機以外的地方時,好比遠程主機上或雲存儲上。
  • 當你須要把容器數據在不一樣的宿主機之間備份、恢復或遷移時,數據卷是很好的選擇。

使用方法

docker volume create --name v1

例如:

root@ubuntu:/# docker volume create --name node1
node1
root@ubuntu:/# docker volume inspect node1
[
    {
        "CreatedAt": "2020-07-08T14:03:16+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/node1/_data",
        "Name": "node1",
        "Options": {},
        "Scope": "local"
    }
]
複製代碼

它把卷建立到了宿主機的/var/lib/docker/volumes/node1/_data目錄下

搭建MySql集羣(PXC方案: 不建議選擇這套方案)

下載pxc

docker pull percona/percona-xtradb-cluster:5.7

圖片中筆者原本想配置mysql8.0的pxc方案, 但主機的ssl配置成功後,從機的ssl一直驗證不經過(筆者給予了幾個文件足夠的權限777). 主機ssl的幾個文件必須是讀寫執行權限全給纔可以驗證成功, 但從機的custom.cnf權限若是仍是讀寫執行權限將會被忽略, 因此筆者建立了兩個config文件夾, 裏面存了兩個custom.cnf配置文件, 只有權限不一樣, 雖然這個配置文件再也不被忽略, 但仍是不行, 會不斷的重複嘗試鏈接ssl//:172.18.0.2:4567, 沒轍. 只能回到5.7的懷抱
docker搭建mysql8.0的pxc方案相關資料

建立docker內部網絡

docker network create --subnet=172.18.0.0/24 pxc_net1

建立docker卷

docker volume create v1
docker volume create v2
docker volume create v3
docker volume create v4
docker volume create v5
docker volume create backup
複製代碼

建立集羣

  • 建立主機
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc -e XTRABACKUP_PASSWORD=123456 -v v1:/var/lib/mysql -v backup:/data --privileged --name pxc_node1 --net=pxc_net1 --ip=172.18.0.2 percona/percona-xtradb-cluster:5.7
複製代碼
  • 建立從機

集羣這幾個地方要改

docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pxc_node1 -v v2:/var/lib/mysql -v backup:/data --privileged --name pxc_node2 --net=pxc_net1 --ip=172.18.0.3 percona/percona-xtradb-cluster:5.7

docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pxc_node1 -v v2:/var/lib/mysql -v backup:/data --privileged --name pxc_node2 --net=pxc_net1 --ip=172.18.0.3 percona/percona-xtradb-cluster:5.7

docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pxc_node1 -v v3:/var/lib/mysql -v backup:/data --privileged --name pxc_node3 --net=pxc_net1 --ip=172.18.0.4 percona/percona-xtradb-cluster:5.7

docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pxc_node1 -v v4:/var/lib/mysql -v backup:/data --privileged --name pxc_node4 --net=pxc_net1 --ip=172.18.0.5 percona/percona-xtradb-cluster:5.7

docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pxc_node1 -v v5:/var/lib/mysql -v backup:/data --privileged --name pxc_node5 --net=pxc_net1 --ip=172.18.0.6 percona/percona-xtradb-cluster:5.7
複製代碼

使用Haproxy負載均衡

docker pull haproxy

mkdir ~/docker/haproxy
cd ~/docker/haproxy
vi 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:123456
#數據庫負載均衡
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數據庫心跳檢測
	# CREATE USER 'haproxy'@'%' IDENTIFIED by ''; FLUSH PRIVILEGES;
    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
複製代碼
docker run -it -d -p 4001:8888 -p 4002:3306 -v /root/docker/haproxy:/usr/local/etc/haproxy --name h1 --net=pxc_net1 --ip 172.18.0.8 --privileged haproxy

docker run -it -d -p 4003:8888 -p 4004:3306 -v /root/docker/haproxy:/usr/local/etc/haproxy --name h2 --net pxc_net1 --ip 172.18.0.9 --privileged haproxy
複製代碼

記住這句上面註釋掉的CREATE USER 'haproxy'@'%' IDENTIFIED by ''; FLUSH PRIVILEGES; 這句話若是不在數據庫中建立好用戶, 將會在出現Haproxy沒法感知mysql是否啓動的狀況, 由於她須要經過數據庫建立的這個帳號haproxy監控數據庫狀況(因此你能夠不給這個帳號任何權限, 只要他們訪問就行)

因此docker exec -it pxc_node1 /usr/bin/mysql -uroot -p123456進入容器, 而後複製CREATE USER 'haproxy'@'%' IDENTIFIED by ''; FLUSH PRIVILEGES;去建立這個帳戶

只要在一個節點建立就好, 其餘數據庫會同步更新

進入docker中的haproxy控制檯中 docker exec -it h1 bash

加載配置文件haproxy -f /usr/local/etc/haproxy/haproxy.cfg

以後訪問 http://192.168.0.135:4001/dbs

至此配置haproxy配置完成了, 咱們使用navicat鏈接下試試

cf014fbc9ef7        haproxy                              "/docker-entrypoint.…"   2 hours ago         Up 2 hours          0.0.0.0:4002->3306/tcp, 0.0.0.0:4001->8888/tcp   h1
複製代碼

我是嘗試鏈接下 4002端口

如今咱們嘗試下關閉掉數據庫節點pxc_node1

docker stop pxc_node1

咱們新建完畢

這裏咱們其餘庫都更新完畢了, 但pxc_node1是空的

咱們如今從新開啓pxc_node1節點看下, 是否是那個表被添加到這個節點了

發現沒法開啓這個節點了(這是怎麼回事???)

vi /var/lib/docker/volumes/v1/_data/grastate.dat 修改 safe_to_bootstrap: 0safe_to_bootstrap: 1

再次嘗試啓動這個節點

雖然成功了, 可是數據沒被同步過去

甚至還會出現這個問題(由於是輪訓, 因此隨機出現沒法找到數據庫問題)

如今咱們嘗試修改下, 別的數據庫中的數據(非pxc_node1數據庫節點)

這數據就這麼丟了

如今咱們重啓docker, 而後在依次從新啓動節點

配置數據庫雙機熱備

爲何須要雙機熱備???

單個Haproxy節點不具有高可用, 必需要給個備機防止主機沒了, 致使咱們的服務沒法訪問的問題

linux提供了虛擬IP的技術, 咱們的雙機熱備須要利用它(虛擬ip就是在一個網卡上能夠對不一樣的程序提供不一樣的虛擬ip)

使用keepalived方式以搶佔虛擬IP的方式完成, 因此咱們須要在docker haproxy內部配置環境

完整方案

安裝keepalived

  • Keepalived必需要安裝在Haproxy所在的容器以內
apt-get update
apt-get upgrade
apt install keepalived
複製代碼
  • keepalived配置文件

Keepalived的配置文件是/etc/keepalived/keepalived.conf

vrrp_instance  VI_1 {
    state  MASTER
    interface  eth0
    virtual_router_id  51
    priority  100
    advert_int  1
    authentication {
        auth_type  PASS
        auth_pass  123456
    }
    virtual_ipaddress {
        172.18.0.201
    }
}
複製代碼

啓動keepalived serivce keepalived start 啓動它

以上操做都在docker容器中操做

而後咱們測試下主機是否可以ping通docker內部的網絡下的虛擬機

ping 172.18.0.201

  • 另外一個docker中的keepalived配置
vrrp_instance  VI_1 {
    state  MASTER
    interface  eth0
    virtual_router_id  51
    priority  100
    advert_int  1
    authentication {
        auth_type  PASS
        auth_pass  123456
    }
    virtual_ipaddress {
        172.18.0.202
    }
}
複製代碼

serivce keepalived start 啓動它

退出回到宿主機, ping 172.18.0.202看下是否可以ping的通

  • 宿主機安裝keepalived

vi /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.0.155
    }
}

virtual_server 192.168.0.155 8888 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 172.18.0.201 8888 {
        weight 1
    }
    real_server 172.18.0.202 8888 {
        weight 1
    }
}

virtual_server 192.168.0.155 3306 {
    delay_loop 6
    lb_algo rr 
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

	real_server 172.18.0.201 3306 {
        weight 1
    }
    real_server 172.18.0.202 3306 {
        weight 1
    }
}
複製代碼

啓動keepalived, systemctl start keepalived(宿主機是centOS7, 因此使用systemctl)

再ping下ping 192.168.0.155

[root@centOS ~]# ping 192.168.0.155
PING 192.168.0.155 (192.168.0.155) 56(84) bytes of data.
From 192.168.0.144 icmp_seq=1 Destination Host Unreachable
From 192.168.0.144 icmp_seq=2 Destination Host Unreachable
From 192.168.0.144 icmp_seq=3 Destination Host Unreachable
From 192.168.0.144 icmp_seq=4 Destination Host Unreachable
^C
--- 192.168.0.155 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3000ms
pipe 4
[root@centOS ~]# ping 192.168.0.155
PING 192.168.0.155 (192.168.0.155) 56(84) bytes of data.
64 bytes from 192.168.0.155: icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from 192.168.0.155: icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from 192.168.0.155: icmp_seq=3 ttl=64 time=0.039 ms
^C
複製代碼

注意下: keepalived的啓動須要一點點時間, 上面控制檯輸出Destination Host Unreachable是由於壓根沒啓動完畢

咱們回到真正的主機(window上)在ping下, 看下行不行 ping 192.168.0.155

正在 Ping 192.168.0.155 具備 32 字節的數據:
來自 192.168.0.155 的回覆: 字節=32 時間<1ms TTL=64
來自 192.168.0.155 的回覆: 字節=32 時間<1ms TTL=64
來自 192.168.0.155 的回覆: 字節=32 時間<1ms TTL=64
來自 192.168.0.155 的回覆: 字節=32 時間<1ms TTL=64

192.168.0.155 的 Ping 統計信息:
    數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒爲單位):
    最短 = 0ms,最長 = 0ms,平均 = 0ms
複製代碼

ok, 配置完成

咱們在navicat上鍊接下

ip: 192.168.0.155
用戶: root
密碼: 123456(我爲了簡便設置了簡單的密碼, 實際項目中千萬別這麼簡單)
端口: 3306
複製代碼

完成

  • 但存在一個問題, 每次啓動docker, 都要進入docker h1和h2容器中再啓動keepalived, 挺麻煩的, 放心後面會慢慢解決的
  • 還存在一個問題, 用戶沒法知道keepalived哪些節點能用, 哪些節點不能用了 keepalived容易出現腦裂, 因此我也不太推薦使用這種方案, 本方案主要目的是學習

熱備方案

冷備份和熱備份之間的關係是會不會實際影響到咱們的業務(鎖住備份區域,或者乾脆阻塞它), 冷備會, 熱備份不會, 顯而易見, 選熱備

而熱備方案中又有全量備份增量備份物理備份

真的是, 各類名詞看膩了, 說白了就是一次備份是否是直接 copy 仍是 copy + 1 這樣的不斷備份, 還有一種就是忽略了文件系統結構的備份

咱們選擇xtrabackup作熱備方案

還記得前面我在建立集羣時加的參數麼? -v backup:/data這個, 如今咱們要將數據庫備份映射到這個目錄, 若是前面建立集羣時, 沒有增長這個參數須要stop後刪除的從新建立

若是咱們沒有添加映射備份目錄, 那麼須要

docker stop pxc_node1
docker rm pxc_node1
docker run -d -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=pxc -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=pxc_node2 --net=pxc_net1 --ip=172.18.0.2 -p 3306:3306  -v v1:/var/lib/mysql -v backup:/data --privileged --name pxc_node1 percona/percona-xtradb-cluster:5.7
複製代碼

如今咱們進入docker容器中的pxc_node1節點 看看這個容器運行的系統是什麼版本的linux系統

red hat 或者 centOS 系統因此咱們須要使用yum去更新

docker exec -it pxc_node1 bash

bash-4.2$ yum update
Loaded plugins: fastestmirror, ovl
ovl: Error while doing RPMdb copy-up:
[Errno 13] Permission denied: '/var/lib/rpm/.dbenv.lock'
You need to be root to perform this command.
複製代碼

exit退出, 而後docker exec -it --user root pxc_node1 bash or docker exec -it --user=root pxc_node1 bash

yum clean all
yum makecache
yum update
yum install wget
wget https://repo.percona.com/yum/percona-release-latest.noarch.rpm
rpm -ivh percona-release-latest.noarch.rpm
rm percona-release-latest.noarch.rpm
yum list | grep percona
複製代碼

進行一次全量熱備

innobackupex --user=root --password=123456 /data/backup/full
複製代碼

回到宿主機, 看看

docker volume inspect backup
複製代碼

cd /var/lib/docker/volumes/backup/_data
複製代碼

就能夠看到已經備份了

全部的pxc_node* 節點都是共享的 backup 目錄

還原也同樣

docker exec -it pxc_node1 bash # 進入節點
rm -rf /var/lib/mysql/* # 刪除掉本來的數據
# 將尚未提交的事務回滾
innobackupex --user=root --password=lezhu123456 --apply-back /data/backup/full/2018-04-15_05-09-07/
# 恢復
innobackupex --user=root --password=lezhu123456 --copy-back /data/backup/full/2018-04-15_05-09-07/
複製代碼

不是我說, 有更好的選擇千萬別選pxc

待續...

相關文章
相關標籤/搜索