MySQL--組從復制的詳解及功能演練

2.MySQL的組從復制

2.1 配置mastesr

[root@mysqlaa ~]# vim /etc/my.cnf
[mysqld]
server-id=10
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
log-bin=mysql-bin[root@mysqlaa ~]# /etc/init.d/mysqld restart
# 進入數據庫配置用戶權限
[root@mysql-node10 ~]# mysql -uroot -p123456# 生成專門用來做復制的用戶,此用戶是用于slave端做認證用
mysql> create user dhj@'%' identified by '123456';				
mysql> grant replication slave on *.* to 'dhj'@'%';				# 對這個用戶進行授權
mysql> show master status;										# 查看master的狀態
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      658 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
**image-20250801141359365**
[root@mysql-node10 ~]# cd /data/mysql/
[root@mysql-node10 mysql]# mysqlbinlog mysql-bin.000001	-vv			# 查看二進制日志

2.2 配置salve

[root@mysql-node2 ~]# vim /etc/my.cnf
[mysqld]
server-id=20
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password[root@mysql-node2 ~]# /etc/init.d/mysqld restart
[root@mysqlb ~]# mysql -uroot -p123456mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10',MASTER_USER='dhj',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=658;						# 這里要去master主機中去查看一遍mysql> start slave;mysql> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Waiting for source to send eventMaster_Host: 172.25.254.10Master_User: dhjMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 1606Relay_Log_File: mysqlb-relay-bin.000002Relay_Log_Pos: 326Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: Yes						# 一定要保證此參數為yesSlave_SQL_Running: Yes						# 一定要保證此參數為yes
image-20250801152150489
# 如果上述內容輸入錯誤可以reset重新填入信息即可
mysql> RESET SLAVE ALL;
# 測試:# 在master主機里面進行建表
[root@mysqlaa ~]# mysql -uroot -p123456mysql> create database ceshi;mysql> create table ceshi.userlist (username varchar(20) not null, password varchar(50) not null);mysql> insert into ceshi.userlist value ('dhj','123');mysql> select * from ceshi.userlist;
+----------+----------+
| username | password |
+----------+----------+
| dhj      | 123      |
+----------+----------+# 在slave中查看數據是否有同步過來
[root@mysqlb ~]# mysql -uroot -p123456mysql> select * from ceshi.userlist;
+----------+----------+
| username | password |
+----------+----------+
| dhj      | 123      |
+----------+----------+
image-20250801152710614

image-20250801152852953

2.3 當有數據時添加slave2

#完成基礎配置
[root@mysql-node3 ~]# vim /etc/my.cnf
[mysqld]
server-id=30
datadir=/data/mysql                                     # 指定數據目錄
socket=/data/mysql/mysql.sock           				# 指定套接字
default_authentication_plugin=mysql_native_password[root@mysql-node3 ~]# /etc/init.d/mysqld restart
#從master節點備份數據
[root@mysql-node1 ~]# mysqldump -uroot -p123456 ceshi  > /mnt/ceshi.sql

[!NOTE]

生產環境中備份時需要鎖表,保證備份前后的數據一致

mysql> FLUSH TABLES WITH READ LOCK;

備份后再解鎖

mysql> UNLOCK TABLES;

mysqldump命令備份的數據文件,在還原時先DROP TABLE,需要合并數據時需要刪除此語句

--
-- Table structure for table `userlist`
--DROP TABLE IF EXISTS `userlist`;		#需要合并數據時需要刪除此語句
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
[root@mysqlaa ~]# scp /mnt/ceshi.sql root@172.25.254.30:/mnt
root@172.25.254.30's password:
ceshi.sql                           100% 1947     2.2MB/s   00:00# 利用master節點中備份出來的lee.sql在slave2中拉平數據
[root@mysql-node3 ~]# mysql -uroot -p123456 -e "create database ceshi;"
[root@mysql-node3 ~]# mysql -uroot -p123456 ceshi </mnt/ceshi.sql
[root@mysql-node3 ~]# mysql -uroot -p123456 -e "select * from ceshi.userlist;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 123      |
+----------+----------+
#配置slave2的slave功能#在master中查詢日志pos
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     3656 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+[root@mysqlc ~]# mysql -uroot -p123456
mysql> CHANGE MASTER TO MASTER_HOST='172.25.254.10', MASTER_USER='dhj', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=3656;mysql> start slave;
mysql> SHOW SLAVE STATUS\G;
mysql> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Waiting for source to send eventMaster_Host: 172.25.254.10Master_User: dhjMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 3656Relay_Log_File: mysqlc-relay-bin.000002Relay_Log_Pos: 326Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: YesSlave_SQL_Running: Yes

