關于MySQL中的binlog

介紹

undo log 和 redo log是由Inno DB存儲引擎生成的。

在MySQL服務器架構中,分為三層:連接層、服務層(server層)、執行層(存儲引擎層)

bin logbinary log的縮寫,即二進制日志。

MySQL在完成一次DML操作后,Server層還會生成一條binlog,等事務提交之后, 還會將該事務執行過程中產生的所有binlog統一寫入到binlog日志文件中

binlog日志文件中保存了所有數據庫的所有表結構的變化和表數據的變化

bin log的作用

bin log主要用于下面兩個方面:

  • 主從復制

對于”雙11“這種級別的千萬級高并發,單臺數據庫服務器是扛不住的!

為了提供并發處理的能力,一般會部署多態MySQL服務器,這些服務器中維護著相同的數據副本。這些MySQL服務器組成一個MySQL集群

一個非常典型的部署方案就是一主多從在這些MySQL服務器中,有一個主服務器Master和多臺從服務器Slave

主服務器只負責數據變更,而從服務器負責查詢,在大部分情況下,查詢是最耗時的,因為多臺從服務器負責查詢操作,分擔了并發壓力。

對于DDL、DML請求,將就給主服務器去執行

對于查詢Select請求,就交給從服務器,因為每個服務器中都維護著相同的數據副本,所以交給任意一個從服務器即可

為了讓各個從服務器中存儲的數據 和主服務器中的數據保持一致,每當我們改變了主服務器中的表結構或者表數據,就需要將這些變更信息同步給各個從服務器,此時bin log就發揮作用了

bin log中保存了所有數據庫的所有表的變化信息,從服務器只需要讀取主服務器的bin log,就能完成主從服務器之間的數據同步

  • 系統備份恢復

如果不小心把整個數據庫的數據都刪除了,能使用redo log日志恢復數據嗎?

當然不能,因為redo log是Inno DB產生的日志文件,Inno DB是表級別的(在創建表時指定表的存儲引擎),當直接刪除了整個數據庫,那么這些redo log日志也不會存在了,即使這些redo log存在,也并不能將這個表的所有數據都恢復,因為redo log日志文件存在復用的情況,對于哪些已經刷新到磁盤的redo log,redo log已經沒有存在的必要性了所以會覆蓋掉,新寫的redo log會覆蓋掉之前的舊的redo log,因此redo log只能保證恢復在事務提交之前的部分數據

因為 redo log 文件是循環寫,是會邊寫邊擦除日志的,只記錄未被刷入磁盤的數據的物理日志,已經刷入磁盤的數據都會從 redo log 文件里擦除。

此時又輪到binlog發揮作用了

因為bin log記錄了所有庫的所有表的變更信息,所以可以借助binlog來完成數據恢復

配置使用binlog

查看MySQL服務器是否開啟了bin log

 show variables like 'log_bin';
  • 查詢到的值是ON,代表當前服務器已開啟binlog日志功能
  • 如果為OFF,代表當前服務器沒有開啟bin log功能

如果當前服務器沒有開啟bin log,需要手動開啟。

關閉服務器,重新啟動服務器時添加此啟動配置項

--log-bin [=base_name]

base_name是用來記錄bin log日志文件的基名稱

bin log日志文件會保存在MySQL的數據目錄下,bin log日志文件不是一個文件,而是一組文件,這一組文件的命名規則是這樣的

basename.000001
basename.000002
basename.000003
basename.000004
....

basename作為基名稱,后面的序號遞增。

如果需要修改bin log文件的基名稱,可以利用啟動項參數修改

--log-bin [=basename]

如果沒有指定基名稱,那么MySQL服務器會默認以主機名-bin作為binlog日志文件的基名稱。

MySQL 8.x 會默認以binlog作為基名稱

binlog.000001
binlog.000002
....

查看binlog中的內容

binlog日志文件并不能直接查看,因為是二進制文件。

binlog中記錄數據庫發生變更的各種事件,事件類型非常多,其實并不需要刻意關注binlog中的內容。

如果真的想要查看binlog的內容,則可以借助MySQL提供的mysqlbinlog工具

mysqlbinlog工具作為可執行文件,存放在MySQL安裝目錄的bin目錄下

將需要查看的binlog日志文件作為mysqlbinlog命令的參數

mysqlbinlog ./data/binlog.0000001

binlog日志文件格式

隨著MySQL版本的更新,binlog文件格式也有不同的版本,在此以v4最新版本的文件格式來講解。

一個binlog日志文件的基本格式主要由兩部分組成:

  • 文件固定頭部
  • 事件

image-20230808111658332

  • 每個binlog日志文件的前4個字節都是固定的,用來作為此文件的一個標識,不用關心。
  • 每個binlog日志文件都有若干個事件組成,這些事件就是對數據庫表的變更事件。

