MySQL 複製 - 性能與擴展性的基石 2:部署及其配置

clipboard.png

正所謂理論造航母,現實小帆船。單有理論,不動手實踐,學到的知識猶如空中樓閣。接下來,咱們一塊兒來看下如何一步步進行 MySQL Replication 的配置。html

爲 MySQL 服務器配置複製很是簡單。但因爲場景不一樣,基本的步驟仍是有所差別。最基本的場景是新安裝主庫和備庫,總得來講分爲如下幾步:mysql

  1. 在每臺服務器上建立複製帳號。
  2. 配置主庫和備庫。
  3. 通知備庫鏈接到主庫並從主庫複製數據。

此外,因爲主備部署須要多臺服務器,可是這種要求對大多數人來講並不怎麼友好,畢竟沒有必要爲了學習部署主備結構,多買個雲服務器。所以,爲了測試方便,咱們經過 docker 容器技術在同臺機器上部署多個容器,從而實如今一臺機器上部署主備結構。面試

這裏咱們先假定大部分配置採用默認值,在主庫和備庫都是全新安裝而且擁有一樣的數據。接下來,咱們將展現如何經過 docker 技術一步步進行復制配置。sql

此外,咱們將推薦一些「安全配置」,以便在不清楚如何配置時,確保數據的安全。docker

1 部署 docker 環境

1) 部署 dockerubuntu

什麼?docker 還沒部署?趕忙參考這裏配一個,docker 都沒玩,怎麼和麪試官吹水呀!vim

2) 拉取 MySQL 鏡像安全

docker pull mysql:5.7

3) 使用 mysql 鏡像啓動容器bash

docker run -p 3339:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 # 啓動 master 容器
docker run -p 3340:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 # 啓動 slave 容器

master 對外的端口是 3339,slave 對外的端口是 3340,咱們在使用客戶端鏈接要使用對應的端口鏈接對應 mysql。服務器

4) 使用命令查看正在運行的容器

docker ps

docker-ps

5) 使用客戶端鏈接工具測試麗鏈接 mysql

鏈接測試

2 配置 Master 和 Slave

1) 配置 master
經過如下命令進入容器內部

docker exec -it mysql-master /bin/bash

a) 更新 apt-get 源

apt-get update

b) 安裝 vim

apt-get install vim

c) 配置 my.cnf

vim /etc/mysql/my.cnf
// 在my.cnf 中添加以下配置
[mysqld]
server-id=110 # 服務器 id,同一局域網內惟一
log-bin=/var/lib/mysql/mysql-bin # 二進制日誌路徑

d) 重啓 mysql 服務使配置生效

service mysql restart

e) 啓動容器
重啓 mysql 服務時會使得 docker 容器中止,須要重啓容器。

docker start mysql-master

f) 建立數據同步用戶並受權

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';

2) 配置 slave
經過如下命令進入容器內部

docker exec -it mysql-slave /bin/bash

a) 配置 my.cnf

vim /etc/mysql/my.cnf
// 在my.cnf 中添加以下配置
[mysqld]
server-id=120 # 服務器 id,同一局域網內惟一
log-bin=/var/lib/mysql/mysql-bin # 二進制日誌路徑
relay_log=/path/to/logs/relay-bin # 中繼日誌路徑

3) 關聯 master 和 slave
配置完 master 和 slave,接下來就要讓 master 和 slave 相關聯。
回到咱們的服務器,先找出 master 和 slave 容器的 IP,執行:

docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql-master

master IP

所以,咱們知道了 mysql-master 容器的 IP 是:172.17.0.3。一樣的方法,mysq-slave 容器的 IP 是:172.17.0.4。記住這兩個值,後面的配置須要用到。

咱們首先配置 master。在 master 容器內經過 mysql -u root -p 進入 MySQL 命令行,執行 show master status;

master狀態

