走進SQL審計視圖——《OceanBase診斷系列》之二

1. 前言


在SQL性能診斷上,OceanBase有一個非常實用的功能 —— SQL審計視圖(gv$sql_audit)。在OceanBase 4.0.0及更高版本中,該功能是 gv$ob_sql_audit。它可以使開發和運維人員更方便地排查在OceanBase上運行過的任意一條SQL,無論這些SQL是成功與否,都有詳細的運行信息記錄。這些信息包括客戶端和服務端的IP端口、SQL語句、執行時間、執行節點、執行計劃ID、會話ID、執行時間、等待時間、總時間、排隊時間、以及相關的塊讀取信息和執行報錯信息等。

查詢方式說明
(g)v$ob_sql_auditOceanBase 4.0.0.0 及以上版本,gv$xx查詢該租戶所有機器v$xxx查詢該租戶本機器(不保證路由準確)
(g)v$sql_auditOceanBase 4.0.0.0 以下版本gv$xx查詢該租戶所有機器v$xxx查詢該租戶本機器(不保證路由準確)

sql_audit是基于虛擬表__all_virtual_sql_audit的視圖, 該虛擬表對應的數據存放在一個可配置的內存空間中,能夠記錄并顯示每一次SQL請求的來源、執行狀態及統計信息,由于存放這些記錄的內存是有限的,因此到達一定內存使用量,會觸發淘汰。

  • sql_audit 每隔 1s 會檢測后臺任務并根據以下標準決定是否淘汰:
    • sql_audit 內存最大可使用上限為?avail_mem_limit = min (OBServer 可使用內存 *10%,sql_audit_memory_limit)。
    • 當?avail_mem_limit?在 [64M, 100M] 范圍內時, 內存使用達到?avail_mem_limit-20M?時觸發淘汰。
    • 當?avail_mem_limit?在 [100M, 5G] 范圍內時, 內存使用達到?availmem_limit*0.8?時觸發淘汰。
    • 當?avail_mem_limit?在 [5G, +∞)范圍內時, 內存使用達到?availmem_limit-1G?時觸發淘汰。
    • 當 sql_audidt 記錄數超過 900 萬條時,觸發淘汰。
  • sql_audit 根據以下標準決定是否停止淘汰:
    • 如果是達到內存上限觸發淘汰則:
    • 當?avail_mem_limit?在 [64M, 100M] 時, 內存使用淘汰到?avail_mem_limit-40M?時停止淘汰。
    • 當?avail_mem_limit?在 [100M, 5G] 時, 內存使用淘汰到?availmem_limit*0.6?時停止淘汰。
    • 當?avail_mem_limit?在 [5G, +∞] 時, 內存使用淘汰到?availmem_limit-2G?時停止淘汰。
    • 如果是達到記錄數上限觸發的淘汰則淘汰到 800 萬行記錄時停止淘汰。

2. sql_audit視圖字段介紹

