1. 程式人生 > 其它 >mysql日誌與備份恢復

mysql日誌與備份恢復

mysql 日誌管理與備份恢復

目錄

一 Mysql 日誌管理


1 ,修改配置檔案開啟mysql 日誌


vim  /etc/my.cnf
....
#在配置檔案的 mysqld設定中
[mysqld]
#配置錯誤日誌,用來記錄mysql啟動,停止,或執行時發生的錯誤資訊。預設已經開啟
log-error=/usr/local/mysql/data/mysql_error.log

#配置通用查詢日誌,用來記錄mysql的所有連線和語句。預設時關閉的
general_log=ON
general_log_file=/usr/local/mysql/data/mysql_general.log

#配置二進位制日誌(binlog),用來記錄所有更新了資料包或者已經潛在更新了資料的語句,記錄了資料的更改,可以用於資料恢復,預設已經開啟。
#也可以設定為log_bin=mysql-bin
log-bin=mysql-bin
#設定binlog日誌的記錄方式
binlog_format=mixed

#配置慢查詢日誌,用來記錄所有執行時間超過log_query_time秒的語句,可以找到那些查詢語句執行時間長,以便於優化。預設時關閉的
slow_query_log=ON
slow_query_log_file=/usr/local/mysql/data/mysql_slow_query.log
long_query_time=5  #設定超過5秒執行的語句被記錄,預設時為10秒





#重啟mysqld 服務
systemctl restart mysqld 

#檢視mysql工作目錄的data目錄中生成的日誌檔案 
ls /usr/local/mysql/data


2 在mysql 中檢視與設定日誌(重啟mysqld服務失效)


2.1 通用日誌檢視與設定


(1) 檢視通用日誌設定

#檢視通用日誌設定
show variables like 'general%';





(2) 配置通用日誌設定

#開啟通用日誌
set global general_log=on;
#設定通用日誌路徑
set  global general_log_file='/usr/local/mysql/data/mysql_general.log';


2.2 慢日誌檢視與設定


(1) 檢視你慢查詢日誌狀態

#檢視慢查詢日誌是否開啟
show  variables like '%slow%';
#檢視長查詢時間設的值
 show  variables like 'long_query_time';
 show  global  variables like 'long_query_time';


(2 ) 開啟慢查詢日誌

#開啟慢查詢日誌 
set global slow_query_log=on;
#設定慢查詢日誌的路徑
set global slow_query_log_file='/usr/local/mysql/data/mysql_slow_query.log';
#設定全域性與當前的長查詢時間
set global long_query_time=5;
set  long_query_time=5;


2.3 binlog日誌檢視是否開啟與臨時關閉bin-log寫入


(1) 檢視bin-log日誌是否開啟

 show variables like '%log_bin%';


(2) 臨時關閉或開啟bin-log日誌寫入。

使用命令 "show variables like '%log_bin%;" 檢視到的變數 log_bin 是一個只讀變數。但是,我們可以修改當前會話變數 sql_log_bin,這個變數沒有全域性global 變數。

我們可以修改 sql_log_bin的值,當為0或者為off時,則臨時關閉命令寫入bin-log日誌的功能,如果值為1或者為on,則開啟命令寫入bin-log日誌功能

#關閉資料庫命令寫入binlog日誌功能
set sql_log_bin=1;
#開啟資料庫命令寫入binlog日誌功能
set sql_log_bin=1;



二 資料庫備份的重要性與備份分類


1 資料庫備份的重要性

  • 備份的主要目的是災難恢復
  • 在生產環境中,資料的安全性至關重要
  • 任何資料的丟失都可能產生嚴重的後果


2 資料庫備份分類


2.1 從物理和邏輯的角度分類

  • 物理備份: 對資料庫作業系統的物理檔案(如資料檔案、日誌檔案等)的備份
  • 邏輯備份:對資料庫邏輯元件(如:表等資料庫物件)的備份

