1. 數據庫的6種日志
數據庫有6種日志,分別是:查詢日志、慢查詢日志、錯誤日志、二進制日志、中繼日志以及事務日志。
1> 查詢日志
查詢日志記錄每一條sql語句,建議不開啟,因為如果訪問量較大,會占用相當大的資源,影響性能。
查詢日志的開啟:
編輯配置文件:/etc/my.cnf.d/server.cnf
vim /etc/my.cnf.d/server.cnf general_log = ON| OFF #查詢日志開關,開為1,關為0 general_log_file localhost.log #查詢日志的文件名字(/var/lib/mysql),可以是絕對路徑,也可以是相對路徑,如果是絕對路徑則生成絕對路徑下的日志文件文件;如果是相對路徑,則默認生成/var/lib/mysql下的路徑 log_output TABLE | FILE | NONE #查詢日志的存儲形式,有三種形式,table是以表的方式存儲,file是以文件的方式,none是使用兩種方式存儲
示例:
[root@alph ~]# vim /etc/my.cnf.d/server.cnf [server] general_log=1 #開啟查詢日志 general_log_file=localhost.log #日志文件名,自定義 # this is only for the mysqld standalone daemon 保存退出,重啟數據庫,進入數據庫查看日志查詢方式 MariaDB [(none)]> show variables like '%general%'; +------------------+---------------+ | Variable_name | Value | +------------------+---------------+ | general_log | ON | | general_log_file | localhost.log | +------------------+---------------+ 2 rows in set (0.001 sec) [root@alph ~]# cd /var/lib/mysql/ [root@alph mysql]# ls ............ localhost.log [root@alph mysql]# tail -f localhost.log #已經開始監控 /usr/sbin/mysqld, Version: 10.3.16-MariaDB-log (MariaDB Server). started with: Tcp port: 0 Unix socket: (null) Time Id Command Argument /usr/sbin/mysqld, Version: 10.3.16-MariaDB-log (MariaDB Server). started with: Tcp port: 0 Unix socket: (null) Time Id Command Argument 190803 2:53:53 8 Connect root@localhost as anonymous on 8 Query select @@version_comment limit 1 190803 2:53:58 8 Query show variables like '%general%' 190803 2:59:43 8 Quit #監控到的sql語句 可以看到,查詢日志會記錄每一條操作過得SQL語句
2> 慢查詢日志
執行時長超出指定時間的查詢操作(測試命令:select sleep(4);)(超出指定的時長后才記錄下來)。一般企業都將慢查詢日志打開,用來優化SQL語句
慢查詢日志的開啟:
同樣的,編輯配置文件/etc/my.cnf.d/server.cnf
slow_query_log = OFF|ON #開啟慢查詢日志 slow_query_log_file = LOCALHOST-SLOW.log #慢查詢日志的文件路徑,默認在/var/lib/mysql,文件名默認為LOCALHOST-SLOW.log,localhost為主機名。 long_query_time #慢查詢時長;默認是10s,超出10s將會被記錄 log_slow_rate_limit #如果要記錄的慢查詢日志非常多的話,會按照速率來記錄,默認1秒記錄一個 log_slow_verbosity=1|0 #記錄的詳細級別,1代表詳細,0代表不太詳細;
例如:
[root@alph ~]# vim /etc/my.cnf.d/server.cnf [serve #general_log=1 #general_log_file=localhost.log slow_query_log=1 #開啟詳細的慢查詢 long_query_time=4 #超出時長為4秒,四秒后開始記錄 沒有指定路徑和文件,默認為/var/lib/mysql/ LOCALHOST-SLOW.log 保存退出,重啟生效 [root@alph ~]# systemctl restart mariadb [root@alph mysql]# ls -ltr -rw-rw---- 1 mysql mysql 142 Aug 3 16:53 alph-slow.log
進入數據庫查看,同時打開交互界面進行監控日志 執行一個模擬5秒的SQL語句,等待tail -f監控文件內容 MariaDB [mysql]> select sleep(5); +----------+ | sleep(5) | +----------+ | 0 | +----------+ [root@alph mysql]# tail -f alph-slow.log /usr/sbin/mysqld, Version: 10.3.16-MariaDB-log (MariaDB Server). started with: Tcp port: 0 Unix socket: (null) Time Id Command Argument # Time: 190803 17:00:31 # User@Host: root[root] @ localhost [] # Thread_id: 8 Schema: mysql QC_hit: No # Query_time: 5.000527 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0 # Rows_affected: 0 Bytes_sent: 63 use mysql; SET timestamp=1564822831; select sleep(5);
3> 錯誤日志
錯誤日志記錄mysqld啟動和關閉過程中輸出的事件信息,mysqld運行中產生的錯誤信息。同樣的,配置文件為/etc/my.cnf.d/server.cnf
event scheduler #運行一個event時產生的日志信息,在主從復制架構中的從服務器上啟動從服務器線程時產生的信息 log_error = /var/log/mysql_error.log #指定錯誤日志的輸出位置,該路徑必須具有mysql權限(不指定路徑默認放在/var/lib/mysql/) log_warnings #為0, 表示不記錄告警信息。為1, 表示告警信息寫入錯誤日志。大於1, 表示各類告警信息,例如有關網絡故障的信息和重新連接信息寫入錯誤日志。(默認為2)
[root@alph ~]# vim /etc/my.cnf.d/server.cnf [server] #general_log=1 #general_log_file=localhost.log #slow_query_log=1 #long_query_time=4 log_error = /var/lib/mysql/mysql_error.log 保存退出,重啟生效 [root@alph ~]# systemctl restart mariadb [root@alph ~]# cd /var/lib/mysql/ [root@alph mysql]# ls -ltr -rw-rw---- 1 mysql mysql 1883 Aug 3 17:22 mysql_error.lo [root@alph mysql]# tail -f mysql_error.log 在交互界面重新啟動一下數據庫,這些信息都會被記錄到該日志當中 MariaDB [(none)]> exit Bye [root@alph ~]# mysql -uroot -p123 root@alph mysql]# tail -f mysql_error.log 2019-08-03 17:22:12 0 [Note] InnoDB: Waiting for purge to start 2019-08-03 17:22:12 0 [Note] InnoDB: 10.3.16 started; log sequence number 1630860; transaction id 21 2019-08-03 17:22:12 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool 2019-08-03 17:22:12 0 [Note] InnoDB: Buffer pool(s) load completed at 190803 17:22:12 2019-08-03 17:22:12 0 [Note] Plugin 'FEEDBACK' is disabled. 2019-08-03 17:22:12 0 [Note] Server socket created on IP: '::'. 2019-08-03 17:22:12 0 [Note] Reading of all Master_info entries succeeded 2019-08-03 17:22:12 0 [Note] Added new Master_info '' to hash table 2019-08-03 17:22:12 0 [Note] /usr/sbin/mysqld: ready for connections. Version: '10.3.16-MariaDB' socket: '/var/lib/mysql/mysql.sock' port: 3306 MariaDB Server 查看當前錯誤日志的報警級別 MariaDB [(none)]> show variables like '%warning%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_warnings | 2 | #默認為2 | sql_warnings | OFF | | warning_count | 0 | +---------------+-------+ 3 rows in set (0.001 sec)
4> 二進制日志
二進制日志是MariaDB最重要的日志,針對時間點還原起着至關重要的作用,可以根據時間點還原數據。所有的增刪改操作都會被記錄到二進制日志當中。
log_bin = OFF | ON #二進制日志開關 log_bin_basename = /var/lib/mysql/mysql-bin #日志路徑,默認在/var/lib/mysql下 binlog_format=STATEMENT|ROW|MIXED #二進制記錄格式 STATEMENT:基於“語句”記錄,記錄SQL語句,占用空間小,但是當數據庫有該日志記錄的語句(如數據庫)的時候,回復數據時是會報錯、失敗 ROW:基於“行”記錄,記錄的是每一行的內容,對於大量的記錄來說占用空間較大,但記錄較精准 MIXED:混合模式,讓系統自行判定該基於哪種方式進行,現在采用的基本都是這種混合模式 sql_log_bin=1|0 #是否啟用二進制日志,或者指定文件名如mysql-bin log_bin_index=PATH #二進制日志索引位置,默認在/var/lib/mysql下,myssql-bin.index,記錄二進制日志文件的路徑,該index不屬於二進制文件,可以用cat或者vim打開,如: [root@alph mysql]# cat mysql-bin.index ./mysql-bin.000001 sync_binlog=1|0 #設定是否啟動二進制日志同步功能。由於磁盤寫入文件較慢,開啟同步則每記錄一條既寫入磁盤,對數據庫的性能以及磁盤io來說是有影響的 max_binlog_size=SIZE #單個二進制文件最大體積,默認為1G,超過設定大小就會滾動到另一個增加的二進制文件 expire_logs_days=0 #消除日志參數,超過多少天就清除二進制日志,默認為0,代表不啟用此功能,二進制日志不清除會一直生成並保存
[root@alph mysql]# vim /etc/my.cnf.d/server.cnf [server] #general_log=1 #general_log_file=localhost.log #slow_query_log=1 #long_query_time=4 #log_error = /var/lib/mysql/mysql_error.log log_bin=mysql-bin #開啟二進制日志 保存退出,重啟生效 [root@alph mysql]# ls -ltr -rw-rw---- 1 mysql mysql 328 Aug 3 17:41 mysql-bin.000001
查看二進制日志:
MariaDB [(none)]> show master status; #當前所使用的二進制文件 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 328 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.001 sec) MariaDB [(none)]> show master logs; #所有的二進制文件 +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 328 | +------------------+-----------+ 1 row in set (0.000 sec)
SHOW {BINARY | MASTER} LOGS SHOW BINLOG EVENTS [IN 'log_name'] #二進制文件記錄的內容 show master status;
二進制日志記錄的是增刪改操作,先創建一個表,在查看狀態
MariaDB [(none)]> create database testdb; MariaDB [(none)]> ues testdb; MariaDB [testdb]> create table classes (id tinyint unsigned primary key,name varchar(20)); MariaDB [testdb]> show master status; #position數據開始變化,二進制日志mysql-bin.000001開始記錄數據 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 643 | | | +------------------+----------+--------------+------------------+
查看二進制日志文件內容:
由於該日志是二進制形式,因此無法用cat或者vim命令來查看,可以用mysql提供的mysqlbinlog來查看指定的二進制日志文件
[root@alph mysql]# mysqlbinlog mysql-bin.000001 .......... #增刪改均會被記錄 create database testdb /*!*/; # at 461 #190803 18:07:55 server id 1 end_log_pos 503 CRC32 0x8ca3d982 GTID 0-1-2 ddl /*!100001 SET @@session.gtid_seq_no=2*//*!*/; # at 503 #190803 18:07:55 server id 1 end_log_pos 643 CRC32 0x3490771f Query thread_id=9 exec_time=0 error_code=0 use `testdb`/*!*/; SET TIMESTAMP=1564826875/*!*/; create table classes (id tinyint unsigned primary key,name varchar(20)) /*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog *//*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
二進制文件的滾動的三種情況:
1)flush logs:手動滾動
2) 文件超出指定大小
3) service mariadb restart
每滾動一次,日志查詢show master log 中的mysql-bin會增1
MariaDB [testdb]> flush logs; Query OK, 0 rows affected (0.003 sec) MariaDB [testdb]> show master logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 690 | | mysql-bin.000002 | 385 | +------------------+-----------+ MariaDB [testdb]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000002 | 385 | | | +------------------+----------+--------------+------------------+ [root@alph mysql]# cat mysql-bin.index ./mysql-bin.000001 ./mysql-bin.000002
二進制日志格式:
190613 14:17:32 server id 1 end_log_pos 666 CRC32 0xeb1cde6b Query thread_id=9 exec_time=0 error_code=0 use `testdb`/*!*/;
事件發生的日期和時間:190613 14:17:32,19-06-13 14:17:32;
事件發生的服務器標識:server id 1,主從架構同步時將按照server-id來同步;
事件的結束位置:end_log_pos 666;
事件的類型:Query;
事件發生時所在服務器執行此事件的線程ID:thread_id=9;
語句的時間戳與將其寫入二進制文件中的時間差:exec_time=0,記錄SQL語句所用的時間,一般不為0;
錯誤代碼:error_code=0;
事件內容:GTID:Global Transaction ID;
專屬屬性:GTID
客戶端命令工具mysqlbinlog:
mysqlbinlog [options] log_file ...
--start-datetime= --stop-datetime= #基於時間點恢復。從start到stop時間點之間的內容將會被恢復 --start-position= --stop-position= #基於position點恢復。從start到stop之間的內容將會被恢復
5> 中繼日志
復制架構中,備服務器用於保存主服務器的二進制日志中讀取到的事件。
6> 事務日志
事務日志transaction log,有兩個文件:ib_logfile0,ib_logfile1。事務日志一般不需要手動的管理,由事務型存儲引擎自行管理和使用(Innodb,myisam引擎是不支持事務,外鍵,行級鎖);
數據庫執行的所有事務都會寫入到事務日志當中,事務里進行的增刪改等操作先記錄到事務日志當中,再寫入到數據庫。由此帶來的問題是由於先將數據寫入事務日志當中,當查詢數據庫時有可能查詢不到。同樣的,在讀取事務日志的內容的同時又讀不到原磁盤的內容。事務日志的數據加上磁盤里的數據才是完整的數據,數據庫的解決辦法是划分內存的一塊區域buffer_pool(緩沖池),將事務日志數據可磁盤數據放入內存,直接調用內存。buffer_pool的大小影響數據庫的性能。
[root@alph mysql]# ll -rw-rw---- 1 mysql mysql 50331648 Aug 3 18:07 ib_logfile0 -rw-rw---- 1 mysql mysql 50331648 Aug 2 22:54 ib_logfile1
innodb_buffer_pool_size #一般在沒有其他業務的情況下設置成為物理內存的3/4,或者4/5 innodb_log_files_in_group = 2 #事務日志文件的個數,默認為2個事務日志文件,數據交替寫入 innodb_log_file_size = 50331648(48M) #事務日志文件的單個大小48M innodb_log_group_home_dir = ./ #事務日志文件的所在路徑,默認就在mariadb的數據目錄/var/lib/mysql
事務型存儲引擎自行管理和使用事務日志,
redo log:重做日志; undo log:撤銷日志。
2. 數據庫的備份
1> 為什么要備份:
災難恢復:硬件故障,軟件故障,自然災害,黑客攻擊,誤操作;測試
2> 備份要注意的點:
- 備份需要多少時間:需要估算出來;
- 能容忍最多丟失多少數據;
- 恢復數據需要在多長時間內完成;
- 需要恢復哪些數據。
數據庫備份完成后要做還原測試,定期的去做還原演練,用於測試備份的可用性。
3> 備份類型:
a) 完全備份和部分備份:
i. 完全備份:整個數據集(整個庫的整個表);
ii.部分備份:只備份數據子集;
b) 完全備份、增量備份、差異備份:
i. 增量備份:僅備份最近一次完全備份或增量備份(如果有增量備份)以來變化的數據;
ii. 差異備份:僅備份最近一次完全備份以來變化的數據。
c) 熱備、溫備、冷備
i. 熱備:讀寫操作均可執行(不影響業務的操作);
ii. 溫備:讀操作可以、寫不行(需要將整個庫的整個表鎖住);
iii.冷備:讀寫操作均不能執行(停掉業務);
- iv. MyISAM:溫備,不能熱備;
d) 物理備份、邏輯備份
i. 物理備份:直接復制數據文件進行備份,與存儲引擎無關(如cp,備份的時候要注意不能有數據插入);
ii. 邏輯備份:從數據庫中“導出”數據庫另存而進行備份(如二進制日志、Mysqldump備份的數據,結構不變)。
4> 備份時需要考慮的因素:
1) 持續多久;
2) 備份過程的時長;
3) 備份負載;
4) 恢復過程的時長。
5> 備份什么
1) 數據;
2) 二進制日志(基於時間點還原),innodb的事務日志;
3) 代碼(存儲過程,存儲函數,觸發器,時間調度器);
4) 服務器的配置文件。
6> 設計備份方案:
1) 數據集:完全+增量+二進制日志 | 完全+差異+二進制日志(最大量的恢復,接近100%);
2) 備份手段:物理,邏輯;
3) 對於備份較大的數據建議物理備份,對於較小的數據建議用邏輯備份。
7> 備份工具的選擇:
1)mysqldump+復制binlog:
mysqldump:完全備份
復制binlog中指定時間范圍內的event:增量備份
2)lvm2快照+復制binlog:
lvm2快照:適用cp或者tar等做物理備份:完全備份;
復制binlog中指定時間范圍內的event:增量備份;
注意:lvm2屬於溫備,要先鎖表。
3)xtrabackup | mariabackup:
xtrabackup作用於mysql數據庫而不是mariadb,由Percona公司提供的支持對InnoDB做熱備(物理備份)工具。xtrabackup在mariadb 10版本之前是可以用的。
mariabackup專門為mariadb設計的,可以做:完全備份,增量工具
3. 數據庫的恢復
1> 基於二進制文件的恢復
1)基於時間點:
a. 算好要恢復數據的時間段,重定向輸入到bin.sql文件中,如:
1 mysqlbinlog --start-datetime="2019-06-08 22:55:13" --stop-datetime="2019-06-08 22:55:13" binlog.0000011 > bin.sql
b. 執行bin.sql文件還原
1 source bin.sql
2)基於position,如:
mysqlbinlog /var/lib/mysql/mysql-bin.000005 --stop-position=1389 | mysql -uroot -p123
如果不提供start則從頭開始恢復;position從二進制日志中查詢。
2> 基於lvm2的備份
因為mariadb的默認數據文件位置是/var/lib/mysql目錄里,並不是文件系統,因此這里用新加磁盤來創建文件系統測試
1.添加磁盤 2.重啟服務器識別硬盤 3.[root@localhost ~]#fdisk /dev/sdb #分區 4.[root@localhost ~]#pvcreate /dev/sdb3 #創建pv 5.[root@localhost ~]#pvdisplay #查看pv "/dev/sdb3" is a new physical volume of "100.00 GiB" --- NEW Physical volume --- PV Name /dev/sdb3 VG Name PV Size 100.00 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID zYUBTH-Eqfa-ZYf7-q8pZ-gWBQ-UtUL-qeZzyd 6.[root@localhost ~]# vgcreate test3vg /dev/sdb3 #創建vg Volume group "test3vg" successfully created 7.[root@localhost ~]# lvcreate -L 99G -n testlv3 test3vg #創建lv Logical volume "testlv3" created. 8.[root@localhost ~]# mkfs.ext4 /dev/test3vg/testlv3 #格式化lv 9.[root@localhost ~]# mkdir /test3 #根目錄下創建一個test3目錄 10.[root@localhost ~]# mount /dev/test3vg/testlv3 /test3/ #掛在剛才所創建的目錄 11.如果是yum安裝默認數據目錄在/var/lib/mysql,如果需要更改 vim /etc/my.cnf.d/server.cnf [mysqld] datadir=/test3/ pid_file=/test3/localhost.pid socket=/test3/mysql.sock wsrep_data_home_dir=/test3/ log-bin=mysql-bin [client] socket=/test3/mysql.sock 12.[root@localhost ~]#chown -R mysql.mysql /test3 #修改目錄下面所有文件的屬主屬組,必須為mysql不然數據庫起不來 13.[root@localhost ~]#service mariadb restart #重啟數據庫 14. MariaDB [(none)]> flush tables with read lock; #將所有表鎖住(只能讀,不能寫) 15.[root@localhost ~]# lvcreate -L 100G -s -p r -n snap_test3 /dev/test3vg/testlv3 #創建快照lv(這里要注意,test3vg中必須有足夠的空間,不然創建lv會失敗) 備注: -L: --size -s: --snap -p: --permission rw|r -n: --name 16. MariaDB [(none)]> unlock tables; #釋放鎖 17.[root@localhost testvg]# mkdir /snap_test3 #創建快照目錄 18.[root@localhost ~]# mount /dev/testvg/snap_test3 /snap_test3/#掛載快照lv 19.這時候你就可以在快照目錄下看到跟源文件系統一模一樣的內容了,此時就可以用cp拷貝了!
3> 基於mysqldump工具進行備份(邏輯備份工具)
mysqldump -uroot -proot -l --databases testdb > testdb.sql #備份testdb數據庫(-l代表備份單個數據庫時鎖定該庫的所有表;-x當對所有數據庫備份時鎖定所有數據庫的所有表) mysqldump -uroot -proot --all-databases > all_databases.sql #備份所有數據庫 mysqldump -uroot -proot testdb students > students.sql #備份testdb數據庫下的students表 source testdb.sql #還原數據(sql命令行下)
4. 備份工具mariabackup
Mariabackup是MariaDB提供的一個開源工具,用於對InnoDB,Aria和MyISAM表進行物理在線備份。這個工具是基於Percona的XtraBackup(版本2.3.8)的解決方案。
在MariaDB10.3.x及以上的版本用Percona XtraBackup工具會有問題。原因可能是MariaDB10.3以上版本的redo日志格式和之前不同了。
Percona的官方文檔:https://www.percona.com/doc/percona-xtrabackup/2.4/index.html
Mariabackup的官方文檔:https://mariadb.com/kb/en/library/mariabackup-overview/
安裝方法
1 yum install MariaDB-backup #需要有MariaDB數據庫的源
備份與恢復
全備+恢復
1)全量備份
1 mariabackup --backup --target-dir=/root/fullbackup --user=root --password=root
2)准備全備數據
1 mariabackup --prepare --target-dir=/root/fullbackup/ --user=root --password=root
3)還原數據(請確保數據目錄下是空的)
mariabackup --copy-back --target-dir=/root/fullbackup/ --user=root --password=root
4)修改屬組和屬主
chown -R mysql.mysql /var/lib/mysql
全備+增量+二進制->恢復
1) 全量備份數據庫
2) 創建一個數據庫
3) 增量備份
4) 刪除一個創建的數據庫
5) 恢復數據
1>> 全量備份
1 mariabackup --backup --target-dir=/root/fullbackup --user=root --password=root
2>> 增量備份
mariabackup --backup --target-dir=/root/inc1 --incremental-basedir=/root/fullbackup/ --user=root --password=root
3>> 准備全備數據
mariabackup --prepare --target-dir=/root/fullbackup/ --user=root --password=root
4>> 增量和全備數據合並
mariabackup --prepare --target-dir=/root/fullbackup/ --user=root --password=root --incremental-dir=/root/inc1/ --apply-log-only
5>> 恢復數據(請確保數據目錄下是空的)
mariabackup --copy-back --target-dir=/root/fullbackup/ --user=root --password=root
6>> 修改屬組和屬主
chown -R mysql.mysql /var/lib/mysql
還原的時候確保屬組和屬主是mysql:mysql