字段名稱類型描述
SVR_IPvarchar(32)ip地址
SVR_PORTbigint(20)端口號
REQUEST_IDbigint(20)請求的id號
TRACE_IDvarchar(128)這條語句的trace_id
CLIENT_IPvarchar(32)發送請求的client ip
CLIENT_PORTbigint(20)發送請求的client port
TENANT_IDbigint(20)發送請求的租戶id
TENANT_NAMEvarchar(64)發送請求的租戶 名稱
USER_IDbigint(20)發送請求的用戶id
USER_NAMEvarchar(64)發送請求的用戶名稱
SQL_IDvarchar(32)這條SQL的id
QUERY_SQLvarchar(32768)實際的SQL語句
PLAN_IDbigint(20)執行計劃id
AFFECTED_ROWSbigint(20)影響行數
RETURN_ROWSbigint(20)返回行數
PARTITION_CNTbigint(20)該請求涉及的分區數
RET_CODEbigint(20)執行結果返回碼
EVENTvarchar(64)最長等待事件名稱
P1TEXTvarchar(64)等待事件參數1
P1bigint(20) unsigned等待事件參數1的值
P2TEXTvarchar(64)等待事件參數2
P2bigint(20) unsigned等待事件參數2的值
P3TEXTvarchar(64)等待事件參數3
P3bigint(20) unsigned等待事件參數3的值
LEVELbigint(20)等待事件的level級別
WAIT_CLASS_IDbigint(20)等待事件所屬的class id
WAIT_CLASS#bigint(20)等待事件所屬的class 的下標
WAIT_CLASSvarchar(64)等待事件所屬的class 名稱
STATEvarchar(19)等待事件的狀態
WAIT_TIME_MICRObigint(20)該等待事件所等待的時間
TOTAL_WAIT_TIME_MICRObigint(20)執行過程所有等待的總時間
TOTAL_WAITSbigint(20)執行過程總等待的次數
RPC_COUNTbigint(20)發送rpc個數
PLAN_TYPEbigint(20)執行計劃類型
IS_INNER_SQLtinyint(4)是否內部sql請求
IS_EXECUTOR_RPCtinyint(4)當前請求是否rpc請求
IS_HIT_PLANtinyint(4)是否命中plan_cache
REQUEST_TIMEbigint(20)開始執行時間點
ELAPSED_TIMEbigint(20)接收到請求到執行結束消耗 總時間
NET_TIMEbigint(20)發送rpc到接收到請求時間
NET_WAIT_TIMEbigint(20)接收到請求到進入隊列時間
QUEUE_TIMEbigint(20)請求在隊列等待事件
DECODE_TIMEbigint(20)出隊列后decode時間
GET_PLAN_TIMEbigint(20)開始process到獲得plan時間
EXECUTE_TIMEbigint(20)plan執行消耗時間
APPLICATION_WAIT_TIMEbigint(20) unsigned所有application類事件的總時間
CONCURRENCY_WAIT_TIMEbigint(20) unsigned所有concurrency類事件的總時間
USER_IO_WAIT_TIMEbigint(20) unsigned所有user_io類事件的總時間
SCHEDULE_TIMEbigint(20) unsigned所有schedule類事件的時間
ROW_CACHE_HITbigint(20)行緩存命中次數
BLOOM_FILTER_CACHE_HITbigint(20)bloom filter緩存命中次數
BLOCK_CACHE_HITbigint(20)塊緩存命中次數
BLOCK_INDEX_CACHE_HITbigint(20)塊索引緩存命中次數
DISK_READSbigint(20)物理讀次數
EXECUTION_IDbigint(20)執行ID
SESSION_IDbigint(20)session id
RETRY_CNTbigint(20)重試次數
TABLE_SCANtinyint(4)判斷該請求是否含全表掃描
CONSISTENCY_LEVELbigint(20)一致性級別
MEMSTORE_READ_ROW_COUNTbigint(20)MEMSTORE中的讀行數
SSSTORE_READ_ROW_COUNTbigint(20)SSSTORE中讀的行數
REQUEST_MEMORY_USEDbigint(20)該請求消耗的內存
  • 一些重要的事件間隔

3. 基于sql_audit的診斷case

3.1. 最近100s某個租戶的TOP SQL耗時監控

  • 檢查語句:
-- OceanBase 4.0.0.0及以上版本,請替換tenant_name的值為實際的租戶名 
select /*+read_consistency(weak),query_timeout(100000000)*/ SQL_ID,count(1),avg(ELAPSED_TIME),avg(EXECUTE_TIME),avg(QUEUE_TIME),avg(AFFECTED_ROWS),avg(GET_PLAN_TIME) 
from gv$ob_sql_audit  
where time_to_usec(now(6))-request_time <1000000000 
and tenant_name='test_tenant' 
group by SQL_ID order by avg(ELAPSED_TIME)*count(1) desc limit 20;-- OceanBase 4.0.0.0以下版本,請替換tenant_name的值為實際的租戶名 
select /*+read_consistency(weak),query_timeout(100000000)*/ SQL_ID,count(1),avg(ELAPSED_TIME),avg(EXECUTE_TIME),avg(QUEUE_TIME),avg(AFFECTED_ROWS),avg(GET_PLAN_TIME) 
from gv$sql_audit  
where time_to_usec(now(6))-request_time <1000000000 
and tenant_name='test_tenant'  
group by SQL_ID order by avg(ELAPSED_TIME)*count(1) desc limit 20 ;
  • 期望值: 觀察SQL 整體耗時,cpu_time, 物理讀及邏輯消耗是否合理,一般單行insert 和 主鍵查詢 500us以內
  • 對應建議:通過SQL語義與表結構比對,確認執行計劃是否合理,耗時是否正常

