Continue building reusable demo assets and technical narratives that actually help customers project themselves, not just admire the tech.

Sylvain Guilbaud · Aug 7, 2025 go to post

Hi Tanguy,

happy to hear you've finally fixed it.

Again, %ZSTART is not at all mandatory ; as soon as your ENV variables are available in your container you should be able to get it either from $system.Util.GetEnviron(env) or ##class(%SYS.Python).Import("os").getenv(env)

With these variables : 

{"Env": [
			"API_CLIENT_SECRET=ea5663885513e5b00df120fa4b4da8e1150398cde9d41ee27b5a8c6f1898dfa63ae711b82bf06b36475b646453a9092f5653895ddd2c3bb067d9a4f562a6b625",
			"TZ=Europe/Paris",
			"ISC_DATA_DIRECTORY=/irisdata",
			"ISC_CPF_MERGE_FILE=/app/merge.cpf",
			"API_CLIENT_ID=3e726f42daaa06a8",
			"ISC_PACKAGE_IRISGROUP=irisowner",
			"ISC_PACKAGE_IRISUSER=irisowner",
			"ISC_PACKAGE_MGRGROUP=irisowner",
			"ISC_PACKAGE_MGRUSER=irisowner",
			"IRISSYS=/home/irisowner/irissys",
			"TINI_VERSION=v0.19.0",
			"ISC_PACKAGE_INSTANCENAME=IRIS",
			"ISC_PACKAGE_INSTALLDIR=/usr/irissys",
			"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/irisowner/bin",
			"PYTHONPATH=/usr/irissys/mgr/python",
			"LANG=en_US.UTF-8",
			"LANGUAGE=en_US.UTF-8",
			"LC_ALL=en_US.UTF-8"
		]}

You should get :
 

write$SYSTEM.Util.GetEnviron("API_CLIENT_ID")
3e726f42daaa06a8
write$SYSTEM.Util.GetEnviron("API_CLIENT_SECRET")
ea5663885513e5b00df120fa4b4da8e1150398cde9d41ee27b5a8c6f1898dfa63ae711b82bf06b36475b646453a9092f5653895ddd2c3bb067d9a4f562a6b625
write$SYSTEM.Util.GetEnviron("TZ")
Europe/Paris
write##class(%SYS.Python).Import("os").getenv("API_CLIENT_ID")
3e726f42daaa06a8
write##class(%SYS.Python).Import("os").getenv("API_CLIENT_SECRET")
ea5663885513e5b00df120fa4b4da8e1150398cde9d41ee27b5a8c6f1898dfa63ae711b82bf06b36475b646453a9092f5653895ddd2c3bb067d9a4f562a6b625
write##class(%SYS.Python).Import("os").getenv("TZ")
Europe/Paris

Or, with %ZSTART containing :
 

ROUTINE %ZSTARTQUIT; Prevents direct execution without a label

SYSTEM ; Subroutine called at system startup; Initialize the IRIS application secretsSet^Secrets("API_CLIENT_ID") = $System.Util.GetEnviron("API_CLIENT_ID")
  Set^Secrets("API_CLIENT_ID","LastUpdated") = $ZDATETIME($HOROLOG,3)
  Set^Secrets("API_CLIENT_SECRET") = $System.Util.GetEnviron("API_CLIENT_SECRET")
  Set^Secrets("API_CLIENT_SECRET","LastUpdated") = $ZDATETIME($HOROLOG,3)
  QUIT

you should obtain :

IRISAPP>zw^Secrets^Secrets("API_CLIENT_ID")="3e726f42daaa06a8"^Secrets("API_CLIENT_ID","LastUpdated")="2025-08-07 17:16:19"^Secrets("API_CLIENT_SECRET")="ea5663885513e5b00df120fa4b4da8e1150398cde9d41ee27b5a8c6f1898dfa63ae711b82bf06b36475b646453a9092f5653895ddd2c3bb067d9a4f562a6b625"^Secrets("API_CLIENT_SECRET","LastUpdated")="2025-08-07 17:16:19"