測試:

[root@mysql-node1 ~]# mysql -uroot -p123456 -e  "INSERT INTO ceshi.userlist VALUES('user2','123');"[root@mysql-node2 mysql]# mysql -uroot -p123456 -e 'select * from ceshi.userlist;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 123      |
| user3    | 123      |
+----------+----------+[root@mysql-node3 ~]# mysql -uroot -p123456 -e 'select * from ceshi.userlist;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 123      |
| user3    | 123      |
+----------+----------+
# 為slave兩臺主機開啟只讀操作+超級只讀操作(root在slave里面都不能寫數據)
# 以下僅為20主機的,30的在此不做演示
[root@mysqlb ~]# more /etc/my.cnf
[mysqld]
server-id=10
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
read-only=1
super-read-only=1[root@mysqlb ~]# /etc/init.d/mysqld restart

image-20250801164929743

2.4 延遲復制

延遲復制時用來控制sql線程的,和i/o線程無關

這個延遲復制不是i/o線程過段時間來復制,i/o是正常工作的

是日志已經保存在slave端了,那個sql要等多久進行回放

#在slave端
mysql> STOP SLAVE SQL_THREAD;
mysql> CHANGE MASTER TO MASTER_DELAY=60;
mysql> START SLAVE SQL_THREAD;
mysql> SHOW SLAVE STATUS\G;Master_Server_Id: 1Master_UUID: db2d8c92-4dc2-11ef-b6b0-000c299355eaMaster_Info_File: /data/mysql/master.infoSQL_Delay: 60			##延遲效果SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for more updatesMaster_Retry_Count: 86400

測試:

在master中寫入數據后過了延遲時間才能被查詢到

2.5 慢查詢日志

  • 慢查詢,顧名思義,執行很慢的查詢

  • 當執行SQL超過long_query_time參數設定的時間閾值(默認10s)時,就被認為是慢查詢,這個SQL語句就是需要優化的

  • 慢查詢被記錄在慢查詢日志里

  • 慢查詢日志默認是不開啟的

  • 如果需要優化SQL語句,就可以開啟這個功能,它可以讓你很容易地知道哪些語句是需要優化的。

mysql> SHOW variables  like "slow%";
+---------------------+----------------------------------+
| Variable_name       | Value                            |
+---------------------+----------------------------------+
| slow_launch_time    | 2                                |
| slow_query_log      | OFF                              |
| slow_query_log_file | /data/mysql/mysql-node1-slow.log |
+---------------------+----------------------------------+
3 rows in set (0.00 sec)

開啟慢查詢日志

mysql> SET GLOBAL slow_query_log=ON;
Query OK, 0 rows affected (0.00 sec)mysql> SET long_query_time=4;
Query OK, 0 rows affected (0.00 sec)mysql> SHOW VARIABLES like "long%";
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 4.000000 |
+-----------------+----------+
1 row in set (0.00 sec)mysql> SHOW VARIABLES like "slow%";
+---------------------+----------------------------------+
| Variable_name       | Value                            |
+---------------------+----------------------------------+
| slow_launch_time    | 2                                |
| slow_query_log      | ON                               |		##慢查詢日志開啟
| slow_query_log_file | /data/mysql/mysql-node1-slow.log |
+---------------------+----------------------------------+
3 rows in set (0.01 sec)[root@mysql-node1 ~]# cat  /data/mysql/mysql-node1-slow.log     #慢查詢日志
/usr/local/mysql/bin/mysqld, Version: 5.7.44-log (Source distribution). started with:
Tcp port: 3306  Unix socket: /data/mysql/mysql.sock
Time                 Id Command    Argument

測試慢查詢