3.2.?查看集群中 SQL 請求流量是否均勻

  • 思路:我們首先可以查出某個時間段內數據庫中所有 SQL 并按照 server 級別進行聚合,再統計該時間段內每臺機器上的 QPS。
  • 語句:
-- OceanBase 4.0.0.0及以上版本,請替換t1.tenant_id的值為實際租戶的值
select t2.zone, t1.svr_ip,  count(*) as QPS
from oceanbase.gv$ob_sql_audit t1, oceanbase.__all_server t2
where t1.svr_ip = t2.svr_ip and t1.tenant_id = 1001
and IS_EXECUTOR_RPC = 0 and request_time > (time_to_usec(now()) - 1000000)
and request_time < time_to_usec(now())
group by t1.svr_ip   order by QPS;-- OceanBase 4.0.0.0以下版本,請替換t1.tenant_id的值為實際租戶的值
select t2.zone, t1.svr_ip,  count(*) as QPS
from oceanbase.gv$ob_sql_audit t1, oceanbase.__all_server t2
where t1.svr_ip = t2.svr_ip and t1.tenant_id = 1001
and IS_EXECUTOR_RPC = 0 and request_time > (time_to_usec(now()) - 1000000)
and request_time < time_to_usec(now())
group by t1.svr_ip   order by QPS;

3.3.?某個時間段請求次數排在 TOP-N 的 SQL

  • 思路:我們首先可以查出某個時間段內數據庫中所有 SQL 并按照 sql_id 級別進行聚合,再統計該時間段內每個SQL_ID的 QPS,取出top值。
  • 語句:
-- OceanBase 4.0.0.0及以上版本,請替換tenant_id的值為實際租戶的值
select SQL_ID, count(*) as QPS, avg(t1.elapsed_time) RT
from oceanbase.gv$ob_sql_audit t1
where   tenant_id = 1001       and IS_EXECUTOR_RPC = 0
and request_time > (time_to_usec(now()) - 10000000)
and request_time < time_to_usec(now())
group by t1.sql_id order by QPS desc limit 10;-- OceanBase 4.0.0.0以下版本,請替換tenant_id的值為實際租戶的值
select SQL_ID, count(*) as QPS, avg(t1.elapsed_time) RT
from oceanbase.gv$sql_audit t1
where   tenant_id = 1001       and IS_EXECUTOR_RPC = 0
and request_time > (time_to_usec(now()) - 10000000)
and request_time < time_to_usec(now())
group by t1.sql_id order by QPS desc limit 10;

3.4.?定位所有SQL中消耗CPU最多的sql

思路:消耗CPU的時間是elapsed_time - queue_time,因為queue_time的過程中是在排隊,并不消耗cpu. 排查消耗CPU最多的sql在cpu飆高的場景非常有用

語句:

-- OceanBase 4.0.0.0及以上版本,請替換tenant_id的值為實際租戶的值
select sql_id, substr(query_sql, 1, 20) as query_sql, sum(elapsed_time - queue_time) sum_t, count(*) cnt, avg(get_plan_time), avg(execute_time)    
from oceanbase.gv$ob_sql_audit     
where   tenant_id = 1001      and request_time > (time_to_usec(now()) - 10000000)     and request_time < time_to_usec(now())
group by sql_id order by sum_t desc   limit 10;-- OceanBase 4.0.0.0以下版本,請替換tenant_id的值為實際租戶的值
select sql_id, substr(query_sql, 1, 20) as query_sql, sum(elapsed_time - queue_time) sum_t, count(*) cnt, avg(get_plan_time), avg(execute_time)    
from oceanbase.gv$sql_audit     
where   tenant_id = 1001      and request_time > (time_to_usec(now()) - 10000000)     and request_time < time_to_usec(now())
group by sql_id order by sum_t desc   limit 10;