IRISAPP>d SYSTEM^%ZSTART

IRISAPP>zw^Secrets^Secrets("API_CLIENT_ID")="3e726f42daaa06a8"^Secrets("API_CLIENT_ID","LastUpdated")="2025-08-07 17:24:02"^Secrets("API_CLIENT_SECRET")="ea5663885513e5b00df120fa4b4da8e1150398cde9d41ee27b5a8c6f1898dfa63ae711b82bf06b36475b646453a9092f5653895ddd2c3bb067d9a4f562a6b625"^Secrets("API_CLIENT_SECRET","LastUpdated")="2025-08-07 17:24:02"
Sylvain Guilbaud · Aug 6, 2025 go to post

Hi Tanguy,

in your environment variables I can see APIclientid and APIclientsecret but nothing called lifenclientid nor lifenclientsecret.

That's probably why you don't get any value.

Sylvain Guilbaud · Aug 6, 2025 go to post

Hi Tanguy,

%ZSTART routine is not mandatory. It's just an example of a way to retrieve and store data at instance startup. If it works you should see the results in   System  > Globals  > View Global Data > ^IRIS.Temp global.
If $System.Util.GetEnviron("APIclientid") works, it means that your environment variables are well configured.
Could you please share your business operation code ?

Sylvain Guilbaud · Jul 31, 2025 go to post

Hi @TAZ.R 
Environment variables set in the Docker container are only visible to processes that inherit the environment. 

You can rapidly check it from a terminal session : 

write$system.Util.GetEnviron("TZ")
Europe/Paris
write##class(%SYS.Python).Import("os").getenv("TZ")
Europe/Paris

Or from a simple Business Operation :

 

BusinessOperation env

Class operations.env Extends Ens.BusinessOperation
{

Method env(pRequest As Ens.StringContainer, Output pResponse As Ens.StringContainer) As%Status
{
    set sc=$$$OKTry {
        set env = pRequest.StringValue
        set value = $system.Util.GetEnviron(env)
        set pResponse = ##class(Ens.StringContainer).%New()
        set pResponse.StringValue = value
        $$$LOGINFO("Environment: "_env _":"_value)
    }
    Catch ex {
        Set tSC=ex.AsStatus()
        $$$LOGERROR("ERROR:" _ $system.Status.GetErrorText(tSC))
        set sc = tSC
    }

	return sc
}

Method pyenv(pRequest As Ens.StringRequest, Output pResponse As Ens.StringContainer) As%Status
{

    set sc=$$$OKTry {

        set env = pRequest.StringValue
        // Use Python to get the environment variableset value = ##class(%SYS.Python).Import("os").getenv(env)
        // Call the Python method to get the environment variable
        #; set value = ..getEnv(env) ; Uncomment this line if you want to use the Python method directlyset pResponse = ##class(Ens.StringContainer).%New()

        set pResponse.StringValue = value

        $$$LOGINFO("Environment: "_env _":"_value)

    }

    Catch ex {

        Set tSC=ex.AsStatus()

        $$$LOGERROR("ERROR:" _ $system.Status.GetErrorText(tSC))

        set sc = tSC

    }

	return sc
}

Method getEnv(env As%String) As%String [ Language = python ]
{
import os
value = os.getenv(env)
return value
}

XData MessageMap
{
<MapItems>
    <MapItem MessageType="Ens.StringContainer">
        <Method>env</Method>
    </MapItem>
    <MapItem MessageType="Ens.StringRequest">
        <Method>pyenv</Method>
    </MapItem>
</MapItems>
}

}

You could also store the content in a global at IRIS startup by creating the %ZSTART routine 

ROUTINE %ZSTARTQUIT; Prevents direct execution without a label