每個事件又可以分為兩部分:

  • 事件頭 event header,用來對這個事件進行描述的信息
  • 真實數據 data

image-20230808112003841

好了,這就是binlog日志文件的基本格式,知道這么多就行了。

兩種binlog

binlog日志文件中存儲的事件就是對數據庫變更的信息,那么如何描述這個事件又有兩種方式。

一條sql語句,如果binlog-format不同,那么可能生成不同類型的binlog事件,大致就可以分為基于語句Statement和基于行row兩種類型的binlog

  • 當以啟動選項--binlog-format=STATEMENT啟動MySQL服務器時,生成的binlog稱作基于語句的日志。此時只會將一條SQL語句將會被完整的記錄到binlog中,而不管該語句影響了多少記錄。

  • 當以啟動選項--binlog-format=ROW啟動MySQL服務器時,生成的binlog稱作基于行的日志此時會將該語句所改動的記錄的全部信息都記錄上。

  • 當以啟動選項 --binlog-format=MIXED啟動MySQL服務器時,生成的binlog稱作基于行的日志。此時在通常情況下采用 基于語句的日志 ,在某些特殊情況下會自動轉為基于行的日志

簡單總結:

  • 基于語句的binlog 只將更新語句是什么記錄下來了。
  • 基于行的binlog 將更新語句執行過程中每一條記錄更新前后的值都記錄下來了

基于語句的binlog可能會導致主從數據不一致的情況,例如下面這條語句

INSERT INTO t(c) SELECT c FROM other_table;

這條語句是從其他表中查詢數據并插入到一張表中。

但是對于這條子查詢SELECT c FROM other_table;,可能由于不同服務器版本、不同的系統變量導致同一條語句的結果順序不同,那么在插入時,自動生成主鍵,不同的順序最終生成的記錄的主鍵值不同。

原因是在基于語句的binlog中,只會記錄這條sql語句,從庫去執行這條sql語句,并不會關心更新前后的記錄值。

但是在基于行的binlog中,還保存了這條記錄更新前后的值,從庫在執行完sql語句后,還會將這條記錄調整到一致的狀態,從而保證主從數據一致性。

redo、undo、buffer pool、binlog的執行順序

當執行一條UPDATE語句時,redo、undo、binlog的寫入順序是怎樣的?

具體的一條記錄的更新流程如下:

  1. 現在B+樹中定位到該記錄(鎖定讀),如果該數據所在的頁面不再Buffer pool中,則先將這一頁數據從磁盤加載到buffer pool中

  2. 讀取到記錄后,判斷記錄更新前后是否一樣,一樣的話就跳過,不用更新了

  3. 首先更新聚簇索引記錄

    更新聚簇索引記錄時:

    1. 首先向undo頁面寫入undo日志,因為這是在修改頁面,所以修改undo頁面前需要先記錄這次的redo日志
    2. 真正的更新記錄,在更新前記錄響應的redo日志
  4. 更新其他的二級索引

至此,一條記錄更新完成

redo 和 bin log的區別

  1. 適用對象不同
  • binlog是MySQL的Server層實現的日志,是整個MySQL服務器級別的
  • redo log是InnoDB存儲引擎實現的日志,是表級別的
  1. 文件格式不同

  2. 寫入方式不同

  • binlog是追加寫,寫滿一個文件,就會新創建一個文件,不會覆蓋以前的文件
  • redo log是循環寫,日志空間的大小是固定的,寫滿了就會從頭開始寫,覆蓋掉之前的redo Log內容
  1. 用途不同
  • binlog 主要用于主從復制、備份恢復
  • redo log主要用于發生故障時,表臟數據的恢復

主從復制

前面已經介紹過主從復制,MySQL的主從復制依賴于bin log

復制過程就是將binlog中的數據從主庫傳輸到從庫

