來源:面包板社區(qū) 時間:2025-09-15 10:27:37 作者:
在日常數(shù)據(jù)庫運維中,“掃表風暴”數(shù)次悄然而至——某條未走索引的SQL突然執(zhí)行全表掃描,短短幾分鐘內(nèi)吃光IO、拖高CPU,最終引發(fā)集群抖動甚至服務(wù)不可用。這樣的事故,你是否也曾經(jīng)歷過?
全表掃描(Full Table Scan)是數(shù)據(jù)庫查詢中常見的性能殺手,尤其在數(shù)據(jù)量巨大的生產(chǎn)環(huán)境中,一條效率低下的SQL就足以引發(fā)連鎖性的系統(tǒng)故障。為從根本上防范此類風險,百度智能云數(shù)據(jù)庫在MySQL內(nèi)核層面設(shè)計并實現(xiàn)了一套全表掃描動態(tài)管控機制,實現(xiàn)對低效SQL的實時檢測、靈活攔截與預警記錄,將運維控制權(quán)真正交到開發(fā)者以及DBA手中。
策略機制:雙模式切換、智能管控掃描行為
百度智能云數(shù)據(jù)庫通常提供如下兩種策略,可通過會話級變量動態(tài)切換,例如:
攔截模式:主動阻斷全表掃描類SQL,直接報錯,避免其執(zhí)行,防患于未然;
告警模式:放行執(zhí)行但記錄詳細日志,用于監(jiān)控、分析或?qū)徲?,做到有跡可循。
用戶可根據(jù)業(yè)務(wù)時段、環(huán)境類型或運維策略,隨時開關(guān)相應模式,兼顧開發(fā)靈活性與生產(chǎn)安全性。
核心設(shè)計:變量控制+白名單機制
通常產(chǎn)品會引入兩個系統(tǒng)變量,用于控制全表掃描行為:
gaia_prevent_full_table_scans(默認 OFF):一旦開啟,MySQL將在優(yōu)化階段識別全表掃描操作并直接拋出錯誤ER_TABLE_FULL_SCAN,同時中斷查詢。
gaia_full_table_scans_alarm_allowed(默認 ON):開啟后雖不攔截執(zhí)行,但會向日志中寫入警告信息,說明發(fā)生全表掃描的SQL文本,輔助后續(xù)優(yōu)化。
為保障系統(tǒng)內(nèi)部查詢不受干擾,產(chǎn)品內(nèi)置了對系統(tǒng)庫(如mysql、sys、information_schema等)的白名單支持。
實現(xiàn)原理:深度鉤入查詢執(zhí)行流程
此項能力并非通過外圍腳本或中間件實現(xiàn),而是以內(nèi)核補丁的方式深度集成在 MySQL 查詢執(zhí)行流程中,例如在Query_expression::execute()階段新增掃描檢查邏輯,優(yōu)化完成后檢查執(zhí)行計劃調(diào)用check_full_table_scan()判斷當前 SQL 是否包含全表掃描。
其中攔截邏輯是這樣的:
如果gaia_prevent_full_table_scans=ON且存在全表掃描:
拋出ER_TABLE_FULL_SCAN錯誤;
中斷執(zhí)行
告警邏輯則是這樣的:
如果gaia_full_table_scans_alarm_allowed=ON且存在全表掃描:
在日志打印WARNING信息,記錄 SQL;
增加計數(shù)器table_full_scan_count。
正常執(zhí)行的情況如下,如果未命中限制條件則正常走執(zhí)行ExecuteIteratorQuery(thd)。
在check_full_table_scan()中:
遍歷JOIN的qep_tab執(zhí)行計劃;
判斷qep_tab->type()是否為JT_ALL(全表掃描);
若表屬于白名單數(shù)據(jù)庫,則跳過檢查;
其他情況則標記 has_full_table_scan=true。
偽代碼示例:
switch (qep_tab->type()) {
case JT_ALL:
if (非系統(tǒng)數(shù)據(jù)庫) {
has_full_table_scan = true;
}
break;
default:
// 非全表掃描
has_full_table_scan = false;
}
使用示例:明快的控制體驗
開啟攔截模式,如下:
// 將攔截模式開關(guān)打開。
SET SESSION gaia_prevent_full_table_scans =ON;
// 查詢一個全表掃描的語句。
SELECT * FROM t1;
// 查詢會被攔截,并且報錯。
--ERROR 12345 (HY000): There is a full table scan in sql. You can modify gaia_prevent_full_table_scans to turn off the restriction
啟用告警模式,如下:
// 關(guān)閉攔截模式,并且打開報警開關(guān)。
SET SESSION gaia_prevent_full_table_scans = OFF;
SET SESSION gaia_full_table_scans_alarm_allowed =ON;
// 查詢一個全表掃描的語句。
SELECT*FROM t1;
// 查詢可以正常執(zhí)行,但是會在日志中,打印涉及全表掃描的sql。
--SQL正常執(zhí)行--日志打印: WARNING [Full table scan sql : SELECT * FROM t1;]
測試表現(xiàn):精準識別、穩(wěn)定可控
我們對該機制進行了多場景驗證,分別是:
正常索引查詢暢通無阻;全表掃描在攔截模式下準確中斷。
設(shè)置 gaia_prevent_full_table_scans=ON,執(zhí)行全表掃描 SQL,確認報錯;
設(shè)置 gaia_full_table_scans_alarm_allowed=ON,確認日志輸出但 SQL 可執(zhí)行。
系統(tǒng)庫查詢不受影響。
在 mysql 數(shù)據(jù)庫執(zhí)行 SELECT * FROM user;,確認不會報錯。
雙變量沖突時以攔截為優(yōu)先策略,避免安全漏洞。
兩個變量都OFF時,全表掃描允許執(zhí)行且不告警;
兩個變量都ON時,以prevent優(yōu)先。
總結(jié):運維新利器、性能守護者
這套全表掃描限制機制雖在實現(xiàn)上簡潔高效,卻可為數(shù)據(jù)庫系統(tǒng)帶來立竿見影的收益:
事前預防:攔截模式將風險查詢拒之門外,保障生產(chǎn)環(huán)境穩(wěn)定;
事中可見:告警模式記錄低效SQL,便于跟蹤與優(yōu)化;
靈活調(diào)度:動態(tài)開關(guān)策略,適配不同業(yè)務(wù)時段與環(huán)境類型;
無縫集成:內(nèi)核級實現(xiàn),無需修改業(yè)務(wù)SQL,零侵入。
對于具備中大規(guī)模MySQL集群的企業(yè)來說,這類細粒度、內(nèi)核級的管控工具,無疑是提升數(shù)據(jù)庫可靠性與運維效率的關(guān)鍵一步。
責任編輯:張薇
貴州省印發(fā)《行動計劃》—— 打造“千兆黔省、萬兆筑城”
近日,省人民政府辦公廳印發(fā)《貴州省“千兆黔 ... 詳細
貴州網(wǎng)絡(luò)視聽產(chǎn)業(yè)園:數(shù)智賦能筑就全國性視聽產(chǎn)業(yè)集聚高地
在貴陽觀山湖區(qū),貴州網(wǎng)絡(luò)視聽產(chǎn)業(yè)園(以下簡 ... 詳細
貴陽大數(shù)據(jù)交易所有限責任公司總經(jīng)理(職業(yè)經(jīng)理人)招聘公告
當前,貴州奮力在實施數(shù)字經(jīng)濟戰(zhàn)略上搶新機, ... 詳細
云測數(shù)據(jù):場景化、精細化、安全合規(guī)的數(shù)據(jù)助力AI落地
AI數(shù)據(jù)作為生產(chǎn)資料,是推動整個AI行業(yè)發(fā)展的 ... 詳細
同心抗疫,眾盟與一線65個地區(qū)的鐵路乘警們“戰(zhàn)”在一起
2月4日上午,在南京南站派出所女民警張佩卿的 ... 詳細
朗瑪信息四度入選“中國互聯(lián)網(wǎng)企業(yè)100強”
8月14日,2019年“中國互聯(lián)網(wǎng)企業(yè)100強”榜單 ... 詳細