You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Informix连接会话对应的数据库服务器名称或别名?

问题描述

在AIX系统上运行Informix Dynamic Server Version 11.50,服务器配置了多个DB Server Aliases,分别监听不同TCP端口,sqlhosts文件内容如下:

# dbservername     nettype    hostname         servicename        options
# DBSERVERNAME
infx_1             onsoctcp   host             port1
# DBSERVERALIASES
infx_2             onsoctcp   host             port2
infx_3             onsoctcp   host             port3

为记录数据库连接信息,使用了如下存储过程:

CREATE PROCEDURE public.sysdbopen()

    -- Log session details on database connection
    -- Doug Lawry, Oninit Consulting, August 2020

    DEFINE session, process INTEGER;
    DEFINE dbname, client, program VARCHAR(255);

    -- Continue calling session after any error
    ON EXCEPTION
        RETURN;
    END EXCEPTION;

    -- Ignore high frequency or system users
    IF USER IN ('no_exceptions_for now') THEN
        RETURN;
    END IF

    LET session = DBINFO('sessionid');
    LET dbname = TRIM(DBINFO('dbname'));

    SELECT pid, TRIM(hostname), TRIM(feprogram)
    INTO process, client, program
    FROM sysmaster:informix.syssessions
    WHERE sid = session;

    SYSTEM
        'echo ' || '"' ||
        CURRENT :: DATETIME YEAR TO SECOND || '|' ||
        session || '|' ||
        dbname  || '|' ||
        USER    || '|' ||
        client  || '|' ||
        process || '|' ||
        program || '|"' ||
        ' >> $INFORMIXDIR/logs/connection.log';

END PROCEDURE;

该存储过程能获取大部分所需信息,但无法区分连接时使用的是DB Server Name还是某个DB Server Aliases。尝试过DBSERVERNAME/SITENAME,但始终返回DB Server Name,即便连接用的是别名。需要找到方法获取该信息并添加到日志中。

解决方案

在Informix 11.50中,没有直接的内置函数可以获取连接时使用的服务器别名,但可以通过以下两种方式实现需求:

方法1:通过端口关联sqlhosts中的别名

每个DB Server Aliases对应唯一的TCP端口,因此可以通过会话使用的监听端口,反向匹配sqlhosts文件中的别名:

修改后的存储过程示例:

CREATE PROCEDURE public.sysdbopen()

    DEFINE session, process, port_num INTEGER;
    DEFINE dbname, client, program, sqlhosts_path VARCHAR(255);

    ON EXCEPTION
        RETURN;
    END EXCEPTION;

    IF USER IN ('no_exceptions_for now') THEN
        RETURN;
    END IF

    LET session = DBINFO('sessionid');
    LET dbname = TRIM(DBINFO('dbname'));
    LET sqlhosts_path = '$INFORMIXDIR/etc/sqlhosts'; -- 若sqlhosts在自定义路径,替换此处

    -- 获取会话进程ID、客户端地址和程序名
    SELECT pid, TRIM(hostname), TRIM(feprogram)
    INTO process, client, program
    FROM sysmaster:informix.syssessions
    WHERE sid = session;

    -- 获取当前会话对应的监听端口
    SELECT s_port
    INTO port_num
    FROM sysmaster:informix.sysnetstat
    WHERE s_pid = process
      AND s_type = 'listen';

    -- 写入日志,同时从sqlhosts匹配端口对应的别名
    SYSTEM
        'echo ' || '"' ||
        CURRENT :: DATETIME YEAR TO SECOND || '|' ||
        session || '|' ||
        dbname  || '|' ||
        USER    || '|' ||
        client  || '|' ||
        process || '|' ||
        program || '|' ||
        '$(awk ''$4 == "' || port_num || '" {print $1}'' ' || sqlhosts_path || ')' || '|"' ||
        ' >> $INFORMIXDIR/logs/connection.log';

END PROCEDURE;

补充说明

  • 如果sqlhosts中使用的是服务名而非直接端口号,需要先解析服务名对应的端口,可将awk命令改为:
    $(awk ''$4 == "' || servicename || '" {print $1}'' ' || sqlhosts_path || ' | xargs getservbyname | awk ''{print $2}''')
    
  • 确保Informix运行用户有读取sqlhosts文件的权限

方法2:为每个别名配置独立的标识逻辑

如果应用可以配合调整连接参数,可以为每个别名设置独立的环境变量或逻辑库,在sysdbopen中读取该变量直接写入日志。比如:

  • 应用连接infx_2时,设置环境变量CONNECT_ALIAS=infx_2
  • 在存储过程中添加LET alias_name = TRIM(ENVIRONMENT('CONNECT_ALIAS'));,并将该变量写入日志

这种方法需要应用侧配合调整,灵活性较低,但实现更简单。

内容的提问来源于stack exchange,提问作者tjn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 12:00:56