這個過程是異步的,

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rLPw0Yy5-1691478160467)(https://cdn.xiaolincoding.com/gh/xiaolincoder/mysql/how_update/%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E8%BF%87%E7%A8%8B.drawio.png?image_process=watermark,text_5YWs5LyX5Y-377ya5bCP5p6XY29kaW5n,type_ZnpsdHpoaw,x_10,y_10,g_se,size_20,color_0000CD,t_70,fill_0)]

MySQL主從復制的三個步驟:

  1. Master 寫入binlog:主服務器寫binlog日志,提交事務
  2. Slave 同步 binlog:把binlog復制到所有從庫上,每個從庫把binlog保存到暫存日志中
  3. 回訪binlog:從服務器執行完數據的更新后,記錄到自己的bin log日志文件中

具體的過程:

  • MySQL 主庫在收到客戶端提交事務的請求之后,會先寫入 binlog,再提交事務,更新存儲引擎中的數據,事務提交完成后,返回給客戶端“操作成功”的響應。
  • 從庫會創建一個專門的 I/O 線程,連接主庫的 log dump 線程,來接收主庫的 binlog 日志,再把 binlog 信息寫入 relay log 的中繼日志里,再返回給主庫“復制成功”的響應。
  • 從庫會創建一個用于回放 binlog 的線程,去讀 relay log 中繼日志,然后回放 binlog 更新存儲引擎中的數據,最終實現主從的數據一致性。

從服務器的數量是不是越多越好?這樣分擔下來的流量不就更小,每個數據庫的壓力更小嗎?

不是的

從服務器數量增加,對于主服務器來說,IO連接的數量越多,對于每一個從服務器的連接,主服務器都需要創建一個log dump線程來專門負責與這個從服務器的請求。從服務器的數量越多,對主服務器的資源消耗越多,同時還要受限于主庫的網絡帶寬。

在實際使用中,一般遵循一主一副多從的設計,也就是一個主服務器,一個備用的主服務器(在主服務器崩潰后擔任主服務器),2-3個從服務器

巨人的肩膀

  • 小林Coding——MySQL日志
  • 《MySQL是怎么運行的》

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

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

相關文章

android開發之Android 自定義滑動解鎖View

自定義滑動解鎖View 需求如下: 近期需要做一個類似屏幕滑動解鎖的功能,右劃開始,左劃暫停。 需求效果圖如下 實現效果展示 自定義view如下 /** Desc 自定義滑動解鎖View Author ZY Mail sunnyfor98gmail.com Date 2021/5/17 11:52 *…

數據結構——線性表

文章目錄 線性表的定義和基本操作順序表線性表的鏈式表示 線性表的定義和基本操作 線性表是具有相同數據類型的(n≥0)個數據元素的有限序列,其中n為表長,當n0時線性表是一個空表。若用L命名線性表,則其中一般表示為:L(a1,a2,a3, …

.NET實現解析字符串表達式

一、引子功能需求 我們創建了一個 School 對象&#xff0c;其中包含了教師列表和學生列表。現在&#xff0c;我們需要計算教師平均年齡和學生平均年齡。 //創建對象 School school new School() {Name "小菜學園",Teachers new List<Teacher>(){new Teach…

CCLINK轉MODBUS-TCP網關cclink通訊接線圖 終端電阻

大家好&#xff0c;今天我們要聊的是生產管理系統中的CCLINK和MODBUS-TCP協議&#xff0c;它們的不同使得數據互通比較困難&#xff0c;但捷米JM-CCLK-TCP網關的出現改變了這一切。 1捷米JM-CCLK-TCP是一款自主研發的CCLINK從站功能的通訊網關&#xff0c;它的主要功能是將各種…

后端開發5.Redis的搭建

使用docker安裝 Redis【redis】(6379) 拉取Redis鏡像 docker pull redis:6.2.6 啟動Redis容器 docker run -di --name=redis -p 6379:6379 redis:6.2.6 啟動Redis容器并設置密碼 docker run -di --name=redis -p 6379:6379 redis:6.2.6 --requirepass "密碼" 測…

D455+VINS-Fusion+surfelmapping 稠密建圖(三)

繼續&#xff0c;由surfelmapping建立的點云生成octomap八叉樹柵格地圖 一、安裝OctomapServer 建圖包 安裝插件 sudo apt-get install ros-melodic-octomap-ros sudo apt-get install ros-melodic-octomap-msgs sudo apt-get install ros-melodic-octomap-server sudo apt-…

cubemx hal stm32 舵機 可減速 任意位置停止 驅動代碼

CubeMX配置 對于 STM32 F407VE 這里的84是來自APB1那路2倍頻得到&#xff1a; 代碼部分 兩個舵機都是180度的 servo.c #include "servo.h" #include "tim.h" #include "stdio.h"__IO uint32_t g_SteerUWT[2] {0}; uint16_t g_SteerDeg[…

React Native Maps的使用

介紹 React Native Maps是一個用于在React Native應用中顯示地圖的庫。它提供了許多功能&#xff0c;如顯示地圖、標記位置、繪制多邊形等。以下是React Native Maps的使用步驟&#xff1a; 使用 首先&#xff0c;你需要在你的React Native項目中安裝React Native Maps庫。可…

青大數據結構【2014】

一、單選 二、簡答 為了解決順序隊列的假溢出問題&#xff0c;提出了循環隊列&#xff0c;即把存儲隊列的表從邏輯上看成一個環 判別隊列空和滿有三種方法&#xff1a; 1&#xff09;采用計數器判別&#xff0c;空時&#xff0c;計數器為0&#xff1b;滿時&#xff0c;計數器…

【設計模式——學習筆記】23種設計模式——中介者模式Mediator(原理講解+應用場景介紹+案例介紹+Java代碼實現)

文章目錄 案例引入案例一普通實現中介者模式 案例二 介紹基礎介紹登場角色尚硅谷 《圖解設計模式》 案例實現案例一&#xff1a;智能家庭類圖實現 案例二&#xff1a;登錄頁面邏輯實現說明類圖實現 總結文章說明 案例引入 案例一 普通實現 在租房過程中&#xff0c;客戶可能…

css 實現 html 元素內文字水平垂直居中的N種方法

上一篇博文寫了div 中元素居中的N種常用方法&#xff0c;那么單個html元素&#xff1a;div&#xff08;塊級元素代表&#xff09;&#xff0c;span&#xff08;行內元素代表&#xff09;中的文字如何水平垂直都居中呢&#xff1f;實現方法如下&#xff1a; 本文例子使用的 html…

WebAPIs 第二天

DOM事件基礎 事件監聽事件類型事件對象 一.事件監聽 ① 概念&#xff1a;就是讓程序檢測是否有事件發生&#xff0c;一旦有事件觸發&#xff0c;就立即調用一個函數做出響應&#xff0c;也成為綁定事件或者注冊事件 ② 語法&#xff1a;元素對象.addEventListener(事件類型&…

機器學習---對數幾率回歸

1. 邏輯回歸 邏輯回歸&#xff08;Logistic Regression&#xff09;的模型是一個非線性模型&#xff0c; sigmoid函數&#xff0c;又稱邏輯回歸函數。但是它本質上又是一個線性回歸模型&#xff0c;因為除去sigmoid映射函 數關系&#xff0c;其他的步驟&#xff0c;算法都是…

從零開始,貪吃蛇小游戲系列專欄完美收官!

&#x1f3ae; 從零開始&#xff0c;貪吃蛇小游戲系列專欄完美收官&#xff01; &#x1f40d; 各位游戲開發探索者們&#xff0c;大家好&#xff01;我是[億元程序員]&#xff0c;一位擁有8年游戲開發經驗的主程。經過一段時間的努力&#xff0c;我很高興地宣布&#xff0c;我…

阿里云預裝LAMP應用導致MySQL不顯示訪問密碼如何解決

&#x1f600;前言 本篇博文是關于阿里云云服務器ECS部署MySQL過程中出現的一下坑&#xff0c;希望能夠幫助到您&#x1f60a; &#x1f3e0;個人主頁&#xff1a;晨犀主頁 &#x1f9d1;個人簡介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以幫助到大家…

SUB-1G SOC芯片DP4306F 32 位 ARM Cortex-M0+內核替代CMT2380F32

DP4306F是一款高性能低功耗的單片集成收發機&#xff0c;集成MO核MCU&#xff0c;工作頻率可覆蓋200MHiz^ 1000MHz。 支持230/408/433/470/868/915頻段。該芯片集成了射頻接收器、射頻發射器、頻率綜合器、GFSK調制器、GFSK解調器等功能模塊。通過SPI接口可以對輸出功率、頻道選…

gitlab-Runner搭建

root wget https://packages.gitlab.com/runner/gitlab-runner/packages/fedora/29/gitlab-runner-12.6.0-1.x86_64.rpm/download.rpm rpm -ivh download.rpm ---- 安裝 rpm -Uvh download.rpm -----更新升級 然后運行&#xff1a; gitlab-runner register --url https://git…

RabbitMQ相關面試題

用到了哪些MQ?什么使用場景?MQ的組成部分?MQ宕機了怎么辦?如何進行持久化的? MQ的選型? Kafka:高吞吐量、低延遲的分布式消息隊列,主要用于大規模數據處理和流式處理 RocketMQ:RocketMQ是阿里巴巴開源的分布式消息隊列,具有高吞吐量、低延遲、高可靠性等特點 RabbitM…

【Go 基礎篇】Go語言浮點類型:探索浮點數的特點與應用

介紹 浮點數是計算機編程中用于表示實數的一種數據類型&#xff0c;用于處理具有小數部分的數值。Go語言&#xff08;Golang&#xff09;提供了兩種主要的浮點數類型&#xff1a;float32和float64&#xff0c;分別用于單精度和雙精度浮點數的表示。本篇博客將深入探討Go語言中…

38 | 浦發銀行股票分析案例

本文將通過一個浦發銀行股票分析案例,探討如何從多個維度對股票進行分析,包括基本面、技術面和市場環境等因素。我們將深入挖掘浦發銀行的財務數據、業務模式以及市場定位,以了解其內在價值和潛在風險。同時,我們還將考察技術面的指標,如價格走勢、均線形態等,以揭示市場…