mysql> select sleep (10);[root@mysql-node1 ~]# cat  /data/mysql/mysql-node1-slow.log
/usr/local/mysql/bin/mysqld, Version: 5.7.44-log (Source distribution). started with:
Tcp port: 3306  Unix socket: /data/mysql/mysql.sock
Time                 Id Command    Argument
# Time: 2024-07-29T17:04:07.612704Z
# User@Host: root[root] @ localhost []  Id:     8
# Query_time: 10.000773  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
SET timestamp=1722272647;
select sleep (10);

2.6 mysql的并行復制

查看slave中的線程信息

image-20250730200425000

默認情況下slave中使用的是sql單線程回放

在master中時多用戶讀寫,如果使用sql單線程回放那么會造成組從延遲嚴重

開啟MySQL的多線程回放可以解決上述問題

# 在slaves中設定
# 以下僅為20,30不做演示[root@mysql-node2 ~]# vim /etc/my.cnf
[mysqld]
server-id=20
datadir=/data/mysql
socket=/data/mysql/mysql.sock
default_authentication_plugin=mysql_native_password
read-only=1
super-read-only=1slave-parallel-type=LOGICAL_CLOCK			#基于組提交,
slave-parallel-workers=16					#開啟線程數量
master_info_repository=TABLE				#master信息在表中記錄,默認記錄在/data/mysql//master.info
relay_log_info_repository=TABLE				#回放日志信息在表中記錄,默認記錄在/data/mysql/relay-log.info
relay_log_recovery=ON						#日志回放恢復功能開啟[root@mysql-node2 ~]# /etc/init.d/mysql restart# 進行測試
mysql> show processlist;

image-20250801165536603

此時sql線程轉化為協調線程,16個worker負責處理sql協調線程發送過來的處理請求

[!NOTE]

MySQL 組提交(Group commit)是一個性能優化特性,它允許在一個事務日志同步操作中將多個事務的日志記錄一起寫入。這樣做可以減少磁盤I/O的次數,從而提高數據庫的整體性能。

2.7 原理刨析

image-20250730195631273 image-20250801194633466

三個線程

實際上主從同步的原理就是基于 binlog 進行數據同步的。在主從復制過程中,會基于3 個線程來操作,一個主庫線程,兩個從庫線程。

  • 二進制日志轉儲線程(Binlog dump thread)是一個主庫線程。當從庫線程連接的時候, 主庫可以將二進制日志發送給從庫,當主庫讀取事件(Event)的時候,會在 Binlog 上加鎖,讀取完成之后,再將鎖釋放掉。

  • 從庫 I/O 線程會連接到主庫,向主庫發送請求更新 Binlog。這時從庫的 I/O 線程就可以讀取到主庫的二進制日志轉儲線程發送的 Binlog 更新部分,并且拷貝到本地的中繼日志 (Relay log)。

  • 從庫 SQL 線程會讀取從庫中的中繼日志,并且執行日志中的事件,將從庫中的數據與主庫保持同步。

復制三步驟

步驟1:Master將寫操作記錄到二進制日志(binlog)。

步驟2:Slave將Master的binary log events拷貝到它的中繼日志(relay log);

步驟3:Slave重做中繼日志中的事件,將改變應用到自己的數據庫中。 MySQL復制是異步的且串行化的,而且重啟后從接入點開始復制。

具體操作

1.slaves端中設置了master端的ip,用戶,日志,和日志的Position,通過這些信息取得master的認證及信息

2.master端在設定好binlog啟動后會開啟binlog dump的線程

3.master端的binlog dump把二進制的更新發送到slave端的

4.slave端開啟兩個線程,一個是I/O線程,一個是sql線程,

  • i/o線程用于接收master端的二進制日志,此線程會在本地打開relaylog中繼日志,并且保存到本地磁盤
  • sql線程讀取本地relog中繼日志進行回放

5.什么時候我們需要多個slave?

當讀取的而操作遠遠高與寫操作時。我們采用一主多從架構

數據庫外層接入負載均衡層并搭配高可用機制

2.8 架構缺陷

主從架構采用的是異步機制

master更新完成后直接發送二進制日志到slave,但是slaves是否真正保存了數據master端不會檢測

master端直接保存二進制日志到磁盤

當master端到slave端的網絡出現問題時或者master端直接掛掉,二進制日志可能根本沒有到達slave

master出現問題slave端接管master,這個過程中數據就丟失了

