C-17.其他資料日誌
在之前的資料庫事務的章節中,已經講過,redo log和undo log。
對於線上資料庫應用系統,突然遭遇資料庫當機
怎麼辦?在這種情況下,定位當機的原因
就非常關鍵。我們可以檢視資料庫的錯誤日誌
。因為日誌中記錄了資料庫執行中的診斷資訊,包括了錯誤,警告和註釋等資訊。比如:從日誌中發現某個連線中的SQL操作發生了死迴圈,導致記憶體不足,被系統強制終止了。明確了原因,處理起來也就輕鬆了,系統很快就恢復了執行。
除了發現錯誤,日誌在資料複製,資料恢復,操作審計,以及確報資料的永久性和一致性等方面,都有著不可替代的作用。
千萬不要小看日誌。很多看似奇怪的問題,答案往往就藏在日誌裡。很多情況下,只有透過檢視日誌才能發現問題的原因,真正解決問題。所以,一定要學會檢視日誌,養成檢查日誌的習慣,對提升你的資料庫應用開發能力至關重要。
MySQL8.0官網日誌地址
1.MySQL支援的日誌
1.1 日誌型別
MySQL有不同的日誌檔案,用來儲存不同型別的日誌,分為二進位制日誌
、錯誤日誌
、通用查詢日誌
和慢查詢日誌
,這也是常用的4種。MySQL8.0之後又新增了兩種支援的日誌:中繼日誌
和資料定義語句日誌
。使用這些日誌檔案,可以檢視MySQL內部發生的事情。
這六類日誌分別為:
- 慢查詢日誌:記錄所有執行時間超過long_query_time的所有查詢,方便我們對查詢進行最佳化。
- 通用查詢日誌:記錄所有連線的起始時間和終止時間,以及連線傳送給資料庫伺服器的所有指令,對我們復原操作的實際場景,發現問題,甚至是對資料庫操作的審計都有很大的幫助。
- 錯誤日誌:記錄MySQL服務的啟動,執行或停止MySQL服務時出現的問題,方便我們瞭解伺服器的狀態,從而對伺服器進行維護。
- 二進位制日誌:記錄所有更改資料的語句,可以用於主從伺服器之間的資料同步,以及伺服器遇到的故障時資料的無損失恢復。
- 中繼日誌:用於主從伺服器架構中,從伺服器用來存放主伺服器二進位制日誌內容中的一箇中間檔案。從伺服器透過讀取中繼日誌的內容,來同步主伺服器上的操作。
- 資料定義語句日誌:記錄資料定義語句執行的後設資料操作。
除二進位制日誌外,其他日誌都是文字檔案
。預設情況下,所有日誌建立於MySQL資料目錄
中。
1.2 日誌的弊端
- 日誌功能會
降低MySQL資料庫的效能
。例如,在查詢非常頻繁的MySQL資料庫系統中,如果開啟了通用查詢日誌和慢查詢日誌,MySQL資料庫會花費很多時間記錄日誌。 - 日誌會
佔用大量的磁碟空間
。對於使用者量非常大,操作非常頻繁的資料庫,日誌檔案需要的儲存空間設定比資料庫檔案需要的儲存空間還大。
2.慢查詢日誌(slow query log)
見前面章節《第09章.效能分析工具的使用》
3.通用查詢日誌(general query log)
通用查詢日誌用來記錄使用者的所有操作
,包括啟動和關閉MySQL服務、所有使用者的連線開始時間和截止時間、發給MysQL資料庫伺服器的所有SQL指令等。當我們的資料發生異常時,檢視通用查詢日誌,還原操作時的具體場景,可以幫助我們準確定位問題。
3.1 問題場景
在電商系統中,購買商品並且使用微信支付完成以後,卻發現支付中心的記錄並沒有新增,此時使用者再次使用支付寶支付,就會出現重複支付
的問題。但是當去資料庫中查詢資料的時候,會發現只有一條記錄存在。那麼此時給到的現象就是隻有一條支付記錄,但是使用者卻支付了兩次。
我們對系統進行了仔細檢查,沒有發現資料問題,因為使用者編號和訂單編號以及第三方流水號都是對的。可是使用者確實支付了兩次,這個時候,我們想到了檢查通用查詢日誌,看看當天到底發生了什麼。
檢視之後,發現: 1月1日下午2點,使用者使用微信支付完以後,但是由於網路故障,支付中心沒有及時收到微信支付的回撥通知,導致當時沒有寫入資料。1月1日下午2點30,使用者又使用支付寶支付,此時記錄更新到支付中心。1月1日晚上9點,微信的回撥通知過來了,但是支付中心已經存在了支付寶的記錄,所以只能覆蓋記錄了。
由於網路的原因導致了重複支付。至於解決問題的方案就很多了,這裡省略。
可以看到通用查詢日誌可以幫助我們瞭解操作發生的具體時間和操作的細節,對找出異常發生的原因極其關鍵。
3.2 檢視當前狀態
mysql> show variables like '%general%'; #檢視通用日誌相關的資訊
+------------------+-------------------------------------+
| Variable_name | Value |
+------------------+-------------------------------------+
| general_log | OFF |#通用查詢日誌預設處於關閉狀態
| general_log_file | /var/lib/mysql/LinuxCentOS7-132.log |#通用查詢日誌檔案的名稱是主機名.log
+------------------+-------------------------------------+
2 rows in set (0.01 sec)
說明1:系統變數general_log的值是OFF,即通用查詢日誌處於關閉狀態。在MySQL中,這個引數的預設值是關閉的
。因為一旦開啟記錄通用查詢日誌,MySQL會記錄所有的連線起止和相關的sQL操作,這樣會消耗系統資源並且佔用磁碟空間。我們可以透過手動修改變數的值,在需要的時候開啟日誌
。
說明2:通用查詢日誌檔案的名稱是atguiguo1.log。儲存路徑是/var/lib/mysql/,預設也是資料路徑。這樣我們就知道在哪裡可以檢視通用查詢日誌的內容了。
3.3 啟動日誌
方式1:永久性方式
修改my.cnf或者my.ini配置檔案來設定。在[mysqld]組下加入log選項,並重啟MySQL服務。格式如下:
[mysqld]
general_log=ON
general_log_file=[path[filename]] #日誌檔案所在目錄路徑,filename為日誌檔名
如果不指定目錄和檔名,通用查詢日誌將預設儲存在MysQL資料目錄中的hostname.log檔案中,hostname表示主機名。
方式2:臨時性方式
SET GLOBAL general_log = on; #開啟通用查詢日誌
SET GLOBAL general_log_file = 'path/filename';#設定日誌檔案儲存位置
SET GLOBAL general_log=off; #關閉通用查詢日誌
3.4 檢視日誌
通用查詢日誌是以文字檔案
的形式儲存在檔案系統中的,可以使用文字編輯器
直接開啟日誌檔案。每臺MySQL伺服器的通用查詢日誌內容是不同的。
- 在Windows作業系統中,可以使用文字檔案檢視器;
- 在Linux系統中,可以使用vi工具或者使用
cat x | more
指令檢視;x是日誌檔案路徑 - 在Mac OSX系統中,可以使用文字檔案檢視器或者vi等工具檢視;
從SHOW VARIABLES LIKE 'general_log%';
可以看到通用查詢日誌的位。
透過通用查詢日誌,可以瞭解使用者對MySQL進行的操作。比如,MySQL啟動資訊和使用者root連線伺服器和執行查詢表的記錄。
[root@LinuxCentOS7-132 mysql]# cat LinuxCentOS7-132.log | more
/usr/sbin/mysqld, Version: 8.0.25 (MySQL Community Server - GPL). started with:
Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock
Time Id Command Argument
2024-07-05T05:54:17.793401Z 8 Connect root@localhost on using Socket
2024-07-05T05:54:17.793957Z 8 Query show variables like '%general%'
2024-07-05T05:55:27.533798Z 8 Query SELECT DATABASE()
2024-07-05T05:55:27.534388Z 8 Init DB atguigudb3
2024-07-05T05:55:27.535351Z 8 Query show databases
2024-07-05T05:55:27.538430Z 8 Query show tables
2024-07-05T05:55:27.541006Z 8 Field List a
2024-07-05T05:55:27.549343Z 8 Field List b
2024-07-05T05:55:27.550761Z 8 Field List book
2024-07-05T05:55:27.552245Z 8 Field List class
2024-07-05T05:55:27.553020Z 8 Field List mylock
2024-07-05T05:55:27.554347Z 8 Field List student
2024-07-05T05:55:27.555107Z 8 Field List student1
2024-07-05T05:55:27.555770Z 8 Field List t1
2024-07-05T05:55:27.556666Z 8 Field List t2
2024-07-05T05:55:27.557287Z 8 Field List teacher
2024-07-05T05:55:27.557999Z 8 Field List test
2024-07-05T05:55:27.558670Z 8 Field List type
2024-07-05T05:55:27.559399Z 8 Field List user1
2024-07-05T05:55:31.015640Z 8 Query show tables
2024-07-05T05:55:37.341184Z 8 Query select * from student1
在通用查詢日誌裡面,我們可以看到,什麼時候開啟了新的客戶端登入資料庫,登入之後做了什麼SQL操作,針對的是那個資料表等資訊。
3.5 停止日誌
方式1:永久性方式
修改my.cnf
或者my.ini
檔案,把[mysqld]組下的general_log
值設定為OFF
或者把general_log註釋掉。修改後儲存,再重啟MySQL服務
,即可生效。
舉例1:
[mysqld]
general_log=OFF
舉例2:
[mysqld]
#general_log=ON;
方式2:臨時性方式
使用SET語句停止MySQL通用查詢日誌功能:
SET GLOBAL general_log=off;
3.6 刪除\重新整理日誌
如果資料的使用非常頻繁,那麼通用查詢日誌會佔用伺服器非常大的磁碟空間。資料管理員可以刪除很長時間之前的查詢日誌,以保證MySQL伺服器上的硬碟空間。
手動刪除檔案
SHOW VARIABLES LIKE 'general_log%';
執行上述指令,通用查詢日誌的目錄預設為MySQL資料目錄。在該目錄下手動刪除通用查詢日誌x.log(x為通用查詢日誌名稱,rm -rf指令)。
使用如下命令重新生成查詢日誌檔案,具體命令如下。重新整理MySQL資料目錄,發現建立了新的日誌檔案。前提一定要開啟通用日誌。
mysqladmin -uroot -p flush-logs
如果希望備份舊的通用查詢日誌,就必須先將舊的日誌檔案複製出來或者改名,然後執行上面的mysqladmin命令。正確流程如下
cd /var/lib/mysql/ #注意,使用自己通用日誌檔案所在目錄
mv mysql.general.log mysql.general.log.old #進行備份,將通用檔案,移動到新的目錄
mysqladmin -uroot -p flush-logs
注意,通用查詢日誌,是記錄客戶端,連線上服務端,執行的所有指令的記錄,如果使用者多的話,開啟該日誌檔案,可能日誌檔案會很大,所以一般,通用查詢日誌,是不開啟的。
4.錯誤日誌(error log)
錯誤日誌記錄了MySQL伺服器啟動、停止執行的時間,以及系統啟動、執行和停止過程中的診斷資訊,包括錯誤
、警告
和提升
等。
透過錯誤日誌可以檢視系統的執行狀態,便於即時發現故障、修復故障。如果MySQL服務出現異常
,錯誤日誌是發現問題,解決故障的首選
。
4.1 啟動日誌
在MySQL資料庫中,錯誤日誌功能是預設開啟
的。而且,錯誤日誌無法被禁止
。
預設情況下,錯誤日誌儲存在MySQL資料庫的資料資料夾下,名稱預設為mysqld.log
(Linux系統)或者hostname.err
(mac系統)。如果需要制定檔名,則需要在my.cnf或者my.ini中做如下配置:
[mysqld]
log_error=[path/[filename]] #path為日誌檔案所在的目錄路徑,filename為日誌檔名
#有可能安裝後,配置檔案裡,指定了該檔案的位置/var/log/mysqld.log
修改配置項後,需要重啟MySQL服務以生效。systemctl restart mysqld
4.2 檢視日誌
MySQL錯誤日誌是以文字檔案形式儲存的,可以使用文字編輯器直接檢視。
查詢錯誤日誌的儲存路徑:
mysql> show variables like 'log_err%';
+----------------------------+----------------------------------------+
| Variable_name | Value |
+----------------------------+----------------------------------------+
| log_error | /var/log/mysqld.log |
| log_error_services | log_filter_internal; log_sink_internal |
| log_error_suppression_list | |
| log_error_verbosity | 2 |
+----------------------------+----------------------------------------+
4 rows in set (0.00 sec)
執行結果中可以看到錯誤日誌檔案是mysqld.log,位於MySQL預設的資料目錄下。
下面我們檢視以下錯誤日誌的內容
2024-07-05T05:54:14.502073Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.25' socket: '/var/lib/mysql/mysql.sock'
port: 3306 MySQL Community Server - GPL.
2024-07-05T06:31:17.063408Z 0 [System] [MY-013172] [Server] Received SHUTDOWN from user <via user signal>. Shutting down mysqld (Version: 8.0.25).
2024-07-05T06:31:19.069534Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 8 user: 'root'.
2024-07-05T06:31:19.725053Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.25) MySQL Community Server - GPL.
2024-07-05T06:31:20.693990Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.25) starting as process 3940
2024-07-05T06:31:20.703321Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2024-07-05T06:31:20.835983Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2024-07-05T06:31:20.937480Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.
sock
2024-07-05T06:31:20.980691Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2024-07-05T06:31:20.980871Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this
channel.
可以看到,錯誤日誌檔案中記錄了伺服器啟動的時間,以及儲存引擎InnoDB啟動和停止的時間等。以及在安裝mysql初始化的時候生成的資料庫密碼也是記錄在mysqld.log中。
4.3 刪除\重新整理日誌
對於很久以前的錯誤日誌,資料庫管理員檢視這些錯誤日誌的可能性不大,可以將這些錯誤日誌刪除,以保證MySQL伺服器上的硬碟空間
。MySQL的錯誤日誌是以文字檔案的形式儲存在檔案系統中的,可以直接刪除
。
- 第1步(方式1):刪除操作
rm -f /var/lib/mysql/mysqld.log
在執行狀態下刪除錯誤日誌檔案後,MySQL並不會自動建立日誌檔案。
- 第1步(方式2):重新命名檔案
mv /var/log/mysqld.log /var/log/mysqld.log.old
- 第2步:重建日誌
mysqladmin -uroot -p flush-logs
可能會報錯
[root@LinuxCentOS7-132 log]# mysqladmin -uroot -p flush-logs
Enter password:
mysqladmin: refresh failed; error: 'Could not open file '/var/log/mysqld.log' for error logging.'
官網提示:
補充操作:
install -omysql -gmysql -m0644 /dev/null /var/log/mysqld.log
flush-logs
指令操作
- MySQL5.5.7以前的版本,flush-logs將錯誤日誌檔案重新命名為filename.err_old,並建立新的日誌檔案。
- 從MySQL5.5.7開始,flush-logs只是重新開啟日誌檔案,並不做日誌備份和建立的操作。
- 如果日誌檔案不存在,MySQL啟動或者執行flush-logs時會自動建立新的日誌檔案。重新建立錯誤日誌,大小為0位元組。
4.4 MySQL8.0新特性
MySQL8.0裡對錯誤日誌的改進。MySQL8.o的錯誤日誌可以理解為一個全新的日誌,在這個版本里,接受了來自社群的廣泛批評意見,在這些意見和建議的基礎上生成了新的日誌。
下面這些是來自社群的意見:
- 預設情況下內容過於冗長
- 遺漏了有用的資訊
- 難以過濾某些資訊
- 沒有標識錯誤資訊的子系統源
- 沒有錯誤程式碼,解析訊息需要識別錯誤
- 引導訊息可能會丟失
- 固定格式
針對這些意見,MySQL做了如下改變
- 採用元件架構,透過不同的元件執行日誌的寫入和過濾功能
- 寫入錯誤日誌的全部資訊都具有唯一的錯誤程式碼從10000開始
- 增加了一個新的訊息分類《system》用於在錯誤日誌中始終可見的非錯誤但伺服器狀態更改事件的訊息
- 增加了額外的附加資訊,例如關機時的版本資訊,誰發起的關機等等
- 兩種過濾方式,Internal和Dragnet
- 三種寫入形式,經典、JSON和syseventlog
小結:
通常情況下,管理員不需要檢視錯誤日誌。但是,MySQL伺服器發生異常時,管理員可以從錯誤日誌中找到發生異常的時間、原因,然後根據這些資訊來解決異常。
5.二進位制日誌(bin log)
binlog可以說是MySQL中比較重要
的日誌了,在日常開發及運維過程中,經常會遇到。
binlog即binary log,二進位制日誌檔案,也叫作變更日誌(update log)。它記錄了資料庫所有執行的DDL
和DML
等資料庫更新事件的語句,但是不包含沒有修改任何資料的語句(如資料查詢語句select、show等)。
它以事件形式
記錄並儲存在二進位制檔案
中。透過這些資訊,我們可以再現資料更新操作的全過程。
如果想要記錄所有語句(例如,為了識別有問題的查詢),需要使用通用查詢日誌。
binlog主要應用場景:
- 一是用於
資料恢復
,如果MySQL資料庫意外停止,可以透過二進位制日誌檔案來檢視使用者執行了那些操作,對資料庫伺服器檔案做了那些修改,然後根據二進位制日誌檔案中的記錄來恢復資料庫伺服器。 - 二是用於
資料複製
,由於日誌的延續性和時效性,master把它的二進位制日誌傳遞給slaves來達到master-slave資料一致的目的。
可以說MySQL資料庫的資料備份、主備、主主、主從都離不開binlog,需要依靠binlog來同步資料,保證資料一致性。
5.1 檢視預設情況
檢視記錄二進位制日誌是否開啟:在MySQL8.0中預設情況下,二進位制檔案是開啟的。
mysql> show variables like '%log_bin%';#預設值
+---------------------------------+-----------------------------+
| Variable_name | Value |
+---------------------------------+-----------------------------+
| log_bin | ON |#是否開啟二進位制日誌
| log_bin_basename | /var/lib/mysql/binlog |#二進位制日誌檔案的路徑和檔名字首
| log_bin_index | /var/lib/mysql/binlog.index |#字尾 binlog.000058
| log_bin_trust_function_creators | OFF |#是否信任,建立的儲存函式或儲存過程
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |#是否將寫(變更)的sql寫入到bin_log中
+---------------------------------+-----------------------------+
6 rows in set (0.00 sec)
log_bin_basename
: 是binlog日誌的基本檔名,後面會追加標識來表示每一個檔案。
log_bin_index
:是binlog檔案的索引檔案,這個檔案管理了所有的binlog檔案的目錄。
log_bin_trust_function_creators
:限制儲存過程,前面我們已經講過了,這是因為二進位制日誌的一個重要功能是用於主從複製,而儲存函式有可能導致主從的資料不一致。所以當開啟二進位制日誌後,需要限制儲存函式的建立、修改、呼叫。
log_bin_use_v1_row_events
:此只讀系統變數已棄用。ON表示使用版本1二進位制日誌行,OFF表示使用版本2二進位制日誌行(MySQL 5.6的預設值為2)。
5.2 日誌引數的設定
方式1:永久性方式
修改MySQL的my.cnf
或my.ini
檔案可以設定二進位制日誌的相關引數:
[mysqld]
#啟用二進位制日誌
#設定binlog日誌的檔名字首預設就是binlog
log-bin=binlog
binlog_expire_logs_seconds=600
max_binlog_size=100M
提示:
- log-bin=mysql-bin #開啟日誌(主機需要開啟),這個mysql-bin也可以自定義,這裡也可以加上路徑,
如: /home/www/mysql_bin_log/mysql-bin- binlog_expire_logs_seconds:此引數控制二進位制日誌檔案保留的時長,單位是
秒
,預設2592000 30天--14400 4小時;86400 1天;259200 3天;- max_binlog_size:控制單個二進位制日誌大小,當前日誌檔案大小超過此變數時,執行切換動作。此引數的
最大和預設值是1GB
,該設定並不能嚴格控制Binlog的大小
,尤其是Binlog比較靠近最大值而又遇到一個比較大事務時,為了保證事務的完整性,可能不做切換日誌的動作,只能將該事務的所有SQL都記錄進當前日誌,直到事務結束。一般情況下可採取預設值。
設定帶資料夾的bin-log日誌存放目錄
如果想改變日誌檔案的目錄和名稱,可以對my.cnf或my.ini中的log_bin引數修改如下:
[mysqld]
#x代表binlog日誌的字首
log-bin="/var/lib/mysql/binlog/x"
注意:新建的資料夾需要使用mysql使用者,或者使用chown命令,改變資料夾的所有者為mysql
chown -R mysql:mysql 自定義目錄
#修改目錄的所有者和所在組 newowner:newgroup
提醒資料庫檔案,和binlog檔案最好不要放在一起,磁碟損壞(機率很低)的時候,還能有個資料恢復。
方式2:暫時性方式
如果不希望透過修改配置檔案並重啟的方式設定二進位制日誌的話,還可以使用如下指令,需要注意的是在mysql 8.0中只有會話級別
的設定,沒有了global級別的設定。
mysql> set session sql_log_bin=1;#該引數只是會話級別的系統引數
Query OK, 0 rows affected (0.00 sec)
5.3 檢視日誌
當MySQL建立二進位制日誌檔案時,先建立一個以“filename"為名稱、以".index”為字尾的檔案,再建立一個以“filename”為名稱、以".o00001”為字尾的檔案。
MySQL服務重新啟動一次
,以".000001”為字尾的檔案就會增加一個,並且字尾名按1遞增。即日誌檔案的個數與MysQL服務啟動的次數相同;如果日誌長度超過了max_binlog_size
的上限(預設是1GB),就會建立一個新的日誌檔案。
檢視當前的二進位制日誌檔案列表及大小。指令如下:
mysql> show binary logs;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000058 | 179 | No |
| binlog.000059 | 156 | No |
+---------------+-----------+-----------+
2 rows in set (0.00 sec)
所有對資料庫的修改都會記錄在binglog中。但binlog是二進位制檔案,無法直接檢視,想要更直觀的觀測它就要藉助mysqlbinlog
命令工具了。指令如下:在檢視執行,先執行一條sQL語句,如下
update student1 set name = '錢七1' where id = 1;
開始檢視binlog
mysqlbinlog "/var/lib/mysql/binlog.000059";
[root@LinuxCentOS7-132 ~]# mysqlbinlog "/var/lib/mysql/binlog.000059";
#240705 17:00:21 server id 1 end_log_pos 235 CRC32 0xad231a5f Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=yes original_committed_timestamp=1720170021748050 immediate_commit_timestamp=1720170021748050 transaction_length=344
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1720170021748050 (2024-07-05 17:00:21.748050 CST)
# immediate_commit_timestamp=1720170021748050 (2024-07-05 17:00:21.748050 CST)
/*!80001 SET @@session.original_commit_timestamp=1720170021748050*//*!*/;
/*!80014 SET @@session.original_server_version=80025*//*!*/;
/*!80014 SET @@session.immediate_server_version=80025*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 235
#240705 17:00:21 server id 1 end_log_pos 325 CRC32 0x2ea22ae6 Query thread_id=8 exec_time=0 error_code=0
SET TIMESTAMP=1720170021/*!*/;
SET @@session.pseudo_thread_id=8/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1168113696/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
/*!80011 SET @@session.default_collation_for_utf8mb4=255*//*!*/;
BEGIN
/*!*/;
# at 325
#240705 17:00:21 server id 1 end_log_pos 394 CRC32 0x2571f337 Table_map: `atguigudb3`.`student1` mapped to number 96
# at 394
#240705 17:00:21 server id 1 end_log_pos 469 CRC32 0x199dbf5d Update_rows: table id 96 flags: STMT_END_F
BINLOG '
JbaHZhMBAAAARQAAAIoBAAAAAGAAAAAAAAEACmF0Z3VpZ3VkYjMACHN0dWRlbnQxAAMDDw8EPAAe
AAYBAQACASE383El
JbaHZh8BAAAASwAAANUBAAAAAGAAAAAAAAEAAgAD//8AFAAAAAbpkrHkuIMG5LiJ54+tABQAAAAH
6ZKx5LiDMQbkuInnj61dv50Z
'/*!*/;
# at 469
#240705 17:00:21 server id 1 end_log_pos 500 CRC32 0x64542cc0 Xid = 26
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
執行結果可以看到,這是一個簡單的日誌檔案,日誌中記錄了用屍的一些操作,這裡並沒有出現具體的SQL語句,這是因為binlog關鍵字後面的內容是經過編碼後的二進位制日誌
。
這裡一個update語句包含如下事件
- Query事件負責開始一個事務(BEGIN)
- Table_map事件負責對映需要的表
- Update_rows事件負責寫入資料
- Xid事件負責結束事務
下面命令將行事件以偽SQL的形式
表現出來
mysqlbinlog -v "/var/lib/mysql/binlog.000059";
[root@LinuxCentOS7-132 ~]# mysqlbinlog -v "/var/lib/mysql/binlog.000059";
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#240705 16:33:40 server id 1 end_log_pos 125 CRC32 0x9d6cf625 Start: binlog v 4, server v 8.0.25 created 240705 16:33:40 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
5K+HZg8BAAAAeQAAAH0AAAABAAQAOC4wLjI1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADkr4dmEwANAAgAAAAABAAEAAAAYQAEGggAAAAICAgCAAAACgoKKioAEjQA
CigBJfZsnQ==
'/*!*/;
# at 125
#240705 16:33:40 server id 1 end_log_pos 156 CRC32 0x3235c33d Previous-GTIDs
# [empty]
# at 156
#240705 17:00:21 server id 1 end_log_pos 235 CRC32 0xad231a5f Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=yes original_committed_timestamp=1720170021748050 immediate_commit_timestamp=1720170021748050 transaction_length=344
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1720170021748050 (2024-07-05 17:00:21.748050 CST)
# immediate_commit_timestamp=1720170021748050 (2024-07-05 17:00:21.748050 CST)
/*!80001 SET @@session.original_commit_timestamp=1720170021748050*//*!*/;
/*!80014 SET @@session.original_server_version=80025*//*!*/;
/*!80014 SET @@session.immediate_server_version=80025*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 235
#240705 17:00:21 server id 1 end_log_pos 325 CRC32 0x2ea22ae6 Query thread_id=8 exec_time=0 error_code=0
SET TIMESTAMP=1720170021/*!*/;
SET @@session.pseudo_thread_id=8/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1168113696/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
/*!80011 SET @@session.default_collation_for_utf8mb4=255*//*!*/;
BEGIN
/*!*/;
# at 325
#240705 17:00:21 server id 1 end_log_pos 394 CRC32 0x2571f337 Table_map: `atguigudb3`.`student1` mapped to number 96
# at 394
#240705 17:00:21 server id 1 end_log_pos 469 CRC32 0x199dbf5d Update_rows: table id 96 flags: STMT_END_F
BINLOG '
JbaHZhMBAAAARQAAAIoBAAAAAGAAAAAAAAEACmF0Z3VpZ3VkYjMACHN0dWRlbnQxAAMDDw8EPAAe
AAYBAQACASE383El
JbaHZh8BAAAASwAAANUBAAAAAGAAAAAAAAEAAgAD//8AFAAAAAbpkrHkuIMG5LiJ54+tABQAAAAH
6ZKx5LiDMQbkuInnj61dv50Z
'/*!*/;
### UPDATE `atguigudb3`.`student1`
### WHERE
### @1=20
### @2='錢七'
### @3='三班'
### SET
### @1=20
### @2='錢七1'
### @3='三班'
# at 469
#240705 17:00:21 server id 1 end_log_pos 500 CRC32 0x64542cc0 Xid = 26
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
上述指令同時顯示binlog格式的語句,使用如下命令不顯示
mysqlbinlog -v --base64-output=DECODE-ROWS "/var/lib/mysql/binlog.000059";
[root@LinuxCentOS7-132 ~]# mysqlbinlog -v --base64-output=DECODE-ROWS "/var/lib/mysql/binlog.000059";
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#240705 16:33:40 server id 1 end_log_pos 125 CRC32 0x9d6cf625 Start: binlog v 4, server v 8.0.25 created 240705 16:33:40 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
# at 125
#240705 16:33:40 server id 1 end_log_pos 156 CRC32 0x3235c33d Previous-GTIDs
# [empty]
# at 156
#240705 17:00:21 server id 1 end_log_pos 235 CRC32 0xad231a5f Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=yes original_committed_timestamp=1720170021748050 immediate_commit_timestamp=1720170021748050 transaction_length=344
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1720170021748050 (2024-07-05 17:00:21.748050 CST)
# immediate_commit_timestamp=1720170021748050 (2024-07-05 17:00:21.748050 CST)
/*!80001 SET @@session.original_commit_timestamp=1720170021748050*//*!*/;
/*!80014 SET @@session.original_server_version=80025*//*!*/;
/*!80014 SET @@session.immediate_server_version=80025*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 235
#240705 17:00:21 server id 1 end_log_pos 325 CRC32 0x2ea22ae6 Query thread_id=8 exec_time=0 error_code=0
SET TIMESTAMP=1720170021/*!*/;
SET @@session.pseudo_thread_id=8/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1168113696/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
/*!80011 SET @@session.default_collation_for_utf8mb4=255*//*!*/;
BEGIN
/*!*/;
# at 325
#240705 17:00:21 server id 1 end_log_pos 394 CRC32 0x2571f337 Table_map: `atguigudb3`.`student1` mapped to number 96
# at 394
#240705 17:00:21 server id 1 end_log_pos 469 CRC32 0x199dbf5d Update_rows: table id 96 flags: STMT_END_F
### UPDATE `atguigudb3`.`student1`
### WHERE
### @1=20
### @2='錢七'
### @3='三班'
### SET
### @1=20
### @2='錢七1'
### @3='三班'
# at 469
#240705 17:00:21 server id 1 end_log_pos 500 CRC32 0x64542cc0 Xid = 26
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
關於mysqlbinlog工具的使用技巧還有很多,例如只解析對某個庫的操作或者某個時間段內的操作等。下面是宋老師,分享的常用語句,更多操作參考官方文件。
# 可檢視引數幫助
mysqlbinlog --no-defaults --help
# 檢視最後100行
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 | tail -100
# 根據position查詢
mysqlbinlog --no-defaults --base64-output=decode-rows -vv atguigu-bin.000002 |grep -A 20 '4939002'
上面這種方法讀取出binlog日誌的全文內容比較多,不容易分辨檢視到pos點資訊下面介紹一種更為方便的查詢命令:
mysql> show binlog events [in 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
IN 'log_name'
:指定要查詢的binlog檔名(不指定就是第一個binlog檔案)FROM pos
:指定從哪個pos起始點開始查起((不指定就是從整個檔案首個pos點開始算)LIMIT [ offset]
:偏移量(不指定就是0)row_count
:查詢總條數(不指定就是所有行)
mysql> show binlog events in 'binlog.000059';
+---------------+-----+----------------+-----------+-------------+--------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+---------------+-----+----------------+-----------+-------------+--------------------------------------+
| binlog.000059 | 4 | Format_desc | 1 | 125 | Server ver: 8.0.25, Binlog ver: 4 |
| binlog.000059 | 125 | Previous_gtids | 1 | 156 | |
| binlog.000059 | 156 | Anonymous_Gtid | 1 | 235 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000059 | 235 | Query | 1 | 325 | BEGIN |
| binlog.000059 | 325 | Table_map | 1 | 394 | table_id: 96 (atguigudb3.student1) |
| binlog.000059 | 394 | Update_rows | 1 | 469 | table_id: 96 flags: STMT_END_F |
| binlog.000059 | 469 | Xid | 1 | 500 | COMMIT /* xid=26 */ |
+---------------+-----+----------------+-----------+-------------+--------------------------------------+
7 rows in set (0.00 sec)
上面這條語句可以將指定的binlog日誌檔案,分成有效事件行的方式返回,並可使用limit指定pos點的起始偏移,查詢條數。其他舉例:
#a、以事件的方式查詢binlog日誌
show binlog events\G;
#b、指定查詢mysql-bin . 088882這個檔案
show binlog evehts in 'atguigu-bin.000802'\G;
#c、指定查詢mysql-bin.088882這個檔案,從pos點:391開始查起:
show binlog events in 'atguigu-bin.008802 ' from 391\G;
#d、指定查詢mysql-bin.000002這個檔案,從pos點:391開始查起,查詢5條(即5條語句)
show binlog events in 'atguigu-bin.808882' from 391 limit 5\G;
#e、指定查詢 mysql-bin.000082這個檔案,從pos點:391開始查起,偏移2行〈即中間跳過2個)查詢5條(即5條語句)。
show binlog events in 'atguigu-bin.000882' from 391 limit 2,5\G;
上面我們講了很多都是基於binlog的預設格式,binlog格式檢視
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.01 sec)
除此之外,binlog還有2中格式,分別是Statement和Mixed
- Statement
每一條會修改資料的sql都會記錄在binlog中。
優點:不需要記錄每一行的變化,減少了binlog日誌量,節約了IO,提高效能。
- Row
5.1.5版本的MySQL才開始支援row level 的複製,它不記錄sql語句上下文相關資訊,僅儲存哪條記錄被修改。
優點:row level的日誌內容會非常清楚的記錄下每一行資料修改的細節。而且不會出現某些特定情況下的儲存過程,或function,以及trigger的呼叫和觸發無法被正確複製的問題。
- Mixed
從5.1.8版本開始,MySQL提供了Mixed格式,實際上就是Statement與Row的結合。
詳細情況,下章講解。
5.4 使用日誌恢復資料
如果MySQL伺服器啟用了二進位制日誌,在資料庫出現意外丟失資料時,可以使用MysQLbinlog工具從指定的時間點開始(例如,最後一次備份)直到現在或另一個指定的時間點的日誌中恢復資料。
mysqlbinlog恢復資料的語法如下:
mysqlbinlog [option] filename | mysql -uuser -ppass;
這個命令可以這樣理解:使用mysqlbinlog命令來讀取filename中的內容,然後使用mysql命令將這些內容恢復到資料庫中。
filename
:是日誌檔名option
:可選項,比較重要的兩對option引數是--start-date、--stop-date 和--start-position、--stop-position--start-data和--stop-data
:可以指定恢復資料庫的起始時間點和結束時間點。--start-position和--stop-position
:可以指定恢復資料的開始位置和結束位置。
注意:使用mysqlbinlog命令進行恢復操作時,必須是編號小的先恢復,例如x.000001必須在x.000002之前恢復。
#使用mysqlbinlog指令和binlog檔案,恢復資料
#這是使用執行的修改語句,在binlog中的位置(show binlog events指令中的Pos列)作為開始和結束的依據
mysqlbinlog --start-position=起始位置 --stop-position=結束位置 --database=恢復資料庫
/var/bin/mysql/binlog.00005 #被恢復的binlog日誌的全路徑(例 )
| mysql -uroot -p -v 恢復資料庫
#輸入密碼就可以了,
#這是使用執行的修改語句,的時間作為開始和結束的依據
mysqlbinlog --start-datetime="yyyy-MM-dd HH:mm:ss" --stop-datetime="yyyy-MM-dd HH:mm:ss"
--database=恢復資料庫
/var/bin/mysql/binlog.00005 #被恢復的binlog日誌的全路徑(例 )
| mysql -uroot -p -v 恢復資料庫
這裡,不在舉例。因為我覺得實際專案的使用中,執行的sql語句,很難準確的去確定某一個寫語句,在binlog日誌中的位置。所以,對於涉及到寫 (增刪改),應該慎重,對於刪除表或庫的語句更應該慎重,或者提前備份。而不是把保持資料完整性,寄託在根據binlo日誌的恢復上。
我個人覺得,binlog的作用,更多的是用於MySQL資料庫叢集中,保持單體之間資料的一致性。如果,想看mysqlbinlog指令恢復的例子,這裡給出影片地址。
5.5 刪除日誌
MySQL的二進位制檔案可以配置自動刪除,同時MysQL也提供了安全的手動刪除二進位制檔案的方法。PURGE MASTER LOGS
只刪除指定部分的二進位制日誌檔案,RESET MASTER
刪除所有的二進位制日誌檔案。具體如下:
1.PURGE MASTER LOGS:刪除指定日誌檔案
PURGE MASTER LOGS語法如下
PURGE {MASTER | BINARY} LOGS TO '指定日誌檔名';
PURGE {MASTER | BINARY} LOGS BEFORE '指定日期';
舉例:使用PURGE MASTER LOGS語句刪除建立時間比binlog.000005早的所有日誌
(1)多次重新啟動MySQL服務,便於生成多個日誌檔案。然後用SHOW語句顯示二進位制日誌檔案列表
mysql> show BINARY LOGS;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000060 | 179 | No |
| binlog.000061 | 179 | No |
| binlog.000062 | 179 | No |
| binlog.000063 | 156 | No |
+---------------+-----------+-----------+
4 rows in set (0.03 sec)
(2)執行PURGE MASTER LOGS語句刪除建立時間比binlog.000062早的所有日誌
mysql> purge master logs to 'binlog.000062';
Query OK, 0 rows affected (0.00 sec)
(3)顯示二進位制日誌檔案列表
mysql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000062 | 179 | No |
| binlog.000063 | 156 | No |
+---------------+-----------+-----------+
2 rows in set (0.00 sec)
舉例:使用PURGE MASTER LOGS語句刪除2020年10月25號前建立的所有日誌檔案。具體步驟如下:
(1)檢視日誌檔案的建立時間
mysqlbinlog --no-defaults "/var/lib/mysql/binlog.000062";#created 240707
(2)使用PURGE MASTER LOGS語句刪除
purge master logs before "20240707";
2.RESET MASTER:刪除所有的二進位制日誌檔案
使用RESET MASTER
語句,清空所有的binlog日誌。MySQL會重新建立二進位制檔案,新的日誌副檔名將重新從000001開始編號。慎用!
5.6 其他場景
二進位制日誌可以透過資料庫的全量備份
和二進位制日誌中儲存的增量資訊
,完成資料庫的無損失恢復
。但是,如果遇到資料量大、資料庫和資料表很多(比如分庫分表的應用)的場景,用二進位制日誌進行資料恢復是很有挑戰性的,因為起止位置不容易管理。
在這種情況下,一個有效的解決辦法是配置主從資料庫伺服器
,甚至是一主多從
的架構,把二進位制日誌檔案的內容透過中繼日誌,同步到從資料庫伺服器中,這樣就可以有效避免資料庫故障導致的資料異常等問題。
6.再談二進位制日誌(binlog)
6.1 寫入機制
binlog的寫入時機也非常簡單,事務執行過程中,先把日誌寫到binlog cache
,事務提交的時候,再把binlog cache寫到binlog檔案中。因為一個事務的binlog不能被拆開,無論這個事務多大,也要確保一次性寫入,所以系統會給每個執行緒分配一個塊記憶體作為binlog cache。
我們可以透過binlog_cache_size
引數控制單個執行緒binlog cache大小,如果儲存內容超過了這個引數,就要暫存到磁碟(Swap)。binlog日誌刷盤流程如下:
- 上圖的write,是指把日誌寫入到檔案系統的page cache,並沒有把資料持久化到磁碟,所以速度比較快
- 上圖的fsync,才是將資料持久化到磁碟的操作
write和fsync的時機,可以由引數sync_binlog
控制。為0的時候,表示每次提交事務都只write,由系統自行判斷什麼時候執行fsync。雖然效能得到提升,但是機器當機,page cache裡面的binglog 會丟失。如下圖:
為了安全起見,可以設定為 1 ,表示每次提交事務都會執行fsync,就如同redo log 刷盤流程一樣。
最後還有一種折中方式,可以設定為N(N>1),表示每次提交事務都write,但累積N個事務後才fsync。
在出現IO瓶頸的場景裡,將sync_binlog設定成一個比較大的值,可以提升效能。同樣的,如果機器當機,會丟失最近N個事務的binlog日誌。
6.2 binlog與redolog對比
-
redo log 是
物理日誌
,記錄內容是“在某個資料頁上做了什麼修改”,屬於 InnoDB 儲存引擎層產生的。 -
binlog 是
邏輯日誌
,記錄內容是語句的原始邏輯,類似於“給 ID=2 這一行的 c 欄位加 1”,屬於MySQL Server 層。 -
雖然它們都屬於持久化的保證,但是側重點不同。
- redo log讓InnoDB儲存引擎擁有了崩潰恢復能力。
- binlog保證了MySQL叢集架構的資料一致性。
6.3 兩階段提交
在執行更新語句過程,會記錄redo log與binlog兩塊日誌,以基本的事務為單位,redo log在事務執行過程中可以不斷寫入,而binlog只有在提交事務時才寫入,所以redo log與binlog的寫入時機
不一樣。
redo log與binlog兩份日誌之間的邏輯不一致,會出現什麼問題?
以update語句為例,假設id=2的記錄,欄位c值是0,把欄位c值更新成1,SQL語句為update T set c=1where id=2。
假設執行過程中寫完redo log日誌後,binlog日誌寫期間發生了異常,會出現什麼情況呢?
由於binlog沒寫完就異常,這時候binlog裡面沒有對應的修改記錄。因此,之後用binlog日誌恢復資料時,就會少這一次更新,恢復出來的這一行c值是0,而原庫因為redo log日誌恢復,這一行c值是1,最終資料不一致。
為了解決兩份日誌之間的邏輯一致問題,InnoDB儲存引擎使用兩階段提交方案。
使用兩階段提交後,寫入binlog時發生異常也不會有影響,因為MySQL根據redo log日誌恢復資料時,發現redo log還處於prepare階段,並且沒有對應binlog日誌,就會回滾該事務。
另一個場景,redo log設定commit階段發生異常,那會不會回滾事務呢?
並不會回滾事務,它會執行上圖框住的邏輯,雖然redo log是處於prepare階段,但是能透過事務id找到對應的binlog日誌,所以MySQL認為是完整的,就會提交事務恢復資料。
7.中繼日誌
7.1 介紹
中繼日誌只在主從伺服器架構的從伺服器上存在。從伺服器為了與主伺服器保持一致,要從主伺服器讀取二進位制日誌的內容,並且把讀取到的資訊寫入本地的日誌檔案
中,這個從伺服器本地的日誌檔案就叫中繼日誌
。然後,從伺服器讀取中繼日誌,並根據中繼日誌的內容對從伺服器的資料進行更新,完成主從伺服器的資料同步
。
搭建好主從伺服器之後,中繼日誌預設會儲存在從伺服器的資料目錄下。
檔名的格式是:從伺服器名 -relay-bin.序號
。中繼日誌還有一個索引檔案:從伺服器名 -relay-bin.index
,用來定位當前正在使用的中繼日誌。
7.2 檢視中繼日誌
中繼日誌與二進位制日誌的格式相同,可以用mysqlbinlog
工具進行檢視。
7.3 恢復的典型錯誤
如果從伺服器當機,有的時候為了系統恢復,要重灌作業系統,這樣就可能會導致你的伺服器名稱
與之前不同
。而中繼日誌裡是包含從伺服器名
的。在這種情況下,就可能導致你恢復從伺服器的時候,無法從當機前的中繼日誌裡讀取資料,以為是日誌檔案損壞了,其實是名稱不對了。解決的方法也很簡單,把從伺服器的名稱改回之前的名稱。
只是為了記錄自己的學習歷程,且本人水平有限,不對之處,請指正。