
本記事は、コマンドによるジャーナルファイルの参照方法についての解説になります。
はじめに
ジャーナル・ファイルは、データベースのトランザクション履歴を記録する重要なファイルです。
障害時の復旧や、データ整合性・トランザクションログの確認等々に役立ちます。
各ジャーナル・レコードの参照方法は、管理ポータルから参照する方法が一番楽だと思いますが、管理ポータルが使えない場合の代替手段も知っておくと便利です。
前々回の中級編では、「d ^JRNDUMP」コマンドでジャーナルファイルを参照しました。
ただし、この方法では、一覧から選択する以外に方法はなく、別ディレクトリ等にバックアップしたジャーナルファイルの参照は行えません。
そこで、異なるディレクトリにあるジャーナルファイルを含め、ファイルパスを指定してジャーナルファイルの参照を行いたいと思います。
では解説を始めます。
SELECT^JRNDUMP
「d ^JRNDUMP」コマンドと同じく、対話型で参照を行います。
コマンドは下記になります。
SELECT^JRNDUMP(%jfile, %pid, %dir, %glo, %gloall, %operation, %remsysid)
【引数の説明】
引数 | 説明 |
---|---|
$jfile | ジャーナルファイルのフルパス |
%pid | ジャーナルファイル内のプロセスIDを指定する。任意 |
%dir | ジャーナルファイル内のディレクトリを指定する。任意 |
%glo | ジャーナルファイル内のグローバル名を指定する。任意 |
%gloall | 0 : %gloで指定した名前に完全一致するグローバル(default) 1 : %gloで指定した名前を使用しているグローバル |
%operation | ジャーナル・レコードの処理タイプ。任意 |
%remsysid | ジャーナルファイル内のECPシステムIDを指定する。任意 |
【%operationの説明】
引数(数値) | 引数(文字列) | Type | 説明 |
---|---|---|---|
6 | “s” | Set | SET文を抽出する |
14 | “bs” | BitSet | ビットのSET文を抽出する |
7 | “k” | KillNode | KILL文を抽出する |
8 | “k” | KillDesc | 下位ノードのKILL文を抽出する |
9 | “zk” | ZKill | ZKILL文を抽出する |
4 | BeginTrans | トランザクション開始 | |
16 | BeginTrans with Level | トランザクション・レベル開始 | |
5 | CommitTrans | トランザクションをコミット | |
18 | CommitTrans with Level | 分離されたトランザクション・レベルをコミット | |
17 | CommitTrans Pending with Level | 保留中のトランザクション・レベルをコミット | |
21 | Rollback | トランザクションのロールバック | |
13 | JrnMark | ジャーナル・マーカ | |
15 | NetReq | ECPネットワーキング |
リモートSET, KILL, ZKILLはクラスタ関連で出力するため、割愛します。
ミラーSET, KILLも内部仕様のため割愛します。
動作の確認
各引数に対し、動作の検証を行っていきます。
準備
2つのターミナルからグローバルの操作を実行し、ジャーナルファイルを別ディレクトリに移します。
ターミナル(3704)から実行する
s ^test = "テスト"
s ^test(1) = "テスト(1)"
s ^test(2) = "テスト(2)"
k ^test(2)
s ^test(3) = "テスト(3)"
s ^test(3,1) = "テスト(3,1)"
zk ^test(3)
別ターミナル(1840)にて実行する
s ^sample = "サンプル"
s ^sample(1) = "サンプル(1)"
s ^sample(2) = "サンプル(2)"
k ^sample(2)
s ^sample(3) = "サンプル(3)"
s ^sample(3,1) = "サンプル(3,1)"
zk ^sample(3)
プロセス指定でのジャーナルレコード出力検証
プロセス毎のジャーナルを出力するには、下記コマンドになります。
zn "%SYS"
s path = [ジャーナルファイルのフルパス]
d SELECT^JRNDUMP(path, 3704)
ターミナルにて実行

出力された内容を下記に張り付けます。
Address: 135744
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 135728
Next address: 135792
Global: ^["^^d:\irisdb\sample-data\"]test
New Value: "テスト"
Address: 135792
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 135744
Next address: 135840
Global: ^["^^d:\irisdb\sample-data\"]test(1)
New Value: "テスト(1)"
Address: 135840
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 135792
Next address: 135892
Global: ^["^^d:\irisdb\sample-data\"]test(2)
New Value: "テスト(2)"
Address: 135892
Type: KillNode
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 135840
Next address: 135932
Global: ^["^^d:\irisdb\sample-data\"]test(2)
Address: 135932
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 135892
Next address: 135984
Global: ^["^^d:\irisdb\sample-data\"]test(3)
New Value: "テスト(3)"
Address: 135984
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 135932
Next address: 136040
Global: ^["^^d:\irisdb\sample-data\"]test(3,1)
New Value: "テスト(3,1)"
Address: 136040
Type: ZKill
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 135984
Next address: 136080
Global: ^["^^d:\irisdb\sample-data\"]test(3)
Address: 140736
Type: KillNode
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76799 - 03/12/2025 21:19:59
Collation sequence: 5
Prev address: 140720
Next address: 140772
Global: ^["^^d:\irisdb\sample-data\"]test
Address: 199728
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 199712
Next address: 199776
Global: ^["^^d:\irisdb\sample-data\"]test
New Value: "テスト"
Address: 199776
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 199728
Next address: 199824
Global: ^["^^d:\irisdb\sample-data\"]test(1)
New Value: "テスト(1)"
Address: 199824
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 199776
Next address: 199876
Global: ^["^^d:\irisdb\sample-data\"]test(2)
New Value: "テスト(2)"
Address: 199876
Type: KillNode
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 199824
Next address: 199916
Global: ^["^^d:\irisdb\sample-data\"]test(2)
Address: 199916
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 199876
Next address: 199968
Global: ^["^^d:\irisdb\sample-data\"]test(3)
New Value: "テスト(3)"
Address: 201520
Type: Set
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 201504
Next address: 201576
Global: ^["^^d:\irisdb\sample-data\"]test(3,1)
New Value: "テスト(3,1)"
Address: 201576
Type: ZKill
In transaction: No
Job ID: 0x00000E78
Process ID: 3704
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 201520
Next address: 201616
Global: ^["^^d:\irisdb\sample-data\"]test(3)
ちゃんと出力されていますね。
特定のジャーナルレコードを絞り込む
特定のレコードを絞り込んでみます。
サンプルとして、ZKILL(%operation=9)を実行したジャーナルレコードを出力してみます。
コマンドは下記になります。
zn "%SYS"
s path = [ジャーナルファイルのフルパス]
d SELECT^JRNDUMP(path, "", "", "^sample", 1, 9)
実行結果が下記になります。
グローバル「^sample」でZKILLを行ったのは1回のみなので、1レコードが出力されています。
Address: 205024
Type: ZKill
In transaction: No
Job ID: 0x00000730
Process ID: 1840
ECP system ID: 0
Time stamp: 67276,76837 - 03/12/2025 21:20:37
Collation sequence: 5
Prev address: 204968
Next address: 205068
Global: ^["^^d:\iris\mgr\user\"]sample(3)
他サンプルです。
各引数を組み合わせて、対象のジャーナル・レコードを出力する事が可能です。
// ^sample(3)のSET文、ZKILL文が出力
d SELECT^JRNDUMP(path, "", "", "^sample(3)")
// USERのDATに関連するジャーナル・レコードが全て出力される
d SELECT^JRNDUMP(path, "", "D:\IRIS\mgr\user")
// ECPシステムID = 1のジャーナル・レコードが全て出力
d SELECT^JRNDUMP(path, "", "", "",,,1)
%SYS.Journal.Record
ジャーナルレコードAPIのクラス・クエリを利用して、ジャーナルファイルの参照を行います。
ある程度の検索も行えるので、目的のジャーナル・レコードを出力する事が可能です。
恐らく管理ポータルも、このクラス・クエリを利用していると思われます。
ジャーナルファイルからの読み込みサンプル
ClassMethod readJornalRecord(path As %String, clms As %String = "*", offset As %Integer = 0, order As %Integer = 0, match As %List = "")
{
try {
n $namespace
s $namespace = "%SYS"
s stmt = ##class(%SQL.Statement).%New()
$$$ThrowOnError( stmt.%PrepareClassQuery("%SYS.Journal.Record", "List") )
s res = stmt.%Execute(path, clms, offset, order, match)
while (res.%Next(.sts)) {
w:(res.%Get("Address")'="") "Address:",?25,res.%Get("Address"),!
w:(res.%Get("Type")'="") "Type:",?25,res.%Get("Type"),!
w:(res.%Get("TypeName")'="") "TypeName:",?25,res.%Get("TypeName"),!
w:(res.%Get("PrevAddress")'="") "PrevAddress:",?25,res.%Get("PrevAddress"),!
w:(res.%Get("NextAddress")'="") "NextAddress:",?25,res.%Get("NextAddress"),!
w:(res.%Get("InTransaction")'="") "InTransaction:",?25,res.%Get("InTransaction"),!
w:(res.%Get("TimeStamp")'="") "TimeStamp:",?25,res.%Get("TimeStamp"),!
w:(res.%Get("ProcessID")'="") "ProcessID:",?25,res.%Get("ProcessID"),!
w:(res.%Get("RemoteSystemID")'="") "RemoteSystemID:",?25,res.%Get("RemoteSystemID"),!
w:(res.%Get("ClusterSequence")'="") "ClusterSequence:",?25,res.%Get("ClusterSequence"),!
w:(res.%Get("DatabaseName")'="") "DatabaseName:",?25,res.%Get("DatabaseName"),!
w:(res.%Get("GlobalReference")'="") "GlobalReference:",?25,res.%Get("GlobalReference"),!
w:(res.%Get("GlobalNode")'="") "GlobalNode:",?25,res.%Get("GlobalNode"),!
w:(res.%Get("NumberOfValues")'="") "NumberOfValues:",?25,res.%Get("NumberOfValues"),!
w:(res.%Get("NewValue")'="") "NewValue:",?25,res.%Get("NewValue"),!
w:(res.%Get("OldValue")'="") "OldValue:",?25,res.%Get("OldValue"),!
w:(res.%Get("Collation")'="") "Collation:",?25,res.%Get("Collation"),!
w:(res.%Get("Bit Position")'="") "Bit Position:",?25,res.%Get("Bit Position"),!
w:(res.%Get("Bit OldLength")'="") "Bit OldLength:",?25,res.%Get("Bit OldLength"),!
w:(res.%Get("Marker MID")'="") "Marker MID:",?25,res.%Get("Marker MID"),!
w:(res.%Get("Marker Sequence")'="") "Marker Sequence:",?25,res.%Get("Marker Sequence"),!
w:(res.%Get("Marker Text")'="") "Marker Text:",?25,res.%Get("Marker Text"),!
w:(res.%Get("MirrorDatabaseName")'="") "MirrorDatabaseName:",?25,res.%Get("MirrorDatabaseName"),!
w !
}
} catch e {
w !,$system.Status.DisplayError(e.AsStatus())
}
}
引数説明
引数 | 説明 |
---|---|
path | ジャーナルファイルのフルパス |
clms | カラムの指定 “*”を指定すると、全てのカラムを取得する 特定のカラムを出力したい場合は、カンマで接続する 例)”Address,TypeName” 等 |
offset | 指定したオフセット値(Address)の値以降を対象とする |
order | 0 : オフセット値(Address)の昇順から出力する(default値) 1 : オフセット値(Address)の降順から出力する |
match | ジャーナル・レコードの検索を行う $lb([カラム名], [演算子], [検索対象]) 例)^SYS.Historyグローバルを除外する $lb(“GlobalNode”, “‘[“, “^SYS.History”) 演算子:=, ‘=, [, ‘[, <, <=, >…etc… |
テキスト等に出力する場合は、下記を参考にしてみてください。
%SYS.Journal.File
ジャーナルファイルのAPIを利用する方法になります。
下記サンプルは、ジャーナルファイルを引数として読み込み、各ジャーナル・レコードを取得してプロパティの値を表示しています。
後は、煮るなり焼くなり、自作で絞り込むなりファイルに出力するなり。。。
かなり手間ですが、知っておくとジャーナルの構造が理解できます。
また、完全自作なので、思うがままに検索を行うことができるのもメリットです。
ジャーナルファイルからの読み込みサンプル
ClassMethod readJornal(path As %String)
{
try {
n $namespace
s $namespace = "%SYS"
s jrnforef = ##class(%SYS.Journal.File).%OpenId(path)
s (cnt,address) = 0
f {
s recObj = jrnforef.GetRecordAfter(address)
q:'$IsObject(recObj)
s address =recObj.Address
s clsNm = $p($className(recObj),".",*)
w "classname:",?25,clsNm,!
w "Address:",?25,address,!
w "Type:",?25,recObj.Type,!
w "TypeName:",?25,recObj.TypeName,!
w "In transaction:",?25,recObj.InTransaction,!
w "JobID",?25,recObj.JobID,!
w "ProcessID:",?25,recObj.ProcessID,!
w "ECP system ID:",?25,recObj.ECPSystemIDGet(),!
w "Timie stamp:",?25,recObj.TimeStamp,!
i (clsNm="Record"){
}elseif (clsNm="SetKillRecord")||(clsNm="BitSetRecord"){
w "Collation sequence:",?25,recObj.Collation,!
w "DatabaseName:",?25,recObj.DatabaseName,!
w "GlobalNode:",?25,recObj.GlobalNode,!
w "OldValue:",?25,recObj.OldValue,!
w "NewValue:",?25,recObj.NewValue,!
w "GlobalReference:",?25,recObj.GlobalReference,!
i (clsNm="BitSetRecord"){
w "OldLength:",?25,recObj.OldLength,!
w "Position:",?25,recObj.Position,!
}
}elseif (clsNm="Marker"){
w "Sequence:",?25,recObj.Sequence,!
w "MID:",?25,recObj.MID,!
w "Text:",?25,recObj.Text,!
}
w "Prev address:",?25,recObj.PrevAddress,!
w "Next address:",?25,recObj.NextAddress,!
w !
s cnt = cnt + 1
}
w !,"レコード件数: ",cnt,"件",!
} catch e {
w !,$system.Status.DisplayError(e.AsStatus())
}
}
管理ポータルを利用する
「結局管理ポータルに戻るんかーい」
と突っ込む方もいらっしゃるかと思いますが、最後に管理ポータルを利用したジャーナルファイルの確認方法をご紹介して〆たいと思います。
管理ポータルを起動し[ システムオペレーション ] > [ ジャーナル ] でジャーナル画面に遷移し、どのジャーナルファイルでも構わないので、「参照」をクリックし、「ジャーナル表示」画面へ進みます。
URLの「?$ID1=」以降を削除し、参照したいジャーナルファイルのフルパスを指定します。

見事管理ポータルから、指定のジャーナル・ファイルを参照する事が出来ました。

うん。
これが一番楽かな・・・
おわりに
いかがだったでしょうか。
管理ポータルのGUIを活用する方法から、コマンドラインで詳細な情報を取得する方法まで、用途に応じたアプローチを理解しておくと、トラブルシューティングがスムーズに進みます。
特に、システムの障害発生時やデータの不整合が疑われる場合には、ジャーナルファイルを素早く確認し、問題の原因を特定できることが求められます。
日常的な運用ではジャーナルファイルを意識する機会は少ないかもしれませんが、いざという時のために、その仕組みと操作方法を理解しておくことが大切だと思います。
本記事の紹介が、適切なトラブルシューティングを行うための一助となれば幸いです。