AB復制(重點)
一、什么是主從復制?
1、主從同步也叫AB復制,是用來建立一個和主數據庫完全一樣的數據庫環境,稱為從數據庫;主數據庫一般是準實時的業務數據庫。
2、主從復制的作用
1.做數據的熱備,作為后備數據庫,主數據庫服務器故障后,可切換到從數據庫繼續工作,避免數據丟失。
2.架構的擴展。業務量越來越大,I/O訪問頻率過高,單機無法滿足,此時做多庫的存儲,降低磁盤I/O訪問的頻率,提高單個機器的I/O性能。
3.讀寫分離,使數據庫能支撐更大的并發。1--在從服務器可以執行查詢工作(即我們常說的讀功能),降低主服務器壓力;(主庫寫,從庫讀,降壓)2--在從服務器進行備份,避免備份期間影響主服務器服務;(確保數據安全)
為什么要搞主從同步?
因為只有一個服務器 上面跑著mysql 萬一發生故障 數據會丟失 業務訪問無法正常運行,業務量過大的情況下,對服務器的壓力也是很大的,所以要考慮到服務要高可用,既降低服務器壓力又提高可用性寫庫(寫入)專門放一個數據庫 主庫負責寫入
查詢(select)在專門放一個庫 從庫負責查詢AB復制也叫讀寫分離
二、主從同步原理(面試題)
主服務器把數據修改之后,會放入到二進制日志中(binary log)中,然后通過內部進程機制把日志傳遞到從服務器(從服務器在通過IO線程寫入到中繼日志)中并表示為中繼日志(中繼日志在通過sql線程傳輸給從服務器并執行),從而達到了主從一致
從服務器有倆個線程(I/O線程和SQL線程)I/O線程負責把主服務器上的日志拉取過來,slq線程是負責把日志執行的,從服務器干的活最多
主服務器寫入數據,從服務器就寫入,主服務器刪除數據,從服務器就會接著刪除數據從服務器不能寫入數據主從同步也叫異步模式,時間會有0.幾毫秒延時,主服務器做好授權 從服務器具有授權的憑證進行把日志傳遞叢庫可以寫數據庫 但是主庫是不會有的
三、M-S 架構GTID 基于事務ID復制
1、什么是GTID?
全局事務標識:global transaction identifiers
是用來代替傳統復制的方法,GTID復制與普通復制模式的最大不同就是不需要指定二進制文件名和位置。
2、GTID工作原理
1、master更新數據時,會在事務前產生GTID,一同記錄到binlog日志中。
2、slave端的i/o 線程將變更的binlog,寫入到本地的relay log中。
3、sql線程從relay log中獲取GTID,然后對比slave端的binlog是否有記錄。
4、如果有記錄,說明該GTID的事務已經執行,slave會忽略。
5、如果沒有記錄,slave就會從relay log中執行該GTID的事務,并記錄到binlog。
3、部署主從復制
-A, --all-databases #備份所有庫
-B, --databases #備份多個數據庫
-F, --flush-logs #備份之前刷新binlog日志
--default-character-set #指定導出數據時采用何種字符集,如果數據表不是采用默認的latin1字符集的話,那么導出時必須指定該選項,否則再次導入數據后將產生亂碼問題。
--no-data,-d #不導出任何數據,只導出數據庫表結構。
--lock-tables #備份前,鎖定所有數據庫表
--single-transaction #保證數據的一致性和服務的可用性
-f, --force #即使在一個表導出期間得到一個SQL錯誤,繼續。對主庫已有的數據庫不會進行自動同步(可選操作 兩邊的庫要一樣)
邏輯備份 先暫時關閉gtid
--single-transaction 做一次性檢查
--all-databases 導出所有數據庫mkdir /dackupdb
mysqldump -uroot -p'123456' --set-gtid-purged=OFF --single-transaction --all-databases > /data/backupdb/all_$(date +%Y%m%d%H%M%S).sql在從庫上導入單個數據庫。
mysql -uroot -p'' 庫名 < /path/dbname.bak
mysql -uroot -p'123456' company < all_20240524195401.sql在從庫上導入多個數據庫
mysql -uroot -p'123456' < all_20240524195401.sql
部署主從復制詳細流程
開始執行第一步
master操作:
cd /usr/local/mysql/
mkdir bin-log
chown -R mysql:mysql bin-log[root@mysql-master ~]# vim /etc/my.cnf
#在[mysqld]下添加如下內容
server-id=1
log-bin = /usr/local/mysql/bin-log/binlog //前面是路徑后面是文件名
gtid_mode = on
enforce_gtid_consistency=1
#強制gtid
sync_binlog = 1[root@mysql-master ~]# systemctl restart mysqld檢查一下bin-log文件夾(此時二進制文件已經生成好了)
cd /usr/local/mysql/
cd bin-log/ llreplication slave //同步到從服務器
reload //重新加載
super //超級權限
slave //賬號
% //從服務器的id地址和主機
openssl rand -base64 40 | cut -c 2-15
+GVUrydHxuf4FK在主服務器創建授權賬戶:
mysql> grant replication slave,reload,super on *.* to 'slave'@'%' identified by '+GVUrydHxuf4FK';
#注:生產環境中密碼采用高級別的密碼,實際生產環境中將'%'換成slave的ip
mysql> flush privileges;
mysql> show master status; //查看狀態注意:如果不成功刪除以前的binlog日志
replication slave:擁有此權限可以查看從服務器,從主服務器讀取二進制日志。
super權限:允許用戶使用修改全局變量的SET語句以及CHANGE MASTER語句
reload權限:必須擁有reload權限,才可以執行flush [tables | logs | privileges]
slave操作(從服務器):
[root@mysql-slave ~]# vim /etc/my.cnf #添加如下配置relay-log-info-repository=TABLE //要不要這個表的數據記錄server-id=2
gtid_mode = ON
enforce_gtid_consistency=1
master-info-repository=TABLE
relay-log-info-repository=TABLE在重啟服務
[root@mysql-slave ~]# systemctl restart mysqld檢查一下有沒有錯誤的配置文件
cat /usr/local/mysql/mysql.log master_host='' //主服務器是多少
master_user='' //賬號是多少
master_password='+GVUrydHxuf4FK', //主服務器的密碼是多少
master_auto_position=1; //主服務器的標識是幾
[root@mysql-slave ~]# mysql -uroot -p'123456' #登陸mysqlmysql> change master to
master_host='192.168.171.15',
master_user='slave',
master_password='+GVUrydHxuf4FK',
master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)mysql> start slave; #真實啟動slave(從)角色
mysql> show slave status\G #查看狀態,驗證sql和IO是不是yes。Slave_IO_Running: Yes //表示主從同步已經配置成功Slave_SQL_Running: Yes
4、測試同步
在主庫新建數據庫,在從庫查看同步回到主服務器上
mysql> show master status;
創建數據庫
mysql> create database test_db;
主服務器狀態碼會發生變化為773
mysql> show master status;
回到從服務器上 狀態碼也會發生變化為773
mysql> show slave status\G
查看test_db庫是否存在
mysql> show databases;在主服務器上創建庫shuihu
mysql -uroot -p'123456' -e"create database shuihu";
回到從服務器上 查看shuihu庫是否存在
mysql> show databases;
查看動態日志
tail -f /usr/local/mysql/mysql.log
5、重設從庫
什么場景需要重設從庫,比如網絡發生異常,主庫地址(position)會發生變化,從庫上方網絡ok就可以做一次從連從庫重設#全在從庫執行(斷開于主庫之間的通信,脫離主從關系)
mysql>stop slave;
mysql>reset slave;
mysql>reset master;
#從庫的binlog已經無效了,所以要執行這個命令清空binlogmysql> change master to
master_host='192.168.171.15',
master_user='slave',
master_password='+GVUrydHxuf4FK',
master_auto_position=1;mysql> start slave; #啟動slave角色
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G #查看狀態,驗證sql和IO是不是yes。
6、常見錯誤
ERROR 3081 (HY000): This operation cannot be performed with running replication threads; run STOP SLAVE FOR CHANNEL '' first
如果遇到這種錯誤(是因為之前做主從同步的時候有殘留)要先斷開服務
從庫重設#全在從庫執行(斷開于主庫之間的通信,脫離主從關系)
mysql>stop slave;
mysql>reset slave;
mysql>reset master;
在進行重啟就ok了
systemctl stop mysqld
systemctl start mysqld常見故障1
Slave has more GTIDs than the master has,using the master's SERVER_UUID
該問題代表從庫獲取到的GTID超過了主庫,比如主庫在未指定binlog文件名的同時修改了系統主機名,導致binlog全部被修改,從庫就會判斷失敗;或者主庫未配置雙1參數時斷電,導致從庫提前獲取到了還未執行的GTID,解決方法如下:
重設從庫
stop slave;
reset slave;
reset master;
#從庫的binlog已經無效了,所以要執行這個命令清空binlog
change master to
master_host='10.36.107.10',
master_port=3306,
master_user='slave',
master_password='Qf@12345!',
master_auto_position=1;常見故障2
如果從庫未指定relaylog的同時修改了系統主機名,只需要在從庫重新執行一次同步
stop slave;
reset slave;
change master to
master_host='10.36.107.10',
master_port=3306,
master_user='slave',
master_password='Qf@12345!',
master_auto_position=1;常見故障3
Master_has_purged_require_gtids
主庫提前刪除了還未同步完成的binlog
在主庫上查看master信息
mysql> show master status\G;
*************************** 1. row ***************************File: mylog.000001Position: 465Binlog_Do_DB: Binlog_Ignore_DB:
Executed_Gtid_Set: 402c0020-4012-11ed-8d7e-000c292b8f0e:1-2
1 row in set (0.00 sec)
#在從庫上手動指定二進制日志文件master_log_file和位置master_log_pos與master上的一致
mysql > stop slave;
mysql > change master to
master_host='10.36.107.10',
master_user='slave',
master_password='Qf@12345!',
master_log_file='mylog.000001',
master_log_pos=465,
master_auto_position=0;
mysql > start slave;
6、故障切換
叢庫可以創數據庫 但是主庫是不會有的mysql主從,主服務器發生故障,如何進行切換?
主機故障,要把從服務器替換成主服務器1)在從服務器執行:(脫離主從關系)
mysql> stop slave;
mysql> reset master;2)查看是否只讀模式:(此時只讀模式是關閉模式 OFF)
show variables like 'read_only';
關閉只讀模式
vim /etc/my.cnf
read-only=1
并重啟mysql服務
systemctl restart mysqld或者不重啟使用命令關閉只讀,但下次重啟后失效:set global read_only=off;
3)查看show slave status \G;
4)在程序中將原來主庫IP地址改為現在的從庫IP地址,測試應用連接是否正常