Find

Article
· Mar 18, 2024 6m read

コンソールログに"There exists a MISMATCH.WIJ file" が記録され、インスタンスの開始ができない時の対処法

これは InterSystems FAQ サイトの記事です。
 

インスタンスの開始が失敗し、コンソールログに"There exists a MISMATCH.WIJ file"が記録されている場合、何らかのシステム障害の影響でデータベースの整合性に関して問題が生じていることを示しています。

このような状況が発生した際にインスタンスの開始ができるようにするためには、以下の手順を実施します。

(1) a. インスタンスをNOSTUモードで起動       注1:
(2) b. データベースの整合性チェック

◆(2)の整合性チェックでエラーを検出しなかった場合、
 (3) d. MISMATCH.WIJ ファイルのリネーム
 (4) e. インスタンスの再起動
を実施します。

◆(2)の整合性チェックでエラーが検出された場合は、
 (3) c. MISMATCH.WIJファイルの適用
 (4) b. データベースの整合性チェック
 (5) d. MISMATCH.WIJファイルのリネーム
 (6) e. インスタンスの再起動
を実施します。 

以下に各手順の詳細を説明します。 

a. インスタンスをNOSTUモードで起動します。

以下に記載の手順の内、1)および2)の手順まで実行します。

3)以降は実施する必要はありません。

(Cachéの場合は、右括弧なしの1,2,3)

NOSTUで開始する(Caché)

NOSTUで開始する(IRIS)

b. データベースの整合性チェック

STURECOV ルーチンを実行してデータベースの整合性チェックを行います。

%SYS>do ^STURECOV
Logins are not disabled.
This routine is designed to run when Cache' is in single user mode due to a problem running the STU startup routine.
Do you want to continue ? No => yes
Warning: Misuse of this utility can harm your system
There is no record of any errors during the prior startup
This could be because there was a problem writing the data to disk or because the system failed to start for some otherreason.
Do you want to continue ? No => yes
Enter error type (? for list) [^] => MISMATCHWIJ

1) List Affected Databases and View Blocks
2) Apply mismatched blocks from WIJ to databases 
3) Rename MISMATCH.WIJ         
4) Dismount a database
5) Mount a database
6) Database Repair Utility
7) Check Database Integrity
8) Bring down the system prior to a normal startup
--------------------------------------------------------------
H) Display Help
E) Exit this utility
--------------------------------------------------------------
Enter choice (1-8) or [Q]uit/[H]elp? 7
This utility is used to check the integrity of a database and the pointer structure of one or more globals.
Output results on
Device: Integrity_STURECOV.log        整合性チェックの結果をログファイルに出力します
Parameters? "WNS" =>
Stop after any error?  No=>
Do you want to check all databases?  No=> Yes
Checking c:\intersystems\irishealth\mgr\ at 23:09:20
Checking c:\intersystems\irishealth\mgr\enslib\ at 23:09:21
Checking c:\intersystems\irishealth\mgr\hscustom\ at 23:09:22
Checking c:\intersystems\irishealth\mgr\hslib\ at 23:09:23
Checking c:\intersystems\irishealth\mgr\hssys\ at 23:09:31
Checking c:\intersystems\irishealth\mgr\irisaudit\ at 23:09:31
Checking c:\intersystems\irishealth\mgr\irislib\ at 23:09:31
Checking c:\intersystems\irishealth\mgr\irislocaldata\ at 23:09:33
Checking c:\intersystems\irishealth\mgr\iristemp\ at 23:09:33
Checking c:\intersystems\irishealth\mgr\test\ at 23:09:33
Checking c:\intersystems\irishealth\mgr\user\ at 23:09:34
--------------------------------------------------------------
1) List Affected Databases and View Blocks
2) Apply mismatched blocks from WIJ to databases
3) Rename MISMATCH.WIJ
4) Dismount a database
5) Mount a database
6) Database Repair Utility
7) Check Database Integrity
8) Bring down the system prior to a normal startup
--------------------------------------------------------------
H) Display Help
E) Exit this utility
--------------------------------------------------------------
Enter choice (1-8) or [Q]uit/[H]elp?

 

出力されたログファイルの末尾に "No Errors were found." と記録されていれば整合性チェックでエラーは検出していません。

 

c. MISMATCH.WIJファイルの適用

STURECOV ルーチンよりMISMATCH.WIJファイルを適用します。

--------------------------------------------------------------
1) List Affected Databases and View Blocks
2) Apply mismatched blocks from WIJ to databases 
3) Rename MISMATCH.WIJ         
4) Dismount a database
5) Mount a database
6) Database Repair Utility
7) Check Database Integrity
8) Bring down the system prior to a normal startup
--------------------------------------------------------------
H) Display Help
E) Exit this utility
--------------------------------------------------------------
Enter choice (1-8) or [Q]uit/[H]elp? 2