物理備份方法:

  • 冷備份(離線備份):是在關閉資料庫的時候進行的
  • 熱備份(聯機備份):資料庫處於執行狀態,依賴於資料庫的日誌檔案
  • 溫備份:資料庫鎖定表格(不可寫入但可讀)的狀態下進行備份操作


2.2 從資料庫的備份策略角度分類

  • 完全備份:每次對資料庫進行完整的備份
  • 差異備份:備份自從上次完全備份之後被修改過的檔案
  • 增量備份:只有在上次完全備份或者增量備份後被修改的檔案才會被備份


3 常見的備份方法

  • 物理冷備
    • 備份時,資料庫處於關閉狀態,直接打包資料庫檔案
    • 備份速度快,恢復也是最簡單的

  • 專用工具mysqldump 或者mysqlhotcopy
    • mysqldump 常用的邏輯備份工具
    • mysqlhotcopy 僅擁有備份 myisam 和archive 表

  • 啟用二進位制日誌binlog日誌進行增量備份
    • 進行增量備份,需要重新整理二進位制日誌

  • 第三方工具備份
    • 免費的mysql 熱備份軟體Percona XtraBackup



三: 資料庫的完全備份


1 物理冷備份與恢復


  1. 關閉mysql 資料庫
  2. 使用tar 命令直接打包資料庫資料夾(工作目錄下的data目錄)
  3. 直接替換現有Mysql目錄即可


1.1 物理冷備份

#停止mysqld服務
systemctl stop mysqld
#建立專門用來存放資料庫備份檔案的目錄
mkdir /backu
#打包資料資料夾
tar Jcvf /backup/mysql_all_$(date +%F).tar.xz /usr/local/mysql/data/
ls /backup


1.2 刪除資料庫裡的任意資料

systemctl restart mysqld
mysql -uroot -pabc123 -e 'drop database bank;'
mysql -uroot -pabc123 -e 'show databases;'


1.3 恢復資料

#先停止mysql 服務
systemctl stop  mysqld
#解壓備份的tar包
tar -Jxf mysql_all_2021-09-01.tar.xz
#將原來的mysql工作目錄的data目錄移走備份
mv /usr/local/mysql/data/ ./data.bak
#將tar包解壓後目錄usr裡的data目錄 移動到mysql的工作目錄
mv usr/local/mysql/data/ /usr/local/mysql/
#重啟mysqld服務
systemctl start mysqld.service
#查詢資料庫,發現bank庫恢復了
mysql -uroot -pabc123 -e 'show databases;'


2 mysqldump 備份與恢復


2.1 mysqldump 備份

(1) 完全備份一個或多個完整 的庫(包括其中所有的表)

格式

mysqldump -u root -p[密碼] --databases 庫名1 [庫名2] .... > /備份路徑/備份檔名.sql

#備份資料庫 bank 庫(備份單個數據庫可以不用加 --databases)
mysqldump -uroot -pabc123 --databases bank > /backup/bank.sql
#備份資料庫 test, test2 (備份多個庫,要加--databases)
mysqldump -uroot -pabc123 --databases  test test2 > /backup/tests.sql
ls /backup


(2) 完全備份mysql 伺服器中所有的庫

mysqldump -uroot -p密碼 --all-databases > /備份路徑/備份檔名.sql

#完全備份資料庫中所有的庫
mysqldump -uroot -pabc123 --all-databases > /backup/all_bak.sql


(3) 完全備份資料庫中的部分表

mysqldump -uroot -p密碼 [-d ] 庫名 [表名1] 表名2 ..... > /備份路徑/備份檔名.sql

-d 選項:表示使用-d 選項,表示只備份資料表的表結構。不使用-d 表示連同資料也一起備份

#備份資料表,連同資料也一起備份(備份資料表時,不可以加--databases 選項)
mysqldump  -uroot -pabc123  test location store_info > /backup/test_tables.sql
#備份資料表,只備份資料表的表結構
mysqldump  -uroot -pabc123   -d  test2 Total_Sales city > /backup/test2_tables.sql


