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 中的布林字面量就是 truefalse,就像 SQL 中一樣。

返回目錄

空值

特殊的 null 關鍵字表示空值 (類似於 SQL 中的 null 值)。

YSQL 通常不涉及空值,因此很少使用此字面量。包含它只是為了完整性。

返回目錄

表名必須始終以其完全限定形式指定,除非使用者給出了別名 (如在 from 子句中使用 as ALIAS 語法)。

YSQL 目前支援許多內建表,如 ngx.reqscpu.profile。詳情請參見"內建表"部分。

返回目錄

當沒有歧義時,列名可以用其裸名稱表示,如 urihost,或者用帶表名的完全限定形式表示,如:

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 betweenis not 未在運算子優先順序表中列出。

返回目錄

算術表示式

YSQL 支援以下二元算術運算子:加法 (+)、減法 (-)、乘法 (*)、除法 (/) 和取模 (%)。

它還支援一元算術運算子 -+

返回目錄

字串連線

支援 SQL 風格的字串連線運算子 ||

返回目錄

關係表示式

YSQL 支援大多數常見的 SQL 風格關係運算子:

  • = (等於)
  • !=<> (不等於)
  • <=
  • <
  • >
  • >=
  • between ... and
  • in (value...)
  • likenot like
  • isis not

like 運算子支援兩種形式的模式:

  1. SQL 風格的模式,帶有元字元如 %(匹配零個或多個任意字元) 和 _(匹配一個任意字元)。元字元可以用反斜槓 (/) 轉義以表示 %_ 字元本身。
  2. 正規表示式字面量,如 /.../rx{...}

此外,YSQL 支援以下字串匹配運算子,分別測試右側字串是否是左側字串中的字首、子串或字尾:

  • prefix
  • contains
  • suffix

返回目錄

邏輯表示式

支援以下 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 joininner 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 目前有一些限制:

  1. order by 子句中只允許一列。
  2. 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 子請求。

它具有以下列:

  • args

    HTTP 請求的 URI 查詢字串。

  • host

    HTTP 請求的主機名。

  • 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。

  • method

    HTTP 請求的方法字串。

  • scheme

    當前 HTTP 請求的協議字串,如 httphttps

  • uri

    HTTP 請求 URI(不包括任何查詢字串)。

  • raw_uri

    HTTP 原始請求 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_bt

    Lua 函式級回溯

  • lua_line_bt

    Lua 行級回溯

  • vm_state

    應返回 LuaJIT VM 狀態常量的整數值。

  • gc_count

    lj-gc.y 工具的大小輸出,以位元組為單位。

  • is_gc64

    布林型別,用於 GC64 模式。

  • jit_maxtrace

    LuaJIT JIT 選項 maxtrace 的值

  • jit_hotloop

    LuaJIT JIT 選項 hotloop 的值

  • jit_maxmcode

    LuaJIT JIT 選項 maxmcode 的值

  • jit_sizemcode

    LuaJIT JIT 選項 sizemcode 的值

  • jit_maxside

    LuaJIT JIT 選項 maxsize 的值。

  • jit_maxsnap

    LuaJIT JIT 選項 maxsnap 的值。

  • jit_minstitch LuaJIT 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. 保留所有權利。

本文件為專有文件,包含機密資訊。未經版權所有者書面許可, 禁止在任何時候重新分發本文件。

返回目錄