上圖中,File 和 Position 字段對應的值要記錄下來,後續在 slave 配置時須要用到這兩個值。要注意的是,記錄完這兩個值後,就不能在 master 庫上作任何操做,不然會出現數據不一樣步的狀況。

接下來配置 slave,一樣的,在 slave 上進入 MySQL 命令行。而後執行下面語句:

change master to master_host='172.17.0.3', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=42852, master_connect_retry=30;

change master to 是 slave 配置 master 的命令,相關參數含義以下:

  • master_host:master 的IP,就是咱們上面獲取的 IP 地址
  • master_port:master 的端口號,也就是咱們 master mysql 的端口號
  • master_user:進行數據同步的用戶
  • master_password:同步用戶的密碼
  • master_log_file:指定 slave 從 master 的哪一個日誌文件開始複製數據,也就是咱們上面提到的 File 字段的值
  • master_log_pos:從 master 日誌文件的那個位置開始讀,上面提到的 Position 字段的值
  • master_connect_retry:重試時間間隔。單位是秒,默認 60

3 啓動複製

配置完 slave 後,能夠經過 show slave statusG; 查看 slave 的狀態。

![slave 狀態]](/img/bVbqPxZ)

正常狀況下,剛配置完 slave 的 Slave_IO_Running 和 Slave_SQL_Runing 都是 NO,由於咱們還沒開啓主從複製。使用 start slave 開啓主從複製,而後再查下 slave 狀態。

開啓主從複製後的 slave 狀態

slave 的 Slave_IO_Running 和 Slave_SQL_Runing 都是 YES,說明主從複製已成功啓動。此時,能夠經過客戶端可否成功複製數據。

咱們在 master 新建 replication 庫,而後觀察 slave 庫是否建立了 replication 庫,以下圖,表示複製成功。

主從複製測試

另外,開啓主從複製後,若是出現如下狀況:

Slave_IO_Running: CONNECTING
Slave_SQL_RUNNING: Yes

表示開啓主從複製後, slave 的 IO 進程鏈接 master 出現問題,一直在重試鏈接。咱們能夠根據 Last_IO_Error 的提示進行解決:

  1. 網絡不通。檢查 IP、port。
  2. 密碼錯誤。檢查配置的同步用戶和密碼是否正確。
  3. pos 錯誤。檢查 slave 配置的 Position 的值 與 master 是否一致。

4 從另外一個服務器開始複製

前面的設置都是假定主備庫均爲剛剛安裝好且都是默認的數據,也就是說兩臺服務器上數據相同,而且知道當前主庫的二進制日誌。但在實際環境中,大多數狀況下是有一個一級運行了一段時間的主庫,而後用一臺新安裝的備庫與之同步,此時這臺備庫尚未數據。

有幾種方法來初始化備庫或者從其餘服務器克隆數據到備庫。包括從主庫複製數據、從另一臺備庫克隆數據,以及使用最近的一次備份來啓動備庫等。而這些方法都須要有三個條件來讓主庫與備庫保持同步:

  • 在某個時間點的主庫的數據快照。
  • 主庫當前的二進制日誌文件,和得到數據快照時在該二進制日誌文件中的偏移量。咱們把這兩個值稱爲日誌文件座標(log file coordinates)。經過這兩個值能夠肯定二進制日誌的位置。能夠經過 SHOW MASTER STATUS 命令來獲取這些值。
  • 從快照時間到如今的二進制日誌。