這樣的問題出現就無法達到數據的強一致性,零數據丟失

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917283.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917283.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917283.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript將String轉為base64 筆記250802

JavaScript將String轉為base64 筆記250802 在 JavaScript 中將字符串轉換為 Base64 編碼有多種方法&#xff0c;每種方法都有其適用場景。下面我將全面介紹這些方法&#xff0c;包括處理 ASCII 字符、Unicode 字符以及性能優化方案。 基礎方法&#xff1a;btoa() 基本用法&a…

Unity3D數學第四篇:射線與碰撞檢測(交互基礎篇)

Unity3D數學第一篇&#xff1a;向量與點、線、面&#xff08;基礎篇&#xff09; Unity3D數學第二篇&#xff1a;旋轉與歐拉角、四元數&#xff08;核心變換篇&#xff09; Unity3D數學第三篇&#xff1a;坐標系與變換矩陣&#xff08;空間轉換篇&#xff09; Unity3D數學第…

數據處理和統計分析——09 數據分組

1 聚合 1.1 簡介 在SQL中我們經常使用GROUP BY將某個字段&#xff0c;按不同的取值進行分組&#xff0c;在Pandas中也有groupby()函數&#xff1b;分組之后&#xff0c;每組都會有至少1條數據&#xff0c;將這些數據進一步處理返回單個值的過程就是聚合&#xff0c;比如分組之后…

【數據結構與算法】數據結構初階:排序內容加餐(一)——快速排序:三路劃分、自省排序

&#x1f525;個人主頁&#xff1a;艾莉絲努力練劍 ?專欄傳送門&#xff1a;《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題 &#x1f349;學習方向&#xff1a;C/C方向 ??人生格言&#xff1a;為天地立心&#xff0c;為生民立命&#xff0c;為…

MySqL(加餐)

范式第一范式數據庫表的每一列都是不可分割的原子數據項&#xff0c;而不能是集合&#xff0c;數組&#xff0c;對象等非原子數據。在關系型數據庫的設計中&#xff0c;滿足第一范式是對關系模式的基本要求。不滿足第一范式的數據庫就不能被稱為關系數據庫。第一范式實際上只要…

【redis】基于工業界技術分享的內容總結

Redis 實踐指南與核心概念 一、Java 中常用的 Redis 使用場景與實踐 緩存&#xff08;Caching&#xff09; 場景&#xff1a;熱點數據、頻繁訪問的數據&#xff0c;如商品詳情、用戶信息。通過緩存減少數據庫壓力&#xff0c;提高系統響應速度。 工業界實踐&#xff1a; 淘寶…

服務端之nestJS常用異常類及封裝自定義響應模塊

MENU前言常用異常類&#xff08;由nestjs/common提供&#xff09;示例自定義異常&#xff08;可選&#xff09;自定義響應模塊前言 在NestJS中&#xff0c;nestjs/common提供了大量的內置異常類&#xff0c;主要用于在控制器、服務等層拋出特定的HTTP錯誤響應。 常用異常類&…

數據鏈路層、NAT、代理服務、內網穿透

目錄 一. 以太網 以太網幀格式 二. MAC地址 三. MTU 四. ARP協議 五. NAT NAPT 六. 代理服務器 正向代理 反向代理 七. 內網穿透 八. 內網打洞 一. 以太網 ? "以太網" 不是一種具體的網絡, 而是一種技術標準; 既包含了數據鏈路層的內 容, 也包含了一些物理層…

Rust在CentOS 6上的移植

Rust已不支持Cent OS 6 rhel是Redhat 發布的Red Hat Enterprise Linux的簡稱&#xff0c;使用rhel源代碼編譯的CentOS&#xff0c;最新的版本是CentOS 7&#xff0c;于2024年停止支持。而更古老的CentOS 6&#xff0c;則在2020年就已經結束了。 而面對如此老舊的系統&#xf…

C++音視頻開發:基礎面試題

音視頻領域技術門檻高&#xff0c;學習資料稀缺&#xff0c;體系化書籍和開發工具有限&#xff0c;新手入門困難。音視頻開發涉及眾多任務&#xff1a;音頻&#xff08;采集、編解碼、降噪等&#xff09;、視頻&#xff08;采集、編解碼、圖像處理&#xff09;、實時傳輸&#…

C++刷題 - 7.27

