当前等待时间诊断一例

1、查看当前events,比如发现row lock contention 偏高,可能是想加锁,但是有别的session占着,所以等待。
SQL> select event,count(*) from v$session_wait where event not like 'SQL*%' and event not like 'rdbms%' group by event order by count(*);
SQL> select event,sid,p1,p2,p3 from gv$session_wait where event not like 'SQL*%' and event not like 'rdbms%';
EVENT                                   SID     P1             P2             P3
----------------------------------      ----    ----------     ----------     ----------
enq: TX - row lock contention     101     1415053318     196638       55836
RMAN backup & recovery I/O       5       1              256       2147483647
enq: TX - row lock contention     993     1415053318     524293         51153
RMAN backup & recovery I/O     25      1              256       2147483647
db file sequential read             27      16             2876703         1




2、下面我们通过查看事件enq: TX - row lock contention来看看这些session都在等什么
SQL> select ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW# from v$session where event='enq: TX - row lock contention';
ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW#
------------- -------------- --------------- -------------
        87549             19         3200776            13
        87549              6         3385926            39


3、通过上面sql查找出来的对象编号找到对应的对象名称
SQL> select object_name from dba_objects where object_id in (87549);


OBJECT_NAME
--------------------------------------------------------------------------------------------------------------------------------
PMUSRINF


4、通过对象名称找出该对象的对应属性,对象属性为TABLE
SQL>  select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID, OBJECT_TYPE from all_objects where object_name='PMUSRINF';


OWNER                          OBJECT_NAME                     OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ------------------------------ ---------- -------------- -------------------
NEWSDUSER                      PMUSRINF                            87549          87549 TABLE


5、通过正在等待的SID查看它们都在执行什么操作
SQL> select sid,sql_text from v$session a,v$sql b where sid in(101,993) and (b.sql_id=a.sql_id or b.sql_id=a.prev_sql_id);
       SID SQL_TEXT
---------- ----------------------------------------------------------------------------------------------------------------------------------
       101 select opeip as last_ip, TO_CHAR (TO_DATE (operdate || opetime, 'yyyyMMddHH24miss'),                 'yyyy-MM-dd HH24:mi:ss')
                 AS last_login_time  from LIMOPEREC  where opeid='U201502110739'  and opetype='03'  and operec=(
                  select max(operec) from LIMOPEREC  where opeid='U201502110739'  and opetype='03'                                      )


       101 update PMUSRINF set random = 'oucqhmncas' where user_id = 'U201502110739'
       993 SELECT FJPATH FROM FJ WHERE instr(FJPATH,'/posa/dat/upload/201604/05/03055225/20160405095215.jpg') > 0


6、下面我们去找一下对应sid产生的锁
SQL> select SID,TY,ID1,ID2,LMODE,REQUEST,CTIME,BLOCK from V$lock where block=1 or request<>0;


解决方法:
1:通过v$session找到BLOCK=1的用户,告知用户提交事务
2:通过sid找到pid,kill掉该进程
3:更改sql语句,SELECT ... FOR UPDATE no wait





