如何获得已获得锁的语句?

2020-09-06 12:47发布

点击此处---> 群内免费提供SAP练习系统(在群公告中)加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)您好,所有 我正在尝试在HANA...

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


您好,所有

我正在尝试在HANA中编写查询或脚本,该查询或脚本将显示有关系统中当前锁的详细信息,包括已获取该锁的SQL语句。 这是我到目前为止的内容:

选择
     BT.BLOCKED_CONNECTION_ID为"阻止的会话",
     TR.CONNECTION_ID AS"阻止会话",
     BT.BLOCKED_TIME AS为"开始",
     SECONDS_BETWEEN(BT.BLOCKED_TIME,NOW())作为"长度",
     CN.CURRENT_SCHEMA_NAME AS"架构",
     CN.CLIENT_HOST ||  ''||
       CAST(CN.CLIENT_PID AS VARCHAR(5))AS"主机/PID",
     SC_AP.VALUE AS"程序",
     SC_AS.VALUE AS为"程序源",
     BT.TABLE_NAME AS为"锁定对象",
     BT.LOCK_OWNER_UPDATE_TRANSACTION_ID,
     PS.STATEMENT_STRING AS"锁定声明"
 来自SYS.M_BLOCKED_TRANSACTIONS_ BT
 加入SYS.M_TRANSACTIONS_ TR ON
     TR.HOST = BT.HOST和
     TR.PORT = BT.PORT AND
     TR.UPDATE_TRANSACTION_ID = BT.LOCK_OWNER_UPDATE_TRANSACTION_ID
 加入SYS.M_CONNECTIONS CN ON
     CN.HOST = TR.HOST AND
     CN.PORT = TR.PORT AND
     CN.CONNECTION_ID = TR.CONNECTION_ID
 JOIN M_SESSION_CONTEXT SC_AP开启
     SC_AP.HOST = TR.HOST AND
     SC_AP.PORT = TR.PORT AND
     SC_AP.CONNECTION_ID = TR.CONNECTION_ID AND
     SC_AP.KEY ='应用程序'
 JOIN M_SESSION_CONTEXT SC_AS开启
     SC_AS.HOST = TR.HOST AND
     SC_AS.PORT = TR.PORT AND
     SC_AS.CONNECTION_ID = TR.CONNECTION_ID AND
     SC_AS.KEY ='APPLICATIONSOURCE'
 向左联接M_SERVICE_THREADS TH ON
     TH.UPDATE_TRANSACTION_ID = BT.LOCK_OWNER_UPDATE_TRANSACTION_ID
 LEFT JOIN M_PREPARED_STATEMENTS PS ON
     PS.CONNECTION_ID = TR.CONNECTION_ID AND
     -不起作用,因为TR.CURRENT_STATEMENT_ID为NULL:
     PS.STATEMENT_ID = TR.CURRENT_STATEMENT_ID 

此查询可正确显示所有内容,但最重要的字段(锁定语句始终为 NULL )除外。 如何提取已获得锁定的语句的文本?

由于我无法查明导致锁定的一个查询,因此我决定在阻塞转换中输出所有准备好的语句