3.5.?查看SQL的執行是否出現大量請求不合理的使用了遠程執行

思路:sql_audit的PLAN_TYPE字段可以看到該SQL的執行計劃類型,

  • plan_type=1?:本地執行計劃。性能最好。
  • plan_type=2?: 遠程執行計劃。
  • plan_type=3?: 分布式執行計劃。包含本地執行計劃和遠程執行計劃。

一般情況下,如果出現遠程執行比較多時可能時出現切主或proxy客戶端路由不準的情況。

語句:

-- OceanBase 4.0.0.0及以上版本,請替換tenant_id的值為實際租戶的值
select count(*), plan_type    
from oceanbase.gv$ob_sql_audit     
where tenant_id = 1001          and IS_EXECUTOR_RPC = 0          and request_time > (time_to_usec(now()) - 10000000)         and request_time < time_to_usec(now()) 
group by plan_type ;-- OceanBase 4.0.0.0以下版本,請替換tenant_id的值為實際租戶的值
select count(*), plan_type    
from oceanbase.gv$sql_audit     
where tenant_id = 1001          and IS_EXECUTOR_RPC = 0          and request_time > (time_to_usec(now()) - 10000000)         and request_time < time_to_usec(now()) 
group by plan_type ;

3.6. 查詢全表掃描的SQL

思路:sql_audit的TABLE_SCAN字段是標識語句是否走了全表掃描,=1 表示全表掃描了。可以進一步分析一下SQL是否可以添加索引來防止全表掃描:

語句:

-- OceanBase 4.0.0.0及以上版本,請替換tenant_id的值為實際租戶的值
select query_sql 
from oceanbase.gv$ob_sql_audit 
where table_scan = 1 and tenant_id = 1001 
group by sql_id;-- OceanBase 4.0.0.0以下版本,請替換tenant_id的值為實際租戶的值
select query_sql 
from oceanbase.gv$sql_audit 
where table_scan = 1 and tenant_id = 1001 
group by sql_id;

3.7 如何分析RT突然抖動的SQL?

? ? 在線上如果出現RT抖動,但RT并不是持續很高的情況,可以考慮在抖動出現后,立刻將sql audit關閉(alter system set ob_enable_sql_audit = 0),從而確保該抖動的SQL請求在sql audit中存在;然后通過3.3章節的【某個時間段請求次數排在 TOP-N 的 SQL】,分析有異常的SQL。

? ?如果在sql_audit中找到了對應的RT異常請求,則可以分析該請求在sql audit中記錄:

  • 查看retry次數是否很多(RETRY_CNT, 如果次數很多,則是否考慮是否有鎖沖突或切主等情況)
  • 查看queue time是不是很大(QUEUE_TIME字段)
  • 查看獲取執行計劃時間(GET_PLAN_TIME), 如果時間很長,一般會伴隨IS_HIT_PLAN = 0, 表示沒有命中plan cache)
  • 查看EXECUTE_TIME是否很長,如果很長,則

? ? ?a. 查看是否有很長等待事件耗時

? ? ?b. 查看訪問的行數是否很多, 看SSSTORE_READ_ROW_COUNT, MEMSTORE_READ_ROW_COUNT兩個字段, 比如大小賬號場景可能導致rt抖動。

第一篇“神醫”的修煉秘籍——《OceanBase診斷系列》之一
第二篇一起走進sql_audit性能視圖——《OceanBase診斷系列》之二

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715541.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715541.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715541.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

字節前端實習一面

