从Oracle迁移应用,或需要在数据库层面实现精细化的操作审计与应用追踪时,SYS_CONTEXT函数提供了一个与 Oracle兼容的接口。此函数用于获取当前会话的用户、网络、应用等上下文信息,以支持安全策略、性能诊断和业务追踪等高级功能。
核心示例
以下示例展示了如何一次性查询当前会话的关键信息,如数据库名、会话用户、客户端IP地址和正在执行的应用模块,便于快速了解其核心用法。
SELECT
SYS_CONTEXT('USERENV', 'DB_NAME') AS db_name,
SYS_CONTEXT('USERENV', 'SESSION_USER') AS session_user,
SYS_CONTEXT('USERENV', 'IP_ADDRESS') AS client_ip,
SYS_CONTEXT('USERENV', 'MODULE') AS app_module;预期输出示例(输出内容取决于实际会话环境):
db_name | session_user | client_ip | app_module
---------+--------------+-----------------+------------
testdb | dev_user | 172.xx.xx.xx/xx | 适用范围
您的PolarDB PostgreSQL版(兼容Oracle)集群的修订版本需为2.0.14.18.37.0及以上
语法说明
SYS_CONTEXT(namespace VARCHAR2, attribute VARCHAR2) RETURN VARCHAR2参数说明
namespace:命名空间,目前主要支持
'USERENV'。attribute:要获取的属性名称。
返回值
VARCHAR2类型的属性值。
使用场景
配置并追踪应用信息
在复杂的应用中,追踪是哪个模块、哪个具体操作触发了数据库行为至关重要。SYS_CONTEXT不仅能读取信息,还能配合DBMS_APPLICATION_INFO包来设置和读取应用上下文,形成完整的追踪链路。
目的:为当前数据库会话设置应用模块和操作信息,以便后续审计或性能分析。
设置应用上下文信息。
在应用程序代码连接数据库后,调用DBMS_APPLICATION_INFO包中的过程来设置当前会话的模块和操作。
-- 假设这是一个处理订单的后台服务 CALL DBMS_APPLICATION_INFO.SET_MODULE('OrderProcessing', 'CreateNewOrder');在数据库中查询上下文信息。
设置后,可在数据库的任何地方(例如,在触发器或日志记录函数中)通过SYS_CONTEXT获取这些信息。
SELECT SYS_CONTEXT('USERENV', 'MODULE') AS current_module, SYS_CONTEXT('USERENV', 'ACTION') AS current_action;预期返回结果如下:
current_module | current_action -----------------+---------------- OrderProcessing | CreateNewOrder
在触发器中实现操作审计
SYS_CONTEXT在自动化审计场景中尤其有用。可在触发器中捕获操作者的环境信息,并将其存入审计日志,而无需应用层传递额外参数。
目的:当employees表的记录被更新时,自动在audit_log表中记录操作者的操作系统用户、客户端 IP 和会话 ID。
创建目标表并插入示例数据。
创建employees表并插入一条用于测试的记录。
CREATE TABLE employees ( employee_id INT PRIMARY KEY, name TEXT, salary NUMERIC ); INSERT INTO employees VALUES (101, 'test_user', 50000);创建审计日志表。
用于存储审计信息。
CREATE TABLE audit_log ( log_id SERIAL PRIMARY KEY, table_name TEXT NOT NULL, os_user TEXT, client_ip TEXT, session_id TEXT, change_time TIMESTAMPTZ DEFAULT NOW() );创建审计触发器函数。
该函数从USERENV命名空间中获取上下文信息并插入日志表。
CREATE OR REPLACE FUNCTION fn_audit_employees_update() RETURNS TRIGGER AS $$ BEGIN INSERT INTO audit_log (table_name, os_user, client_ip, session_id) VALUES ( TG_TABLE_NAME, SYS_CONTEXT('USERENV', 'OS_USER'), SYS_CONTEXT('USERENV', 'IP_ADDRESS'), SYS_CONTEXT('USERENV', 'SESSIONID') ); RETURN NEW; END; $$ LANGUAGE plpgsql;绑定触发器到目标表。
在
employees表每次更新后执行此函数。CREATE TRIGGER trg_audit_employees_update AFTER UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION fn_audit_employees_update();验证审计功能。
执行一次更新操作,然后查询审计日志表。
-- 模拟一次更新 UPDATE employees SET salary = salary * 1.1 WHERE employee_id = 101;查询
audit_log表,是否会自动新增一条记录,包含执行更新操作的用户的环境信息。SELECT * FROM audit_log;预期返回结果如下:
log_id | table_name | os_user | client_ip | session_id | change_time --------+------------+----------+---------------------+------------+-------------------------------- 1 | employees | postgres | 172.xxx.xxx.xxx/xxx | 30 | 2025-10-17 07:41:50.666905 +00
属性详解
SYS_CONTEXT函数通过不同的参数获取多样的会话信息。属性名不区分大小写。
用户和会话信息
属性名 | 详细说明 | 示例 |
| 当前有效用户。 | |
| 会话初始用户。即客户端初始连接时进行身份验证的用户名,在整个会话期间保持不变。 | |
| 当前有效用户的ID。 | |
| 会话初始用户的ID。 | |
| 连接到数据库服务器的客户端操作系统用户名。 | |
| 判断当前用户是否为数据库超级管理员(Superuser)。 | |
会话标识信息
属性名 | 详细说明 | 示例 |
| 会话标识符,通常是数据库后端的进程ID(PID)。两者功能相同,互为别名。 | |
| ||
| 客户端标识符。 | |
| 客户端信息。 | |
数据库和模式信息
属性名 | 详细说明 | 示例 |
| 当前连接的数据库名称。 | |
| 数据库的唯一名称。 | |
| 当前默认的模式名称。 | |
| 会话模式名称。 | |
| 实例编号。 | |
| 实例名称。 | |
网络和连接信息
属性名 | 详细说明 | 示例 |
| 客户端的IP地址. | |
| 数据库服务器的主机地址。 | |
| 客户端的主机名。 | |
| 客户端的终端标识。 | |
应用程序信息
属性名 | 详细说明 | 示例 |
| 当前应用程序模块名。 | |
| 当前执行的操作名。 | |
| 数据库角色。 | |
语言和本地化信息
属性名 | 详细说明 | 示例 |
| 当前编码。 | |
| 完整的语言和区域设置。 | |
| 当前会话的日期显示格式。 | |
版本信息
属性名 | 详细说明 | 示例 |
| 会话版本ID。 | |
| 当前版本ID。 | |