mysql-5.7主從複製
一、MySQL主從複製
將主資料庫中的DDL和DML操作通過二進位制日誌傳輸到從資料庫上,然後將這些日誌重新執行(重做)一遍;從而使得從資料庫的資料與主資料庫保持一致。
二、MySQL 主從複製的基本介紹
MySQL支援單向、非同步複製,複製過程中一個伺服器充當主伺服器,而一個或多個其它伺服器充當從伺服器。
MySQL複製是基於主伺服器在二進位制日誌中跟蹤所有對資料庫的更改。因此,要進行復制,必須在主伺服器上啟用二進位制日誌。每個從伺服器從主伺服器接收主伺服器已經記錄到日誌的資料。
當一個從伺服器連線主伺服器時,它通知主伺服器從伺服器在日誌中讀取的最後一次成功更新的位置。從伺服器接收從那時起發生的任何更新,並在本機上執行相同的更新。然後封鎖並等待主伺服器通知新的更新。從伺服器執行備份不會干擾主伺服器,在備份過程中主伺服器可以繼續處理更新。
三、什麼是主從複製
簡單來說,是使用兩個或兩個以上相同的資料庫,將一個數據庫當做主資料庫,而另一個數據庫當做從資料庫。在主資料庫中進行相應操作時,從資料庫記錄下所有主資料庫的操作,使其二者一模一樣。
MySQL資料庫主從複製主要分為三步:
1.master將改變記錄到二進位制日誌(binlog)中(這些記錄叫做二進位制日誌事件,binlog events)。
2.slave的io執行緒將master的binary log events拷貝到它的中繼日誌(relay log)。
3.slave的sql執行緒解析中繼日誌中的事件並在從庫執行,保持與主庫一致。
Binlog:主資料庫的二進位制日誌。
Relay log:從伺服器的中繼日誌。
注意:複製過程有一個很重要的限制——複製在slave上是序列化的,也就是說master上的並行更新操作不能在slave上並行操作。
四、同步過程
# 從庫準備 1.從庫change master to 時,ip port user password binlog position寫入到master.info進行記錄。 2.從庫 start slave 時,會啟動IO執行緒和SQL執行緒。 # 同步流程 1. 從庫的IO執行緒,讀取master.info資訊,獲取主庫資訊並連線主庫。 2. 主庫接收從庫的連結請求後,會生成一個準備binlog dump的執行緒,來響應從庫。 3. 主庫一旦有新的日誌生成,會發送“訊號”給主庫的binlog dump執行緒,然後binlog dump執行緒會讀取binlog日誌的更新。 4. 通過binlog dump執行緒將資料傳送給從庫的IO執行緒。 5. IO執行緒將收到的日誌儲存到了TCP/IP 快取。 6. 寫入TCP/IP快取後,立即返回ACK訊息給主庫 ,此時主庫工作完成。 7. IO執行緒更新master.info檔案、binlog 檔名和postion定位。 8. IO執行緒將快取中的資料,儲存到relay-log日誌檔案,此時io執行緒工作完成。 9. 從庫SQL執行緒讀取relay-log.info檔案,獲取到上次執行到的relay-log的位置,作為起點。 10. 從庫SQL執行緒基於從步驟9中獲取到的起點,去中繼日誌relay-log.000001獲取後續操作,在從庫回放relay-log中繼日誌之中內從主庫複製過來的資料。 11. SQL執行緒回放完成之後,會更新relay-log.info檔案,把當前操作的位置記入,作為下一次操作的起點。 12. relay-log會有自動清理的功能。 #注:在tcp協議中通訊之前都要經過三次握手,請求方發出一個syn訊號請求連線,對方收到並接受的時候就會發出ack訊息,ack就是迴應的意思。
五、主從複製的方式
MySQL的主從複製有兩種複製方式,分別是非同步複製和半同步複製。
1.非同步複製
我們之前介紹的就是非同步複製,即客戶端執行緒提交一個寫操作,寫入主庫的binlog日誌後就立即返回,並不需要等待從庫完成同步操作,而主庫的dump執行緒會監測binlog日誌的變數然後主動將更新推送給從庫。
MySQL 主從複製預設是非同步的模式。
# 要實現主從複製,需要如下幾步:
1、在主庫上建立一個用於複製的賬號。
2、修改主庫配置檔案,開啟主庫的Binlog,並設定server-id和重啟。
3、匯出主庫中所有的資料,先導給從庫
4、修改從庫配置檔案並重啟
5、配置主從複製
6、開啟主從複製
# 1.主庫建立用於複製的賬號
mysql> grant replication slave on *.* to cp@'172.16.1.%' identified by '123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 2.修改主庫配置檔案
[root@db01 ~]# vim /etc/my.cnf
port=3306
socket=/tmp/mysql.sock
character-set-server=utf8mb4
log-error=/var/log/mysqld.log
pid-file=/usr/local/mysql/data/mysqld.pid
server-id=1
log-bin=mysql-bin
binlog_format=row
sync_binlog=1
expire_logs_days=10
max_binlog_size=100M
binlog_cache_size=4M
max_binlog_cache_size=512M
binlog-ignore-db=mysql
auto-increment-offset=1
auto-increment-increment=1
slave-skip-errors=all
binlog_rows_query_log_events=on
[mysql]
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
[root@db01 ~]# systemctl restart mysqld
# 3.匯出主庫中所有的資料
[root@db01 ~]# mysqldump -uroot -p123 -A -E -R --triggers --master-data=2 --single-transaction > /tmp/all.sql
# 4.將資料匯入從庫
[root@db01 ~]# scp /tmp/all.sql 172.16.1.52:/root/
all.sql 100% 731KB 2.8MB/s 00:00
[root@db02 ~]# mysql -uroot -p123 < /root/all.sql
# 5.修改從庫配置檔案
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
socket=/tmp/mysql.sock
character-set-server=utf8mb4
log-error=/var/log/mysqld.log
pid-file=/usr/local/mysql/data/mysqld.pid
server-id=2
# 中繼日誌
relay-log=mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
[mysql]
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
[root@db02 ~]# systemctl restart mysqld
# 6.配置主從複製
-- 配置主從複製,首先得在MySQL Master節點查出binlog日誌狀態,然後配置主從複製
-- 在MySQL master節點查出binlog日誌狀態
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 | 864 | | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
-- 從庫配置主從複製
#先測試是否能連線主庫
[root@db02 ~]# mysql -ucp -p123 -h172.16.1.51
[root@db02 ~]# mysql -uroot -p123
mysql> change master to
-> master_host='172.16.1.51', -- 主庫伺服器的IP
-> master_user='cp', -- 主庫授權用於複製的使用者
-> master_password='123', -- 密碼
-> master_port=3306, -- 主庫埠
-> master_log_file='mysql-bin.000005', -- 主庫日誌名
-> master_log_pos=864; -- 主庫日誌偏移量,即從何處開始複製
Query OK, 0 rows affected, 2 warnings (0.11 sec)
#開啟主從複製
mysql> start slave;
Query OK, 0 rows affected (0.36 sec)
#檢視狀態
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.1.51
Master_User: cp
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 864
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# Slave_IO_Running 和 Slave_SQL_Running 為Yes即成功
#測試
-- 主庫插入資料
mysql> select * from linux13;
+----+--------+------+------+------+
| id | name | city | age | addr |
+----+--------+------+------+------+
| 1 | 張三 | NULL | 18 | NULL |
| 2 | 李四 | NULL | 27 | NULL |
| 3 | 小米 | NULL | 18 | NULL |
| 4 | 熊大 | NULL | 19 | NULL |
| 5 | 熊二 | NULL | 20 | NULL |
+----+--------+------+------+------+
5 rows in set (0.00 sec)
mysql> insert into linux13(id,name,age) values (6,'楊雪',21);
Query OK, 1 row affected (0.01 sec)
mysql> select * from linux13;
+----+--------+------+------+------+
| id | name | city | age | addr |
+----+--------+------+------+------+
| 1 | 張三 | NULL | 18 | NULL |
| 2 | 李四 | NULL | 27 | NULL |
| 3 | 小米 | NULL | 18 | NULL |
| 4 | 熊大 | NULL | 19 | NULL |
| 5 | 熊二 | NULL | 20 | NULL |
| 6 | 楊雪 | NULL | 21 | NULL |
+----+--------+------+------+------+
6 rows in set (0.00 sec)
-- 從庫查詢資料
mysql> select * from linux13;
+----+--------+------+------+------+
| id | name | city | age | addr |
+----+--------+------+------+------+
| 1 | 張三 | NULL | 18 | NULL |
| 2 | 李四 | NULL | 27 | NULL |
| 3 | 小米 | NULL | 18 | NULL |
| 4 | 熊大 | NULL | 19 | NULL |
| 5 | 熊二 | NULL | 20 | NULL |
| 6 | 楊雪 | NULL | 21 | NULL |
+----+--------+------+------+------+
6 rows in set (0.00 sec)
2.半同步複製
介於非同步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於非同步複製,半同步複製提高了資料的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網路中使用。
半同步複製超時則會切換回非同步複製,正常後則切回半同步複製
在半同步複製時,如果主庫的一個事務提交成功了,在推送到從庫的過程當中,從庫宕機了或網路故障,導致從庫並沒有接收到這個事務的Binlog,此時主庫會等待一段時間(這個時間由rpl_semi_sync_master_timeout的毫秒數決定),如果這個時間過後還無法推送到從庫,那MySQL會自動從半同步複製切換為非同步複製,當從庫恢復正常連線到主庫後,主庫又會自動切換回半同步複製。
3.主庫配置
# 1.確認主從的MySQL伺服器是否支援動態增加外掛
mysql> select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES |
+------------------------+
1 row in set (0.00 sec)
# 2.分別在主從資料庫安裝對應外掛
#二進位制安裝的MySQL的外掛一般放在 /usr/local/mysql/lib/plugin/ 該目錄下
-- 主庫安裝外掛
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.28 sec)
#在主庫開啟半同步複製
mysql> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.09 sec)
mysql> set global rpl_semi_sync_master_timeout=1000; -- 單位毫秒
Query OK, 0 rows affected (0.00 sec)
# 新增到配置檔案
[root@db01 ~]# vim /etc/my.cnf
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000
4.從庫配置
# 1.確認主從的MySQL伺服器是否支援動態增加外掛
mysql> select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES |
+------------------------+
1 row in set (0.00 sec)
# 2.從庫安裝外掛
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.20 sec)
# 3.從庫開啟半同步複製
mysql> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.07 sec)
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.09 sec)
mysql> start slave io_thread;
Query OK, 0 rows affected (0.06 sec)
# 4.新增到配置檔案之中
[root@mysql-2 ~]# vim /etc/my.cnf
rpl_semi_sync_slave_enabled =1
[root@db02 ~]# systemctl restart mysqld
# 5.在主庫上檢視半同步複製的狀態
-- 主庫檢視
mysql> show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON |
+-----------------------------+-------+
1 row in set (0.00 sec)
-- 從庫檢視
mysql> show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.00 sec)
#這兩個變數常用來監控主從是否執行在半同步複製模式下。
六、主從故障
# IO執行緒故障
#Slave_IO_Running: No 或者 Connecting
1.檢測網路
[root@db02 ~]# ping 172.16.1.51
2.檢測埠
[root@db02 ~]# telnet 172.16.1.51 3306
3.防火牆是否開啟
4.主從的使用者名稱或者密碼錯誤
#測試使用主從使用者的使用者名稱和密碼連線主庫
[root@db02 ~]# mysql -urep -p123 -h172.16.1.51
5.反向解析
[root@db01 ~]# mysql -uroot -p123 -h172.16.1.51
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'db01' (using password: YES)
#解決
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
skip_name_resolve
# sql執行緒故障
#Slave_SQL_Running: No 或者 Connecting
1.主庫有的資料,從庫沒有
2.從庫有的資料,主庫沒有
3.主庫資料與從庫不一致
#1)解決辦法一:(不認)
1.停止主從複製
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
2.跳過一個錯誤
mysql> set GLOBAL sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)
3.開啟主從
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
#2)解決辦法二:
1.停止主從複製
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
2.清空主從複製的資訊
mysql> reset slave all;
Query OK, 0 rows affected (0.00 sec)
3.同步主庫所有資料
4.重新配置主從複製
七、多主多從
在企業中,資料庫高可用一直是企業的重中之重,中小企業很多都是使用mysql主從方案,一主多從,讀寫分離等,但是單主存在單點故障,從庫切換成主庫需要作改動。因此,如果是雙主或者多主,就會增加mysql入口,增加高可用。不過多主需要考慮自增長ID問題,這個需要特別設定配置檔案,比如雙主,可以使用奇偶,總之,主之間設定自增長ID相互不衝突就能完美解決自增長ID衝突問題。
1.MySQL雙主(主主)架構方案思路
兩臺mysql都可讀寫,互為主備,預設只使用一臺(masterA)負責資料的寫入,另一臺(masterB)備用。
- masterA是masterB的主庫,masterB又是masterA的主庫,它們互為主從。
- 兩臺主庫之間做高可用,可以採用keepalived等方案(使用VIP對外提供服務)。
- 所有提供服務的從伺服器與masterB進行主從同步(雙主多從)。
- 建議採用高可用策略的時候,masterA或masterB均不因宕機恢復後而搶佔VIP(非搶佔模式)。
這樣做可以在一定程度上保證主庫的高可用,在一臺主庫down掉之後,可以在極短的時間內切換到另一臺主庫上(儘可能減少主庫宕機對業務造成的影響),減少了主從同步給線上主庫帶來的壓力;但是也有幾個不足的地方:
- masterB可能會一直處於空閒狀態。
- 主庫後面提供服務的從庫要等masterB先同步完了資料後才能去masterB上去同步資料,這樣可能會造成一定程度的同步延時。
2.修改主節點的配置檔案
[root@db01 ~]# cat /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
socket=/tmp/mysql.sock
character-set-server=utf8mb4
log-error=/var/log/mysqld.log
pid-file=/usr/local/mysql/data/mysqld.pid
# 節點ID,確保唯一
server-id = 1
#開啟mysql的binlog日誌功能
log-bin=binlog
#控制資料庫的binlog刷到磁碟上去 , 0 不控制,效能最好,1每次事物提交都會刷到日誌檔案中,效能最差,最安全
sync_binlog=1
#binlog日誌格式
binlog_format=row
#binlog過期清理時間
expire_logs_days=7
#binlog每個日誌檔案大小
max_binlog_size=100m
#binlog快取大小
binlog_cache_size=4m
#最大binlog快取大小
max_binlog_cache_size=512m
#不生成日誌檔案的資料庫,多個忽略資料庫可以用逗號拼接,或者 複製黏貼下述配置項,寫多行
binlog-ignore-db=mysql
# 表中自增欄位每次的偏移量
auto-increment-offset=1
# 表中自增欄位每次的自增量
auto-increment-increment=2
#跳過從庫錯誤
slave-skip-errors=all
#將複製事件寫入binlog,一臺伺服器既做主庫又做從庫此選項必須要開啟
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=file
relay-log-info-repository=file
sync-master-info=1
slave-parallel-workers=0
sync_binlog=0
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
max_binlog_size=1024M
# 忽略同步的資料庫
replicate-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=sys
max_connections=3000
max_connect_errors=30
#忽略應用程式想要設定的其他字符集
skip-character-set-client-handshake
#連線時執行的SQL
init-connect='SET NAMES utf8mb4'
#服務端預設字符集
character-set-server=utf8mb4
#請求的最大連線時間
wait_timeout=1800
#和上一引數同時修改才會生效
interactive_timeout=1800
#sql模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
max_allowed_packet=10M
bulk_insert_buffer_size=8M
query_cache_type=1
query_cache_size=128M
query_cache_limit=4M
key_buffer_size=256M
read_buffer_size=16K
# 禁用反向解析
skip-name-resolve
slow_query_log=1
long_query_time=6
slow_query_log_file=slow-query.log
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=16M
[mysql]
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
3.修改備節點的配置檔案
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
socket=/tmp/mysql.sock
character-set-server=utf8
log-error=/var/log/mysqld.log
pid-file=/usr/local/mysql/data/mysqld.pid
# 節點ID,確保唯一
server-id=2
#開啟mysql的binlog日誌功能
log-bin=binlog
#控制資料庫的binlog刷到磁碟上去 , 0 不控制,效能最好,1每次事物提交都會刷到日誌檔案中,效能最差,最安全
sync_binlog=1
#binlog日誌格式
binlog_format=row
#binlog過期清理時間
expire_logs_days=7
#binlog每個日誌檔案大小
max_binlog_size=100m
#binlog快取大小
binlog_cache_size=4m
#最大binlog快取大小
max_binlog_cache_size=512m
#不生成日誌檔案的資料庫,多個忽略資料庫可以用逗號拼接,或者 複製黏貼下述配置項,寫多行
binlog-ignore-db=mysql
# 表中自增欄位每次的偏移量
auto-increment-offset=2
# 表中自增欄位每次的自增量
auto-increment-increment=2
#跳過從庫錯誤
slave-skip-errors=all
#將複製事件寫入binlog,一臺伺服器既做主庫又做從庫此選項必須要開啟
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=file
relay-log-info-repository=file
sync-master-info=1
slave-parallel-workers=0
sync_binlog=0
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
max_binlog_size=1024M
# 忽略同步的資料庫
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
replicate-ignore-db=sys
max_connections=3000
max_connect_errors=30
#忽略應用程式想要設定的其他字符集
skip-character-set-client-handshake
#連線時執行的SQL
init-connect='SET NAMES utf8'
#服務端預設字符集
character-set-server=utf8
#請求的最大連線時間
wait_timeout=1800
#和上一引數同時修改才會生效
interactive_timeout=1800
#sql模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
max_allowed_packet=10M
bulk_insert_buffer_size=8M
query_cache_type=1
query_cache_size=128M
query_cache_limit=4M
key_buffer_size=256M
read_buffer_size=16K
# 禁用反向解析
skip-name-resolve
slow_query_log=1
long_query_time=6
slow_query_log_file=slow-query.log
innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=16M
[mysql]
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
4.兩個master階段都必須重新初始化
#停止MySQL並刪除data目錄下的所有檔案
[root@db01 ~]# systemctl stop mysqld
[root@db01 ~]# rm -rf /usr/local/mysql/data/*
[root@db02 ~]# systemctl stop mysqld
[root@db02 ~]# rm -rf /usr/local/mysql/data/*
[root@db01 ~]# mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@db02 ~]# mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
# --initialize-insecure 不安全初始化,即沒有密碼。
# --initialize 安全初始化,會自動生成臨時密碼。在log-error裡,查詢 temporary password
5.分別登入資料庫並建立複製賬號
# 使用臨時密碼登入
[root@db01 ~]# systemctl start mysqld
[root@db01 ~]# grep 'temporary password' /var/log/mysqld.log
2021-10-19T08:01:08.782788Z 1 [Note] A temporary password is generated for root@localhost: O=i#f4Bfjy&t
[root@db01 ~]# mysql -uroot -p'O=i#f4Bfjy&t'
[root@db02 ~]# systemctl start mysqld
[root@db02 ~]# grep 'temporary password' /var/log/mysqld.log
2021-10-19T08:01:27.407550Z 1 [Note] A temporary password is generated for root@localhost: 4i?k*cU,I2d=
[root@db02 ~]# mysql -uroot -p'4i?k*cU,I2d='
# 修改臨時密碼
mysql> alter user root@localhost identified by '123';
Query OK, 0 rows affected (0.00 sec)
# 重新登入資料庫
[root@db01 ~]# mysql -uroot -p123
[root@db02 ~]# mysql -uroot -p123
# 建立遠端連線賬號
mysql> grant all on *.* to root@'%' identified by '12345' with grant option;
Query OK, 0 rows affected, 1 warning (0.00 sec)
# 刪除其他密碼
mysql> delete from mysql.user where host='localhost';
Query OK, 2 rows affected (0.00 sec)
# 重新整理許可權
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 重新登入並建立遠端複製賬號
mysql> grant replication slave on *.* to cp@'%' identified by '12345';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
6.配置主從複製
# db01主機binlog資訊
mysql> show master status;
+---------------+----------+--------------+------------------+--------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+--------------------------------+
| binlog.000003 | 1184 | | mysql | b7cf4a55-30b2-11ec-bda8-000c29577624:1-12 |
+---------------+----------+--------------+------------------+--------------------------------+
1 row in set (0.01 sec)
# db02主機binlog資訊
mysql> show master status;
+---------------+----------+--------------+------------------+----------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+----------------------------------+
| binlog.000002 | 1791 | | mysql | c2e9e04e-30b2-11ec-aa81-000c29e11414:1-10 |
+---------------+----------+--------------+------------------+----------------------------------+
1 row in set (0.00 sec)
# 在db01上執行
mysql> change master to
-> master_host='172.16.1.52',
-> master_port=3306,
-> master_user='cp',
-> master_password='12345',
-> master_log_file='binlog.000002',
-> master_log_pos=1791;
Query OK, 0 rows affected, 2 warnings (0.10 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.1.52
Master_User: cp
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000002
Read_Master_Log_Pos: 1791
Relay_Log_File: db01-relay-bin.000002
Relay_Log_Pos: 317
Relay_Master_Log_File: binlog.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# 在db02上執行
mysql> change master to
-> master_host='172.16.1.51',
-> master_port=3306,
-> master_user='cp',
-> master_password='12345',
-> master_log_file='binlog.000003',
-> master_log_pos=1184;
Query OK, 0 rows affected, 2 warnings (0.11 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.1.51
Master_User: cp
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000003
Read_Master_Log_Pos: 1184
Relay_Log_File: db02-relay-bin.000002
Relay_Log_Pos: 317
Relay_Master_Log_File: binlog.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
7.測試
# db01建立資料庫和表
mysql> create database linux13;
Query OK, 1 row affected (0.00 sec)
mysql> use linux13;
Database changed
mysql> create table student(id int);
Query OK, 0 rows affected (0.01 sec)
# db02插入資料
mysql> use linux13;
Database changed
mysql> insert into student values (1),(2);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
# db01查詢資料
mysql> select * from student;
+------+
| id |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
#雙方寫入的資料均能在對方查詢到,雙主架構資料庫成功
八、雙主高可用
高可用是使用keepalived實現VIP。從而實現一個IP無感知操作兩個主節點
# 兩個節點都安裝keepalived
[root@db01 ~]# yum install -y keepalived
[root@db02 ~]# yum install -y keepalived
# 修改keepalived的配置檔案
[root@db01 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_DEVEL
}
vrrp_script chk_kubernetes {
script "/etc/keepalived/check_kubernetes.sh"
interval 2
weight -5
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
mcast_src_ip 10.0.0.51 # 所在節點的IP
virtual_router_id 51
priority 100
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.3
}
#呼叫計劃指令碼
track_script {
check_kubernetes
}
}
[root@db02 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_DEVEL
}
vrrp_script chk_kubernetes {
script "/etc/keepalived/check_kubernetes.sh"
interval 2
weight -5
fall 3
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
mcast_src_ip 10.0.0.52 # 所在節點的IP
virtual_router_id 51
priority 90
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
10.0.0.3
}
#呼叫計劃指令碼
track_script {
check_kubernetes
}
}
[root@db01 ~]# vim /etc/keepalived/check_kubernetes.sh
#!/bin/bash
/usr/local/mysql/bin/mysql -uroot -p12345 -e 'status;' &> /dev/null
if [ $? -ne 0 ];then
systemctl start mysqld
sleep 2
/usr/local/mysql/bin/mysql -uroot -p12345 -e 'status;' &> /dev/null
if [ $? -ne 0 ];then
systemctl stop keepalived
fi
fi
[root@db01 ~]# chmod +x /etc/keepalived/check_kubernetes.sh
[root@db01 ~]# scp /etc/keepalived/check_kubernetes.sh 172.16.1.52:/etc/keepalived/