下面是一些從別的服務器克隆備庫的方法:

  1. 使用冷備份。最基本的方法是關閉主庫,把數據複製到備庫。重啓主庫後,會使用一個新的二進制日誌文件,咱們在備庫經過執行 CHANGE MASTER TO 指向這個文件的起始處。不過這個方法的缺點很明顯:在複製數據時須要關閉主庫。
  2. 使用熱備份。若是僅使用了 MyISAM 表,能夠在主庫運行時使用 mysqlhotcopy 或 rsync 來複制數據。
  3. 使用 mysqldump。若是隻包含 InnoDB 表,可使用如下命令來轉儲主庫數據並將其加載到備庫,而後設置相應的二進制日誌座標:mysqldump --single-transaction --all-databases --master-data=1 --host=server1 | mysql --host=server2。選項 --single-transaction 使得轉儲的數據爲事務開始前的數據。若是使用的是非事務型表,可使用 --lock-all-tables 選項來得到全部表的一致性轉儲。
  4. 使用快照或備份。只要知道對應的二進制日誌座標,就可使用主庫的快照或者備份來初始化備庫。(若是使用備份,須要確保從備份的時間點開始的主庫二進制日誌都要存在)。只須要把備份或快照恢復到備庫,而後使用 CHANGE MASTER TO 指定二進制日誌的座標。
  5. 使用 Percona Xtrabackup。Percona 的 Xtrabackup 是一款開源的熱備份工具。它可以在備份時不阻塞服務器的操做,所以能夠在不影響主庫的狀況下設置備庫。能夠經過克隆主庫或另外一個已存在的備庫的方式來創建備庫。
  6. 使用另外的備庫。可使用任何一種克隆或拷貝技術從任意一臺備庫上將數據克隆到另一臺服務器。可是若是使用的是 mysqldump,--master-data 選項就會不起做用。此外,不能使用 SHOW MASTER STATUS 來得到主庫的二進制日誌座標,而是在獲取快照時使用 SHOW SLAVE STATUS 來獲取備庫在主庫上的執行位置。使用另外的備庫進行數據克隆最大的缺點是,若是這臺備庫的數據已經和主庫不一樣步,克隆獲得的就是髒數據。

5 推薦的複製配置

咱們知道,MySQL 的複製有許多參數能夠控制,其中一些會對數據安全和性能產生影響。這裏,咱們介紹一種「安全配置」,能夠最小化問題發生的機率。

在主庫上二進制日誌最重要的選項是 sync_binlog:

sync_binlog=1
若是開啓該選項,MySQL 每次在提交事務前會將二進制日誌同步到磁盤上,保證在服務器崩潰時不會丟失時間。若是禁止該選項,服務器會少作一些工做,但二進制日誌文件可能在服務器崩潰時損壞或丟失信息。在一個不須要做爲主庫的備庫上 ,該選項會帶來沒必要要的開銷。要注意的是,它只適用於二進制日誌,而非中繼日誌。

若是沒法接受服務器崩潰致使表損壞,推薦使用 InnoDB。MyISAM 表在備庫服務器崩潰重啓後,可能已經處於不一致狀態。

若是使用 InnoDB,推薦設置以下選項:

innodb_flush_logs_at_trx_commit=1 # 每次事務提交時,將 log buffer 寫入到日誌文件並刷新到磁盤。默認值爲 1
innodb_safe_binlog

明確指定二進制日誌文件的名稱。當服務器間轉移文件、克隆新的備庫、轉儲備份或者其餘場景下,若是以服務器名來命名二進制日誌可能會致使不少問題。所以,咱們須要給 log_bin 選項指定一個參數。

log_bin=/var/lib/mysql/mysql-bin

在備庫上,一樣開啓以下培訓,爲中繼日誌指定絕對路徑:

relay_log=/path/to/logs/relay-bin
skip_slave_start
read_only

經過設置 relay_log 能夠避免中繼日誌文件基於機器名來命名,防止以前提到的可能在主庫上發生的問題。而 skip_slave_start 選項可以阻止備庫在崩潰後自動啓動複製,以留出時間修復可能發生的問題。read_only 選項能夠阻止大部分用戶更改非臨時表。

6 小結

  1. 複製初始化配置三部曲:建立帳號、配置主備庫、備庫鏈接到主庫開始複製;
  2. 從已有服務器複製時,可用熱備份或 mysqldump 命令進行備份;
  3. 在不肯定相關配置時,選擇最安全的配置準沒錯;
相關文章
相關標籤/搜索