OpenResty XRay™ YSQL 用户手册

YSQL 语言用户手册 本手册从用户角度记录 YSQL 语言。 为了方便起见,本文档通篇使用 ysql 一词来表示 Ops 语言。 有问题的示例代码每行开头会有一个问号 ?。例如: YSQL 语言受 SQL 语言启发,但从未打算与 SQL 标准或某种 SQL 方言 100% 兼容。

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 ... and
  • in (value...)
  • like 和 not like
  • is 或 is 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 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 目前有一些限制:

  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 请求的协议字符串,如 http 和 https。

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

本文档为专有文档,包含机密信息。未经版权所有者书面许可, 禁止在任何时候重新分发本文档。

返回目录