<think>我们正在处理用户关于CAPL语言中UDS诊断例程或脚本的查询。用户希望获得示例脚本或例程。根据提供的引用,特别是引用[4]和引用[5],我们可以提取一些相关的代码片段和思路。引用[4]提到使用CAPL脚本进行UDS诊断自动化测试,可以节省大量时间。引用[5]则展示了一个动态生成测试用例的示例,用于通过数据标识符(DID)读取数据。因此,我们可以为用户提供一个简单的CAPL脚本示例,该示例展示了如何发送一个UDS请求(例如读取数据标识符)并处理响应。此外,我们还可以展示如何组织多个测试用例。以下是一个基本的CAPL脚本示例,用于发送UDS请求(以读取数据标识符0xF190为例)并处理响应:```c//定义变量variables{//定义诊断请求消息diagRequestReadDIDReqreadDIDReq;bytegResponseData[4096];//用于存储响应数据longgRespLength;//响应数据长度msTimerdelayTimer;//延时计时器inttestStep=0;//测试步骤控制}//主测试函数testcaseTC_ReadDID_F190(){//初始化请求:读取数据标识符0xF190readDIDReq.SetService(0x22);//0x22是读取数据标识符的服务IDreadDIDReq.SetParameter(0xF190);//设置要读取的DID//发送请求diagSendRequest(readDIDReq);testStep=1;//设置一个超时计时器,等待响应setTimer(delayTimer,2000);//等待2秒}//处理诊断响应事件ondiagResponsereadDIDReq{//获取响应数据gRespLength=diagGetLastResponse(readDIDReq,gResponseData,elCount(gResponseData));//检查响应是否为正响应(第一个字节为0x62,表示正响应)if(gRespLength>0&&gResponseData[0]==0x62){write("读取DID0xF190成功!响应数据:");//打印响应数据(跳过服务ID和DID,实际数据从第3个字节开始)for(inti=2;i<gRespLength;i++){write("%02X",gResponseData[i]);}write("\n");}else{write("读取DID0xF190失败!响应码:%02X",gResponseData[0]);}//停止计时器cancelTimer(delayTimer);testStep=0;}//超时处理ontimerdelayTimer{if(testStep==1){write("等待DID0xF190的响应超时!");testStep=0;}}```如果用户需要同时测试多个DID,可以如引用[5]所示动态生成测试用例:```cvariables{//定义测试数据:DID值,期望数据(可选),超时时间structTestData{worddataIdentifier;byteexpectedData[];//可选,用于比较longtimeout;};TestDatadynamicTestCases[]={{0xF190,{},2000},{0xF1A0,{},2000}};}//动态生成测试用例testcase*GenerateTestCases(){chartcName[64];inti;for(i=0;i<elCount(dynamicTestCases);i++){snprintf(tcName,elCount(tcName),"TC_ReadDID_0x%04X",dynamicTestCases[i].dataIdentifier);testcasetcName{ReadDataByIdentifier(dynamicTestCases[i]);}}}//读取数据标识符的函数voidReadDataByIdentifier(TestDatadata){diagRequestReadDIDReqreq;byteresponseData[4096];longrespLength;req.SetService(0x22);req.SetParameter(data.dataIdentifier);diagSendRequest(req);//等待响应或超时setTimer(delayTimer,data.timeout);testStep=1;currentTestData=data;//保存当前测试数据(需要定义currentTestData为全局变量)}//在ondiagResponse事件中处理响应(需要根据currentTestData进行比较)```注意:上述代码仅为示例,实际使用时需要根据具体环境调整。例如,动态生成测试用例的部分需要结合测试模块的结构,并且需要定义全局变量来跟踪当前测试用例的数据。此外,引用[2]提到,在CAPL中,通过传入诊断请求对象(diagRequest)来获取诊断响应的参数值,因为CDD文件中已经定义了对应的诊断响应。因此,建议用户确保在CANoe工程中正确加载了诊断数据库(CDD文件),这样CAPL脚本才能正确解析诊断请求和响应。相关问题:1.如何在CAPL中加载CDD文件以支持UDS诊断?2.除了读取数据标识符(0x22),CAPL中如何实现其他UDS服务(如写入DID、会话控制等)?3.如何用CAPL脚本生成UDS诊断测试报告?4.在CAPL中如何处理UDS否定响应码(NRC)?</think>### CAPL UDS诊断示例脚本 以下是一个完整的CAPL脚本示例,用于实现UDS诊断服务(以读取数据标识符0xF190为例): ```c variables { diagRequest DIDReq ReadDIDReq; // 声明诊断请求对象 byte responseData[4096]; // 存储响应数据 long respLength; // 响应数据长度 msTimer timeoutTimer; // 超时计时器 } // 发送诊断请求函数 void SendReadDIDRequest(word dataIdentifier) { DIDReq.SetService(0x22); // 设置服务ID:读取数据标识符(0x22) DIDReq.SetParameter(dataIdentifier); // 设置DID参数 diagSendRequest(DIDReq); // 发送诊断请求 setTimer(timeoutTimer, 2000); // 设置2秒超时 write("发送读取DID请求: 0x%04X", dataIdentifier); } // 处理诊断响应 on diagResponse DIDReq { cancelTimer(timeoutTimer); // 取消超时计时器 // 获取响应数据 respLength = diagGetLastResponse(DIDReq, responseData, elCount(responseData)); if (respLength > 0) { // 检查响应类型:首字节=0x62表示肯定响应 if (responseData[0] == 0x62) { write("成功读取DID 0x%04X", DIDReq.GetParameter()); write("响应数据: %02X %02X %02X...", responseData[1], responseData[2], responseData[3]); } else { // 否定响应处理(首字节=0x7F) write("否定响应! NRC: 0x%02X", responseData[2]); } } } // 超时处理 on timer timeoutTimer { write("错误: 读取DID 0x%04X超时!", DIDReq.GetParameter()); } // 测试用例示例 testcase ReadDID_F190() { SendReadDIDRequest(0xF190); // 读取特定DID testWaitForDiagResponse(3000); // 等待响应 } ``` ### 关键功能说明: 1. **诊断请求设置** - 使用 `SetService(0x22)` 设置读取数据标识符服务 - `SetParameter()` 指定要读取的DID(如0xF190) 2. **响应处理** - 肯定响应:首字节为0x62(服务ID+0x40) - 否定响应:首字节为0x7F,第三字节为否定响应码(NRC) - 使用 `diagGetLastResponse()` 获取完整响应数据 3. **超时管理** - 通过`msTimer`实现2000ms超时检测 - 超时触发错误处理流程 4. **测试用例集成** - `testcase`关键字定义自动化测试用例 - `testWaitForDiagResponse()`同步等待响应 ### 动态测试用例生成(引用[5]改进版) ```c variables { struct TestData { word did; long timeout; }; TestData testCases[] = { {0xF190, 2000}, {0xF1A0, 1500}, {0xE020, 3000} }; } testcase* GenerateTestCases() { char tcName[32]; for(int i=0; i<elCount(testCases); i++) { snprintf(tcName, elCount(tcName), "TC_ReadDID_0x%04X", testCases[i].did); testcase tcName { SendReadDIDRequest(testCases[i].did); testWaitForDiagResponse(testCases[i].timeout); } } } ``` ### 实际应用建议: 1. **诊断数据库集成** 在CANoe中加载CDD/ODX诊断描述文件后,可直接使用预定义的诊断服务对象[^2][^3]: ```c diagRequest *req = diagGetRequest("ReadDataByIdentifier"); req.SetParameter("DID_F190"); // 使用数据库定义的参数名 ``` 2. **测试报告生成** 添加测试结果记录: ```c on diagResponse DIDReq { if(responseData[0] == 0x62) { testStepPass("DID读取成功"); } else { testStepFail("失败NRC:0x%02X", responseData[2]); } } ``` 3. **多会话控制** 扩展会话处理示例: ```c void EnterExtendedSession() { diagRequest sessionReq = diagGetRequest("DiagnosticSessionControl"); sessionReq.SetParameter(0x03); // 扩展会话 diagSendRequest(sessionReq); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值