
本記事はグローバル・ジャーナル(上級編)についての解説になります。
はじめに
前回の記事では、ターミナルを利用してのジャーナル操作をご紹介いたしました。
本記事では、クラスやルーチン上でジャーナルの操作を行っていこうと思います。
それでは、クラスを作成し、ジャーナル操作を始めましょう。
%SYS.NOJRN.incの利用
ジャーナルの制御
%SYS.NOJRNルーチンを使用する事で、プロセス間でジャーナルの停止/出力を制御する事が可能です。
※他のプロセスではジャーナルの制御は行われません。
下記がサンプルになります。
ClassMethod jorStop(mode As %Boolean = 0)
{
// 出力を停止する
d:mode DISABLE^%SYS.NOJRN
k ^test
s ^test = "テスト"_$zdt($now(),3,1,6)
s obj = ##class(developer.data.Patient2).%OpenId(1)
w obj.漢字氏名
s obj.漢字氏名 = "埼玉 タケ"_$now()
d obj.%Save()
// 出力を再開する
d:mode ENABLE^%SYS.NOJRN
k ^sample
s ^sample=$zdt($now(),3,1,6)
s obj = ##class(developer.data.Patient2).%OpenId(3)
w obj.漢字氏名
s obj.漢字氏名 = "栃木 ウメ"_$now()
d obj.%Save()
}
ターミナルから関数を実行すると、ジャーナル停止区間のデータ更新が、ジャーナリングされていない事が確認できます。

他の停止・開始コマンド
似たようなコマンドがあるので併せて紹介します。
ジャーナル停止
各コマンドは、最終的にコマンド「DISABLE^%SYS.NOJRN」を呼んでいます。
なので↓のコマンドは、そこまで使わなくても良いかなーって感触です。
d STOP^%SYS.NOJRN
w $$STOP^%SYS.NOJRN // 1:ジャーナル停止
d DisableJournal^%SYS.NOJRN
w $$DisableJournal^%SYS.NOJRN
ジャーナル再開
現在使用している「$roles」が%All以外である場合、$ETRAPをクリアする等々の処理を実行します。
それ以外は、コマンド「ENABLE^%SYS.NOJRN」を実行するだけです。
d EnableJournal^%SYS.NOJRN
ジャーナルの状態確認
w $$CURRENT^%SYS.NOJRN // 1:ジャーナル開始, 0:ジャーナル停止
ジャーナルの開始/停止
引数によって停止と開始を制御可能。
※このコマンドは、「DISABLE」も「ENABLE」も呼ばない。
// ジャーナル停止
w $$SetJournal^%SYS.NOJRN(0)
// ジャーナル開始
w $$SetJournal^%SYS.NOJRN(1)
%SYS.Journal.File.clsの利用
ジャーナルのパージ
ジャーナルファイルの削除を実施します。
s sts = ##class(%SYS.Journal.File).Purge([NDaysOld],[NBackupsOld])
NDaysOld : 指定日数を経過したジャーナルを削除する(作成日ではなく完了日基準)
NBackupsOld : 「この回数のバックアップ成功後」
両引数は、管理ポータルのジャーナル設定画面の↓の設定になります。

トランザクションのロールバックまたはクラッシュ回復に必要なジャーナル ファイルを除き、すべてのジャーナル ファイルを消去します。
s sts = ##class(%SYS.Journal.File).PurgeAll()
%SYS.Journal.System.clsの利用
Queries
このクラスのカスタム・クエリは、「SQLProc」が付与されていないため「%ResultSet」を使用した実行方法しか行えません。
ただ、クラスの編集自体は可能なので、任意にSQLProcを付与してSQLとして実行する事は可能です。
ジャーナルファイルの進捗確認
下記サンプルは、コマンドを実行後ジャーナルの状態を60秒おきに確認します。
※明確な停止を行わない限り、ずっとループし続けます。
rowNo | 列名 | 説明 |
---|---|---|
1 | File Name | ジャーナルファイル名(フルパス) |
2 | File Count | ジャーナルファイルのファイル数 ジャーナルファイルを切り替える度にカウントアップしている。 |
3 | offset | ジャーナルのオフセット値 |
4 | offset Committed | 不明… |
5 | TimeStamp | 確認した時刻(GMT) |
ClassMethod Progress()
{
s rs=##class(%ResultSet).%New("%SYS.Journal.System:Progress")
d rs.Execute()
while rs.Next() {
w "Name:",rs.Data("File Name"),!
w "Count:",rs.Data("File Count"),!
w "Offset:",rs.Data("Offset"),!
w "Offset Committed:",rs.Data("Offset Committed"),!
w "TimeStamp:",$zdt($SYSTEM.Util.UTCtoLocalWithZTIMEZONE(rs.Data("TimeStamp")),3,1,6),!!
h 60
}
}
ジャーナルシステムの状態確認
下記サンプルは、コマンドを実行後ジャーナル・システムの状態を60秒おきに確認します。
※明確な停止を行わない限り、ずっとループし続けます。
ClassMethod Status()
{
s rs=##class(%ResultSet).%New("%SYS.Journal.System:Status")
d rs.Execute()
while rs.Next() {
w "Main Status:", rs.Data("Main Status"),!
w "Cause:", rs.Data("Cause"),!
w "Full Status:", rs.Data("Full Status"),!!
h 60
}
}
ジャーナルシステムの設定確認
ClassMethod Summary()
{
new $namespace
s $namespace = "%SYS"
s rs=##class(%ResultSet).%New("%SYS.Journal.System:Summary")
d rs.Execute()
w !,rs.GetColumnHeader(1),?40," ",rs.GetColumnHeader(2),!
while rs.Next() { w !,rs.Data("Parameter"),?40," ",rs.Data("Value") }
}
出力例