貪心算法的詳細邏輯這個問題的最優解可以用 貪心算法 在 O(N) 時間 內解決。它的核心思想是&#xff1a;每次操作盡可能覆蓋最長的連續非零區間&#xff0c;并通過數學分析發現&#xff1a;最小操作次數等于所有“上升臺階”的高度差之和。1. 直觀理解假設 steps [1, 2, 3, 2,…

音頻3A處理簡介之AGC(自動增益控制)

在音頻通話和視頻會議中&#xff0c;音頻自動增益控制AGC模塊的主要作用&#xff1a;? 穩定音頻信號的輸出電平。無論麥克風采集信號的強弱&#xff08;如用戶離麥克風遠近程度不同&#xff09;&#xff0c;盡可能保證音頻采集模塊的輸出音量保持相對一致&#xff0c;不會偏大…

web前端打包apk包

我用的是HBuilder工具,可視化更便捷&#xff0c;目前我這操作的apk包是不需要上架的&#xff0c;所以跟實際需要上架的可能還有些出入 首先先新建個項目&#xff0c;選擇5App模式 把目前需要打包的內容上傳到服務器&#xff0c;我們以嵌套的形式進行打包&#xff0c;找到index.…

Ansible提權sudo后執行報錯

1.問題 配置了sudo提權信息后&#xff0c;執行ansible-play報錯&#xff0c;報錯信息如下&#xff1a;2.原因 sudo沒有執行**/bin/sh的權限&#xff0c;而ansible腳本中依賴/bin/sh**&#xff0c;所以報錯了&#xff1a; 查看日志sudo tail -f /var/log/secure3.解決方式 修改*…

.NET報表控件ActiveReports發布v19.0——正式兼容 .NET 9

ActiveReports 是一款專注于 .NET 和 .NET Core 平臺的報表控件。通過拖拽式報表設計器&#xff0c;可以快速地設計 Excel表格、Word文檔、圖表、數據過濾、數據鉆取、精準套打等類型報表&#xff0c;全面滿足 WinForm、ASP.NET、ASP.NET MVC、WPF 平臺中各種報表的開發需要。同…

SCI論文選詞煉句

標準句子不能啰嗦&#xff1b;詞不能有問題&#xff0c;得是SCI中經常出現的&#xff0c;符合上下文的。SCI論文中常出現的摸棱兩可的詞單詞涵義例子Architecture指 整體系統設計方案&#xff0c;如網絡層次結構、模塊組合、激活函數選擇等深度學習模型架構Structure更泛泛&…

Qt deleteLater 延遲刪除原理

deleteLater 調用 事件發送 void QObject::deleteLater() {QCoreApplication::postEvent(this, new QDeferredDeleteEvent()); }首先該對象繼承QObject調用deleteLater&#xff0c; 內部會發送刪除事件QCoreApplication::postEvent(this, new QDeferredDeleteEvent()) 到事件循…

TypeScript SDK 升級:通過 Upload Relay 賦能更多應用

自 3 月主網上線以來&#xff0c;Walrus 開發者社區持續展現出強勁的發展勢頭&#xff1a; 當前 Walrus 已存儲超 758 TB 數據&#xff0c;為數百個項目提供支持。在 2025 年 6 月舉辦的 Sui Overflow 黑客松上&#xff0c;Walrus 成為最受歡迎的數據層。該賽事共收到 599 個項…

C#線程同步(二)鎖

目錄 1.lock 2.Monitor 3.鎖的其它要注意的問題 3.1同步對象的選擇 3.2什么時候該上鎖 3.3鎖和原子性 3.4嵌套鎖 3.5 死鎖 3.6 性能 4.Mutex 5.Semaphore 1.lock 讓我們先看一段代碼&#xff1a; class ThreadUnsafe {static int _val1 1, _val2 1;static void G…

鴻蒙智能居家養老系統構思(續二)—— 適老化烹飪中心詳細構思

一、背景在“寫給華為鴻蒙智家 —— 智能居家養老系統構思”一文中&#xff0c;結合對居家養老的理解及個人體驗&#xff0c;提出了基于鴻蒙OS實現居家養老系統的粗略構思。其中包含“吃得好”。當老人到了不能隨性外出活動、只能在家消耗時光時&#xff0c;除了一些看看電視、…