1.自我介紹 實習經歷介紹 2.選擇前端的原因 3.如何解決跨域 4.tailwind CSS 這個是我其中一個項目中使用的&#xff0c;但我當時只是當它工具使用的&#xff0c;直接問我實現原理和優勢等等。實現原理我沒回答好&#xff0c;但這個確實是一個好問題 代碼題&#xff1a; 1.let …

層級鎖筆記

注意看test_hierarchy_lock函數 如果thread t2的不注釋&#xff0c;就會報錯。 這是因為層級鎖強調的單個線程內上鎖的順序。 線程t2若已經獲取了hmtx2&#xff0c;再試圖獲取hmtx1就會因為違反層級順序而拋出異常。 #include <mutex> #include <thread> //層級鎖…

kafka文件存儲機制和消費者

1.broker文件存儲機制 去查看真正的存儲文件&#xff1a; 在/opt/module/kafka/datas/ 路徑下 kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.index 如果是6415那么這個會存儲在563的log文件之中&#xff0c;因為介于6410和10090之間。 2.…

java mysql八股

mysql中如何定位慢查詢 表象&#xff1a;頁面加載過慢、接口壓測響應時間較長&#xff08;超過1秒&#xff09; 可以采用開源工具如Arthas以及Skywalking&#xff0c;使用skywalking可以檢測出哪個接口過慢。同時可以在mysql中開啟慢日志查詢&#xff0c;設置值為2秒&#xff0…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的行人車輛檢測與計數(Python+PySide6界面+訓練代碼)

摘要&#xff1a;開發行人車輛檢測與計數系統對于提升城市交通管理和監控系統的效率至關重要。本篇博客詳細介紹了如何利用深度學習構建一個行人車輛檢測與計數系統&#xff0c;并提供了完整的實現代碼。該系統基于強大的YOLOv8算法&#xff0c;并結合了YOLOv7、YOLOv6、YOLOv5…

[Java 探索者之路] 一個大廠都在用的分布式任務調度平臺

分布式任務調度平臺是一種能夠在分布式計算環境中調度和管理任務的系統&#xff0c;在此環境下&#xff0c;各個任務可以在獨立的節點上運行。它有助于提升資源利用率&#xff0c;增強系統擴展性以及提高系統對錯誤的容忍度。 文章目錄 1. 分布式任務調度平臺1. 基本概念1.1 任…

Linux文本處理三劍客:sed

在Linux操作系統中&#xff0c;grep、sed、awk被稱為文本操作“三劍客”&#xff0c;上一期中&#xff0c;我們將詳細介紹grep的基本使用方法&#xff0c;希望能夠幫助到有需要的朋友&#xff0c;現在&#xff0c;我們繼續學習sed。 我會參考官方文檔來做翻譯理解。下面正式開…

使用Java同步Linux服務器時間

前言 公司客戶線上服務器采用的是UOS系統&#xff0c;實施發現系統不會同步時間&#xff0c;并且時間有真實時間有偏差&#xff0c;本意想安裝NTP授時服務&#xff0c;結果發現UOS安裝NTP都要折騰好久&#xff0c;遂采用Java來曲線救國了。 添加依賴 <dependency><…

Java基于SpringBoot的旅游網站的設計與實現論文

目 錄 摘 要 2 Abstract 3 1.1 課題開發的背景 4 1.2 課題研究的意義 4 1.3 研究內容 5 第二章 系統開發關鍵技術 6 2.1 JSP技術介紹 6 2.2 JAVA簡介 6 2.3 MyEclipse開發環境 7 2.4 Tomcat服務器 7 2.5 Spring Boot框架 7 2.6 MySQL數據庫 8 第三章 系統分析 9 3.1 系統可行性…

實踐航拍小目標檢測,基于YOLOv8全系列【n/s/m/l/x】參數模型開發構建無人機航拍場景下的小目標檢測識別分析系統

關于無人機相關的場景在我們之前的博文也有一些比較早期的實踐&#xff0c;感興趣的話可以自行移步閱讀即可&#xff1a; 《deepLabV3Plus實現無人機航拍目標分割識別系統》 《基于目標檢測的無人機航拍場景下小目標檢測實踐》 《助力環保河道水質監測&#xff0c;基于yolov…