ジャーナルシステムの制御関連
クラス「%SYS.Journal.System」には、中級編で紹介したコマンドと同様の機能を有する関数がいくつか存在しています。
中級編と同様の機能ではありますが、異なる点として対話型になっていないため、実行時にシステムから確認等が求められません。
対話型ではないため、実行前にコマンドや引数等を念入りに確認する必要がありますが、バッチ処理等に組み込むには丁度良いと思います。
※全てのコマンドは%SYSネームスペースで実行して下さい。
ジャーナル開始
ジャーナルを開始します。既に開始している場合はエラーとなります。
w ##class(%SYS.Journal.System).Start()
w ##class(%SYS.Journal.System).Start(curdir, altdir, maxsiz, expsiz, prefix, okshdw)
関数「Start」実行時に下記を引数とすることで、ジャーナルシステムの設定を変更する事が可能です。
引数名 | 説明 |
---|---|
curdir | プライマリ・ジャーナルパス |
altdir | セカンダリ・ジャーナルパス |
maxsiz | ジャーナルファイルの最大サイズ |
expsiz | ジャーナルファイルの増加量 |
prefix | ジャーナルファイルのプリフィックス |
okshdw | ファイルの競合が発生する可能性があっても、シャドウ ジャーナル ファイルとディレクトリを共有する |
ジャーナル停止
ジャーナルを停止します。既に開始している場合はエラーとなります。
w ##class(%SYS.Journal.System).Stop()
ジャーナルの切り替え
処理内で、関数「RollToNextFile」を呼んでいる。
ただジャーナルを切り替えるだけであれば、次に紹介する「RollToNextFile」でも十分です。
w ##class(%SYS.Journal.System).SwitchFile()
w ##class(%SYS.Journal.System).SwitchFile(curdir, altdir, maxsiz, expsiz, okshdw, reason)
関数「SwitchFile」実行時に下記を引数とすることで、ジャーナル・システムの設定を変更する事が可能です。
※Startと一部重複するため割愛します
引数名 | 説明 |
---|---|
reason | 切り替え時の説明 省略すると管理ポータルのジャーナル画面に「指定されていません」と表示される。 ■下記数値から選択する 0 or null:指定されていません 1:ユーザにより 2:ファイルサイズの上限に到達 3:失敗したI/Oの再試行をするため 4:バックアップにより 5:リストアにより 6:タスクマネージャにより 7:ジャーナル設定変更を有効にするため 8:ジャーナルを再度有効にするため 9:ミラースタートアップにより 10:ミラーシャットダウンにより 11:ミラーデータベースが削除されました 12:UNKNOWN:12 13:ディレクトリテーブルを拡張するには 以下:UNKNOWN:[reason値] |
ジャーナルの切り替え
ジャーナリングを次のファイルに変更します
w ##class(%SYS.Journal.System).RollToNextFile(reason, .newFile),!
w newFile,!
ディレクトリの切り替え
切り替えが成功した後、現在のジャーナル ファイルのパスをNewFileに格納する
w ##class(%SYS.Journal.System).SwitchDirectory(.newFile),!
w newFile
ジャーナルシステムの情報取得
コマンドは全て%SYSネームスペースで実行して下さい。
WIJに保存されているジャーナルチェックポイント情報を返す
w ##class(%SYS.Journal.System).GetImageJournalInfo(.JournalFileName, .JournalFileOffset, .JournalFileCount, .OpenTransFileOffset, .OpenTransFileCount)
w JournalFileName,!
w JournalFileOffset,!
w JournalFileCount,!
w OpenTransFileOffset,!
w OpenTransFileCount,!
プライマリジャーナルディレクトリのパスを返す
w ##class(%SYS.Journal.System).GetPrimaryDirectory(.sts),!
w sts
セカンダリジャーナルディレクトリのパスを返す
w ##class(%SYS.Journal.System).GetAlternateDirectory(.sts),!
w sts
クラスタジャーナルログのパスを返す
w ##class(%SYS.Journal.System).GetClusterJournalLog()
最新のジャーナルファイル・オブジェクトを返す
obj : %SYS.Journal.File.cls
s obj = ##class(%SYS.Journal.System).GetCurrentFile()
w obj.Name
ジャーナルファイルのファイル数を返す
w ##class(%SYS.Journal.System).GetCurrentFileCount()
最新のジャーナルファイルのパスを返す
w ##class(%SYS.Journal.System).GetCurrentFileName()
最新のジャーナルファイルのオフセット値を返す
ジャーナリングがオフの場合は0を返す
w ##class(%SYS.Journal.System).GetCurrentFileOffset()
不明
ジャーナルファイルに使用可能な空き領域を返すらしい・・・
w ##class(%SYS.Journal.System).GetFreeSpace()
ジャーナルファイル名のプリフィックスを返す
w ##class(%SYS.Journal.System).GetJournalFilePrefix()
最後のジャーナルファイルのパスを返す
w ##class(%SYS.Journal.System).GetLastFileName()
ジャーナルシステムの状態を返す
w ##class(%SYS.Journal.System).Status()
ステータス値 | 説明 |
---|---|
0 | 有効 |
1 | 無効 (停止) |
2 | 一時停止 (I/O エラーのため) |
3 | フリーズ (I/O エラーのため) |
4 | 一時停止 (ジャーナル ファイルの切り替え中) |
ジャーナルシステムの状態を返す(ステータスを文字列で返す)
w ##class(%SYS.Journal.System).GetStateString()
日本語の場合、$$$Textで下記変換が行われる
ステータス値($$$Text変換) | 本来の戻り値 | 説明 |
---|---|---|
正常 | Normal | 有効で正常に実行中 |
無効 | Disabled | 停止中 |
一時停止 | Suspended | I/O エラーのため |
凍結 | Frozen | I/O エラーのため |
一時停止 | Paused | ジャーナル ファイルの切り替え中 |
現在のディレクトリではない方のディレクトリを返す
w ##class(%SYS.Journal.System).GetTheOtherDirectory(.Directory, .Type)
w Directory,!
w Type,!
Typeの値 | 説明 |
---|---|
1 | プライマリ・ジャーナルディレクトリ |
2 | セカンダリ・ジャーナルディレクトリ |
0 | 他にディレクトリがない |
ジャーナルシステムの状態確認
システム全体でジャーナルが無効になっているか確認する
w ##class(%SYS.Journal.System).IsDisabled()
システム全体でジャーナルがフリーズしているか確認する
w ##class(%SYS.Journal.System).IsFrozen()
システムが回復しようとしているジャーナリングエラーがあるか確認する
w ##class(%SYS.Journal.System).IsGettingIOError()
システム全体でジャーナルが一時停止しているか確認する
w ##class(%SYS.Journal.System).IsPaused()
ジャーナルシステムへの設定
プライマリ・ジャーナルディレクトリの設定
w ##class(%SYS.Journal.System).SetPrimaryDirectory(dir, create)
セカンダリ・ジャーナルディレクトリの設定
w ##class(%SYS.Journal.System).SetAlternateDirectory(dir, create)
ジャーナルファイルに目印を付ける
ジャーナルファイルに目印(マーカ)を入力する事が出来ます。
デバッグ用などに利用すると便利です。
引数「id(%Integer)」「テキスト(%String)」は自由に設定が可能です。
zn "%SYS"
w $$ADD^JRNMARK([id], [テキスト])
// 例
w $$ADD^JRNMARK(4649, "よろしく!")
ジャーナルファイルにマーカを設定できます。

おわりに
いかがだったでしょうか。
処理上でジャーナルファイルを操作する場合は、対話のない処理が必要になります。
中級編では、対話型でのジャーナル操作を行いましたが、上級編ではユーザへのアクションが無いため、処理の成功/失敗は必ず確認する必要があります。
ジャーナル操作を処理に組み込む必要がある場合は、この記事を参考にして下さい。