欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL的慢日志線上問題及優(yōu)化方案

 更新時(shí)間:2017年12月18日 10:58:36   投稿:laozhang  
給大家詳細(xì)分析了MySQL慢日志線上問題分析及功能優(yōu)化方案,需要的朋友跟著學(xué)習(xí)下吧。

MySQL 慢日志(slow log)是 MySQL DBA 及其他開發(fā)、運(yùn)維人員需經(jīng)常關(guān)注的一類信息。使用慢日志可找出執(zhí)行時(shí)間較長或未走索引等 SQL 語句,為進(jìn)行系統(tǒng)調(diào)優(yōu)提供依據(jù)。

本文將結(jié)合一個(gè)線上案例,分析如何正確設(shè)置 MySQL 慢日志參數(shù)和使用慢日志功能,并介紹下網(wǎng)易云 RDS 對 MySQL 慢日志功能的增強(qiáng)。

MySQL 參數(shù)組功能

網(wǎng)易云 RDS 實(shí)例提供了參數(shù)組管理功能,可通過參數(shù)管理界面查看絕大部分常用的 MySQL 系統(tǒng)參數(shù),用戶可了解當(dāng)前運(yùn)行值和建議值:


用戶還可通過參數(shù)管理頁面對所列的參數(shù)進(jìn)行修改,點(diǎn)擊 “修改參數(shù)” 按鈕進(jìn)行在線設(shè)置,點(diǎn)擊 “保存修改” 即可一鍵完成 MySQL 主從節(jié)點(diǎn)的參數(shù)修改: 


查看參數(shù)管理界面不難發(fā)現(xiàn),與慢查詢相關(guān)的參數(shù)比較多,那么,這些參數(shù)都是如何起作用的呢,相互關(guān)系又是如何,滿足什么條件的 SQL 語句才會記錄到慢日志中?只有了解這些才能更好地利用慢日志進(jìn)行系統(tǒng)調(diào)優(yōu)和問題定位。

下面,我們以這個(gè)線上案例為依托,介紹下該如何正確配置慢日志參數(shù):

有用戶報(bào)告,他們使用的多個(gè) RDS 5.7 版本實(shí)例慢日志異常,明明執(zhí)行了一分多鐘的 SQL 語句,卻沒有記錄到慢日志中。還提供了用于復(fù)現(xiàn)的 SQL 語句。

慢日志參數(shù)正確配置姿勢

首先,我們需要確認(rèn)該實(shí)例是否開啟了慢日志功能,默認(rèn)情況下,MySQL 慢日志功能是關(guān)閉的。慢日志開關(guān)參數(shù)為 slow_query_log,可在 mysqld 啟動(dòng)命令行或配置文件中顯式指定,若指定 slow_query_log=1 或不指定值,則表示開啟慢日志,賦值為 0 表示關(guān)閉。用戶可以在運(yùn)行時(shí)動(dòng)態(tài)開啟和關(guān)閉。

網(wǎng)易云 RDS 實(shí)例默認(rèn)開啟慢日志功能,我們確認(rèn)了該用戶未關(guān)閉實(shí)例的慢日志開關(guān)。

接下來,需確認(rèn)慢日志記錄位置,MySQL 使用 log_output 參數(shù)指定以文件(FILE)還是以表 (TABLE) 的方式來保存慢日志。需要強(qiáng)調(diào)的是,僅指定 log_output 而將 slow_query_log 置為 0 并不會記錄慢日志,也就是說 slow_query_log 才是慢日志的開關(guān)。若使用文件形式記錄慢日志,則可通過 slow_query_log_file 指定文件名,如果用戶沒有顯式指定 slow_query_log_file,則 MySQL 將其初始化為 host_name-slow.log,host_name 即為運(yùn)行 mysqld 的主機(jī)名,慢日志文件默認(rèn)位于 MySQL 數(shù)據(jù)目錄。

網(wǎng)易云 RDS 實(shí)例不允許用戶修改日志文件路徑,但可以配置 log_output 參數(shù),通過查詢,確認(rèn)該實(shí)例以文件方式記錄慢日志,查看日志文件確認(rèn)沒有用戶所述的 SQL 語句。

由于用戶提供了復(fù)現(xiàn)語句,我們執(zhí)行了其 SQL 語句,確實(shí) 1 分多鐘才返回,通過 explain 命令發(fā)現(xiàn)其未走索引,掃描了較多的記錄數(shù),再次查看慢日志仍沒有記錄該 SQL 語句。

MySQL 會記錄滿足執(zhí)行時(shí)間超過 long_query_time 秒,掃描記錄數(shù)超過 min_examined_row_limit 行的 SQL 語句。