SYSTEM ; Subroutine called at system startupSet^IRIS.Temp("Secrets", $System.Util.GetEnviron("API_CLIENT_ID")) = $System.Util.GetEnviron("API_CLIENT_SECRET")
  QUIT

That way, you can retrieve your secret by executing this code:

$Get(^IRIS.Temp("Secrets", "your-client-id"), "")
 

Business Operation secret

Class operations.secrets Extends Ens.BusinessOperation
{

Method secret(pRequest As Ens.StringContainer, Output pResponse As Ens.StringContainer) As%Status
{
    set sc=$$$OKTry {
        set env = pRequest.StringValue
        set value = $Get(^IRIS.Temp("Secrets", env), "")
        set pResponse = ##class(Ens.StringContainer).%New()
        set pResponse.StringValue = value
        $$$LOGINFO("Environment: "_env _":"_value)
    }
    Catch ex {
        Set tSC=ex.AsStatus()
        $$$LOGERROR("ERROR:" _ $system.Status.GetErrorText(tSC))
        set sc = tSC
    }

	return sc
}

XData MessageMap
{
<MapItems>
    <MapItem MessageType="Ens.StringContainer">
        <Method>secret</Method>
    </MapItem>
</MapItems>
}

}
Sylvain Guilbaud · Jul 17, 2025 go to post

Thank you @Anastasia Dyubaylo for these guidelines which are always good to remember.

I don't know if this is intentional on your part to ensure that your article is properly read by the community, but a typo has crept in: %SYSTEM.JSON isn't an existing class in IRIS.

Or is this simply an unverified hallucination, which would prove that you yourself should be applying your recommendations for the proper use of generative AI?

I'd go with the first option 😊

Sylvain Guilbaud · Feb 18, 2025 go to post

You can also use the ":sql" alias to launch the SQL Shell :

USER>:sql
SQL Command Line Shell
----------------------------------------------------

The command prefix is currently set to: <<nothing>>.
Enter <command>, 'q' to quit, '?' for help.
[SQL]USER>>select sysdate
2.      select sysdate

| Expression_1 |
| -- |
| 2025-02-1813:39:24 |

1 Rows(s) Affected
statement prepare time(s)/globals/cmds/disk: 0.0928s/35,642/155,490/1ms
          execute time(s)/globals/cmds/disk: 0.0001s/3/408/0ms
                                query class: %sqlcq.USER.cls6
---------------------------------------------------------------------------
[SQL]USER>>quit

USER>

And just type ":?" to get the list of all the alias :

USER>:?
 :<number>    Recall command # <number>
 :py          Do$system.Python.Shell()
 :mdx         Do$system.DeepSee.Shell()
 :sql         Do$system.SQL.Shell()
 :tsql        Do$system.SQL.TSQLShell()
 :alias       Create/display aliases
 :unalias     Remove aliases
 :history     Display command history
 :clear       Clear history buffer
 :?           Display help
 Ctrl+R       Reverse incremental search

USER>
Sylvain Guilbaud · Jan 13, 2025 go to post

You can schedule the following task which removes any file from a directory, based on its age, using Python:

Class admin.purge Extends%SYS.Task.Definition
{

Property Directory As%String(MAXLEN = 2000) [ InitialExpression = "/usr/irissys/mgr/Backup" ];Property DaysToKeep As%Integer(VALUELIST = ",0,1,2,3,4,5") [ InitialExpression = "1" ];

Method OnTask() As%Status
{
    set sc = $$$OKTry {
        do..purge(..Directory,..DaysToKeep)
    }
    Catch ex {
        Set sc=ex.AsStatus()
    }
    return sc
}

ClassMethod purge(path As%String, daysToKeep As%Integer) As%Status [ Language = python ]
{
import iris
import os
import time
from datetime import datetime, timedelta

event = "[TASK PURGE OLD BACKUP FILES]"class FileDeletionError(Exception):
    """Custom exception for file deletion errors."""
    pass

def delete_old_files(path, days_limit):
    limit_date = datetime.now() - timedelta(days=int(days_limit))

    for file in os.listdir(path):
        file_path = os.path.join(path, file)
        if os.path.isfile(file_path):
            creation_date = datetime.fromtimestamp(os.path.getctime(file_path))
            if creation_date < limit_date:
                try:
                    os.remove(file_path)
                    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Deleted: {str(file_path)}")
                except PermissionError:
                    raise FileDeletionError(f"Permission error: Unable to delete {file}")
                except FileNotFoundError:
                    raise FileDeletionError(f"File not found: {file}")
                except Exception as e:
                    raise FileDeletionError(f"Unexpected error while deleting {file}: {str(e)}")

try:
    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Executing task to delete backup files from directory {path} created more than {str(daysToKeep)} days ago")
    days_limit = daysToKeep
    delete_old_files(path, days_limit)
except FileDeletionError as e:
    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Error during deletion: {str(e)}",0,1)
except Exception as e:
    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Unexpected error: {str(e)}",0,1)
}

}
01/13/25-18:21:00:549 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Executing task to delete backup files from directory /usr/irissys/mgr/Backup created more than 0 days ago
01/13/25-18:21:00:550 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_009.cbk
01/13/25-18:21:00:550 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_008.log
01/13/25-18:21:00:598 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_008.cbk
01/13/25-18:21:00:598 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_009.log
Sylvain Guilbaud · Jan 13, 2025 go to post

You can schedule the following task which removes any file from a directory, based on its age, using Python:

Class admin.purge Extends%SYS.Task.Definition
{

Property Directory As%String(MAXLEN = 2000) [ InitialExpression = "/usr/irissys/mgr/Backup" ];Property DaysToKeep As%Integer(VALUELIST = ",0,1,2,3,4,5") [ InitialExpression = "1" ];

Method OnTask() As%Status
{
    set sc = $$$OKTry {
        do..purge(..Directory,..DaysToKeep)
    }
    Catch ex {
        Set sc=ex.AsStatus()
    }
    return sc
}

ClassMethod purge(path As%String, daysToKeep As%Integer) As%Status [ Language = python ]
{
import iris
import os
import time
from datetime import datetime, timedelta

event = "[TASK PURGE OLD BACKUP FILES]"class FileDeletionError(Exception):
    """Custom exception for file deletion errors."""
    pass

def delete_old_files(path, days_limit):
    limit_date = datetime.now() - timedelta(days=int(days_limit))

    for file in os.listdir(path):
        file_path = os.path.join(path, file)
        if os.path.isfile(file_path):
            creation_date = datetime.fromtimestamp(os.path.getctime(file_path))
            if creation_date < limit_date:
                try:
                    os.remove(file_path)
                    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Deleted: {str(file_path)}")
                except PermissionError:
                    raise FileDeletionError(f"Permission error: Unable to delete {file}")
                except FileNotFoundError:
                    raise FileDeletionError(f"File not found: {file}")
                except Exception as e:
                    raise FileDeletionError(f"Unexpected error while deleting {file}: {str(e)}")

try:
    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Executing task to delete backup files from directory {path} created more than {str(daysToKeep)} days ago")
    days_limit = daysToKeep
    delete_old_files(path, days_limit)
except FileDeletionError as e:
    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Error during deletion: {str(e)}",0,1)
except Exception as e:
    iris.cls("%SYS.System").WriteToConsoleLog(f"{event} Unexpected error: {str(e)}",0,1)
}

}

The task logs its actions in messages.log :

01/13/25-18:21:00:549 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Executing task to delete backup files from directory /usr/irissys/mgr/Backup created more than 0 days ago
01/13/25-18:21:00:550 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_009.cbk
01/13/25-18:21:00:550 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_008.log
01/13/25-18:21:00:598 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_008.cbk
01/13/25-18:21:00:598 (35722) 0 [Utility.Event] [TASK PURGE OLD BACKUP FILES] Deleted: /usr/irissys/mgr/Backup/FullAllDatabases_20250113_009.log
Sylvain Guilbaud · Jul 9, 2024 go to post