(4) 檢視備份檔案



2.2 mysql 完全恢復


(1) 恢復資料庫

mysql -uroot -p密碼 < /備份檔案路徑/備份檔名.sql

#刪除資料庫bank
mysql -uroot -pabc123 -e 'drop database bank;'
#線上恢復資料庫bank
mysql -uroot -pabc123 < /backup/bank.sql


(2)恢復資料表

mysql -uroot -p密碼 庫名 < /備份檔案路徑/備份檔名.sql

當備份檔案中只包含表的備份,而不包含建立的庫的語句時,執行匯入操作時,必須指定庫名,並且,目標庫必須存在

#如果沒有庫,則先建立資料庫
mysql -uroot -pabc123 -e 'create database bank;'
#向資料庫中匯入資料表
mysql -uroot -pabc123 bank  < /backup/bank_employee.sql



四: mysql 增量備份


1 增量備份的特點


  • 增量備份是自上一次備份後增加/變化的檔案或者內容
  • 沒有重複資料,備份量不大,時間短
  • 恢復需要上次-完全備份及完全備份之後的所有增量備份才能恢復,而且要對所有增量備份進行逐個反推恢復


2 mysql 的增量被與二進位制檔案binlog


mysql沒有提供直接的增量備份方法,需要通過mysql提供的二進位制日誌間接實現增量備份


mysql二進位制日誌對備份的意義

  • 二進位制日誌儲存了所有更新或者可能更新資料庫的操作
  • 二進位制日誌在啟動MySQL伺服器後開始記錄,並在檔案達到max_ binlog_ size所設 置的大小或者接收到flush logs命令後重新建立新的日誌檔案
  • 只需定時執行flush logs方法重新建立新的日誌,生成二進位制檔案序列,並及時把這些日誌儲存到安全的地方就完成了-一個時間段的增量備份


3 mysql 增量備份


3.1 開啟二進位制日誌功能

二進位制binlog有3種不同的記錄格式:statement(基於sql語句),row(基於行),mixed(混合模式),預設格式是statement