long_query_time 參數(shù)最小值和默認(rèn)值分別為 1 和 10s,該參數(shù)可以精確到微秒(ms)。如果選擇將慢日志記錄到文件中,那么所記錄的時(shí)間精確到微秒,如果記錄到慢日志表(mysql.slow_log)中,那么僅精確到秒,微秒部分被忽略。

網(wǎng)易云 RDS 實(shí)例允許用戶設(shè)置這兩個(gè)參數(shù)值,那么是不是用戶調(diào)整了上述兩個(gè)閾值,導(dǎo)致無法滿足記錄條件呢,進(jìn)一步查詢發(fā)現(xiàn)也不是問題原因所在。

我們注意到 MySQL 還有個(gè)名為 log_queries_not_using_indexes 的參數(shù)用于控制是否記錄未走索引的 SQL 查詢,代碼如下:


重點(diǎn)關(guān)注箭頭所指內(nèi)容,如果查詢未走索引或者索引無效,且相關(guān)參數(shù)開啟,那么 warn_no_index 設(shè)置為 true,若同時(shí)滿足掃描記錄數(shù)超過閾值,也會像慢查詢一樣被記錄,那么是不是該參數(shù)未開呢?結(jié)果仍是否定的。

問題原因之所在

由于數(shù)據(jù)庫實(shí)例中可能有較多不走索引的 SQL 語句,若開啟 log_queries_not_using_indexes,則存在日志文件或表容量增長過快的風(fēng)險(xiǎn),此時(shí)可通過設(shè)置 log_throttle_queries_not_using_indexes 來限制每分鐘寫入慢日志中的不走索引的 SQL 語句個(gè)數(shù),該參數(shù)默認(rèn)為 0,表示不開啟,也就是說不對寫入 SQL 語句條數(shù)進(jìn)行控制。

啟用后,系統(tǒng)會在第一條不走索引的查詢執(zhí)行后開啟一個(gè) 60s 的窗口,在該窗口內(nèi),僅記錄最多 log_throttle_queries_not_using_indexes 條 SQL 語句。超出部分將被抑制,在時(shí)間窗結(jié)束時(shí),會打印該窗口內(nèi)被抑制的慢查詢條數(shù)以及這些慢查詢一共花費(fèi)的時(shí)間。下一個(gè)統(tǒng)計(jì)時(shí)間窗并不是馬上創(chuàng)建,而是在下一條不走索引的查詢執(zhí)行后開啟。

對應(yīng)到該線上問題,log_throttle_queries_not_using_indexes 被設(shè)置為 10,在日志文件中看到周期性打印了如下內(nèi)容:


確實(shí)符合上面描述的現(xiàn)象,用戶的慢日志應(yīng)該是被抑制了,匯總到了 359 里面去。我們嘗試將 log_throttle_queries_not_using_indexes 設(shè)置為 0,再執(zhí)行對應(yīng)的 SQL 語句,果然在日志文件中記錄了相應(yīng)的 SQL 語句。

這個(gè)線上問題似乎已經(jīng)定位到了,就是系統(tǒng)產(chǎn)生的不走索引的慢日志太多,而設(shè)置的 log_throttle_queries_not_using_indexes 太小,導(dǎo)致無法正常記錄用戶未走索引的慢日志。但還有一個(gè)疑惑點(diǎn)沒有解決,那就是 log_throttle_queries_not_using_indexes 為 0 時(shí),每分鐘并沒有打印超過10條慢日志,更沒有 throttle 提示的 359 條這么多,那么設(shè)置為 10 的時(shí)候用戶提供的那條 SQL 語句應(yīng)該被記錄到慢日志中才對啊,為何沒有記錄,原因何在?其實(shí),仔細(xì)看下 MySQL 記錄不走索引的日志的代碼邏輯可以找到答案:


上圖是記錄慢日志的主邏輯,是否記錄日志由函數(shù) log_slow_applicable 控制,該函數(shù)先前已分析了一部分,我們進(jìn)一步看該函數(shù)的其他相關(guān)內(nèi)容,見下圖紅框:


Suppress_logging 是個(gè)決定性的變量,只有它為 false,該 SQL 語句才可能被記錄。其結(jié)果就跟 log_throttle_queries_not_using_indexes 相關(guān),我們進(jìn)一步看下 log_throttle_qni.log 相關(guān)實(shí)現(xiàn),如下圖:


Eligible 即為 warn_no_index,inc_log_count() 函數(shù)在 1 分鐘內(nèi)不走索引的語句總數(shù)超過 log_throttle_queries_not_using_indexes 時(shí)返回值為 true,只有 warn_no_index 和 inc_log_count() 返回值都為 true,suppress_current 才為 true,而 suppress_current 即為 suppress_logging。

