每個 MySQL 版本在發布之前都會在許多平台上進行測試。這並不表示 MySQL 沒有錯誤,但如果有錯誤,應該非常少且難以發現。如果您有問題,嘗試找出確切導致系統崩潰的原因總是有幫助的,因為這樣您更有機會快速解決問題。
首先,您應該嘗試找出問題是 mysqld 伺服器死掉還是您的問題與客戶端有關。您可以透過執行 mysqladmin version 來檢查您的 mysqld 伺服器已執行多久。如果 mysqld 已死機並重新啟動,您可以透過查看伺服器的錯誤記錄來找到原因。請參閱 第 7.4.2 節,「錯誤記錄」。
在某些系統上,您可以在錯誤記錄中找到 mysqld 死機時的堆疊追蹤。請注意,錯誤記錄中寫入的變數值可能不總是 100% 正確。
如果您發現 mysqld 在啟動期間的 InnoDB
復原時失敗,請參考 第 17.20.2 節,「疑難排解復原失敗」。
許多意外的伺服器退出都是由損壞的資料檔案或索引檔案引起的。MySQL 在每個 SQL 陳述式之後以及通知客戶端結果之前,使用 write()
系統呼叫更新磁碟上的檔案。(如果您在啟用 delay_key_write
系統變數的情況下執行,則情況並非如此,在這種情況下,會寫入資料檔案,但不會寫入索引檔案。)這表示即使 mysqld 崩潰,資料檔案內容也是安全的,因為作業系統會確保未刷新資料會寫入磁碟。您可以使用 --flush
選項啟動 mysqld,強制 MySQL 在每個 SQL 陳述式之後將所有內容刷新到磁碟。
以上表示,除非發生以下情況之一,否則您通常不應該獲得損壞的資料表
MySQL 伺服器或伺服器主機在更新期間被強制關閉。
您在 mysqld 中發現錯誤,導致它在更新期間死機。
某些外部程式在 mysqld 同時操作資料檔案或索引檔案,而沒有正確鎖定資料表。
您在不支援良好檔案系統鎖定(通常由
lockd
鎖定管理員處理)的系統上執行許多 mysqld 伺服器,使用相同的資料目錄,或者您在禁用外部鎖定的情況下執行多個伺服器。您有一個崩潰的資料檔案或索引檔案,其中包含非常損壞的資料,讓 mysqld 感到困惑。
您在資料儲存程式碼中發現錯誤。這不太可能,但至少是可能的。在這種情況下,您可以嘗試使用
ALTER TABLE
在資料表的修復副本上,將儲存引擎變更為另一個引擎。
由於很難知道為什麼會崩潰,首先嘗試檢查對其他人有效的操作是否會導致您出現意外退出。請嘗試以下操作
使用 mysqladmin shutdown 停止 mysqld 伺服器,從資料目錄執行 myisamchk --silent --force */*.MYI 以檢查所有
MyISAM
資料表,然後重新啟動 mysqld。這可確保您從乾淨的狀態執行。請參閱 第 7 章,「MySQL 伺服器管理」。啟動 mysqld 時啟用一般查詢記錄(請參閱 第 7.4.3 節,「一般查詢記錄」)。然後嘗試從寫入記錄的資訊判斷是否有某些特定查詢導致伺服器死機。約 95% 的所有錯誤都與特定查詢有關。通常,這是記錄檔中在伺服器重新啟動之前最後的查詢之一。請參閱 第 7.4.3 節,「一般查詢記錄」。如果您可以透過特定查詢重複讓 MySQL 死機,即使您在發出查詢之前已檢查所有資料表,那麼您已隔離出錯誤,應該提交錯誤報告。請參閱 第 1.6 節,「如何報告錯誤或問題」。
嘗試建立一個測試案例,我們可以利用它來重複這個問題。請參閱 第 7.9 節,「偵錯 MySQL」。
嘗試
fork_big.pl
指令碼。(它位於原始碼發行版的tests
目錄中。)為偵錯設定 MySQL,如果在某些地方發生錯誤,可以更容易地收集關於可能錯誤的資訊。使用
-DWITH_DEBUG=1
選項重新設定 MySQL,CMake 然後重新編譯。請參閱 第 7.9 節,「偵錯 MySQL」。請確保您已套用作業系統的最新修補程式。
對 mysqld 使用
--skip-external-locking
選項。在某些系統上,lockd
鎖定管理員無法正常運作;--skip-external-locking
選項會告知 mysqld 不要使用外部鎖定。(這表示您無法在同一資料目錄上執行兩個 mysqld 伺服器,並且如果您使用 myisamchk,則必須小心。儘管如此,嘗試將此選項作為測試可能會有所啟發。)如果 mysqld 看起來正在執行但沒有回應,請嘗試 mysqladmin -u root processlist。 有時候,即使 mysqld 看起來沒有回應,實際上並沒有當機。問題可能是所有連線都在使用中,或者可能存在某些內部鎖定的問題。即使在這些情況下,mysqladmin -u root processlist 通常也能建立連線,並提供有關當前連線數量及其狀態的有用資訊。
在另一個視窗中執行命令 mysqladmin -i 5 status 或 mysqladmin -i 5 -r status,以便在執行其他查詢時產生統計資料。
嘗試以下操作:
從 gdb (或其他除錯工具) 啟動 mysqld。 請參閱 第 7.9 節,「除錯 MySQL」。
執行您的測試腳本。
列印最底層三個層級的回溯追蹤和區域變數。在 gdb 中,當 mysqld 在 gdb 內部當機時,您可以使用以下指令來完成此操作:
backtrace info local up info local up info local
使用 gdb,您也可以使用
info threads
檢查有哪些執行緒存在,並使用thread
切換到特定執行緒,其中N
N
是執行緒 ID。
嘗試使用 Perl 腳本模擬您的應用程式,以強制 MySQL 結束或行為異常。
傳送正常的錯誤報告。 請參閱 第 1.6 節,「如何回報錯誤或問題」。 請比平常更詳細。 因為 MySQL 對於很多人來說都能正常運作,所以當機可能是因為您的電腦上才有的問題(例如,與您特定系統函式庫相關的錯誤)。
如果您的資料表在包含動態長度列時發生問題,而且您只使用
VARCHAR
欄 (而不是BLOB
或TEXT
欄),您可以嘗試使用ALTER TABLE
將所有VARCHAR
變更為CHAR
。 這會強制 MySQL 使用固定大小的列。 固定大小的列會佔用一些額外的空間,但對於損壞的容忍度更高。目前的動態列程式碼已使用多年,問題很少,但動態長度的列本質上更容易發生錯誤,因此嘗試此策略以查看是否有幫助可能會是個好主意。
在診斷問題時,請考慮硬體故障的可能性。 有缺陷的硬體可能會導致資料損壞。 在疑難排解硬體時,請特別注意您的記憶體和磁碟子系統。