国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

MySQL的binlog需如何恢復數據

2024-07-24 12:33:16
字體:
來源:轉載
供稿:網友
  小編給大家分享一下MySQL的binlog如何恢復數據,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
 
  1. binlog
  binlog 我們中文一般稱作歸檔日志,如果大家看過松哥之前發的 MySQL 主從搭建,應該對這個日志有印象,當我們搭建 MySQL 主從的時候就離不開 binlog(傳送門:MySQL8 主從復制踩坑指南)。
 
  binlog 是 MySQL Server 層的日志,而不是存儲引擎自帶的日志,它記錄了所有的 DDL 和 DML(不包含數據查詢語句)語句,而且是以事件形式記錄,還包含語句所執行的消耗的時間等,需要注意的是:
 
  binlog 是一種邏輯日志,他里邊所記錄的是一條 SQL 語句的原始邏輯,例如給某一個字段 +1,注意這個區別于 redo log 的物理日志(在某個數據頁上做了什么修改)。
  binlog 文件寫滿后,會自動切換到下一個日志文件繼續寫,而不會覆蓋以前的日志,這個也區別于 redo log,redo log 是循環寫入的,即后面寫入的可能會覆蓋前面寫入的。
  一般來說,我們在配置 binlog 的時候,可以指定 binlog 文件的有效期,這樣在到期后,日志文件會自動刪除,這樣避免占用較多存儲空間。
  根據 MySQL 官方文檔的介紹,開啟 binlog 之后,大概會有 1% 的性能損耗,不過這還是可以接受的,一般來說,binlog 有兩個重要的使用場景:
 
  MySQL 主從復制時:在主機上開啟 binlog,主機將 binlog 同步給從機,從機通過 binlog 來同步數據,進而實現主機和從機的數據同步。
  MySQL 數據恢復,通過使用 mysqlbinlog 工具再結合 binlog 文件,可以將數據恢復到過去的某一時刻。
  2. 開啟 binlog
  為了演示方便,松哥這里在 Docker 中安裝了 MySQL,我們以此為例來開始今天的演示。如果小伙伴們還不懂 docker 的使用,可以在公眾號后臺回復 docker,有松哥寫的教程。
 
  首先我們在 docker 中安裝好 MySQL,然后進入到容器中,通過如下命令可以查看 binlog 是否開啟:
 
  這個 OFF 就表示 binlog 是一個關閉狀態,沒有開啟,接下來我們來開啟 binlog。
 
  開啟 binlog 主要是修改 MySQL 的配置文件 mysqld.cnf,該文件在容器的 /etc/mysql/mysql.conf.d 目錄下。
 
  針對該配置文件,我們做如下修改:
 
  # 這個參數表示啟用 binlog 功能,并指定 binlog 的存儲目錄
  log-bin=javaboy_logbin
 
  # 設置一個 binlog 文件的最大字節
  # 設置最大 100MB
  max_binlog_size=104857600
 
  # 設置了 binlog 文件的有效期(單位:天)
  expire_logs_days = 7
 
  # binlog 日志只記錄指定庫的更新(配置主從復制的時候會用到)
  #binlog-do-db=javaboy_db
 
  # binlog 日志不記錄指定庫的更新(配置主從復制的時候會用到)
  #binlog-ignore-db=javaboy_no_db
 
  # 寫緩存多少次,刷一次磁盤,默認 0 表示這個操作由操作系統根據自身負載自行決定多久寫一次磁盤
  # 1 表示每一條事務提交都會立即寫磁盤,n 則表示 n 個事務提交才會寫磁盤
  sync_binlog=0
 
  # 為當前服務取一個唯一的 id(MySQL5.7 之后需要配置)
  server-id=1
  各項配置的含義松哥已經在注視中說明了。截圖如下:
 
  配置完成后,執行如下命令重啟 mysql 容器(mysql1 是我這里容器的名字):
 
  docker restart mysql1
  重啟之后,再次執行 show variables like 'log_bin%'; 即可看到 binlog 已經開啟了。
 
  這里除了 log_bin 變量外,還有兩個變量名也值得我們關注:
 
  log_bin_basename:這個是將來產生的 binlog 日志文件的名稱前綴,換句話說,根據大家目前所看到的配置,將來產生的 binlog 日志文件名為 javaboy_logbin.xxx,這個文件中將會用來記錄所有的 DDL 和 DML 語句事件。
  log_bin_index:這個是 binlog 的索引文件,保存了所有 binlog 的目錄,因為 binlog 可能會有多個。我們可以來查看一下現在的 javaboy_logbin.index 文件:
 
  可以看到,目前只有一個 logbin 文件。
 
  3. 常見 binlog 操作
  接下來我們再來介紹幾個常見的 binlog 操作命令。
 
  查看所有 binlog 日志
  通過如下方式我們可以查看 binlog 日志列表:
 
  show master logs;
 
  可以看到,我這里目前只有一個日志文件,文件名為 javaboy_logbin.000001,File_size 表示這個文件占用的字節大小是 154。
 
  查看 master 狀態
  這個命令我們在搭建 MySQL 主從的時候經常會用到,如下:
 
  這個時候可以看到最新的 binlog 日志文件名稱以及最后一個操作事件的 Position 值(這個值有啥用,我們后面會給大家詳細介紹)。
 
  刷新 binlog
  正常來說,一個 binlog 寫滿之后,會自動切換到下一個 binlog 開始寫,不過我們也可以執行一個 flush logs 命令來手動刷新 binlog,手動刷新 binlog 之后,就會產生一個新的 binlog 日志文件,接下來所有的 binlog 日志都將記錄到新的文件中。如下:
 
  可以看到,我們刷新日志之后,再通過 show master logs 去查看日志,發現日志文件已經多了一個新產生的了,然后再通過 show master status 去查看最新的日志文件信息,發現也已經變為 javaboy_logbin.000002。
 
  重置 binlog
  reset master 可以重置 binlog 日志文件,讓日志重新從 000001 開始記錄,不過如果當前主機有一個或者多個從機在運行,那么該命令就運行不了(因為從機是通過 binlog 來實現數據庫同步的,主機把 binlog 清空了,從機會報找不到 binlog 的錯誤)。
 
  查看 binlog
  由于 binlog 是二進制日志文件,所以要是直接打開,那肯定是看不了的:
 
  MySQL的binlog如何恢復數據
 
  沒有看到任何有用的信息。
 
  為了查看 binlog,MySQL 為我們提供了兩個官方工具,我們一個一個來看,首先是 mysqlbinlog 命令,如下:
 
  雖然看起來亂糟糟的,不過仔細看著其實都有跡可循。因為我這里是一個新安裝的數據庫,里邊只是創建了一個名為 javaboy 的庫,然后創建了一個名為 user 的表加了兩條數據,其他什么事情都沒做,所以創建庫的腳本我們其實能夠從紛雜的文件中找到。
 
  產生的日志文件中有一個 end_log_pos 是日志文件的 pos 點,這個將來在數據恢復的時候有用。
 
  不過這種查看方式不夠人性化,我們說 binlog 是按照事件來記錄日志的,所以如果我們能夠按照事件的方式查看日志,就會好很多,我們再來看看如下一個命令:
 
  show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
  這個表示以事件的方式來查看 binlog,這里涉及到幾個參數:
 
  log_name:可以指定要查看的 binlog 日志文件名,如果不指定的話,表示查看最早的 binlog 文件。
  pos:從哪個 pos 點開始查看,凡是 binlog 記錄下來的操作都有一個 pos 點,這個其實就是相當于我們可以指定從哪個操作開始查看日志,如果不指定的話,就是從該 binlog 的開頭開始查看。
  offset:這是是偏移量,不指定默認就是 0。
  row_count:查看多少行記錄,不指定就是查看所有。
  我們來看一個簡單的例子:
 
  show binlog events in 'javaboy_logbin.000001';
 
  這下就清晰多了,我們可以看到之前的所有操作,例如:
 
  在 Pos 219-322 之間創建了一個庫。
  在 Pos 387-537 之間創建了一張表。
  在 Pos 677-780 之間添加了一條記錄。
  …
  4. 數據恢復實戰
  好啦,有了前面的基礎知識準備,接下來松哥來給大家手把手演示一個刪庫/恢復的場景。
 
  我先來說說我這個數據庫目前的情況。
 
  這是一個新安裝的數據庫,里邊我新建了一個數據庫名為 javaboy,javaboy 庫中新建了一張表名為 user,user 中有兩條記錄,如下:
 
  現在假設我們定期(每周三凌晨三點)對數據庫進行備份。
 
  現在凌晨三點了,數據庫自動備份開始了,我們通過如下命令將數據庫備份成 SQL 腳本,如下:
 
  mysqldump -uroot -p --flush-logs --lock-tables -B javaboy>/root/javaboy.bak.sql
 
  這里有幾個參數跟大家解釋下:
 
  -u、-p 這兩個就不用說了。
  –flush-logs:這個表示在導出之前先刷新 binlog,刷新 binlog 之后將會產生新的 binlog 文件,后續的操作都存在新的 binlog 中。
  –lock-tables:這個表示開始導出前,鎖定所有表。需要注意的是當導出多個數據庫時,–lock-tables 分別為每個數據庫鎖定表,因此這個選項不能保證導出文件中的表在數據庫之間的邏輯一致性,不同數據庫表的導出狀態可以完全不同。
  -B:這個表示指定導出的數據庫名稱,如果使用 --all-databases 或者 -A 代替 -B 表示導出所有的數據庫。
  以上命令執行完成后,會在 /root 目錄下生成一個 javaboy.bak.sql 文件,該文件就是備份的 sql 文件了。
 
  這是星期三凌晨三點發生的事情。
 
  接下來到了星期四早上,來上班了,一頓操作后,往數據庫中又添加了兩條操作,如下:
 
  接下來,小 X 今天跟領導吵架了很不爽,決定刪除跑路:
 
  領導發現了大驚,當即要求立馬恢復數據。這時候該你表現了。
 
  首先,我們有星期三凌晨的備份文件,先用那個文件進行數據恢復:
 
  恢復之后,現在到星期三早上凌晨三點的數據有了。
 
  從星期三早上凌晨三點到星期四的數據現在沒了。
 
  這個時候我們就要借助于 binlog 來恢復了。大家還記得,我們星期三凌晨三點執行備份的時候,用了一個參數叫做 --flush-logs,使用了該參數表示從備份那一刻起,新的 binlog 將產生在一個新的日志文件中,對于我們這里來說,新的 binlog 文件當然就是 javaboy_logbin.000002 了,我們去查看一下該文件:
 
  show binlog events in 'javaboy_logbin.000002';
  我這里生成的該文件比較長,我截取其中一部分:
 
  可以看到,在 764-865 這個 Pos 中發生了刪庫跑路事件,那么我們只需要回放該文件將數據恢復到 764 這個位置即可。
 
  由于 javaboy_logbin.000002 文件是在星期三凌晨三點備份之后產生的新文件,因此這個文件從起始到 764 這個 Pos 之間的操作,就是星期三凌晨三點到刪庫之前的操作了。
 
  那么我們來看下通過 binlog 來恢復數據的命令:
 
  mysqlbinlog /var/lib/mysql/javaboy_logbin.000002 --stop-position=764 --database=javaboy | mysql -uroot -p
  那么這里涉及到兩個參數:
 
  –stop-position=764 表示恢復到 764 這個 Pos,不指定的話就把按整個文件恢復了,如果按當前文件恢復的話,由于這個 binlog 文件中有刪除數據庫的語句,那么就會導致執行完該 binlog 之后,javaboy 庫又被刪除了。
  –database=javaboy 表示恢復 javaboy 這個庫。
  另外還有一個我們這里沒用到的參數叫做 --start-position,這個表示起始的 Pos,不指定的話表示從頭開始數據恢復。
 
  好啦,弄完之后,再來查看數據庫:

  數據恢復啦~
 
  注意:所有操作之前,記得該備份就備份(防止你操作錯了又回不去),松哥為了省事上面省略了一些備份操作。
 
  以上是“MySQL的binlog如何恢復數據”這篇文章的所有內容,感謝各位的閱讀!

(編輯:武林網)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 云龙县| 正阳县| 边坝县| 蛟河市| 石河子市| 南宁市| 无棣县| 和顺县| 藁城市| 尼玛县| 湘潭市| 漳州市| 桂东县| 兴业县| 岱山县| 六枝特区| 自治县| 万全县| 靖边县| 泊头市| 九寨沟县| 泗阳县| 广德县| 平果县| 宜良县| 平度市| 祁阳县| 吉林省| 连山| 壤塘县| 兰考县| 博湖县| 武陟县| 曲沃县| 彰化县| 福建省| 阳西县| 綦江县| 云梦县| 南昌县| 桂林市|