通過對上述 2 個(gè)截圖內(nèi)容進(jìn)行分析,可以解答之前的疑惑點(diǎn):

log_throttle_queries_not_using_indexes 統(tǒng)計(jì)的是所有不走索引的語句,其中有些語句因?yàn)椴粷M足掃描記錄數(shù)的約束而不會記錄到慢日志中,這就是為什么該值為 10 的時(shí)候,慢日志文件中并沒有 10 條記錄。因?yàn)檫@ 10 條中有 8 條 SQL 語句由于掃描記錄數(shù)太少并沒有被記錄。


這也解惑了上圖中 359 這個(gè)數(shù)字,它是這個(gè)時(shí)間窗內(nèi)不走索引的 SQL 語句總數(shù)。所以,log_throttle_queries_not_using_indexes 是個(gè)很關(guān)鍵的參數(shù),設(shè)置不當(dāng)會無法正常記錄不走索引的慢查詢,導(dǎo)致慢日志功能部分失效。所以,用戶首先需盡可能避免出現(xiàn)大量不走索引的 SQL 語句,可以通過 RDS 健康檢查功能進(jìn)行優(yōu)化,再次,若出現(xiàn)慢日志中存在上述提示,應(yīng)該調(diào)大 log_throttle_queries_not_using_indexes 的值,以便以進(jìn)一步分析問題。

InnoSQL 慢日志功能增強(qiáng)

還有部分 RDS 實(shí)例用戶問我們,為什么我的 SQL 語句執(zhí)行時(shí)間沒有超過所設(shè)置的 long_query_time,而且走了索引,但還是被記錄到慢日志中,是不是出 Bug 了?其實(shí)這不是 Bug,而是因?yàn)榫W(wǎng)易云 RDS 使用的 InnoSQL(網(wǎng)易維護(hù)的 MySQL 開源分支)版本對慢日志做了優(yōu)化,除了考察 SQL 語句的執(zhí)行時(shí)間外,還關(guān)注該查詢所需的磁盤頁面(Disk Page)數(shù),因?yàn)樗璧捻撁鏀?shù)目過多,也可能會對系統(tǒng)負(fù)載造成較大影響。為了能夠量化統(tǒng)計(jì),我們收集了 SQL 查詢所需讀取的總頁面數(shù)和這些頁面中實(shí)際進(jìn)行 IO 的次數(shù),分別記錄為 logical_reads和physical_reads,前者包括命中 InnoDB Buffer Pool 和未命中需要進(jìn)行 IO 的頁面請求。

通過引入 slow_query_type 和 long_query_io 兩個(gè)參數(shù)為用戶提供該功能。前者可設(shè)置為 0/1/2/3?!?” 表示啟用基于執(zhí)行時(shí)間來記錄慢日志,“2” 表示基于搜索總頁面數(shù)來記錄慢日志,“3” 是 “1” 和 “2” 的合集。所以在 InnoSQL 中,SQL 查詢只需滿足執(zhí)行時(shí)間夠長或所需總頁面數(shù)夠多即可記錄到慢日志中。代碼實(shí)現(xiàn)片段如下:


頁面數(shù)閾值通過 long_query_io 參數(shù)來衡量,用戶可動(dòng)態(tài)設(shè)置,如果總頁面數(shù) m_logical_reads 超過了該值,即使執(zhí)行時(shí)間未超標(biāo),也會被記錄。相應(yīng)的,RDS 實(shí)例慢日志表結(jié)構(gòu)和慢日志文件輸出內(nèi)容也增加了新的字段。


上圖即為 InnoSQL 版的 slow_log 表結(jié)構(gòu),其中,logical_reads 和 physical_reads 為 InnoSQL 增加字段。同樣的,慢日志文件的輸出內(nèi)容也增加了兩個(gè)字段,如下所示:


除了以上詳細(xì)描述的內(nèi)容外,MySQL 慢日志模塊還有如下幾個(gè)特性值得關(guān)注:

○ 進(jìn)行慢日志統(tǒng)計(jì)及慢日志中所記錄的時(shí)間并不包括該 SQL 語句開始執(zhí)行前獲取鎖所需等待的時(shí)間;

○ MySQL 在 SQL 語句執(zhí)行完且所持有的鎖均已釋放后才將其寫入慢日志中,所以慢日志中的 SQL 語句記錄順序并不能準(zhǔn)確反映這些 SQL 語句的實(shí)際執(zhí)行順序;

○ 每條慢日志都包含一個(gè)時(shí)間戳,若寫入文件中,log_timestamps 參數(shù)用于將慢日志時(shí)間戳轉(zhuǎn)化為指定時(shí)區(qū)的時(shí)間。但該參數(shù)對于 mysql.slow_log 表中的慢日志不起作用;

