在MySQL或MariaDB中,任意時間對數據庫所作的修改,都會被記錄到日誌文件中。例如,當你添加了一個新的表,或者更新了一條數據,這些事件都會被存儲到二進制日誌文件中。二進制日誌文件在MySQL主從複合中是很是有用的,主服務器會發送其數據到遠程服務器中。mysql
當你須要恢復MySQL時,也會須要使用到二進制日誌文件。linux
mysqlbinlog 命令,以用戶可視的方式展現出二進制日誌中的內容。同時,也能夠將其中的內容讀取出來,供其餘MySQL實用程序使用。sql
在此示例中,咱們將會涉及如下內容:數據庫
在mysql中執行如下命令,便可查看二進制日誌文件的列表。服務器
1
2
3
4
5
6
7
8
|
mysql
>
SHOW
BINARY
LOGS
;
+
--
--
--
--
--
--
--
--
--
--
--
+
--
--
--
--
--
+
|
Log_name
|
File_size
|
+
--
--
--
--
--
--
--
--
--
--
--
--
--
+
--
--
--
--
--
--
+
|
mysqld
-
bin
.
000001
|
15740
|
|
mysqld
-
bin
.
000002
|
3319
|
.
.
.
.
|
若是熊沒有開啓此功能,則會顯示:session
1
2
|
mysql
>
SHOW
BINARY
LOGS
;
ERROR
1381
(
HY000
)
:
You
are
not
using
binary
logging
|
二進制日誌文件默認會存放在 /var/lib/mysql 目錄下ide
1
2
3
4
5
|
$
ls
-
l
/
var
/
lib
/
mysql
/
-
rw
-
rw
--
--
.
1
mysql
mysql
15740
Aug
28
14
:
57
mysqld
-
bin
.
000001
-
rw
-
rw
--
--
.
1
mysql
mysql
3319
Aug
28
14
:
57
mysqld
-
bin
.
000002
.
.
.
.
|
下面將以一種用戶友好的格式顯示指定的二進制日誌文件(例如:mysqld.000001)的內容。this
1
|
$
mysqlbinlog
mysqld
-
bin
.
000001
|
mysqlbinlog默認會顯示爲如下內容:編碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/*!40019 SET @@session.max_insert_delayed_threads=0*/
;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/
;
DELIMITER
/*!*/
;
# at 4#170726 14:57:37 server id 1 end_log_pos 106 Start: binlog v 4, server v 5.1.73-log created 170726 14:57:37 at startup# Warning: this binlog is either in use or was not closed properly.
ROLLBACK
/*!*/
;
BINLOG
' IeZ4WQ8BAAAAZgAAAGoAAAABAAQANS4xLjczLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAh5nhZEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC '
/*!*/
;
# at 106
#170726 14:59:31 server id 1 end_log_pos 182 Query thread_id=2 exec_time=0 error_code=0
SET
TIMESTAMP
=
1501095571
/*!*/
;
SET
@
@
session
.
pseudo_thread_id
=
2
/*!*/
;
SET
@
@
session
.
foreign_key_checks
=
1
,
@
@
session
.
sql_auto_is_null
=
1
,
@
@
session
.
unique_checks
=
1
,
@
@
session
.
autocommit
=
1
/*!*/
;
SET
@
@
session
.
sql_mode
=
0
/*!*/
;
SET
@
@
session
.
auto_increment_increment
=
1
,
@
@
session
.
auto_increment_offset
=
1
/*!*/
;
/*!\C latin1 */
/*!*/
;
SET
@
@
session
.
character_set_client
=
8
,
@
@
session
.
collation_connection
=
8
,
@
@
session
.
collation_server
=
8
/*!*/
;
.
.
.
.
.
.
# at 14191
#170726 15:20:38 server id 1 end_log_pos 14311 Query thread_id=4 exec_time=0 error_code=0SET TIMESTAMP=1501096838/*!*/;
insert
into
salary
(
name
,
dept
)
values
(
'Ritu'
,
'Accounting'
)
/*!*/
;
DELIMITER
;
# End of log file
ROLLBACK
/* added by mysqlbinlog */
;
/
*
!
50003
SET
COMPLETION_TYPE
=
@
OLD_COMPLETION_TYPE*
|
上面的命令將會顯示出,在該系統上數據庫發生的全部改變事件。spa
默認狀況下,mysqlbinlog會顯示全部的內容,太過於雜亂。使用 -d 選項,能夠指定一個數據庫名稱,將只顯示在該數據庫上所發生的事件。
1
|
$
mysqlbinlog
-
d
crm
mysqld
-
bin
.
000001
>
crm
-
events
.
txt
|
也可使用 --database 命令,效果相同。
1
|
$
mysqlbinlog
-
database
crm
mysqld
-
bin
.
000001
>
crm
-
events
.
txt
|
在使用二進制日誌文件進行數據庫恢復時,該過程當中也會產生日誌文件,就會進入一個循環狀態,繼續恢復該過程當中的數據。所以,當使用mysqlbinlog命令時,要禁用二進制日誌,請使用下面所示的-D選項:
1
|
$
mysqlbinlog
-
D
mysqld
-
bin
.
000001
|
也可使用 --disable-log-bin 命令,效果相同。
1
|
$
mysqlbinlog
--
disable
-
log
-
bin
mysqld
-
bin
.
000001
|
備註:在輸出中,當指定-D選項時,將看到輸出中的第二行。也就是SQL_LOG_BIN=0
1
2
3
|
/*!40019 SET @@session.max_insert_delayed_threads=0*/
;
/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/
;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/
;
|
當使用-to-last-log選項時,這個選項也會有所幫助。另外,請記住,該命令須要root權限來執行。
使用base64-output選項,能夠控制輸出語句什麼時候是輸出base64編碼的BINLOG語句。如下是base64輸出設置的可能值:
never:當指定以下所示的「never」時,它將在輸出中顯示base64編碼的BINLOG語句。
1
|
$
mysqlbinlog
--
base64
-
output
=
never
mysqld
-
bin
.
000001
|
將不會有任何與下面相似的行,它具備base64編碼的BINLOG。
1
|
BINLOG
'
IeZ4WQ8BAAAAZgAAABAAQANS4xLjczLWxvZwAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAh5nhZEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
always:當指定「always」選項時,只要有可能,它將只顯示BINLOG項。所以,只有在專門調試一些問題時才使用它。
1
|
$
mysqlbinlog
--
base64
-
output
=
always
mysqld
-
bin
.
000001
|
下面是「always」的輸出,它只顯示了BINLOG項。
1
2
3
4
5
6
7
8
9
10
|
BINLOG
' IeZ4WQ8BAAAAZgAAAGoAAAABAAQANS4xLjczLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAh5nhZEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC '
/*!*/
;
# at 106
#170726 14:59:31 server id 1 end_log_pos 182
BINLOG
' k+Z4WQIBAAAATAAAALYAAAAIAAIAAAAAAAAADAAAGgAAAEAAAAEAAAAAAAAAAAYDc3RkBAgACAAI AHRoZWdlZWtzdHVmZgBCRUdJTg== '
/*!*/
;
# at 182
#170726 14:59:30 server id 1 end_log_pos 291
BINLOG
' kuZ4WQIBAAAAbQAAACMBAAAAAAIAAAAAAAAADAAAGgAAAEAAAAEAAAAAAAAAAAYDc3RkBAgACAAI AHRoZWdlZWtzdHVmZgBJTlNFUlQgSU5UTyB0IFZBTFVFUygxLCAnYXBwbGUnLCBOVUxMKQ== '
/*!*/
;
# at 291
#170726 14:59:30 server id 1 end_log_pos 422
BINLOG
'
kuZ4WQIBAAAAgwAAAKYBAAAAAAIAAAAAAAAADAAAGgAAAEAAAAEAAAAAAAAAAAYDc3RkBAgACAAI
AHRoZWdlZWtzdHVmZgBVUERBVEUgdCBTRVQgbmFtZSA9ICdwZWFyJywgZGF0ZSA9ICcyMDA5LTAx
LTAxJyBXSEVSRSBpZCA9IDE
=
|
decode-rows:這個選項將把基於行的事件解碼成一個SQL語句,特別是當指定-verbose選項時,以下所示。
1
|
$
mysqlbinlog
--
base64
-
output
=
decode
-
rows
--
verbose
mysqld
-
bin
.
000001
|
auto:這是默認選項。當沒有指定任何base64解碼選項時,它將使用auto。在這種狀況下,mysqlbinlog將僅爲某些事件類型打印BINLOG項,例如基於行的事件和格式描述事件。
1
2
|
$
mysqlbinlog
--
base64
-
output
=
auto
mysqld
-
bin
.
000001
$
mysqlbinlog
mysqld
-
bin
.
000001
|
下面的調試選項,在完成處理給定的二進制日誌文件以後,將檢查文件打開和內存使用。
1
|
$
mysqlbinlog
--
debug
-
check
mysqld
-
bin
.
000001
|
以下所示,在完成處理給定的二進制日誌文件以後,下面的調試信息選項將顯示額外的調試信息。
1
2
3
4
5
6
|
$
mysqlbinlog
--
debug
-
info
mysqld
-
bin
.
000001
>
/
tmp
/
m
.
di
User
time
0.00
,
System
time
0.00
Maximum
resident
set
size
2848
,
Integral
resident
set
size
0
Non
-
physical
pagefaults
863
,
Physical
pagefaults
0
,
Swaps
0
Blocks
in
0
out
48
,
Messages
in
0
out
0
,
Signals
0
Voluntary
context
switches
1
,
Involuntary
context
switches
2
|
除了讀取整個mysql二進制日誌文件外,也能夠經過指定偏移量來讀取它的特定部分。可使用 -o 選項。o表明偏移。
下面將跳過指定的mysql bin日誌中的前10個條目。
1
|
$
mysqlbinlog
-
o
10
mysqld
-
bin
.
000001
|
爲了確保它正常工做,給偏移量提供一個巨大的數字,將看不到任何條目。下面的內容將從日誌中跳過10,000個條目(事件)。
1
2
3
4
5
6
|
$
mysqlbinlog
-
o
10000
mysqld
-
bin
.
000001
/*!40019 SET @@session.max_insert_delayed_threads=0*/
;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/
;
.
.
.
.
# End of log file
ROLLBACK
/* added by mysqlbinlog */
;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/
;
|
在本例中,因爲這個特定的日誌文件沒有10,000個條目,因此在輸出中沒有顯示任何數據庫事件。
也可使用簡單的Linux重定向命令,將輸出存儲到一個文件中,以下所示。
1
|
$
mysqlbinlog
mysqld
-
bin
.
000001
>
output
.
log
|
或者也可使用 -r (結果文件)選項,以下所示,將輸出存儲到一個文件中。
1
|
$
mysqlbinlog
-
r
output
.
log
mysqld
-
bin
.
000001
|
備註:還可使用 -server-id 指定mysql服務器,確保是由給定服務器id的mysql服務器所生成的日誌。
1
|
$
mysqlbinlog
--
server
-
id
=
1
-
r
output
.
log
mysqld
-
bin
.
000001
|
一般在mysql二進制日誌文件中,你將看到以下所示的位置號。下面是mysqlbinlog的部分輸出,你能夠看到「15028」是一個位置編號。
1
2
3
4
5
6
7
8
|
#170726 15:38:14 server id 1 end_log_pos 15028 Query thread_id=5 exec_time=0 error_code=0
SET
TIMESTAMP
=
1501097894
/*!*/
;
insert
into
salary
values
(
400
,
'Nisha'
,
'Marketing'
,
9500
)
/*!*/
;
# at 15028
#170726 15:38:14 server id 1 end_log_pos 15146 Query thread_id=5 exec_time=0 error_code=0
SET
TIMESTAMP
=
1501097894
/*!*/
;
insert
into
salary
values
(
500
,
'Randy'
,
'Technology'
,
6000
)
|
下面的命令將從位置編號爲15028的二進制日誌條目處開始讀取。
1
|
$
mysqlbinlog
-
j
15028
mysqld
-
bin
.
000001
>
from
-
15028.out
|
當在命令行中指定多個二進制日誌文件時,開始位置選項將僅應用於給定列表中的第一個二進制日誌文件。還可使用 -H 選項來得到給定的二進制日誌文件的十六進制轉儲,以下所示。
1
|
$
mysqlbinlog
-
H
mysqld
-
bin
.
000001
>
binlog
-
hex
-
dump
.
out
|
就像前面的例子同樣,你也能夠從mysql二進制日誌中截止到一個特定位置的條目,以下所示。
1
|
$
mysqlbinlog
--
stop
-
position
=
15028
mysqld
-
bin
.
000001
>
upto
-
15028.out
|
上面的示例將在15028的位置上中止binlog。當在命令行中指定多個二進制日誌文件時,中止位置將僅應用於給定列表中的最後一個二進制日誌文件。
當二進制日誌文件沒有被正確地關閉時,將在輸出中看到一個警告消息,以下所示。
1
|
$
mysqlbinlog
mysqld
-
bin
.
000001
>
output
.
out
|
以下所示,報告中提示binlog文件沒有正確地關閉。
1
2
3
4
5
6
7
|
# head output.log
/*!40019 SET @@session.max_insert_delayed_threads=0*/
;
.
.
.
.
# Warning: this binlog is either in use or was not closed properly.
.
.
.
.
.
.
BINLOG
'
IeZ4WQ8BAAAAZgAAAGoAAAABAAQANS4xLjczLWxvZwAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAh5nhZEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
當看到這個提示時,須要鏈接到mysql並刷新日誌,以下所示。
1
|
mysql
>
flush
logs
;
|
刷新日誌以後,再次執行mysqlbinlog命令,將不會看到在mysqlbinlog輸出中binlog未正確關閉的警告消息。
默認狀況下,正如在前面的示例輸出中看到的同樣,除了SQL語句以外,在mysqlbinlog輸出中還會有一些附加信息。若是隻想查看常規的SQL語句,而不須要其餘內容,那麼可使用 -s 選項,以下所示。
也可使用 --short-form 選項,效果相同。
1
2
3
|
$
mysqlbinlog
-
s
mysqld
-
bin
.
000001
$
mysqlbinlog
--
short
-
form
mysqld
-
bin
.
000001
|
下面是上述命令的部分輸出。在這裏,它將只顯示來自給定二進制日誌文件的SQL語句。
1
2
3
4
5
6
|
SET
TIMESTAMP
=
1501096106
/*!*/
;
insert
into
employee
values
(
400
,
'Nisha'
,
'Marketing'
,
9500
)
/*!*/
;
SET
TIMESTAMP
=
1501096106
/*!*/
;
insert
into
employee
values
(
500
,
'Randy'
,
'Technology'
,
6000
)
.
.
.
.
|
不會顯示像下面這樣的條目:
1
2
|
# at 1201
#170726 15:08:26 server id 1 end_log_pos 1329 Query thread_id=3 exec_time=0 error_code=0
|
下面將只提取從指定時間開始的條目。在此以前的任何條目都將被忽略。
1
|
$
mysqlbinlog
--
start
-
datetime
=
"2017-08-16 10:00:00"
mysqld
-
bin
.
000001
|
當你想要從一個二進制文件中提取數據時,這是很是有用的,由於你但願使用它來恢復或重構在某個時間段內發生的某些數據庫活動。時間戳的格式能夠是MySQL服務器所理解的DATETIME和timestamp中的任何類型。
與前面的開始時間示例同樣,這裏也能夠指定結束時間,以下所示。
1
|
$
mysqlbinlog
--
stop
-
datetime
=
"2017-08-16 15:00:00"
mysqld
-
bin
.
000001
|
上面的命令將讀取到給定結束時間的條目。任何來自於超過給定結束時間的mysql二進制日誌文件的條目都不會被處理。
在本地機器上,還能夠讀取位於遠程服務器上的mysql二進制日誌文件。爲此,須要指定遠程服務器的ip地址、用戶名和密碼,以下所示。
此處使用-R選項。-R選項與-read-from-remote-server相同。
1
|
$
mysqlbinlog
-
R
-
h
192.168.101.2
-
p
mysqld
-
bin
.
000001
|
在上面命令中:
下面命令與上面的命令徹底相同:
1
|
$
mysqlbinlog
--
read
-
from
-
remote
-
server
--
host
=
192.168.101.2
-
p
mysqld
-
bin
.
000001
|
若是隻指定 -h 選項,將會獲得下面的錯誤消息。
1
2
|
$
mysqlbinlog
-
h
192.168.101.2
mysqld
-
bin
.
000001
mysqlbinlog
:
File
'mysqld-bin.000001'
not
found
(
Errcode
:
2
)
|
當你在遠程數據庫上沒有足夠的特權時,將獲得如下「不容許鏈接」錯誤消息。在這種狀況下,確保在遠程數據庫上爲本地客戶機授予適當的特權。
1
2
3
|
$
mysqlbinlog
-
R
--
host
=
192.168.101.2
mysqld
-
bin
.
000001
ERROR
:
Failed
on
connect
:
Host
'216.172.166.27'
is
not
allowed
to
connect
to
this
MySQL
server
|
若是沒有使用 -p 選項指定正確的密碼,那麼將獲得如下「訪問拒絕」錯誤消息。
1
2
|
$
mysqlbinlog
-
R
--
host
=
192.168.101.2
mysqld
-
bin
.
000001
ERROR
:
Failed
on
connect
:
Access
denied
for
user
'root'
@
'216.172.166.27'
(
using
password
:
YES
)
|
下面的示例顯示,還可使用-u選項指定mysqlbinlog應該用於鏈接到遠程MySQL數據庫的用戶名。請注意,這個用戶是mysql用戶(不是Linux服務器用戶)。
1
|
$
mysqlbinlog
-
R
--
host
=
192.168.101.2
-
u
root
-
p
mysqld
-
bin
.
000001
<
span
style
=
"text-indent: 2em;
|