使用 llama.cpp 在本地部署 AI 大模型的一次嘗試

對于剛剛落下帷幕的2023年,人們曾經給予其高度評價——AIGC元年。隨著 ChatGPT 的火爆出圈,大語言模型、AI 生成內容、多模態、提示詞、量化…等等名詞開始相繼頻頻出現在人們的視野當中,而在這場足以引發第四次工業革命的技術浪潮里,人們對于人工智能的態度,正從一開始的…

JVM(5)

垃圾回收相關 垃圾收集器 警告:純八股文! 如果說上面我們講的收集算法是內存回收的方法論,那么垃圾收集器就是內存回收的具體體現. 垃圾收集器的作用:垃圾收集器是為了保證程序能夠正常,持久運行的一種技術,它是將程序中不用的死亡對象也就是垃圾對象進行清除,從而保證新的…

第四十五天| 322. 零錢兌換、279.完全平方數

Leetcode 322. 零錢兌換 題目鏈接&#xff1a;322 零錢兌換 題干&#xff1a;給你一個整數數組 coins &#xff0c;表示不同面額的硬幣&#xff1b;以及一個整數 amount &#xff0c;表示總金額。計算并返回可以湊成總金額所需的 最少的硬幣個數 。如果沒有任何一種硬幣組合能…

AI大語言模型【成像光譜遙感技術】ChatGPT應用指南

遙感技術主要通過衛星和飛機從遠處觀察和測量我們的環境&#xff0c;是理解和監測地球物理、化學和生物系統的基石。ChatGPT是由OpenAI開發的最先進的語言模型&#xff0c;在理解和生成人類語言方面表現出了非凡的能力。本文重點介紹ChatGPT在遙感中的應用&#xff0c;人工智能…

vscode + git

寫在前面&#xff1a; origin分支&#xff1a; 當我們在使用git clone的時候&#xff0c;git會自動地將這個遠程的repo命名為origin&#xff0c;拉取它所有的數據之后&#xff0c;創建一個指向它master的指針&#xff0c;命名為origin/master&#xff0c;之后會在本地創建一個…

C#單向鏈表實現:用泛型類在當前位置插入新數據的方法Insert()

一、涉及到的知識點 1.ListNode<T>類 ListNode<T>是一個泛型類&#xff0c;用于表示鏈表中的一個節點。Value和Next屬性是ListNode<T>最基本的屬性&#xff0c;用于表示節點的值和指向下一個節點的引用。但是&#xff0c;完全可以根據實際需求添加其他屬性&…

雙非二本找實習前的準備day5

學習目標&#xff1a; 每天2-3到簡單sql&#xff08;刷完即止&#xff09;&#xff0c;每天復習代碼隨想錄上的題目3道算法&#xff08;時間充足可以繼續&#xff09;&#xff0c;今天的八股背少一點&#xff0c;MySQL和Redis各1-2道好了&#xff0c;主攻復習是java基礎 今日…

C語言5道編程題簡單介紹(三)

1、打印楊輝三角 程序分析&#xff1a; 結構如下所示&#xff1a; 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1代碼如下&#xff1a; #include <stdio.h>int main() {int i,j;int a[10][10];printf("\n");for(i0;i<10;i) {a[i][0]1;a…

Vuex 是什么?它在 Vue 應用中扮演什么角色?解釋一下 Vuex 的狀態管理模式。如何在 Vuex 中進行異步操作?

一、Vuex 是什么&#xff1f; Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態&#xff0c;并以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 的出現解決了多個組件間共享狀態的問題&#xff0c;使得狀態管理變得更加直…

#WEB前端(HTML屬性)

1.實驗&#xff1a;a,img 2.IDE&#xff1a;VSCODE 3.記錄&#xff1a; a: href插入超鏈接 默認情況下在本窗口打開鏈接, target可以設置打開的窗口,parent在父窗口打開&#xff0c;blank新開串口打開,top在頂層串口打開,self為默認在本窗口打開 img: 插入圖片 可以插…