Question
· Nov 21, 2024

Is it possible to check retroactive LOCK history?

Is it possible to check retroactive LOCK history?
 

context:

I found it in the application error log. Some LOCK errors - ERROR #5803
Is it possible to somehow identify the point in the job or process code that caused these locks?

At the moment I no longer have table LOCKS on the server, but I would like, if possible, to check the time at which the incidents occurred.

Discussion (1)2
Log in or sign up to continue

Hi @Davi Massaru Teixeira Muta ,

As far as i know, there is no lock log history.

This is understandable, as there would be a lot of them on heavily used systems.

If you can modify the application code, may be you can add log trace when this error happens.

With ^$LOCK you can retrieve the owner of a lock.

Example:

Lock +^my.global(1)
Write "Owner is : ", ^$LOCK($Name(^my.global(1)),"OWNER")
;Owner is : 5216

Even if you recover the PID, analysis can be difficult if the process no longer exists at the time you perform the analysis.  Maybe add something like this for logging (executed with a job):

/// Start this method in job ex:
/// Job ##class(pkg.ClassName).TraceLock($Name(^my.global))
ClassMethod TraceLock(lockname As %String) As %Status
{
    Set sc = $$$OK
    
    Set pid = ^$LOCK(lockname, "OWNER")
    If pid = "", $QLength(lockname)>0 {
        ; check if the node is fully locked
        Set pid = ^$LOCK($QSubscript(lockname,0), "OWNER")
    }
    
    If pid = "" {
        ; no data ...
        Return sc	
    }
    
    Set key = $Increment(^debug.locktrace)
    
    Set ^debug.locktrace(key, "from pid") = $ZParent	; Just to keep a trace of the pid started this job
    Set ^debug.locktrace(key, "info") = $ZDateTime($Horolog, 3, 1) _ " The lock " _ lockname _ " owner is "_pid
    
    Set process = ##CLASS(%SYS.ProcessQuery).Open(pid)
    If $IsObject(process) {
        Set ^debug.locktrace(key, "owner-UserName") = process.UserName
        Set ^debug.locktrace(key, "owner-StartupClientIPAddress") = process.StartupClientIPAddress
        Set ^debug.locktrace(key, "owner-StartupClientNodeName") = process.StartupClientNodeName
        Set ^debug.locktrace(key, "owner-CurrentLineAndRoutine") = process.CurrentLineAndRoutine
        Set ^debug.locktrace(key, "owner-Routine") = process.Routine
    }
    
    Return $$$OK
    
    ; Exemple of result:
    ;^debug.locktrace=1
    ;^debug.locktrace(1,"from pid")=12964
    ;^debug.locktrace(1,"info")="2024-11-22 12:25:25 The lock ^my.global owner is 5216"
    ;^debug.locktrace(1,"owner-CurrentLineAndRoutine")=""
    ;^debug.locktrace(1,"owner-Routine")="shell"
    ;^debug.locktrace(1,"owner-StartupClientIPAddress")="127.0.0.1"
    ;^debug.locktrace(1,"owner-StartupClientNodeName")="TRM:"
    ;^debug.locktrace(1,"owner-UserName")="_SYSTEM"
}

Hope this help.

Lorenzo.