And to answer your question, when you simply restart the Primary Linux server, the Backup member is automatically switching to become primary.

Below the messages.log from the Backup member while the Primary is restarting.

07/09/24-12:05:49:781 (6502) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 0 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-12:05:50:953 (6508) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 200088 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-12:05:51:076 (6362) 0 [Utility.Event] Retrieving journal file #7for mirror MIRROR from 192.168.102.130|2188...(repeated 1 times)
07/09/24-12:05:51:076 (6362) 0 [Utility.Event] GetECPSessionData: Got ECP data from agent len=107/09/24-12:05:51:076 (6362) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-12:05:51:185 (6362) 0 [Utility.Event] Found UBUNTU/IRIS as primary, becoming backup
07/09/24-12:05:51:186 (6362) 0 [Utility.Event] (MIRROR) Becoming a backup mirror member
07/09/24-12:05:51:445 (6510) 0 [Utility.Event] (MIRROR) Starting Mirror.Client("MIRROR-MIRROR-20240709.007",200088,7)
07/09/24-12:05:51:448 (6510) 0 [Generic.Event] MirrorClient: Connected to primary: UBUNTU/IRIS (ver 4)
07/09/24-12:05:51:458 (6512) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-12:05:52:737 (6510) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-12:05:56:740 (6510) 0 [Generic.Event] MirrorClient: The backup node has become active from a status query
07/09/24-12:05:59:766 (6517) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.006 from 262144 bytes to 81920 bytes, compression ratio = 3.207/09/24-12:06:17:920 (6377) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Backup
07/09/24-14:31:54:643 (6512) 2 [Utility.Event] Arbiter connection lost
07/09/24-14:31:55:304 (6362) 0 [Utility.Event] Skipping connection to arbiter while still in Arbiter Controlled failover mode.
07/09/24-14:31:55:419 (6510) 0 [Generic.Event] MirrorClient: Switched from Arbiter Controlled to Agent Controlled failover on request from primary
07/09/24-14:32:25:437 (6584) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-14:32:28:235 (6510) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-14:33:11:438 (6510) 1 [Generic.Event] MirrorClient: Primary AckDaemon failed to answer status request.
07/09/24-14:33:11:438 (6510) 0 [Generic.Event] MirrorClient: Backup waiting for old Dejournal Reader (pid: 6511, job #28) to exit
07/09/24-14:33:12:250 (6510) 0 [Generic.Event] MirrorClient: Set status for MIRROR to Transition
07/09/24-14:33:12:254 (6362) 0 [Utility.Event] Backup taking over for primary in arbiter controlled mode
07/09/24-14:33:12:304 (6589) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 356088 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-14:33:12:330 (6362) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-14:33:12:362 (6362) 0 [Generic.Event] INTERSYSTEMS IRIS JOURNALING SYSTEM MESSAGE
Journaling switched to: /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.00807/09/24-14:33:12:368 (6362) 0 [Utility.Event]   Scanning /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.00707/09/24-14:33:12:388 (6362) 0 [Utility.Event] No open transactions to roll back
07/09/24-14:33:12:391 (6362) 0 [Generic.Event] MirrorServer: New primary activating databases which are current as of 356088 (0x00056ef8) in mirror journal file #707/09/24-14:33:12:391 (6362) 0 [Generic.Event] Changed database /usr/iris/mgr/user/ (SFN 4) to read-write due to becoming primary.
07/09/24-14:33:12:391 (6362) 0 [Generic.Event] MirrorServer: Primary startup reset to Agent Controlled failover
07/09/24-14:33:12:406 (6362) 0 [Utility.Event] Initializing Interoperability during mirror initialization
07/09/24-14:33:12:410 (6362) 2 [Utility.Event] Becoming primary mirror server
07/09/24-14:33:13:141 (6590) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/20240709.010 from 196608 bytes to 73728 bytes, compression ratio = 2.707/09/24-14:33:13:166 (6590) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007 from 393216 bytes to 77824 bytes, compression ratio = 5.107/09/24-14:33:26:097 (6377) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Primary
07/09/24-14:36:51:766 (6651) 0 [Generic.Event] MirrorServer: Starting connection for: UBUNTU/IRIS (failover member) (ver 4) at offset 0x00030d98 (200088) in  file #807/09/24-14:36:52:875 (6651) 0 [Generic.Event] MirrorServer: Client up to date, linking with journal daemon @ 0x000310a4
07/09/24-14:36:52:878 (6651) 0 [Generic.Event] MirrorServer: Switched from Agent Controlled to Arbiter Controlled failover

And from the side of the former primary who's now restarted as backup :
 

07/09/24-14:36:45:825 (1689) 0 [Utility.Event] Mirror manager for MIRROR starting
07/09/24-14:36:45:842 (1697) 0 [Utility.Event] Starting TASKMGR
07/09/24-14:36:45:860 (1704) 0 [Utility.Event] [SYSTEM MONITOR] System Monitor started in %SYS07/09/24-14:36:45:909 (1690) 0 [Utility.Event] Shard license: 107/09/24-14:36:45:910 (1711) 0 [Utility.Event] WorkQueue: Starting work queue daemon parent=169007/09/24-14:36:46:058 (1704) 0 [Utility.Event] [SYSTEM MONITOR] Mirror state: Member type = Failover, Status = Transition
07/09/24-14:36:46:319 (1568) 0 [Generic.Event] Auditing to /usr/iris/mgr/irisaudit/
07/09/24-14:36:46:421 (1568) 0 [Utility.Event] Enabling logons
07/09/24-14:36:46:429 (1568) 0 [Utility.Event] Initializing Interoperability during system startup
07/09/24-14:36:47:653 (1682) 0 [Utility.Event] LMF Info:  Connected to license server 127.0.0.1,400207/09/24-14:36:47:930 (1830) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 356088 in file #7(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007)
07/09/24-14:36:47:930 (1689) 0 [Utility.Event] Retrieving journal file #8for mirror MIRROR from 192.168.102.131|218807/09/24-14:36:48:968 (1830) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 0 in file #8(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.008)
07/09/24-14:36:50:285 (1833) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 200088 in file #8(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.008)
07/09/24-14:36:50:523 (1689) 0 [Utility.Event] Retrieving journal file #8for mirror MIRROR from 192.168.102.131|2188...(repeated 1 times)
07/09/24-14:36:50:523 (1689) 0 [Utility.Event] GetECPSessionData: Got ECP data from agent len=107/09/24-14:36:50:523 (1689) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-14:36:50:712 (1689) 0 [Utility.Event] Found UBUNTU-2/IRIS as primary, becoming backup
07/09/24-14:36:50:713 (1689) 0 [Utility.Event] (MIRROR) Becoming a backup mirror member
07/09/24-14:36:51:239 (1835) 0 [Utility.Event] (MIRROR) Starting Mirror.Client("MIRROR-MIRROR-20240709.008",200088,8)
07/09/24-14:36:51:242 (1835) 0 [Generic.Event] MirrorClient: Connected to primary: UBUNTU-2/IRIS (ver 4)
07/09/24-14:36:51:266 (1837) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-14:36:52:353 (1835) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-14:36:56:358 (1835) 0 [Generic.Event] MirrorClient: The backup node has become active from a status query
07/09/24-14:36:57:774 (1850) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.007 from 393216 bytes to 77824 bytes, compression ratio = 5.107/09/24-14:37:16:627 (1704) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Backup
Sylvain Guilbaud · Jul 9, 2024 go to post

The failover works fine as well if instead of a shutdown of the Linux server, I execute a "iris force iris".

Sylvain Guilbaud · Jul 9, 2024 go to post

Hi @Kamal Suri 
below my results in a mirror env.

After stopping the Primary Linux server, the IRIS instance on the Backup Linux server becomes Primary and forces the previous Primary IRIS to shutdown when it comes back (as expected).

When you restart the IRIS instance in the previous Primary Linux, it becomes Backup.

Below the messages.log from the previous Backup who became Primary :

07/09/24-11:47:15:808 (5427) 0 [Database.MountedRO] Mounted database /usr/iris/mgr/user/ (SFN 5) read-only. Mirrored DB needs activation. 
07/09/24-11:47:29:355 (5312) 0 [Database.MirrorActivated] Activated database /usr/iris/mgr/user/ (SFN 5) in mirror 'MIRROR' foruse on this mirror member; mounted read-only.07/09/24-11:47:34:176 (5552) 0 [Utility.Event] Mirror 'MIRROR' catchup started for1 database.
07/09/24-11:47:34:883 (5552) 1 [Utility.Event] :mirror:MIRROR:USER (sfn 5) remains inactive because it is not active on the primary
07/09/24-11:51:14:822 (5465) 1 [Generic.Event] MirrorClient: Primary AckDaemon failed to answer status request.
07/09/24-11:51:14:823 (5465) 0 [Generic.Event] MirrorClient: Backup waiting for old Dejournal Reader (pid: 5466, job #33) to exit
07/09/24-11:51:15:698 (5465) 0 [Generic.Event] MirrorClient: Set status for MIRROR to Transition
07/09/24-11:51:18:705 (5449) 0 [Utility.Event] Backup taking over for primary in arbiter controlled mode
07/09/24-11:51:18:752 (5649) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 382140 in file #5(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005)
07/09/24-11:51:18:784 (5449) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-11:51:18:812 (5449) 0 [Generic.Event] INTERSYSTEMS IRIS JOURNALING SYSTEM MESSAGE
Journaling switched to: /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.00607/09/24-11:51:18:822 (5449) 0 [Utility.Event]   Scanning /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.00507/09/24-11:51:18:853 (5449) 0 [Utility.Event] No open transactions to roll back
07/09/24-11:51:18:855 (5449) 0 [Generic.Event] MirrorServer: New primary activating databases which are current as of 382140 (0x0005d4bc) in mirror journal file #507/09/24-11:51:18:855 (5449) 0 [Generic.Event] Changed database /usr/iris/mgr/user/ (SFN 5) to read-write due to becoming primary.
07/09/24-11:51:18:855 (5449) 0 [Generic.Event] MirrorServer: Primary startup reset to Agent Controlled failover
07/09/24-11:51:19:012 (5449) 0 [Utility.Event] Initializing Interoperability during mirror initialization
07/09/24-11:51:19:013 (5449) 2 [Utility.Event] Becoming primary mirror server
07/09/24-11:51:28:743 (5192) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Primary
07/09/24-11:51:29:683 (5652) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/20240709.009 from 327680 bytes to 102400 bytes, compression ratio = 3.207/09/24-11:51:29:705 (5652) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005 from 393216 bytes to 106496 bytes, compression ratio = 3.707/09/24-11:51:54:196 (5449) 0 [Utility.Event] Forcing down old primary ("UBUNTU/IRIS") which is currently in a trouble state
07/09/24-11:53:53:566 (5687) 0 [Generic.Event] MirrorServer: Starting connection for: UBUNTU/IRIS (failover member) (ver 4) at offset 0x00031e68 (204392) in  file #607/09/24-11:53:54:669 (5687) 0 [Generic.Event] MirrorServer: Client up to date, linking with journal daemon @ 0x00031e68
07/09/24-11:53:54:858 (5687) 0 [Generic.Event] MirrorServer: Switched from Agent Controlled to Arbiter Controlled failover

and the messages.log from the previous Primary who is now Backup :

07/09/24-11:53:50:157 (6577) 0 [Utility.Event] [SYSTEM MONITOR] Mirror state: Member type = Failover, Status = Transition
07/09/24-11:53:50:236 (6543) 0 [Generic.Event] Auditing to /usr/iris/mgr/irisaudit/
07/09/24-11:53:50:274 (6543) 0 [Utility.Event] Enabling logons
07/09/24-11:53:50:282 (6543) 0 [Utility.Event] Initializing Interoperability during system startup
07/09/24-11:53:50:877 (6695) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 382140 in file #5(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005)
07/09/24-11:53:50:877 (6557) 0 [Utility.Event] Retrieving journal file #6for mirror MIRROR from 192.168.102.131|218807/09/24-11:53:51:905 (6695) 0 [Utility.Event] DejournalProcessor: Applying journal data for mirror "MIRROR" starting at 0 in file #6(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.006)
07/09/24-11:53:51:919 (6550) 0 [Utility.Event] LMF Info:  Connected to license server 127.0.0.1,400207/09/24-11:53:53:071 (6697) 0 [Utility.Event] Applying journal data for mirror "MIRROR" starting at 204392 in file #6(/usr/iris/mgr/journal/MIRROR-MIRROR-20240709.006)
07/09/24-11:53:53:200 (6557) 0 [Utility.Event] Retrieving journal file #6for mirror MIRROR from 192.168.102.131|2188...(repeated 1 times)
07/09/24-11:53:53:200 (6557) 0 [Utility.Event] GetECPSessionData: Got ECP data from agent len=107/09/24-11:53:53:200 (6557) 0 [Utility.Event] Manager initialized for MIRROR
07/09/24-11:53:53:302 (6557) 0 [Utility.Event] Found UBUNTU-2/IRIS as primary, becoming backup
07/09/24-11:53:53:303 (6557) 0 [Utility.Event] (MIRROR) Becoming a backup mirror member
07/09/24-11:53:53:567 (6699) 0 [Utility.Event] (MIRROR) Starting Mirror.Client("MIRROR-MIRROR-20240709.006",204392,6)
07/09/24-11:53:53:569 (6699) 0 [Generic.Event] MirrorClient: Connected to primary: UBUNTU-2/IRIS (ver 4)
07/09/24-11:53:53:582 (6701) 0 [Utility.Event] Arbiter connection established (192.168.102.1:2188)
07/09/24-11:53:54:861 (6699) 0 [Generic.Event] MirrorClient: Switched from Agent Controlled to Arbiter Controlled failover on request from primary
07/09/24-11:53:54:916 (6699) 0 [Generic.Event] MirrorClient: The backup node has become active
07/09/24-11:54:01:989 (6718) 0 [Utility.Event] Journal File Compression: Compressed /usr/iris/mgr/journal/MIRROR-MIRROR-20240709.005 from 393216 bytes to 106496 bytes, compression ratio = 3.707/09/24-11:54:20:174 (6577) 0 [Utility.Event] [SYSTEM MONITOR] Mirror status changed. Member type = Failover, Status = Backup

Sylvain Guilbaud · Jul 9, 2024 go to post

Hi @Kamal Suri 
I've not tested it in a mirror env. 
The restart of the primary Linux server should not increase (neither decrease) the time for the backup member to become primary.

Sylvain Guilbaud · Jul 8, 2024 go to post

Hello @Moussa SAMB 
the problem comes from the expired license of version IRIS 2023.1.1 published in July 2023.

I invite you to use a more recent version to overcome the problem.

Sylvain Guilbaud · Jul 8, 2024 go to post

For my tests, I'm using Ubuntu 24.04

lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 24.04 LTS
Release:	24.04
Codename:	noble
uname -a
Linux ubuntu 6.8.0-36-generic #36-Ubuntu SMP PREEMPT_DYNAMIC Mon Jun 10 10:49:14 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux