OpenResty XRay™ YSQL 使用者手冊
YSQL 語言使用者手冊
本手冊從使用者角度記錄 YSQL 語言。
目錄
約定
為了方便起見,本文件通篇使用 ysql 一詞來表示 Ops 語言。
有問題的示例程式碼每行開頭會有一個問號 ?。例如:
? select *;
描述
YSQL 語言受 SQL 語言啟發,但從未打算與 SQL 標準或某種 SQL 方言 100% 相容。儘管如此,YSQL 程式碼看起來可能與 SQL 程式碼非常相似。
YSQL 語言作為 OpenResty XRay 平臺的一部分提供。它是一種快速建立新的動態追蹤分析器的方法,可以針對任何正在執行的程序,無需日誌資料分析或目標應用程式的特殊資料 API 協作。
程式佈局
YSQL 程式由多個用分號分隔的語句組成。目前只允許單個 select 查詢語句,但將來可能會改變。下面是一個例子:
select uri, host
from ngx.reqs;
最後一個語句的尾部分號可以省略。
詞法結構
整數
整數可以表示為十進位制或十六進位制字面量,如:
-3
519
0xdeadbeef
浮點數
浮點數可以表示如下:
3.1415926
2e8
4.2E2
字串字面量
字串字面量用單引號括起來,就像標準 SQL 語言一樣,如:
'hello, world!'
此外,我們支援以下特殊轉義序列來指定特殊字元:
\a          響鈴,ascii 碼 0x07
\b          退格,ascii 碼 0x08
\f          換頁,ascii 碼 0x0c
\n          換行
\r          回車
\t          製表符
\v          垂直製表符
\\          反斜槓 (\)
\'          單引號字元 (')
\"          雙引號字元 (")
\<newline>  換行字元,就像 \n
下面是使用轉義序列的示例:
'hello\nworld\t!'
正規表示式字面量
正規表示式字面量是一種表示用於模式匹配的正規表示式的方式 (與 like 二元運算子一起使用)。正規表示式字面量,比如 /[0-9]+/,可以用不同的分隔符括起來,如:
/[0-9]+/
rx/[0-9]+/
rx{[0-9]+}
rx([0-9]+)
rx[[0-9]+]
rx'[0-9]+'
rx"[0-9]+"
rx![0-9]+!
rx#[0-9]+#
您可以選擇最佳分隔符來最小化正規表示式模式本身內部的必要轉義。
目前只允許 Perl 相容正規表示式和 POSIX 正規表示式語法的公共子集,但不包括反向引用語法 (如 \1、\2 等)。我們可能會在將來取消此限制。
支援使用括號進行子匹配捕獲。
布林字面量
YSQL 中的布林字面量就是 true 和 false,就像 SQL 中一樣。
空值
特殊的 null 關鍵字表示空值 (類似於 SQL 中的 null 值)。
YSQL 通常不涉及空值,因此很少使用此字面量。包含它只是為了完整性。
表
表名必須始終以其完全限定形式指定,除非使用者給出了別名 (如在 from 子句中使用 as ALIAS 語法)。
YSQL 目前支援許多內建表,如 ngx.reqs 和 cpu.profile。詳情請參見"內建表"部分。
列
當沒有歧義時,列名可以用其裸名稱表示,如 uri 和 host,或者用帶表名的完全限定形式表示,如:
select ngx.reqs.uri
from ngx.reqs
其中 uri 列使用完全限定形式 ngx.reqs.uri 指定。
列也可以透過使用者別名間接引用 (如在 select 列表中使用 as ALIAS 語法)。
運算子和表示式
YSQL 支援許多類似 SQL 的運算子和表示式型別,並有一些自己的補充。
所有運算子的優先順序表如下:
3    一元 !
4    - (一元減), + (一元加)
5    || (字串連線)
7    *, /, %
8    二元 -, +
12    = (比較), >=, >, <=, <, <>, !=, is, like, in, prefix, suffix, contains
13    between
14    not
15    and
17    or
19    left join, inner join
20    , (交叉連線)
通常可以使用括號 (...) 對優先順序較低的運算子進行分組。
not ... 變體如 not between 和 is not 未在運算子優先順序表中列出。
算術表示式
YSQL 支援以下二元算術運算子:加法 (+)、減法 (-)、乘法 (*)、除法 (/) 和取模 (%)。
它還支援一元算術運算子 - 和 +。
字串連線
支援 SQL 風格的字串連線運算子 ||。
關係表示式
YSQL 支援大多數常見的 SQL 風格關係運算子:
=(等於)!=或<>(不等於)<=<>>=between ... andin (value...)like和not likeis或is not
like 運算子支援兩種形式的模式:
- SQL 風格的模式,帶有元字元如 
%(匹配零個或多個任意字元) 和_(匹配一個任意字元)。元字元可以用反斜槓 (/) 轉義以表示%和_字元本身。 - 正規表示式字面量,如 
/.../和rx{...}。 
此外,YSQL 支援以下字串匹配運算子,分別測試右側字串是否是左側字串中的字首、子串或字尾:
prefixcontainssuffix
邏輯表示式
支援以下 SQL 風格的邏輯運算子:
- 二元 
and - 二元 
or - 一元 
not 
子查詢
YSQL 目前不支援子查詢,儘管 YSQL 編譯器可以正常解析它們。
Select 查詢語句
該語句包含一個 select 查詢,帶有以下一個或多個子句。注意 select 子句始終是必需的。
Select 子句
支援 SQL 風格的 select 子句。以下是一些示例:
select 3 + 2;
select 3 > 2;
select 'hello' || 'world';
關係表示式、算術表示式和字串連線表示式都可以出現在 select 列表中。但是,這裡不允許使用邏輯表示式。
每個選定的值可以在值表示式後面帶一個可選的別名,就像標準 SQL 中一樣,如:
select 3 > 2 res;
select 3 > 2 as res;
使用者還可以使用星號(*)來表示 from 子句中出現的表或多個表的所有列,如:
select *
from ngx.reqs;
聚合函式如 sum()、avg()、min()、max() 和 count() 也可以在選定的值表示式中使用,如:
select count(*), sum(latency_s)
from ngx.reqs;
From 子句
from 子句也類似於標準 SQL 語言。可以指定單個表,如:
select uri
from ngx.reqs;
或者多個表連線在一起,如:
select user_bt, count(user_bt) cnt
from cpu.profile inner join proc
group by user_bt
order by count(user_bt) desc
limit 1000
目前 YSQL 僅支援 left join 和 inner join。不支援其他連線型別(儘管它們可能可以正常解析)。
Where 子句
where 子句與標準 SQL 語言中的相同。可以在這裡指定一個邏輯表示式作為搜尋條件。以下是一個示例:
select count(*)
from ngx.reqs
where uri prefix '/css/';
Group By 子句
group by 子句類似於標準 SQL 語言,如:
select count(*) as cnt, host
from ngx.reqs
group by host
order by cnt desc
limit 10;
Having 子句
having 子句類似於標準 SQL 語言。與 where 子句不同,having 子句中的搜尋條件可以使用聚合函式,如 count() 和 sum()。以下是一個示例:
select max(latency_s), host
from ngx.reqs
group by host
having max(latency_s) > 0.5
也可以引用 select 列表中的別名,如:
select max(latency_s) max, host
from ngx.reqs
group by host
having max > 0.5;
Order By 子句
order by 子句類似於標準 SQL 語言。不過 YSQL 目前有一些限制:
order by子句中只允許一列。order by列只能是列名或count()聚合函式。
以下是一個示例:
select count(*), host
from ngx.reqs
group by host
order by count(*) desc;
也可以在 order by 子句中引用選定值表示式的別名(如果有),如:
select count(*) cnt, host
from ngx.reqs
group by host
order by cnt desc;
Limit 子句
limit 子句類似於標準 SQL 語言。以下是一個示例:
select *
from ngx.reqs
limit 10;
Offset 子句
offset 子句語法類似於 PostgreSQL 提供的 PL/SQL 語言。以下是一個示例:
select *
from ngx.reqs
offset 1
limit 10;
這將跳過第一行,僅輸出第 2 到第 10 行。
內建表
以下是 YSQL 編譯器當前支援的內建表的詳細列表。我們正在快速新增新表和新列。
cpu.profile
該表表示 CPU 效能分析。它只能用作 from 子句中的第一個表。它沒有任何列。它通常與其他表(如 ngx.reqs 等)連線使用。
ngx.reqs
該表用於檢查 nginx(主)請求。這裡排除了 Nginx 子請求。
它具有以下列:
argsHTTP 請求的 URI 查詢字串。
hostHTTP 請求的主機名。
latency_ms表示請求延遲的整數,單位為毫秒,如
120。latency_s表示請求延遲的浮點數,單位為秒,如
0.32。rewrite_phase_latency_s表示 rewrite 階段延遲的浮點數,單位為秒,如
0.32。rewrite_phase_latency_ms表示 rewrite 階段延遲的浮點數,單位為毫秒,如
0.32。access_phase_latency_s表示 access 階段延遲的浮點數,單位為秒,如
0.32。access_phase_latency_ms表示 access 階段延遲的浮點數,單位為毫秒,如
0.32。content_phase_latency_s表示 content 階段延遲的浮點數,單位為秒,如
0.32。content_phase_latency_ms表示 content 階段延遲的浮點數,單位為毫秒,如
0.32。req_header_latency_s表示接收 HTTP 請求頭延遲的浮點數,單位為秒,如
0.32。req_header_latency_ms表示接收 HTTP 請求頭延遲的浮點數,單位為毫秒,如
0.32。req_body_latency_s(待實現)表示接收 HTTP 請求體延遲的浮點數,單位為秒,如
0.32。req_body_latency_ms(待實現)表示接收 HTTP 請求體延遲的浮點數,單位為毫秒,如
0.32。keepalive布林值,表示當前請求是否為當前 TCP 連線啟用 HTTP keep-alive。
methodHTTP 請求的方法字串。
scheme當前 HTTP 請求的協議字串,如
http和https。uriHTTP 請求 URI(不包括任何查詢字串)。
raw_uriHTTP 原始請求 URI(包括查詢字串)。
client_ip字串。IP 地址(IPv4 或 IPv6 或 unix socket 檔案路徑)。
req_body_size整數。請求體大小,單位為位元組。
req_size整數。整個請求大小(包括頭和體),單位為位元組。
resp_size整數。整個響應大小(包括頭和體),單位為位元組(如果涉及壓縮,則為壓縮後的大小)。
resp_body_size整數。響應體大小,單位為位元組。
server_port整數。當前請求訪問的伺服器埠。
status整數。HTTP 響應狀態碼(如 502 和 200)或內部 nginx 錯誤程式碼(如果沒有有意義的 HTTP 狀態碼可用)。
is_ssl布林值。當前請求是否使用 SSL 或 TLS。
tls_ver數字。TLS 協議版本號,如 1.2 和 1.3。
ssl_ver數字。SSL 協議版本號,如 2 和 3。
resp_is_chunked布林值。響應體是否使用分塊編碼。
req_is_chunked布林值。請求體是否使用分塊編碼。
http_ver數字。HTTP 協議版本(0.9、1.0、1.1、2.0)。
is_websocket布林值。當前請求是否已升級到 WebSocket 協議。
resp_is_compressed布林值。當前請求的響應體是否被壓縮(透過 gzip 或其他編碼)。
resp_gzip_level整數。響應體實際使用的 gzip 壓縮級別(僅在當前響應實際被壓縮時有意義)。
mime_type字串。應該是類似 application/javascript 的值。應排除任何尾隨引數,如 ; charset=utf-8。
uses_lua布林值。當前請求是否在任何請求處理階段使用任何 Lua 程式碼處理程式(如 log_by_lua、rewrite_by_lua 等)。
for_static_file布林值。當前請求是否使用靜態檔案模組來提供當前機器檔案系統上的靜態檔案。
has_upstream布林值。當前請求是否使用代理(即使用 nginx upstream 模組)。
access_log_buf_size整數。當前請求的訪問日誌緩衝區大小,單位為位元組。
uses_error_page布林值。當前請求是否提供錯誤頁面。
uri_changes整數。在請求處理階段完成的 URI 更改次數(對應於 r->uri_changes)。
uri_changed布林值。當前請求的 URI 是否曾被請求處理階段更改(對應於 r->uri_changed)。
is_pipelined布林值。當前請求是否為流水線請求(即 C 層面的 r->pipeline)。
resp_header_only布林值。當前響應是否僅有頭部(r->header_only)。
location字串。最後服務當前請求的 nginx location 名稱。
user_agent字串。User-Agent 字串。
conn_is_reused布林值。當前請求是否重用了由較早請求建立的連線。
req_pool_size整數。當前請求的 nginx 記憶體池大小,單位為位元組。
conn_pool_size整數。當前連線的 nginx 記憶體池大小,單位為位元組。
proc
此表用於檢查正在執行的作業系統程序。
它包含以下列:
user_bt使用者態回溯,通常用於 C/C++/Rust 程式。
kern_bt核心態回溯。
res_mem整數。常駐記憶體大小,以位元組為單位。
virt_mem整數。虛擬記憶體大小,以位元組為單位。
shr_mem整數。共享記憶體大小,以位元組為單位。
txt_mem整數。文字記憶體大小,以位元組為單位。
page_size整數。頁面大小,以位元組為單位。
data_size整數。程式資料大小,以位元組為單位(資料 + 棧)
pid整數。程序 ID。
pgid整數。程序組 ID。
ppid整數。父程序 ID。
exec_name字串。目標程序的可執行檔名(在 stap 中對映到 execname())。
pexec_name字串。目標程序的父程序的可執行檔名(在 stap 中對映到 pexecname())。
cpu_id整數。目標程序當前執行所在的 CPU 的 CPU ID。
luajit.vm
此表用於檢查 luajit 虛擬機器。
它包含以下列:
lua_btLua 函式級回溯
lua_line_btLua 行級回溯
vm_state應返回 LuaJIT VM 狀態常量的整數值。
gc_countlj-gc.y 工具的大小輸出,以位元組為單位。
is_gc64布林型別,用於 GC64 模式。
jit_maxtraceLuaJIT JIT 選項 maxtrace 的值
jit_hotloopLuaJIT JIT 選項 hotloop 的值
jit_maxmcodeLuaJIT JIT 選項 maxmcode 的值
jit_sizemcodeLuaJIT JIT 選項 sizemcode 的值
jit_maxsideLuaJIT JIT 選項 maxsize 的值。
jit_maxsnapLuaJIT JIT 選項 maxsnap 的值。
jit_minstitchLuaJIT JIT 選項 minstitch 的值
vfs.reads
此表用於檢查 vfs 讀取活動。
它包含以下列:
data_size整數。從 VFS 讀取的資料大小,以位元組為單位。
file_path字串。我們正在讀取資料的檔案路徑。
latency_s數字。當前 VFS 讀取操作的延遲,以秒為單位。納秒精度。允許小數部分。
latency_ms數字。當前 VFS 讀取操作的延遲,以毫秒為單位。納秒精度。允許小數部分。
vfs.writes
此表用於檢查 vfs 寫入活動。
它包含以下列:
data_size整數。寫入 VFS 的資料大小,以位元組為單位。
file_path字串。我們正在寫入資料的檔案路徑。
latency_s數字。當前 VFS 寫入操作的延遲,以秒為單位。納秒精度。允許小數部分。
latency_ms數字。當前 VFS 寫入操作的延遲,以毫秒為單位。納秒精度。允許小數部分。
作者
章亦春 yichun@openresty.com OpenResty Inc.
版權與許可
版權所有 (C) 2020-2025 OpenResty Inc. 保留所有權利。
本文件為專有文件,包含機密資訊。未經版權所有者書面許可, 禁止在任何時候重新分發本文件。