注册
strace诊断disql登陆卡住问题
专栏/技术分享/ 文章详情 /

strace诊断disql登陆卡住问题

codePanda 2025/10/31 268 0 0
摘要

总结:disql在登录时会自动在当前工作目录或DM_SQLPATH指定路径下执行login.sql初始化脚本,在/home/dmdba/dmscript目录正好有配置的Oracle login.sql脚本,里面存在一些sql不兼容导致disql登录过程卡住,移除mv login.sql login.sql.bak后恢复正常。

问题描述

在自己的测试环境遇到一个问题,DM8使用disql登录在其他目录没有问题,在/home/dmdba/dmscripts目录登录会卡住,需要按几下Ctrl+C或者回车才能进去,如下图:
image.png

问题诊断

想知道disql连接数据中间发生了什么,卡在了那里,我们需要了解disql的系统调用,strace是常用的跟踪进程系统调用的工具了。可以根据进程号strace -p 6253跟踪,也可以像下面用strace命令在/home/dmdba/dmscripts目录下直接跟踪disql命令,看看究竟卡在了那里

strace -o disql_trace.log -T -tt -f -s 1000 disql / as sysdba

image.png
跟踪最后一直在报futex 调用 ETIMEDOUT (Connection timed out),多线程互斥可能是因为获取不到资源。从前看,在开始登陆有报大量的No such file or directory,猜测问题出在文件缺失或者缺少权限等。
image.png
接着使用strace-e trace=file 参数只跟踪有关文件操作的系统调用

strace -f -e trace=file disql / as sysdba

image.png
在最后发现disql 自动执行了当前目录下这些 SQL 脚本文件(login.sql, init.sql, htmlset.sql, htmlset2.sql, i.sql),然后挂起。 移除mv login.sql login.sql.bak后恢复正常。

问题原因

/home/dmdba/dmscripts目录下的文件是之前在Oracle产品上用的sql脚本,有一部分和DM8是兼容的所以直接拷贝过来了。在disql登录初始化的时候用到一个login.sql文件,并且文件里引用了其他 SQL 脚本,而这些脚本中某一处 SQL 执行卡住。

[dmdba@panda101:/home/dmdba/dmscripts]$ cat login.sql.bak -- calling init.sql which will set up sqlpus variables @@init.sql -- i.sql is the "who am i" script which shows your session/instance info and -- also sets command prompt window/xterm title @@i.sql -- you can put your own login scripts here

在DM中DIsql在连接成功数据库时会自动运行两个配置文件 glogin.sql 和 login.sql。glogin.sql文件中的设置永久生效,该配置文件需要用户自行创建在DM_HOME/bin/disql_conf路径下,其中DM_HOME 为 DM 的安装目录,需要用户在操作系统配置 DM_HOME 环境变量,disql_conf 目录需要用户自行创建。login.sql 文件为用户自定义配置文件,对其存放路径不做限制。
glogin.sql 文件和 login.sql 文件的执行顺序如下:

  1. 默认在 $DM_HOME/bin/disql_conf 路径下查找 glogin.sql 文件并执行;
  2. 默认在当前工作目录下(注意不是 DIsql 工具所在的目录,而是启动 DIsql 时所在的目录)查找 login.sql 文件并执行,若未找到则执行步骤 3;
  3. 判断操作系统是否配置了 DM_SQLPATH 环境变量,如果配置了该变量则在对应路径下查找 login.sql 文件并执行。
    DIsql 执行上述配置文件时并不会在 DIsql 窗口打印信息,如果没有找到上述配置文件则忽略。
    glogin.sql
[dmdba@panda101:/u01/dm/bin/disql_conf]$ cat glogin.sql -- 显示密钥过期时间 column expired_date new_value _edate select to_char(expired_date,'yyyy-mm-dd') expired_date from v$license; host echo "密钥过期时间:&_edate" -- 设置dbms_output输出缓冲区大小 set serveroutput on size 1000000 -- 设置输出格式 set long 200 set linesize 500 set pagesize 5000 -- 去除重定向输出每行拖尾空格 set trimspool on -- 去除行号显示 set lineshow off -- 显示当前连接信息 col name new_value _dname select name from v$database; col port_num new_value _port select para_value port_num from v$dm_ini where para_name='PORT_NUM'; set SQLPROMPT "_USER'@'_dname':'_port SQL> " -- 显示当前时间 set time on set ver off set echo off

经测试DM_SQLPATH环境变量和Oracle的SQLPATH不一样,DM只对login.sql生效,并不会识别到其他的脚本,会报错fail to open include file [us]

export DM_SQLPATH=/home/dmdba/dmscripts export SQLPATH=/home/dmdba/dmscripts dmdba@DAMENG:5236 SQL> @us panda fail to open include file [us] dmdba@DAMENG:5236 SQL> @us.sql panda fail to open include file [us.sql]
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服