MySQL核心月報2015.03-MySQL·捉蟲動態·pidfile丟失問題分析
現象
mysql5.5,通過命令show variables like `%pid_file%`; 可以查到pid檔案位置,例如/home/mysql/xx.pid。但發現在此目錄下找不到此pid檔案。
背景知識
mysql pid檔案記錄的是當前mysqld程式的pid。
通過mysqld_safe啟動mysqld時,mysqld_safe會檢查PID檔案,未指定PID檔案時,pid檔案預設名為$DATADIR/`hostname`.pid
- pid檔案不存在,不做處理
- 檔案存在,且pid已佔用則報錯”A mysqld process already exists”;檔案存在,但pid未佔用,則刪除pid檔案。
mysqld啟動後會通過create_pid_file函式新建pid檔案,通過getpid()獲取當前程式pid並將pid寫入pid檔案。
因此,通過mysqld_safe啟動時,pid檔案的作用是為了防止同一個資料庫被啟動多次(資料檔案是同一份,但埠不同的情況)。
另一個事實是mysqld在正常關閉時或通過SIGQUIT,SIGKILL,SIGTERM訊號來kill mysqld時,會呼叫clean_up函式將pid檔案刪除。而mysqld異常crash時,pid檔案是保留的。
另外mysqld_safe有一個功能是當mysqld異常crash時,後臺會自動重啟mysqld。mysqld關閉後,mysqld_safe會檢查pid檔案是否存在。如果存在則認為mysqld是異常crash, 需要自動重啟;如果不存在則認為是正常關閉的,不需要自動重啟,mysqld_safe程式也退出。
原因分析
檢視error log發現資料庫在相近的時間內啟動了兩次
前面說到mysqld_safe啟動mysqld時,會根據pid檔案來判斷避免重複啟動mysqld.然而,由於兩次啟動時間較近,導致第一次mysqld啟動生成pid檔案之前,第二個mysqld就已開始啟動了,從而繞過了這個判斷。第一次mysqld啟動會成功,而第二次mysqld啟動會因為檔案鎖而導致啟動失敗。
第二次啟動的mysqld關閉時會將第一次啟動時產生的pid檔案刪除,從而導致pid檔案丟失。
通過mysqld_safe啟動mysqld來重現pid檔案丟失有一定的概率性,必須是同時啟動mysqld_safe。 如果是直接通過mysqld啟動,同時指定相同的引數啟動兩次,那麼就很容易重現了。
修復
參考5.6 官方的修復方法,在上述場景下刪除pid檔案時,需判斷是否是自己新建的pid檔案,同時檔案中的pid是否和自身pid一致,否則不能刪除。參考補丁
MySQL · 答疑釋惑· using filesort VS using temporary
背景
MySQL 執行查詢語句, 對於order by謂詞,可能會使用filesort或者temporary。比如explain一條語句的時候,會看到Extra欄位中可能會出現,using filesort和using temporary。下面我們就來探討下兩個的區別和適用場景。
解釋
1. using filesort
filesort主要用於查詢資料結果集的排序操作,首先MySQL會使用sort_buffer_size大小的記憶體進行排序,如果結果集超過了sort_buffer_size大小,會把這一個排序後的chunk轉移到file上,最後使用多路歸併排序完成所有資料的排序操作。
MySQL filesort有兩種使用模式:
- 模式1: sort的item儲存了所需要的所有欄位,排序完成後,沒有必要再回表掃描。
- 模式2: sort的item僅包括<sort_key, rowid>,待排序完成後,根據rowid查詢所需要的columns。
很明顯,模式1能夠極大的減少回表的隨機IO。
2. using temporary
MySQL使用臨時表儲存臨時的結構,以用於後續的處理,MySQL首先建立heap引擎的臨時表,如果臨時的資料過多,超過max_heap_table_size的大小,會自動把臨時錶轉換成MyISAM引擎的表來使用。
從上面的解釋上來看,filesort和temporary的使用場景的區別並不是很明顯,不過,有以下的原則:
filesort只能應用在單個表上,如果有多個表的資料需要排序,那麼MySQL會先使用using temporary儲存臨時資料,然後再在臨時表上使用filesort進行排序,最後輸出結果。
適用場景
我們看一下下面的三個case:
case 1:
case1: order by欄位能夠使用index的有序性,所以沒有使用filesort,也沒有使用temporary。
case 2:
case2: order by謂詞,是在第一個表t1上完成,所以只需要在t1表上使用filesort,然後排序後的結果集join t2表。
case 3:
case 3: order by的欄位在t2表上,所以需要把t1,t2表join的結果儲存到temporary表上,然後對臨時表進行filesort,最後輸出結果。
特別優化
MySQL對order by + limit的filesort做了特別優化,使用Priority queue來儲存結果,即一個堆的結構,只保留top n的資料滿足limit條件。
另外
filesort和temporary都會在tmp目錄下建立檔案,temporary建立的是MYI,MYD檔案。但filesort的檔案, 因為MySQL使用了create->open->unlink->使用->close的方式,隱藏了檔案,以便程式異常結束的時候,臨時檔案能夠自動回收掉,所以在評估tmp目錄空間的時候,需要特別注意。
相關文章
- MySQL核心月報2014.10-MySQL· 捉蟲動態·binlog重放失敗MySql
- 資料庫核心月報-2015/09-MySQL·捉蟲動態·建表過程中crash造成重建表失敗資料庫MySql
- MySQL·捉蟲動態·唯一鍵約束失效MySql
- 子執行緒 UI 問題捉蟲執行緒UI
- MySQL·捉蟲動態·DROPDATABASE外來鍵約束的GTIDBUGMySqlDatabaseTiDB
- MySQL核心月報2015.02-MySQL·答疑釋惑·InnoDB丟失自增值MySql
- 一次inmemory丟失引起的問題分析
- GoldenGate更新丟失問題Go
- 關於 5月10號 資料丟失問題反饋
- js浮點數丟失問題JS
- iframe跨域session丟失問題跨域Session
- 關於Session值丟失問題Session
- 使用puppeteer爬蟲,檢查頁面靜態資源丟失爬蟲
- RocketMq訊息丟失問題解決MQ
- git server“丟失”commit問題探究GitServerMIT
- Sqlserver表統計資訊丟失問題SQLServer
- dfm檔案資料丟失問題
- 請教tomcat session丟失問題TomcatSession
- max_allowed_packet引起MySQL遷移丟失資料的問題MySql
- Django資料庫連線丟失問題Django資料庫
- Nginx session丟失問題處理解決方法NginxSession
- 記 Ant Designer Vue 2.0.1 layout 丟失樣式類名問題分析Vue
- Verdaccio publish 時包含 deprecated 導致歷史版本丟失問題原因分析
- 資料庫核心月報-2015/07-MySQL·社群動態·MySQL記憶體分配支援NUMA資料庫MySql記憶體
- mysql root密碼丟失MySql密碼
- Oracle_dg歸檔丟失問題處理Oracle
- session定義使用和丟失問題小結Session
- Web-請求資料+號丟失問題Web
- 關於MySQL啟動時,丟失資料檔案不報錯的現象MySql
- git合併丟失程式碼問題分析與解決(錯誤操作導致)Git
- MySQL核心月報2014.12-MySQL· 效能優化·threadpool原理分析MySql優化thread
- Fragment Transactions和Activity狀態丟失Fragment
- 如何檢測 Web 服務請求丟失問題Web
- JavaScript中解決計算精度丟失的問題JavaScript
- oracle 小數點前零丟失的問題<轉>Oracle
- SpringCloud解決feign呼叫token丟失問題SpringGCCloud
- MySQL建立表失敗的問題MySql
- Web伺服器捉蟲速記Web伺服器