○ 可通過設(shè)置 log_slow_slave_statements 來開啟 MySQL 從庫的慢日志功能;

○ ALTER TABLE, ANALYZE TABLE, CHECK TABLE, CREATE INDEX, DROP INDEX, OPTIMIZE TABLE, and REPAIR TABLE 等表管理操作也能夠被記錄到慢日志中,可通過 log_slow_admin_statements 選項(xiàng)開啟。

相關(guān)文章

  • mysql Innodb表空間卸載、遷移、裝載的使用方法

    mysql Innodb表空間卸載、遷移、裝載的使用方法

    從MySQL的Innodb特性中我們知道,Inndob的表空間有共享和獨(dú)享的特點(diǎn),如果是共享的。則默認(rèn)會把表空間存放在一個(gè)文件中(ibdata1),當(dāng)開啟獨(dú)享表空間參數(shù)Innodb_file_per_table時(shí),會為每個(gè)Innodb表創(chuàng)建一個(gè).ibd的文件。文章討論在獨(dú)享表空間卸載、裝載、遷移Innodb表的情況
    2013-11-11
  • MySQL中ON DUPLICATE KEY UPDATE語句的使用

    MySQL中ON DUPLICATE KEY UPDATE語句的使用

    INSERT INTO ... ON DUPLICATE KEY UPDATE?是一個(gè)強(qiáng)大的SQL語句,它結(jié)合了插入新記錄和更新已存在記錄的功能于一體,本文就來介紹一下MySQL中ON DUPLICATE KEY UPDATE語句的使用,感興趣的可以了解一下
    2024-08-08
  • MySQL8新特性:降序索引詳解

    MySQL8新特性:降序索引詳解

    在數(shù)據(jù)庫中我們一般都會對一些字段進(jìn)行索引操作,這樣可以提升數(shù)據(jù)的查詢速度,下面這篇文章主要給大家介紹了關(guān)于MySQL8新特性:降序索引的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • MySQL空間數(shù)據(jù)存儲及函數(shù)

    MySQL空間數(shù)據(jù)存儲及函數(shù)

    這篇文章主要介紹的使MySQL空間數(shù)據(jù)存儲及函數(shù),MySQL提供了數(shù)據(jù)類型geometry用來存儲坐標(biāo)信息,MySQL為空間數(shù)據(jù)存儲及處理提供了專用的類型geometry,下面就和小編一起學(xué)習(xí)下文吧
    2021-09-09
  • Mysql分組查詢每組最新的一條數(shù)據(jù)的五種實(shí)現(xiàn)方法

    Mysql分組查詢每組最新的一條數(shù)據(jù)的五種實(shí)現(xiàn)方法

    在寫報(bào)表功能時(shí)遇到一個(gè)需要根據(jù)用戶id分組查詢最新一條錢包明細(xì)數(shù)據(jù)的需求,本文主要介紹了Mysql分組查詢每組最新的一條數(shù)據(jù)的五種實(shí)現(xiàn)方法,感興趣的可以了解一下
    2024-08-08
  • MySQL?如何將查詢結(jié)果導(dǎo)出到文件(select?…?into?Statement)

    MySQL?如何將查詢結(jié)果導(dǎo)出到文件(select?…?into?Statement)

    我們經(jīng)常會遇到需要將SQL查詢結(jié)果導(dǎo)出到文件,以便后續(xù)的傳輸或數(shù)據(jù)分析的場景,本文就MySQL中select…into的用法進(jìn)行演示,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • MySQL存儲引擎InnoDB的配置與使用的講解

    MySQL存儲引擎InnoDB的配置與使用的講解

    今天小編就為大家分享一篇關(guān)于MySQL存儲引擎InnoDB的配置與使用的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • MySQL存儲過程圖文實(shí)例講解

    MySQL存儲過程圖文實(shí)例講解

    雖然MySQL的存儲過程一般情況下是不會使用到的,但是在一些特殊場景中,還是有需求的,下面這篇文章主要給大家介紹了關(guān)于MySQL存儲過程的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Mysql 數(shù)據(jù)庫常用備份方法和注意事項(xiàng)

    Mysql 數(shù)據(jù)庫常用備份方法和注意事項(xiàng)

    Mysql 數(shù)據(jù)庫常用備份方法和注意事項(xiàng) ,需要的朋友可以參考下。
    2010-04-04
  • Mysql 增加主鍵或者修改主鍵的sql語句操作

    Mysql 增加主鍵或者修改主鍵的sql語句操作

    這篇文章主要介紹了Mysql 增加主鍵或者修改主鍵的sql語句操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02

最新評論