d. MISMATCH.WIJ ファイルのリネーム
 

STURECOV ルーチンよりMISMATCH.WIJファイルをリネームします。

 

--------------------------------------------------------------
1) List Affected Databases and View Blocks
2) Apply mismatched blocks from WIJ to databases 
3) Rename MISMATCH.WIJ         
4) Dismount a database
5) Mount a database
6) Database Repair Utility
7) Check Database Integrity
8) Bring down the system prior to a normal startup
--------------------------------------------------------------
H) Display Help
E) Exit this utility
--------------------------------------------------------------
Enter choice (1-8) or [Q]uit/[H]elp? 3

e. インスタンスの再起動

STURECOV ルーチンよりインスタンスを停止後、インスタンスをランチャー等より通常起動します。

--------------------------------------------------------------
1) List Affected Databases and View Blocks
2) Apply mismatched blocks from WIJ to databases
3) Rename MISMATCH.WIJ
4) Dismount a database
5) Mount a database
6) Database Repair Utility
7) Check Database Integrity
8) Bring down the system prior to a normal startup
--------------------------------------------------------------
H) Display Help
E) Exit this utility
--------------------------------------------------------------
Enter choice (1-8) or [Q]uit/[H]elp? 8

MISMATCH.WIJの適用処理が正常終了しない、またはインスタンスの再開始後の整合性チェックでエラーがある場合は、カスタマーサポートセンターまでお問い合わせください 

WIJ ブロック比較
 

注1:

以下のようにシングルユーザーモードで開始されている旨のメッセージが含まれている場合は、この手順は必要ありません。

Cache is started in single user mode.
To log into Cache, type:
    ccontrol session CACHE -B
and D ^STURECOV for help recovering from this error.

以下のように直接シングルユーザーモードでログインし、b.から始めます。

(これらのコマンドのPATHが設定されているか、コマンドの実行イメージの存在する場所で実行する必要があります。)

Windows
 IRIS
 >irisdb -s ..\mgr -B
 Caché
 >cache -s..\mgr -B  
UNIX
 IRIS
 >iris session iris -B
 Caché
 >ccontrol session cache -B
Discussion (0)1
Log in or sign up to continue
Article
· Mar 18, 2024 2m read

Getting data from InterSystems IRIS CloudSQL using xDBC

Recently, the question came up while discussing the access to the data stored in IRIS from different languages with my students if it was possible to initiate the connection and get data from Cloud solution (InterSystems IRIS CloudSQL) from Microsoft Excel, not the other way around. Considering the many varied ways one can get data in Excel (import data from external sources, connecting to databases using ODBC drivers, using power queries and web queries etc.) the obvious choice was to try ODBC driver. The only task left was to try to connect to the database in the cloud using the ODBC driver.

Quite unsurprisingly, it worked!

If you're new to CloudSQL, I would highly suggest you read the documentation. From it you will be able to get access to the InterSystems Cloud Services Portal (or you can go directly to AWS and subscribe with your AWS account) and download necessary drivers. BTW, if you encounter problems with CloudSQL, you may try to look for answers in this document first.

Now that these preliminaries are out of the way, let's try the simplest approach - setting up the ODBC data source with just a password and getting data from it in MS Excel.

Step 0. Set up your InterSystems IRIS CloudSQL. You will see the necessary settings on the Overview page of your Deployment:

Step 00. Download and install ODBC driver for your OS.

Step 1. Open your ODBC Data Sources and switch to System DSN tab. In it, click on Add...

and fill in the settings from your Overview page (first screenshot of the article).

Step 2. Connect Excel to IRIS. Open Excel, navigate to the Data tab, and select "Get Data" or "From Other Sources," depending on your Excel version. Choose "From ODBC" as the data source

select the ODBC data source you configured earlier

enter authentication credentials if asked

and choose the table you wish to load into Excel

Step 3. You're good to go and do whatever with your data

PS. Some other interesting articles/videos that I would suggest you read/watch regarding ODBC and CloudSQL:

  • a whole series of videos that show how to connect to CloudSQL from solutions written in different languages
  • an interesting article on how to set up roles and give permissions to xDBC connections
  • another article on how to use SSL/TLS to establish secure connections over JDBC and other driver technologies
  • and the last one about switching between ODBC drivers in an environment with multiple versions installed
4 Comments
Discussion (4)2
Log in or sign up to continue
Article
· Mar 18, 2024 3m read

任意のXMLドキュメントの読み込み・書き出しを行う

これは、InterSystems FAQサイトの記事です。

【任意のXMLドキュメントの読み込み】
任意のXMLドキュメントの読み込みを行うには、%XML.TextReaderクラスを使用します。
Parseメソッド(※ドキュメントがファイルの場合はParseFile())を使用してドキュメントをパースし、各ノードのプロパティを取得します。

例えば、下記のXMLの場合、

 <emp empid="1">
    <name>Suzuki</name>
    <address>Tokyo</address>
 </emp>

 
各赤枠が、"ノード"の単位となり、


 下記のようなイメージで取得することができます。

ノード・
プロパティ名
seq NodeType Name Value (属性)
LocalName Value
プロパティ値 1 element emp   empid 1
2 element name      
3 chars   Suzuki    
4 endelement name      
5 element address      
6 chars   Tokyo    
7 endelement address      
8 endelement emp      

 コード例:

readXML
  set sc=##class(%XML.TextReader).ParseFile("C:\temp\aaa.xml",.treader)
  d $SYSTEM.Status.DisplayError(sc)
  while (treader.Read()) {
    write treader.seq," "
    write "[Type]",treader.NodeType," " 
    write "[Name]",treader.Name," "
    write "[Value]",treader.Value," "
    if (treader.NodeType="element"){
      for i=1:1:treader.AttributeCount {
        do treader.MoveToAttributeIndex(i)
        write "[Att] ",treader.LocalName,"=",treader.Value
      }
    }
  write !
  }
  quit


%XML.TextReaderについての詳細は、下記のドキュメントをご参照ください。
[ドキュメント] %XML.TextReader の使用

【任意のXMLドキュメントの書き出し】
任意のXMLドキュメントを作成(書き出し)するには、%XML.Writerを使用します。

コード例:

writeXML
    set xml=##class(%XML.Writer).%New()
    set xml.Indent=1
    do xml.OutputToFile("C:\temp\out.xml")
    do xml.RootElement("employees")
    do xml.Element("emp"),xml.WriteAttribute("empid","1")
    do xml.Element("name"),xml.WriteChars("Suzuki"),xml.EndElement()
    do xml.EndElement() // emp
    do xml.EndRootElement() // employees
    quit

 
上記を実行すると、下記の内容のファイルが出力されます。

<?xml version="1.0" encoding="UTF-8"?>
<employees>
  <emp empid="1">
    <name>Suzuki</name>
  </emp>
</employees>


%XML.Writerについての詳細は、下記のクラスリファレンスをご参照ください。
[クラスリファレンス] %XML.Writer

Discussion (0)1
Log in or sign up to continue
Article
· Mar 16, 2024 4m read

Creating Unit Tests in ObjectScript for HL7 pipelines using %UnitTest class

One of the pain points for maintaining HL7 interfaces is the need to run a reliable regression test upon deployment to new environments and after upgrades. The %UnitTest class allows unit tests to be created and packaged alongside interface code. Test data can also be maintained within the unit test class, allowing for quick and easily repeatable smoke-testing and regression testing.

Resources:

  • Standard %UnitTest class

1 Comment
Discussion (1)1
Log in or sign up to continue
Article
· Mar 15, 2024 4m read

Uncovering Clues by Querying the Interoperability Message tables

When using InterSystems IRIS as an interoperability engine, we all know and love how easy it is to use the Message Viewer to review message traces and see exactly what's going on in your production. When a system is handling millions of messages per day, you may not know exactly where to begin your investigation though.

Over my years supporting IRIS productions, I often find myself investigating things like...

  • What sort of throughput does this workflow have?
  • Where is the bottleneck?
  • What are my most common errors?

One of my favorite places to look for clues is the Message Header table, which stores metadata about every message running through the system. These are the same messages that appear in the Message Viewer and the Visual Traces. 

I've built up a collection of handy SQL queries, and I'd love to share them with you. My examples are mostly from HealthShare or IRIS for Health use cases, but they can be easily adapted for whatever workflow you have...

-- SQL query to find the # of messages through a component per day
select {fn SUBSTRING(timeprocessed,1,10)} AS day, count(*) MessagesThisDay 
FROM Ens.MessageHeader
where TargetConfigName = 'HS.Hub.Push.Evaluator' 
GROUP BY {fn SUBSTRING(timeprocessed,1,10)}
ORDER BY day ASC
-- SQL query to find long-running messages through particular components
SELECT PReq.SessionID as SessionId, 
  PReq.TimeCreated as pReqTimeCreated, 
  PRes.TimeCreated as pResTimeCreated, 
  {fn TIMESTAMPDIFF(SQL_TSI_SECOND, PReq.TimeCreated,PRes.TimeCreated)} as TimeDelay
