1. 程式人生 > >mysql數據庫日誌與備份

mysql數據庫日誌與備份

mysql日誌與備份

1、事務隔離級別

事務隔離級別:
READ UNCOMMITTED 可讀取到未提交的新的數據,產生臟讀
READ COMMITTED 可讀提交數據,但未提交數據不可讀 ,產生不可重復讀,即可讀取到
多個提交數據,導致每次讀取數據不一致;例如一個讀的時間比較長的事務由於其它事務在更改
數據並提交,那麽讀的數據每次都在變化;
REPEATABLE READ 可重復讀,多次讀取數據都一致,產 生幻讀,即讀取過程中,即使有
其它提交的事務修改數據, 當前事務仍只能讀取到未修改前的舊數據。此為MySQL默認設置 ;
但是如果提交當前事務後開啟新的事務進行查詢就會查到更改後的數據;
SERIALIZABILE 可串行化,未提交的讀事務阻塞修改事務,或者未提交的修改事務阻塞讀

事務。導致並發性能較差;容易阻塞效率差;

2、事務隔離級別

3、事務

tx_isolation:服務器變量,默認為REPEATABLE-READ, 可在SESSION級進行修改
SET tx_isolation=‘‘
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE
MVCC: 多版本並發控制,和事務級別相關
常用命令:
show variables like ‘tx_isolation‘; 查看設置隔離級別的系統變量的默認設置
set global tx_isolation=‘read-uncommitted‘; 設置隔離級別為臟讀

start transaction; 手動開啟事務,必須提交才能生效
delete from students where stuid=26;
select * from students; 兩個用戶都執行就可以看到未提交都可讀,此為臟讀
rollback; 撤銷,發現都不能讀了
set tx_isolation=‘read-committed‘; 設置不可重復讀
set tx_isolation=‘serializable‘;
show variables like ‘tx_isolation‘;
start transaction;
select name,sleep(1) from students; 進行讀事務,讀完如果不提交事務;另一個用戶還
會繼續阻塞;
delete from students where stuid=20; 修改數據被阻塞
註意:修改文件使得隔離級別生效時要使用transaction_isolation=serialiazble

4、並發控制

死鎖: 兩個或多個事務在同一資源相互占用,並請求鎖定對方占用的資源的狀態
事務日誌:
事務日誌的寫入類型為“追加”,因此其操作為“順序 IO”,即磁頭不用到處移動就可以寫數
據,而隨機IO寫磁頭移動頻繁比較花費時間;此日誌通常也被稱為:預寫式日誌;同時由於此順
序IO特性,寫日誌的時間明顯比寫磁盤數據快,恰巧產生斷電的幾率就比較小;
write ahead logging
show variables like ‘innodb_log%‘;
innodb_log_file_size 默認5M
innodb_log_files_in_group 默認2,輪流寫滿
innodb_log_group_home_dir 默認數據庫日誌所在目錄
日誌文件: ib_logfile0, ib_logfile1

死鎖實驗:
一邊:
start transaction;
select * from teachers;
update students set name=‘yong‘ where stuid=4; 1 占有
update teachers set name=‘yong‘ where tid=4; 3 訪問另一邊占有的資源被阻塞
另一邊:
start transaction;
update teachers set name=‘wang‘ where tid=4; 2 占有
update students set name=‘hello‘ where stuid=4; 4 訪問一邊占有的資源死鎖
系統發現死鎖,將另一邊的占有資源釋放,即後執行的資源釋放,事務結束;基於innodb行
級鎖實現;

日誌遷移實驗:
mkdir /data/mysqllog -pv 創建新的日誌存放目錄
chown -R mysql.mysql /data/mysqllog/ 設置目錄以及文件的屬主和屬組
vim /etc/my.cnf
innodb-log-group-home-dir=/data/mysqllog
systemctl restart mariadb
ll /data/mysqllog/ -h
測試:執行事務,觀察日誌文件的時間是否變化
結果:事務日誌由/var/lib/mysql目錄遷移到了/data/mysqllog下面
註意:此實驗需要預先關閉防火墻和selinux安全機制

5、日誌