/* ---------------------------查看当前锁---------------  ------------ */
 -用于分析HANA数据库中当前锁的一组查询:
 -1.锁定会议
 -2.在锁定会话中准备的SQL语句
 -3.锁定的会话及其当前的SQL语句

 -1.锁定连接:
 选择
     CN.CONNECTION_ID AS"阻止会话",
     SECONDS_BETWEEN(BC.MAXWAIT,NOW())AS"最长的等待时间,s",
     CN.CLIENT_HOST ||  ''||
       CAST(CN.CLIENT_PID AS VARCHAR(5))AS"主机/PID",
     SC_AP.VALUE AS"程序",
     SC_AS.VALUE AS"程序源"
 FROM-TODO:与M_BLOCKED_TRANSACTIONS中的LTR处理进行比较:
 (    选择
         TR.CONNECTION_ID,TR.HOST,TR.PORT,
         MIN(BT.BLOCKED_TIME)作为MAXWAIT
         来自SYS.M_BLOCKED_TRANSACTIONS_ BT
     加入SYS.M_TRANSACTIONS_ TR ON
         TR.HOST = BT.HOST和
         TR.PORT = BT.PORT AND
         TR.UPDATE_TRANSACTION_ID = BT.LOCK_OWNER_UPDATE_TRANSACTION_ID
     GROUP BY TR.CONNECTION_ID,TR.HOST,TR.PORT
 )
 加入SYS.M_CONNECTIONS CN ON
     CN.HOST = BC.HOST AND
     CN.PORT = BC.PORT AND
     CN.CONNECTION_ID = BC.CONNECTION_ID
 JOIN M_SESSION_CONTEXT SC_AP开启
     SC_AP.HOST = BC.HOST AND
     SC_AP.PORT = BC.PORT AND
     SC_AP.CONNECTION_ID = BC.CONNECTION_ID和
     SC_AP.KEY ='应用程序'
 JOIN M_SESSION_CONTEXT SC_AS开启
     SC_AS.HOST = BC.HOST AND
     SC_AS.PORT = BC.PORT AND
     SC_AS.CONNECTION_ID = BC.CONNECTION_ID和
     SC_AS.KEY ='APPLICATIONSOURCE'
 -TODO:按最长等待时间排序:此表和SQL语句列表
 ORDER BY CN.CONNECTION_ID;

 -2.锁定SQL语句:
 选择
     TR.CONNECTION_ID AS"阻止会话",
     PS.STATEMENT_STRING AS"声明"
 来自SYS.M_BLOCKED_TRANSACTIONS_ BT
 加入SYS.M_TRANSACTIONS_ TR ON
     TR.HOST = BT.HOST和
     TR.PORT = BT.PORT AND
     TR.UPDATE_TRANSACTION_ID = BT.LOCK_OWNER_UPDATE_TRANSACTION_ID
 JOIN SYS.M_CONNECTIONS CN ON-待办事项:此JOIN正确吗?
     CN.HOST = TR.HOST AND
     CN.PORT = TR.PORT AND
     CN.CONNECTION_ID = TR.CONNECTION_ID
 LEFT JOIN M_PREPARED_STATEMENTS PS ON
     PS.CONNECTION_ID = TR.CONNECTION_ID
 OR。BY TR.CONNECTION_ID,PS.LAST_EXECUTED_TIME;
    
 -3.锁定连接:
 选择
     BT.BLOCKED_CONNECTION_ID为"阻止的会话",
     TR.CONNECTION_ID AS"阻止会话",
     BT.BLOCKED_TIME AS为"锁定开始",
     SECONDS_BETWEEN(BT.BLOCKED_TIME,NOW())作为"长度,s",
     CN.CURRENT_SCHEMA_NAME AS"架构",
     PS.STATEMENT_STRING作为"声明",
     BT.TABLE_NAME AS为"锁定对象",
     CN.CLIENT_HOST ||  ''||
       CAST(CN.CLIENT_PID AS VARCHAR(5))AS"主机/PID",
     SC_AP.VALUE AS"程序",
     SC_AS.VALUE AS"程序源"
 来自SYS.M_BLOCKED_TRANSACTIONS_ BT
 加入SYS.M_TRANSACTIONS_ TR ON
     TR.HOST = BT.HOST和
     TR.PORT = BT.PORT AND
     TR.TRANSACTION_ID = BT.BLOCKED_TRANSACTION_ID
 加入SYS.M_CONNECTIONS CN ON
     CN.HOST = TR.HOST AND
     CN.PORT = TR.PORT AND
     CN.CONNECTION_ID = TR.CONNECTION_ID
 JOIN M_SESSION_CONTEXT SC_AP开启
     SC_AP.HOST = TR.HOST AND
     SC_AP.PORT = TR.PORT AND
     SC_AP.CONNECTION_ID = TR.CONNECTION_ID AND
     SC_AP.KEY ='应用程序'
 JOIN M_SESSION_CONTEXT SC_AS开启
     SC_AS.HOST = TR.HOST AND
     SC_AS.PORT = TR.PORT AND
     SC_AS.CONNECTION_ID = TR.CONNECTION_ID AND
     SC_AS.KEY ='APPLICATIONSOURCE'
 JOIN M_PREPARED_STATEMENTS PS ON
     PS.CONNECTION_ID = TR.CONNECTION_ID AND
     PS.STATEMENT_ID = TR.CURRENT_STATEMENT_ID; 

但是我的问题仍然存在,因为这种方法非常笨拙,并且如测试所示,并不可靠。

1条回答
me_for_i
2020-09-06 13:38

没有找到更好的解决方案,我被迫输出 M_PREPARED_STATEMENTS 中可用的任何阻塞会话语句:

/*//////////////用于分析和记录HANA中的锁定的设施///////////////*/

/* =================查看当前锁的存储过程================ */

/* ------------------------------表类型----------------  --------------- */
 删除类型GT_LOCKING_SSN_T;
 按表创建类型GT_LOCKING_SSN_T
 (" BlockingSession" INT,
     " MaxWait_sec" BIGINT,
     "架构" NVARCHAR(256),
     " ClientHost" NVARCHAR(256),
     " ClientPID" BIGINT,
     "程序" NVARCHAR(5000),
     " ProgramSrc" NVARCHAR(5000)
 );

 删除类型GT_LOCKING_STMT_T;
 按表创建类型GT_LOCKING_STMT_T
 ("订单" BIGINT,
     " BlockingSession" INT,
     "声明" NVARCHAR(5000)
 );

 拖放类型GT_LOCKED_SSN_T;
 按表创建类型GT_LOCKED_SSN_T
 (" BlockedSession" INT,
     " BlockingSession" INT,
     " LockStart" TIMESTAMP,
     " Wait_sec" BIGINT,
     "架构" NVARCHAR(256),
     "声明" NVARCHAR(5000),
     " LockObject" NVARCHAR(256),
     " ClientHost" NVARCHAR(256),
     " ClientPID" BIGINT,
     "程序" NVARCHAR(5000),
     " ProgramSrc" NVARCHAR(5000)
 );

/* --------------------查看当前锁的步骤--------------------- */
 DROP PROCEDURE GT_VIEW_LOCKS;
 建立程序GT_VIEW_LOCKS
 (IN minwait_sec INT,
     OUT锁定_ssn GT_LOCKING_SSN_T,
     OUT锁定_stmt GT_LOCKING_STMT_T,
     OUT锁定_ssn GT_LOCKED_SSN_T
 )
 AS Locked_ssn_int表
     (HOST VARCHAR(64),
         INT港
         CONNECTION_ID INT,
         LOCKER_SSN INT,
         BLOCKED_TIMETIMESTAMP
     );
 开始
     locked_ssn_int =
     选择
         BT.HOST,BT.PORT,BT.BLOCKED_CONNECTION_ID和CONNECTION_ID,
         TR.CONNECTION_ID AS LOCKER_SSN,
         BT.BLOCKED_TIME
     来自SYS.M_BLOCKED_TRANSACTIONS_ BT
     加入SYS.M_TRANSACTIONS_ TR ON
         TR.HOST = BT.HOST和
         TR.PORT = BT.PORT AND
         TR.UPDATE_TRANSACTION_ID = BT.LOCK_OWNER_UPDATE_TRANSACTION_ID
     WHERE SECONDS_BETWEEN(BT.BLOCKED_TIME,NOW())>:minwait_sec;
    
     locked_ssn =
     选择
         LKSSN.CONNECTION_ID AS" BlockedSession",
         LKSSN.LOCKER_SSN作为" BlockingSession",
         LKSSN.BLOCKED_TIME AS为" LockStart",
         SECONDS_BETWEEN(BT.BLOCKED_TIME,NOW())如" Wait_sec",
         CN.CURRENT_SCHEMA_NAME AS"架构",
         CAST(PS.STATEMENT_STRING AS NVARCHAR(5000))作为"语句",
         BT.TABLE_NAME AS为" LockObject",
         CN.CLIENT_HOST AS" ClientHost",
         CN.CLIENT_PID AS" ClientPID",
         SC_AP.VALUE AS"程序",
         SC_AS.VALUE AS" ProgramSrc"
     来自:locked_ssn_int LKSSN
     加入SYS.M_BLOCKED_TRANSACTIONS_ BT ON
         BT.HOST = LKSSN.HOST和
         BT.PORT = LKSSN.PORT AND
         BT.BLOCKED_CONNECTION_ID = LKSSN.CONNECTION_ID
     加入SYS.M_CONNECTIONS CN ON
         CN.HOST = LKSSN.HOST和
         CN.PORT = LKSSN.PORT AND
         CN.CONNECTION_ID = LKSSN.CONNECTION_ID
     加入SYS.M_TRANSACTIONS_ TR ON
         TR.HOST = BT.HOST和
         TR.PORT = BT.PORT AND
         TR.TRANSACTION_ID = BT.BLOCKED_TRANSACTION_ID
     JOIN M_SESSION_CONTEXT SC_AP开启
         SC_AP.HOST = LKSSN.HOST和
         SC_AP.PORT = LKSSN.PORT AND
         SC_AP.CONNECTION_ID = LKSSN.CONNECTION_ID和
         SC_AP.KEY ='应用程序'
     JOIN M_SESSION_CONTEXT SC_AS开启
         SC_AS.HOST = LKSSN.HOST和
         SC_AS.PORT = LKSSN.PORT AND
         SC_AS.CONNECTION_ID = LKSSN.CONNECTION_ID和
         SC_AS.KEY ='APPLICATIONSOURCE'
     JOIN M_PREPARED_STATEMENTS PS ON
         PS.CONNECTION_ID = TR.CONNECTION_ID AND
         PS.STATEMENT_ID = TR.CURRENT_STATEMENT_ID;

     locking_ssn =
     选择
         CN.CONNECTION_ID AS" BlockingSession",
         SECONDS_BETWEEN(LKSSN.MAXWAIT,NOW())AS" MaxWait_sec",
         CN.CURRENT_SCHEMA_NAME AS"架构",
         CN.CLIENT_HOST AS" ClientHost",
         CN.CLIENT_PID AS" ClientPID",
         SC_AP.VALUE AS"程序",
         SC_AS.VALUE AS" ProgramSrc"
     FROM-TODO:与M_BLOCKED_TRANSACTIONS中的LTR处理进行比较:
     (SELECT HOST,PORT,LOCKER_SSN,MIN(BLOCKED_TIME)AS MAXWAIT
         从:locked_ssn_int
         按主机,端口,LOCKER_SSN分组
     )
     加入SYS.M_CONNECTIONS CN ON
         CN.HOST = LKSSN.HOST和
         CN.PORT = LKSSN.PORT AND
         CN.CONNECTION_ID = LKSSN.LOCKER_SSN
     JOIN M_SESSION_CONTEXT SC_AP开启
         SC_AP.HOST = CN.HOST AND
         SC_AP.PORT = CN.PORT AND
         SC_AP.CONNECTION_ID = CN.CONNECTION_ID和
         SC_AP.KEY ='应用程序'
     JOIN M_SESSION_CONTEXT SC_AS开启
         SC_AS.HOST = CN.HOST AND
         SC_AS.PORT = CN.PORT AND
         SC_AS.CONNECTION_ID = CN.CONNECTION_ID并且
         SC_AS.KEY ='APPLICATIONSOURCE'
     ORDER BY CN.CONNECTION_ID;
    
     locking_stmt =
     选择
         ROW_NUMBER()个(按PS.LAST_EXECUTED_TIME的顺序)为"订单",
         LKSSN。" BlockingSession" AS" BlockingSession",
         CAST(PS.STATEMENT_STRING AS NVARCHAR(5000))AS"语句"
     来自:locking_ssn LKSSN
     LEFT JOIN M_PREPARED_STATEMENTS PS ON
         PS.CONNECTION_ID = LKSSN。" BlockingSession"
     LKSSN的订单。" BlockingSession",PS.LAST_EXECUTED_TIME;
 结束;

/* ==========================记录锁================  ========== */

/* ---------------------------记录表------------------  --------- */

 删除表GT_LOCKING_SSN;
 创建表GT_LOCKING_SSN
 ("快照"时间戳,
     " BlockingSession" INT,
     " MaxWait_sec" BIGINT,
     "架构" NVARCHAR(256),
     " ClientHost" VARCHAR(64),
     " ClientPID" BIGINT,
     "程序" NVARCHAR(5000),
     " ProgramSrc" NVARCHAR(5000)
 );

 删除表GT_LOCKING_STMT;
 创建表GT_LOCKING_STMT
 ("快照"时间戳,
     "订单" BIGINT,
     " BlockingSession" INT,
     "声明" NVARCHAR(5000)
 );

 删除表GT_LOCKED_SSN;
 创建表GT_LOCKED_SSN
 ("快照"时间戳,
     " BlockedSession" INT,
     " BlockingSession" INT,
     " LockStart" TIMESTAMP,
     " Wait_sec" BIGINT,
     "架构" NVARCHAR(256),
     "声明" NVARCHAR(5000),
     " LockObject" NVARCHAR(256),
     " ClientHost" NVARCHAR(256),
     " ClientPID" BIGINT,
     "程序" NVARCHAR(5000),
     " ProgramSrc" NVARCHAR(5000)
 );

/* ---------将当前锁写入日志表的过程--------- */

 DROP PROTEDED GT_LOG_LOCKS;
 创建过程GT_LOG_LOCKS(IN minwait_sec INT)
 AS锁定_ssn GT_LOCKING_SSN_T;
     locking_stmt GT_LOCKING_STMT_T;
     GT_LOCKED_SSN_T;
     快照TIMESTAMP;
 开始
     快照:= NOW();
     呼叫GT_VIEW_LOCKS(:minwait_sec,locking_ssn,locking_stmt,locked_ssn);
    
     插入GT_LOCKING_SSN
     选择
         :snapshot," BlockingSession"," MaxWait_sec","架构",
         " ClientHost"," ClientPID","程序"," ProgramSrc"
     从:locking_ssn;
    
     插入GT_LOCKING_STMT
     选择
         :快照,"订单"," BlockingSession","声明"
     从:locking_stmt;
        
     插入GT_LOCKED_SSN
     选择
         :snapshot," BlockedSession"," BlockingSession"," LockStart",
         " Wait_sec"," Schema"," Statement"," LockObject",
         " ClientHost"," ClientPID","程序"," ProgramSrc"
     从:locked_ssn;
 结束;

/* ------------------从Cron运行的示例Bash脚本----------------------
/usr/sap/hdbclient/hdbsql \
     -s本地主机-i 0 -u系统-p Hana1234 \
     <<<"呼叫SBOCOMMON.GT_LOG_LOCKS(30);"  \
     2>&1 1>/dev/null
 */

/* ----------------------------测试代码-----------------  ---------- */
/*
 呼叫GT_VIEW_LOCKS(1,?,?,?);
 调用GT_LOG_LOCKS(1);

 SELECT * FROM GT_LOCKING_SSN;
 SELECT * FROM GT_LOCKING_STMT;
 SELECT * FROM GT_LOCKED_SSN;

 从GT_LOCKING_SSN删除;
 从GT_LOCKING_STMT删除;
 从GT_LOCKED_SSN删除;
 */

一周热门 更多>