FROM (
  SELECT ID, SessionId, TimeCreated
  FROM Ens.MessageHeader
  WHERE MessageBodyClassName = 'HS.Message.PatientSearchRequest'
  AND SourceConfigName = 'HS.Hub.MPI.Manager'
  AND TargetConfigName = 'HUB'
) as PReq
INNER JOIN (
  SELECT ID, SessionId, TimeCreated
  FROM Ens.MessageHeader
  WHERE MessageBodyClassName = 'HS.Message.PatientSearchResponse'
  AND SourceConfigName = 'HS.Hub.MPI.Manager'
  AND TargetConfigName = 'HS.IHE.PIX.Manager.Process'
) as PRes on pReq.SessionId = PRes.SessionId
WHERE {fn TIMESTAMPDIFF(SQL_TSI_SECOND, PReq.TimeCreated,PRes.TimeCreated)} > 1
ORDER BY SessionId desc ----------------------------------------------------------
/*-- Query to find the bottleneck message through a particular component
  -- set your threshold for "how long is too long (e.g. 20 seconds)
  -- look for clusters of messages that are longer than that (e.g. the first cluster started at 3:22:00, then there was a second cluster at 5:15:30)
  -- in each cluster, look at the first message in that cluster (chronologically). That is likely to be the bottleneck message, and all messages after it are victims of its bottleneck 
*/
SELECT %NOLOCK req.TargetConfigName, req.MessageBodyClassName, req.SessionId, req.TimeCreated, req.TimeProcessed, {fn TIMESTAMPDIFF(SQL_TSI_SECOND, req.TimeCreated, req.TimeProcessed)} as TimeToProcess
FROM Ens.MessageHeader AS req
WHERE req.TargetConfigName = 'HS.Hub.Management.Operations'
  AND req.TimeCreated BETWEEN '2021-04-21 00:00:00' AND '2021-04-21 11:00:00'
  AND {fn TIMESTAMPDIFF(SQL_TSI_SECOND, req.TimeCreated, req.TimeProcessed)} > 20
/* If you have a particular error that you're investigating, try this one. It scans through the Ensemble Error Log for "Object to Load not found" entries, then returns some key fields from the relevant PatientSearchRequest message */
SELECT l.SessionId, mh.MessageBodyID, mh.TimeCreated, psr.SearchMode, psr.RequestingUser, psr.FirstName, psr.MiddleName, psr.LastName, psr.SSN, psr.Sex, psr.DOB
FROM Ens_Util.Log as l
INNER JOIN Ens.MessageHeader as mh on l.SessionId = mh.SessionId
INNER JOIN HS_Message.PatientSearchRequest as psr on mh.MessageBodyID = psr.ID
WHERE l.Type = 'Error'
AND l.ConfigName = 'HSPI.Server.APIOperation'
AND l.Text like 'ERROR #5809: Object to Load not found%'
AND mh.MessageBodyClassName = 'HS.Message.PatientSearchRequest'
AND mh.SourceConfigName = 'HSPI.Server.APIWebService'
AND mh.TargetConfigName = 'HSPI.Server.APIOperation'
-- Scan the Ensemble Error Log for a particular timeframe. Count up the different types of errors
SELECT substring(text,1,80) as AbbreviatedError, count(*) as NumTheseErrors
FROM Ens_Util.Log
WHERE Type = 'Error'
AND TimeLogged > '2022-03-03 00:00:00' -- when the last batch started
AND TimeLogged < '2022-03-03 16:00:00' -- when we estimate this batch might end
GROUP BY substring(text,1,80)
ORDER BY NumTheseErrors desc
-- Find the Gateway Processing Time for each StreameltRequest / ECRFetchResponse pair
SELECT sr.Gateway,request.sessionid, response.sessionid, request.timecreated AS starttime, response.timecreated AS stoptime, 
  datediff(ms,request.timecreated,response.timecreated) AS ProcessingTime, 
  Avg(datediff(ms,request.timecreated,response.timecreated)) AS AverageProcessingTimeAllGateways
FROM Ens.MessageHeader request
INNER JOIN Ens.MessageHeader AS response ON response.correspondingmessageid = request.id
INNER JOIN HS_Message.StreamletRequest AS sr ON sr.ID = request.MessageBodyId
WHERE request.messagebodyclassname = 'HS.Message.StreamletRequest'
AND response.messagebodyclassname = 'HS.Message.ECRFetchResponse'
2 Comments
Discussion (2)1
Log in or sign up to continue