日誌
事務日誌:transaction log;
查詢日誌:query log;
慢查詢日誌:slow query log
錯誤日誌:error log
二進制日誌:binary log
中繼日誌:reley log

6、日誌

查詢日誌
記錄查詢操作:
文件:file
表:table
查詢日誌相關設置
general_log=ON|OFF 不推薦開啟,記錄太詳細
general_log_file=HOSTNAME.log 可以更改路徑
log_output=TABLE|FILE|NONE
實驗:
1、vim /etc/my.cnf 修改文件
general_log=1 開啟日誌,默認寫到/var/lib/mysql下
2、systemctl restart mariadb 重啟服務
3、用命令測試查詢日誌具體記錄的是什麽
cat /var/lib/mysql/localhost.log
select from students;
update students set name=haha where stuid=24;
cat /var/lib/mysql/localhost.log
4、更改查詢日誌文件的路徑
vim /etc/my.cnf
general_log_file=/var/log/mariadb/sql.log 此目錄不必修改權限
5、systemctl restart mariadb 再次重啟服務
6、ls /var/log/mariadb/ 查看是否路徑修改成功
7、將查詢日誌文件寫到表中
vim /etc/my.cnf
log_output=table
8、systemctl restart mariadb 重新啟動服務
9、查看表是否寫入日誌
use mysql;
show tables;
select
from general_log;
10、查看在寫到表後是否還向之前的 /var/lib/mysql/localhost.log文件中寫入日誌
cat /var/lib/mysql/localhost.log 觀察時間可以知道
11、關閉查詢日誌
vim /etc/my.cnf
刪除之前加入的,然後重啟mariadb服務
註意:/root下的.mysql_history文件記錄了在mysql數據庫中執行的所有歷史命令;此查詢日誌不
同,是記錄查詢或修改的SQL語句;

7、日誌

慢查詢日誌:記錄執行查詢時長超出指定時長的操作
SHOW GLOBAL VARIABLES LIKE ‘long_query_time‘;
SELECT @@GLOBAL.long_query_time;
SET GLOBAL long_query_time=N 單位秒
slow_query_log=ON|OFF 開啟或關閉慢查詢
slow_query_log_file=HOSTNAME-slow.log 慢查詢日誌文件
log_slow_filter = admin,filesort,filesort_on_disk,full_join,full_scan,query_cach
e,query_cache_miss,tmp_table,tmp_table_on_disk 這些情況不記錄慢查詢
log_queries_not_using_indexes=ON 不使用索引是否記錄日誌,默認OFF,即不記錄;
log_slow_rate_limit = 1 多少次查詢才記錄,mariadb特有
log_slow_verbosity= Query_plan,explain 記錄內容
log_slow_queries = OFF 同slow_query_log 新版已廢棄
實驗:
1、開啟慢查詢日誌
ls /var/lib/mysql 查看是否有慢查詢日誌文件
set global slow_query_log=on;
ls /var/lib/mysql 查看是否有慢查詢日誌文件
2、查看日誌文件內容
cat /var/lib/mysql/localhost-slow.log
3、模擬慢查詢
show variables like ‘long_query_time‘; 顯示慢查詢時間
select name,sleep(1) from hellodb.students
4、查看慢查詢是否有記錄
cat /var/lib/mysql/localhost-slow.log
5、結果沒有記錄,是sleep模擬不正確
6、重新進行實驗
(1)創建表
create table t1 (id int auto_increment primary key,name char(20),age int default
20);
desc t1;
(2)測試變量組合成名字
set @i=20;
select @i;
select concat(‘wang‘,@i);
(3)創建存儲過程
delimiter //
create procedure slowquery() begin declare i int;set i=1; while i< 100000 do insert
into t1(name,age) values(concat(‘wang‘,i),i);set i=i+1;end while;end //
delimiter ;
call slowquery();
(4)編輯文件
vim /etc/my.cnf
long_query_time=0.05
slow_query_log=on
slow_query_log_file=hello2
(5)重啟服務
systemctl restart mariadb
(6)進行測試
select * from t1; 查詢時間大於0.05秒
cat /var/lib/mysql/hello2 查看慢查詢的記錄
(7)得出結論
慢查詢確實會記錄
常用命令:
select name from hellodb.t1 where name=‘wang99998‘;
create index index_name on t1(name);
select name from hellodb.t1 where name=‘wang99998‘;
explain select name from hellodb.t1 where name=‘wang99998‘;
drop index index_name on t1;
explain select name from hellodb.t1 where name=‘wang99998‘;
8、日誌