statement 模式:每一條修改資料的sql都會記錄在binlog種。不需要記錄每一行的變化,減少了binlog日誌量,節約了IO,提高了效能。但是mysql 的複製,像一些特定函式功能,slave可與master上要保持一致會有很多相關問題(


row模式:不記錄sql語句上下文相關資訊,僅儲存哪條記錄被修改,清楚的記錄下每一行資料修改的細節。但是會產生大量的日誌內容,佔用IO資源


mixed模式:基於statement 和 row 兩種模式混合使用。一般語句修改使用statement格式儲存,但類似與函式操作,statement無法完成主從賦值的操作時,則使用row格式儲存

vim /etc/my.cnf
[mysqld]
.....
log-bin=mysql-bin  #開啟binlog日誌
binlog_format=mixed  #使用mixed混合模式
server-id=1        #節點id
.....



systemctl restart mysqld
#mbinlog日誌設定儲存在工作目錄的data目錄中
ls /usr/local/mysql/data


3.2 重新整理binlog日誌

開啟binlog日誌後,mysql資料庫裡執行的需改資料的命令都會記錄在binlog日誌中。當日志達到設定的大小,或者執行重新整理日誌的命令,就會生成新的binlog日誌。重新整理後,儲存每天產生的binlog日誌,即增量備份可以每週三或週四進行一此完全備份,然後每天進行增量備份

mysqladmin -uroot -p密碼 flush-log

或者

mysql資料庫命令 : flus logs

#mysqladmin 重新整理binlog日誌
mysqladmin  -uroot -pabc123 flush-log

#通過myql資料庫命令flush logs重新整理日誌 
# linux 命令列中,-e 選項,可以在命令列非互動執行mysql資料庫命令。資料庫裡可以也可也使用 \!linux命令,在 mysql資料庫裡執行linux命令如 \! ping 127.0.0.1 )
mysql  -uroot -pabc123 -e 'flush logs'


3.3 插入新資料,模擬資料的增加


#進入mysql資料庫

create database school;
create table school.class(id int primary key,name char(20));
insert into school.class values (1,'zhangsan');
insert into school.class values (2,'lisi');
insert into school.class values (3,'wangwu');
insert into school.class values (4,'zhaoliu');


3.4 重新整理binlog日誌

#重新整理日誌。
flush logs
#從資料庫裡執行linux命令,檢視data目錄下mysql-bin. 開頭的檔案
\! ls /usr/local/mysql/data/mysql-bin.*



4 檢視binlog日誌內容

mysqlbinlog --no-defaults --base64-output=decode-rows -v binlog日誌路徑 > 新的檔案

--base64-output=decode-rows: 使用64位編碼機制去解碼並按行讀取

-v:顯示詳細內容

#將二進位制檔案mysql-bin.000003轉碼後輸入到新的檔案/backup/mysql-bin.000003中
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000003 > /backup/mysql-bin.000003 

vim /backup/mysql-bin.000003


5 增量恢復


mysql 資料庫的增量恢復有三種

  • 一般恢復
    • 將所有備份的二進位制日誌內容全部恢復

  • 基於位置恢復
    • 資料庫在某一時間點可能即有錯誤的操作也有正確的操作
    • 可以基於精準的位置跳過錯誤的操作

  • 基於時間點恢復
    • 跳過某個發生錯誤的時間點實現資料的恢復


5.1 一般恢復

msyqlbinlog [--no-defaults] binlog日誌檔案 | mysql -uroot -p密碼


#刪除庫school
mysql -uroot -pabc123 -e 'drop database school;'
#從binlog日誌中恢復全部資料
mysqlbinlog  --no-defaults /usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -pabc123



5.2 基於位置恢復


mysqlbinlog --no-defaults --start-position='開始位置1' --stop-position='結束位置2' binlog日誌 | mysql -uroot -p密碼

--start-positon=''位置1':

  • 從位置1開始恢復。此位置應該選擇,想要開始恢復的sql語句前面的 ‘begin“欄位的前一個at 位置開始、


  • '如果後面不加--stop-position=''位置2',則表示從位置1開始恢復後面所有binlog日誌的內容.


--stop-position=‘位置2':

恢復到位置2。此位置應該選擇想要結束的sql語句後面的“commit”欄位後一個at位置開始

如果前面不加 --start-position=’位置1' ,則表示從目標binlog日誌最開啟位置恢復到位置2


#清空表記錄
mysql -uroot -pabc123 -e 'truncate table school.class;'

#想要只恢復id為2和3的表記錄,不恢復id為1和id為4的資料
#選擇開啟位置871,結束位置1524恢復期間的資料
mysqlbinlog --no-defaults --start-position='871'  --stop-position='1382'  \
/usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -pabc123



5.3 基於時間點恢復

mysqlbinlog --no-defaults --start-datetime='xxxx-xx-xx hh:mm:ss' --stop-datetime='xxxx-xx-xx hh:mm:ss' binlog日誌 | mysql -uroot -p密碼


基於時間點恢復與基於位置恢復差不多。時間格式有要求,類似於2021-09-03 12:12:12

--start-datetime='xxxx-xx-xx hh:mm:ss' :開始位置,應該以sql語句前begin欄位前面的時間為開始

-stop-datetime='xxxx-xx-xx hh:mm:ss':結束位置,應該以sql 語句後 commit 欄位的後面一個時間為結束

#清空資料表
mysql -uroot -pabc123 -e 'truncate table school.class;'

#以時間為節點,恢復id為2和id為3的兩條表記錄
mysqlbinlog --no-defaults --start-datetime='2021-09-03 01:05:47' \
--stop-datetime='2021-09-03 01:06:08' /usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -pabc123