錯誤日誌
mysqld啟動和關閉過程中輸出的問題事件信息
mysqld運行中產生的錯誤信息
event scheduler運行一個event時產生的日誌信息
在主從復制架構中的從服務器上啟動從服務器線程時產 生的信息
錯誤日誌相關配置
SHOW GLOBAL VARIABLES LIKE ‘log_error‘;
錯誤日誌文件路徑:
log_error=/PATH/TO/LOG_ERROR_FILE
是否記錄警告信息至錯誤日誌文件
log_warnings=1|0: 1記錄,0不記錄
show variables like ‘log_warnings‘;

9、日誌

二進制日誌
記錄導致數據改變或潛在導致數據改變的SQL語句
功能:通過“重放”日誌文件中的事件來生成數據副本
註意:建議二進制日誌和數據文件分開存放
二進制日誌相關配置
查看mariadb自行管理使用中的二進制日誌文件列表
SHOW {BINARY | MASTER} LOGS; master和binary是等價的
查看使用中的二進制日誌文件
show master status;
File:mysql-binlog.000001 指的是日誌為哪個文件
Position:75932947 指的是日誌寫到哪個位置了;一旦發生修改操作,就會導致位
置變化;
查看指定二進制文件中的內容
SHOW BINLOG EVENTS [IN ‘log_name‘] [FROM pos] [LIMIT [offset,] row_count]
show binlog events in ‘mariadb-bin.000001‘ from 6516 limit 2,3;
常用命令:
show binary logs; 顯示二進制日誌
show variables like ‘log_bin‘; 顯示二進制日誌變量,指定文件位置
show variables like ‘sql_log_bin‘; 是否記錄二進制日誌
註意:記錄數據庫的增刪改操作,不是基於引擎的;

10、日誌

二進制日誌記錄格式
二進制日誌記錄三種格式
基於“語句”記錄:statement,記錄語句,默認模式 ;如果語句中有時時變化的函數如
now(),那麽還原就不能和原來完全一樣;
基於“行”記錄:row,記錄數據,日誌量較大;記錄的是語句的返回結果;
混合模式:mixed, 讓系統自行判定該基於哪種方式進行
格式配置
show variables like ‘%binlog_format%‘;
二進制日誌文件的構成
有兩類文件
日誌文件:mysql|mariadb-bin.文件名後綴,二進制格式
如: mysql-bin.000001
索引文件:mysql|mariadb-bin.index,文本格式,記錄二進制文件有哪些
實驗: 二進制日誌記錄格式
1、執行語句,進行測試
delete from students where gender=‘F‘;
mysqlbinlog /data/binlog/mysql-binlog.000002 查看日誌看出只記錄一條語句,
不是很詳細;
mysqlbinlog /data/binlog/mysql-binlog.000002 -v 顯示的詳細了但是語句還是原來
的;
2、編輯文件,改變日誌文件記錄的格式
vim /etc/my.cnf
binlog_format=row
3、重啟服務
systemctl restart mariadb 每重啟一次,二進制日誌文件就滾動一個新的文件
4、測試
delete from students where gender=‘F‘;
mysqlbinlog /data/binlog/mysql-binlog.000002 發現沒有記錄
mysqlbinlog /data/binlog/mysql-binlog.000003 -v 日誌發生滾動了,更改查詢
實驗:利用二進制日誌文件
1、將日誌導入一個文件中
data/binlog/mysql-binlog.000004 > binlog
2、執行命令,測試
delete from students where stuid=22;
mysql < binlog 還原,裏面有insert語句
3、這就是生成原來環境的方法
註意:二進制日誌不要隨便刪除,即使再次完全備份了;留一段時間可以防止誤操作而
不能還原到原來的數據;
11、日誌

二進制日誌相關的服務器變量:
sql_log_bin=ON|OFF:是否記錄二進制日誌,默認ON ;相比於下一項可以動態修改,而不
用重啟服務;
log_bin=/PATH/BIN_LOG_FILE:指定文件位置;默認 OFF,表示不啟用二進制日誌功能,
上述兩項都開啟才可
binlog_format=STATEMENT|ROW|MIXED:二進制日誌記錄的格式,默認STATEMENT
max_binlog_size=1073741824:單個二進制日誌文件的 最大體積,到達最大值會自動滾
動生成新的文件,默認為1G
說明:文件達到上限時的大小未必為指定的精確值
sync_binlog=1|0:設定是否啟動二進制日誌即時同步磁盤 功能,默認0,由操作系統負責同
步日誌到磁盤
expire_logs_days=N:二進制日誌可以自動刪除的天數。 默認為0,即不自動刪除
實驗1:啟動二進制日誌
1、編輯文件
vim /etc/my.cnf
log_bin
2、重啟數據庫服務
systemctl restart mariadb
3、查看二進制日誌文件
ll /var/lib/mysql/
mariadb-bin.index 記錄二進制日誌文件有哪些,列表
cat mariadb-bin.index
mariadb-bin.000001 二進制文件
實驗2:指定分區存放二進制日誌
1、創建目錄(當做分區)
mkdir /data/binlog/ -pv
2、更改目錄的權限屬性
chown -R mysql:mysql /data/binlog/
3、編輯文件
vim /etc/my.cnf
log_bin=/data/binlog/mysql-binlog
4、重啟服務
systemctl restart mariadb
5、查看日誌情況
ll /var/lib/mysql/
ll /data/binlog/
6、數據庫執行命令
call slowquery;
7、時時查看日誌文件的大小
ll /data/binlog/ 發現日誌文件在不斷的變大
8、執行未提交的命令,查看文件的大小變化
start transaction;
call slowquery;
ll /data/binlog/
發現不變
commit
ll /data/binlog/ 提交後查看文件的大小,發現大幅度增長了
註意:由於不可能時時進行備份,所以二進制日誌很重要;如果磁盤壞了,那麽可以先進行一次
全備份恢復,然後利用二進制日誌恢復數據庫到最新狀態;二進制日誌文件記錄的是提交完成的
數據,和存儲引擎無關,記錄所有的數據庫改變操作;而事物日誌文件在未提交就記錄;二進制
日誌文件不會覆蓋寫數據,而是一直增長;二進制日誌在生產中是強烈建議啟用的;

12、日誌

mysqlbinlog:二進制日誌的客戶端命令工具
命令格式:
mysqlbinlog [OPTIONS] log_file…
--start-position=# 指定開始位置
--stop-position=#
--start-datetime= 不推薦,因為一個秒可能進行多個操作,查詢不夠精確
--stop-datetime=
時間格式:YYYY-MM-DD hh:mm:ss
--base64-output[=name]
示例:mysqlbinlog --start-position=6787 --stop-position=7527 /var/lib/mysql/mariadb-
bin.000003
mysqlbinlog --start-datetime="2018-01-30 20:30:10" -stop-datetime="2018-01-30
20:35:22" mariadb-bin.000003;
實驗:mysqlbinlog選項
1、修改文件
vim hellodb2_InnoDB.sql
將hellodb替換為hellodb2
2、導入
mysql < hellodb2_InnoDB.sql
3、對hellodb進行操作
delete from students where stuid=20; 需要use hellodb才能在4中導出到文件
4、查看日誌進行檢驗
mysqlbinlog -d hellodb2 /data/binlog/mysql-binlog.000004 > binlog_hellodb2
mysqlbinlog -d hellodb /data/binlog/mysql-binlog.000004 > binlog_hellodb
13、日誌

二進制日誌事件的格式:

at 328

#151105 16:31:40 server id 1 end_log_pos 431 Query thread_id=1 exec_time=0
error_code=0
use mydb/!/;
SET TIMESTAMP=1446712300/!/;
CREATE TABLE tb1 (id int, name char(30))
/!/;
事件發生的日期和時間:151105 16:31:40
事件發生的數據庫服務器標識:server id 1
事件的結束位置:end_log_pos 431
事件的類型:Query
事件發生時所在服務器執行此事件的線程的ID:thread_id=1
語句的時間戳與將其寫入二進制文件中的時間差:exec_time=0
錯誤代碼:error_code=0
事件內容: GTID:Global Transaction ID,mysql5.6以mariadb10以上版本專屬屬性

14、日誌

清除指定二進制日誌:
PURGE { BINARY | MASTER } LOGS { TO ‘log_name‘ | BEFORE datetime_expr }
示例:
PURGE BINARY LOGS TO ‘mariadb-bin.000003’;刪除3前日誌
PURGE BINARY LOGS BEFORE ‘2017-01-23‘;
PURGE BINARY LOGS BEFORE ‘2017-03-22 09:25:30‘;
刪除所有二進制日誌,index文件重新記數
RESET MASTER [TO #]; 日誌文件從#開始記數,默認 從1開始, 說明:此語句一般是
master第一次啟動時執行;指定數字時要考慮版本問題,5.5.6是不行的
切換日誌文件:
FLUSH LOGS; 手動換為新的二進制文件存放日誌
註意:刪除日誌文件一定慎重;先備份再刪除,備份的日誌一定要確定能夠使用;用purge命令
刪除日誌是按文件進行刪的,如果另一個文件中既有符合條件的又有不符合條件的,那麽不會刪
除這個文件;

15、日誌

中繼日誌:relay log (之後講解)
主從復制架構中,從服務器用於保存從主服務器的二進制日誌 中讀取到的事件
事務日誌:transaction log
事務型存儲引擎自行管理和使用
redo log
undo log
Innodb事務日誌相關配置:
show variables like ‘%innodb_log%‘;
innodb_log_buffer_size 事務日誌的緩存區大小
innodb_log_file_size 5242880 每個日誌文件大小
innodb_log_files_in_group 2 日誌組成員個數
innodb_log_group_home_dir ./ 事務文件路徑
註意:由於日誌的重要性,建議將日誌與數據文件分開存放,日誌文件放到固態磁盤上;日誌文
件要足夠大,否則大事務寫滿兩個文件後將會在事務沒有提交的時候將數據寫磁盤(如/var/lib/mysql/hellodb/t1.ibd)以可以覆蓋舊的日誌,但是如果要rollback那麽沒有之前的日誌是不行的,而且只能撤銷數據不能回收空間,很麻煩了;當然也可以增加日誌文件個數;
事物日誌應該放在 一個獨立的分區,以防止順序寫空間被其它數據文件占用

16、備份和恢復

為什麽要備份
災難恢復:硬件故障、軟件故障、自然災害、××××××、誤操作 測試等數據丟失場景
備份註意要點
能容忍最多丟失多少數據
恢復數據需要在多長時間內完成 恢復數據要先停機
需要恢復哪些數據
還原要點
做還原測試,用於測試備份的可用性
還原演練 定期還原演練以熟練

17、備份和恢復

備份類型:
完全備份,部分備份
完全備份:整個數據集
部分備份:只備份數據子集,如部分庫或表 這些數據變化比較頻繁
完全備份、增量備份、差異備份
增量備份:僅備份最近一次完全備份或增量備份(如果存 在增量)以來變化的數據,備
份較快,還原復雜
差異備份:僅備份最近一次完全備份以來變化的數據,備 份較慢,還原簡單
註意:二進制日誌文件不應該與數據文件放在同一磁盤

18、備份和恢復

熱備份、溫備份、冷備份
熱備:讀寫操作均可執行 事務機制
溫備:讀操作可執行;但寫操作不可執行 如銀行兩個賬號轉賬數據不同步
冷備:讀寫操作均不可進行 關閉服務進行備份
MyISAM:溫備,不支持熱備
InnoDB: 都支持
物理和邏輯備份
物理備份:直接復制數據文件進行備份,與存儲引擎有關, 占用較多的空間,速度快
邏輯備份:從數據庫中“導出”數據另存而進行的備份,與 存儲引擎無關,占用空間少,速度
慢,可能丟失精度 ;相當於執行查詢語句將結果導出;
註意:物理備份需要打包數據文件和日誌文件,而且/etc/my.cnf配置文件也要進行復制;復制之前要將服務停止;mysql是針對中小型數據存放的(在1T以下);
19、備份和恢復

備份時需要考慮的因素
溫備的持鎖多久
備份產生的負載
備份過程的時長
恢復過程的時長
備份什麽
數據
二進制日誌、InnoDB的事務日誌
程序代碼(存儲過程、存儲函數、觸發器、事件調度器)
服務器的配置文件

20、備份和恢復

設計備份方案
數據集:完全+增量
備份手段:物理,邏輯
備份工具
mysqldump:邏輯備份工具,適用所有存儲引擎,溫備; 支持完全或部分備份;對InnoDB
存儲引擎支持熱備
cp, tar等復制歸檔工具:物理備份工具,適用所有存儲引 擎;只支持冷備;完全和部分備份
LVM的快照:先加鎖,做快照後解鎖,幾乎熱備;借助文 件系統管理工具進行備份
mysqlhotcopy:幾乎冷備;僅適用於MyISAM存儲引擎

21、備份和恢復

備份工具的選擇:
mysqldump+復制binlog:
mysqldump:完全備份
復制binlog中指定時間範圍的event:增量備份
LVM快照+復制binlog:
LVM快照:使用cp或tar等做物理備份;完全備份
復制binlog中指定時間範圍的event:增量備份
xtrabackup:
由Percona提供支持對InnoDB做熱備(物理備份)的工具 完全備份、增量備份
mysqlbackup:熱備份, MySQL Enterprise Edition組件 付費的

22、備份和恢復

邏輯備份工具:mysqldump, mydumper, phpMyAdmin
Schema和數據存儲在一起、巨大的SQL語句、單個巨大的備份文件
mysqldump:
客戶端命令,通過mysql協議連接至mysqld服務器
mysqldump [options] [db_name [tbl_name ...]]
mysqldump [options] db_name [tbl_name ...]
mysqldump [options] –databases|B db_name ...
mysqldump [options] --all-databases|A
mysqldump參考:
https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
實驗1:演示備份與還原 數據庫比較大時為保證數據的一致性,不可用
mkdir /backups 創建目錄作為備份文件的存放地
mysql -e ‘show databases;‘ 不進入數據庫就查看有哪些數據庫
mysqldump hellodb|less 發現備份的大SQL語句中沒有創建數據庫的語句
mysqldump hellodb > /backups/hellodb.sql 備份到指定文件
mysql -e ‘drop database hellodb;‘ 先刪除數據庫,然後還原
mysql -e ‘create database hello;‘ 由於備份時沒有創建數據庫的語句,故而此時在還
原之前需要手動創建數據庫,可能和原來創建的語法不一樣,如編碼機制等
show create database hello; 可以查看創建數據庫時的各種定義如編碼字符等
mysql hello < /backups/hellodb.sql 進行數據庫的還原
實驗2:
mysqldump hello students > /backups/hellodb_students.sql 備份數據庫中的一個表
mysql test < /backups/hellodb_students.sql 還原表到數據庫
23、備份和恢復

mysqldump常見選項:
-A, --all-databases 備份所有數據庫,含create database
-B , --databases db_name… 指定備份的數據庫,包括 create database語句
-E, --events:備份相關的所有event scheduler
-R, --routines:備份所有存儲過程和存儲函數
--triggers:備份表相關的觸發器,默認啟用,用--skiptriggers,不備份觸發器
--master-data[=#]: 此選項須啟用二進制日誌
1:所備份的數據之前加一條記錄為CHANGE MASTER TO語 句,非註釋,不指定#,
默認為1;用於主從復制
2:記錄為註釋的CHANGE MASTER TO語句 此選項會自動關閉--lock-tables功能,自
動打開--lock-alltables功能(除非開啟--single-transaction)
實驗1:
mysqldump -A > /backups/all.sql 備份所有數據庫 寫鎖有多個也有可能造成數據不一

cat /backups/all.sql|grep ‘CREATE DATABASE‘|head -n3 可以看到有創建數據庫的語句
systemctl stop mariadb 停止服務
rm -rf /var/lib/mysql/ 刪除數據庫文件
systemctl start mariadb 重啟服務後系統庫被自動創建,而自己寫的數據庫沒有了
mysql < /backups/all.sql 進行還原數據庫操作
select user from user; 查看test賬號是否被還原
show variables like ‘character%‘; 查看字符集的類型;創建數據庫時和字符集有關
實驗2:
mysqldump -B test hello > /backups/hello_test.sql 備份兩個數據庫
less /backups/hello_test.sql 裏面有創建數據庫的操作
rm -rf /var/lib/mysql/hello 刪除hello數據庫
rm -rf /var/lib/mysql/test/ 刪除test數據庫
mysql < /backups/hello_test.sql 進行還原數據庫的操作,不能成功;如果將服務停止後
再進行刪除,也不能還原;說明直接刪除的方式有錯誤;正常用drop命令進行刪除是可以還原的
rm -rf /var/lib/mysql/
清空
systemctl restart mariadb 重啟生成系統數據庫
mysql < /backups/hello_test.sql 進行還原成功
mysqldump -A |gzip > /backups/all_gz.sql.gz 先壓縮再備份
mysqldump -A |xz > /backups/all_xz.sql.xz 壓縮備份;
註意:先壓縮再備份雖然節省空間但會比較慢,要先備份完再壓縮才好點
gzip hello_test.sql 先備份再壓縮
實驗3:
delimiter // 改變結束符
create procedure slowquery() begin declare i int;set i=1; while i< 100000 do insert into
t1(name,age) values(concat(‘wang‘,i),i);set i=i+1;end while;end// 創建存儲過程
mysqldump -A > /backups/all.sql 進行所有數據庫的備份,包括存儲過程、觸發器等
grep slowquery /backups/all.sql 可以看出備份中含有所創建的存儲過程
rm -rf /var/mysql/ 刪除數據庫
systemctl start mariadb 重啟服務
mysql < /backups/all.sql 將備份進行還原
call slowquery; 還原後進行存儲過程的調用
use mysql; 進入系統數據庫
select
from proc\G; 查看表中的數據;表中記錄了存儲過程
實驗4:
mysqldump -A --master-data=1 > /backups/all_1.sql 進行完全備份,並記錄二進制日誌
的當前時間點,以在數據破壞的時候可以先完全備份還原再依靠二進制日誌增量備份還原
mysqldump -A --master-data=2 > /backups/all_2.sql 同上,但是記錄時間點有註釋
diff /backups/all_2.sql /backups/all_1.sql 比較兩個備份文件的不同點
yum install mariadb-server 在新機器上安裝mariadb
delete from students where stuid=22; 在完全備份後執行的語句,由二進制日誌記錄
scp /data/binlog/mysql-binlog.000023 172.18.62.61:/app 將二進制日誌文件放到不被破
壞的地方,如另一個機器;
scp /etc/my.cnf 172.18.62.61:/etc/my.cnf 復制配置文件
scp /backups/all_1.sql 172.18.62.61:/app 復制完全備份的數據文件
systemctl start mariadb 在新機器上啟動服務
mysqlbinlog /app/mysql-binlog.000023 --start-position=530432 > /app/binlog 將完全備
份中指定位置開始的二進制日誌導出來
mysql < /app/all_1.sql 完全備份的還原
mysql < /app/binlog 增量備份的還原
select * from students; 進入數據庫查看是否完成還原
24、備份和恢復

mysqldump常見選項
-F, --flush-logs :備份前滾動日誌,鎖定表完成後,執行flush logs命令,生成新的二進制日誌
文件,配合-A時,會導致刷新多個數據 庫,在同一時刻執行轉儲和日誌刷新,則應同時使用--
flush-logs和x,--master-data或--single-transaction,此時只刷新一次 ;建議:和-x,--master-
data或 --single-transaction一起使用 ;-x一般用於MyISAM引擎的數據庫;
--compact 去掉註釋,適合調試,生產不使用
-d, --no-data 只備份表結構
-t, --no-create-info 只備份數據,不備份create table
-n,--no-create-db 不備份create database,可被-A或-B覆蓋
--flush-privileges 備份mysql或相關時需要使用
-f, --force 忽略SQL錯誤,繼續執行
--hex-blob 使用十六進制符號轉儲二進制列(例如,“abc”變 為0x616263),受影響的數據
類型包括BINARY, VARBINARY, BLOB,BIT
-q, --quick 不緩存查詢,直接輸出,加快備份速度
實驗1:
mysqldump -A -F > /backups/all_A-F.sql 備份前刷新日誌
ls /data/binlog/ -l 發現有幾個數據庫就生成幾個日誌文件;每備份一個數據庫前就刷新一次
日誌;
實驗2:
mysqldump -A --compact > /backups/all_c.sql 去掉註釋進行備份
mysqldump -A > /backups/all.sql 包含註釋的備份
ll /backups/ 比較兩個備份的大小
25、備份和恢復

MyISAM備份選項: 支持溫備;不支持熱備,所以必須先鎖定要備份的庫,而後 啟動備份操作
鎖定方法如下:
-x,--lock-all-tables:加全局讀鎖,鎖定所有庫的所有表 ,同時加--single-transaction或--
lock-tables選項會關閉 此選項功能
註意:數據量大時,可能會導致長時間無法並發訪問數據庫
-l,--lock-tables:對於每個單獨的數據庫,在啟動備份之 前分別鎖定其所有表,默認為on,可
使用--skip-lock-tables 禁用,對備份MyISAM的多個庫,可能會造成數據不一致
註:以上選項對InnoDB表一樣生效,實現溫備,但不推薦 使用

26、備份和恢復

InnoDB備份選項:
支持熱備,可用但不建議用溫備
--single-transaction 此選項Innodb中推薦使用,不適用MyISAM,此選項會 開始備份
前,先執行START TRANSACTION指令,並且在 備份期間,不允許對數據進行修改操作
此選項和--lock-tables(此選項隱含提交掛起的事務) 選項是相互排斥
備份大型表時,建議將--single-transaction選項和-quick結合一起使用

27、生產備份策略

InnoDB建議備份策略
mysqldump –uroot –A –F –E –R –single-transaction -master-data=1 --flush-privileges --
triggers --hexblob >$BACKUPDIR/fullback$BACKUP_TIME.sql
MyISAM建議備份策略
mysqldump –uroot –A –F –E –R –x -–master-data=1 -flush-privileges --triggers --hex-blob

$BACKUPDIR/fullback$BACKUP_TIME.sql
實驗:恢復誤刪除的數據庫到最新狀態
(1)完全備份
mysqldump -A -F --master-data=2 --single-transaction > /app/all-date +%F%T.sql
(2)對數據庫修改
insert into students(name,age,gender) values(‘a‘,‘29‘,‘F‘);
drop database hellodb;
(3)發現問題
mysql>flush tables with read lock; 加鎖
iptables 禁止其它用戶訪問
(4)查看完全備份的位置
less /app/all-2018-02-2309\:48\:53.sql
CHANGE MASTER TO MASTER_LOG_FILE=‘mariadb-bin.000008‘,
MASTER_LOG_POS=245;
(5)flush logs 生成新日誌文件
(6)備份日誌文件
cp /var/lib/mysql/mariadb-bin.000008 /app/
mysqlbinlog --start-position=245 mariadb-bin.000008 > /app/bin.sql
mysqlbinlog mariadb-bin.000009 >> /app/bin.sql 還有日誌就追加
(7)刪除日誌中的誤操作命令
vim /app/bin.sql
刪除drop database hellodb; 此命令
(8)還原前關閉二進制日誌記錄
mysql>set sql_log_bin=0;
(9)解鎖
mysql>unlock tables;
(10)還原完全備份
mysql> source /app/all-2018-02-2309\:48\:53.sql
(11)還原二進制日誌的備份
mysql> source /app/bin.sql
(12)重新開啟二進制日誌
mysql>set sql_log_bin=1;
(13)重新允許用戶訪問
iptables 恢復用戶訪問

mysql數據庫日誌與備份