FIS GT.M アカルチュレーション ワークショップ(Ver 0.7)にようこそ

Copyright © 2011 Fidelity Information Services, Inc. All rights reserved.

Free Software Foundationによって公開されているGNU Free Documentation License, Version1.3 またはそれ以降のバージョンで同意されたものとして、本マニュアルの修正版の複写と配布は、修正版全体が本許可告知と同一の条件のもとに配布される場合にのみ許可します。但し、「変更不可能部分」「おもて表紙テキスト」「うら表紙テキスト」など変更不可部分は含みません。

GT.M™ は、Fidelity Information Services, Inc. のトレードマークです。その他商標は、それぞれの所有者の所有物です。

このドキュメントにおけるGT.Mの説明および操作方法は、システムを構成するさまざまな機能に関するものが含まれます。このドキュメントには、FISのコミットメントは何も含まれていません。FISは、この文書の情報は発表日現在において正確であると考えていますが、情報は予告なしに変更される場合があります。FISのすべてのエラーまたは欠陥について責任は負いません。

目次 - ナビゲーション

アカルチュレーション ワークショップ(Ver 0.7)に期待すること
GT.M
パッケージング
はじめに
基本
セキュリティ
ジャーナリング
データベース レプリケーション
バックアップ
簡便に巻き戻すレプリケーション
ユニコード(ISO/IEC-10646)
データベース暗号化
GT.M 協力者

概要

アカルチュレーション ワークショップ(Ver 0.7)に期待すること

GT.Mアカルチュレーション ワークショップ(文化変容ワークショップ)は、GT.M上で設定、管理、アプリケーションなどの操作をする中で、これらに興味を持っていただくために、ハンズオンでの GT.M "ブートキャンプ" です。このファイルには、スクリプト、または、ワークショップのためのワークブックで、以下の演習で構成されています。

これらの演習の最後には、GT.Mの管理とオペレーションの重要なアスペクトの基本的な知識を持つことになります。このワークショップでは、任意の手段により独学でGT.Mのエキスパートになるものではありませんが、基本的な作業の知識は、ユーザドキュメンテーションに記載されているコンセプトをすぐに理解し、エキスパートになるための道を行くのに、に役立ちます。

ワークショップは、Mプログラミングのコースではありません。Linux ® の知識 (あるいは、少なくともUNIX ® の知識 )は、この教材を介して素早く習得することができるようになりますが、必ずしも必要ではありません。あなたがLinuxまたはUNIXの経験が全くないならば、座右の補助チュートリアル教材は、あなたの快適さのレベルを向上するでしょう。

GT.Mと他のM言語実装と違いは、M言語の機能と言うよりは、むしろ、設定やシステム管理の領域が大きいです。前者のトピックは、ワークショップの主要な推力です。

GT.M

FIS GT.M™ は、 ISO標準のスクリプト言語でアプリケーション開発 M言語で実装されています。一般的にMUMPSとして知られ、 FISにより開発されリリースされています。 FIS Profileアプリケーションのプラットフォームとして、GT.MはMの実装として最も広く使われ、銀行や金融、我々が知っている最大のリアルタイムのコア処理システムの中で、世界のどこにでもある銀行で活躍しています。さらに、GT.Mは益々、医療に使用されます。業界標準x86アーキテクチャハードウェアでGNU/Linuxオペレーティングシステム上のGT.Mの実装では、VistA FOSS (フリー/オープンソースソフトウェア)スタックとして、Mの実装は使用されています。

GT.Mは、以下の目的で設計されています:

GT.Mのフリーなサポートとしては、様々なメーリングリストや電子フォーラムなどのコミュニティがあります。保証を必要とするサービスレベルのサポートは、FISのコマーシャルベースから利用できます。

GT.Mが提供するもの:

構造化システム変数名(SSVNs)を除いて、GT.Mは、ACID(Atomic, Consistent, Isolated, Durable)トランザクションを提供するトランザクション処理(TP)を完全な実装を含む、ISO標準のM言語(ISO 11756 1999)です。Mの実装と同様に、それらは拡張です。I/Oパラメータは実装に明記され、例えば、VIEWコマンドのパラメータや頭文字がZで始まるコマンドと変数などです。

事実にもかかわらず、他のMの実装とあまり共通点がGT.M共有によって実装されるMの方言では、運用、GT.Mは、任意の他のMの実装とは違っていることを確認します。

このアカルチュレーション ワークショップはGT.M V5.4-002Bをベースにします。

パッケージング

演習は、ホストコンピュータ上のゲスト仮想マシン(また、ソフトウェアアプライアンスと呼ばれる)を起動して実行します。仮想マシンは、"コンピュータ内のコンピュータ"として考えてください。ゲスト仮想マシンは、ホストコンピュータとは異なるオペレーティングシステムで実行することができます。ホストコンピュータはWindows、Solaris、OS X、または、他のオペレーティングシステムで動作でき、ゲストでは、他のアプリケーションと同様に、Linux上でGT.Mを動作できます。"エミュレーション" または "仮想化"ソフトウェアは、ホストコンピュータ上のゲストシステムをセットアップすることを助けます。ホストコンピュータ上では、GT.Mアカルチュレーション ワークショップのディスクイメージを、ファイルシステム内の通常のファイルと同じようにゲストと見なします。

Linux

LinuxはGNU/Linuxオペレーティングシステムの一般名称で、Linuxカーネルでは、GNUユーティリティとライブラリから構成され、オペレーティングシステムのハードウェアの広い範囲にわたって利用されています。最も広く業界標準アーキテクチャであるx86ハードウェア上で使用され(すなわち、インテル、AMDおよび他のベンダーから人気のあるCPU)、そしてアプリケーションとしてますます世界中で人気があり、組み込みコンピューティング(アプライアンス)、個人のデスクトップ、ファイル、印刷、Webサーバー、スーパーコンピューティング、そして、ミッションクリティカルなソフトウェア上で展開しています。LinuxはVistAのFOSSスタックのオペレーティングシステムで利用されています。

Linuxのフリーサポートとして、多くのメーリングリストや電子フォーラムがあります。商用サポートは、広く複数のベンダーから提供されています。

日は経過していますが、 Linux: Rute User's Tutorial and Expositionは、誰もがLinuxを始めるために、非常に有用で利用可能なチュートリアルです。Linux上の DebianプロジェクトメンテナンスブックDebian Wikiは、有益なリファレンス情報です、さらに、 Debianリファレンスカードのペーパーコピーの手軽さを持っていることは、誰もが全く、Linuxで快適に役に立つでしょう。

GT.M アカルチュレーション ワークショップは、最小のディスクイメージを使用して起動する仮想マシンで、 Ubuntu 11.10 ( " Oneiric Ocelot " :夢見がちな大形ヤマネコ ) Linuxディストリビューションです、追加のドキュメントリソースがあります 。

表記法

青色の等幅フォントのテキストは、GT.Mプロンプトにタイプ入力するためのものです(GDEなどのユーティリティプログラムと同様に、メインの GTM>プロンプトを含む )。赤色の等幅フォントのテキストは、シェルまたはLinux上の他の場所から実行されるコマンドへの入力としてシェルプロンプトにタイプするためのものですが、- しかし、ホスト上で 実行されるGT.Mコマンドではなく、そのようなもは上記のように、緑色の等幅フォントです 。

キーボード&マウスの制御

ゲスト仮想マシンが起動する際に、キーボードまたはマウスの占有権を、ホストとゲストとで切り替える必要があるでしょう。仮想化として使用するソフトウェアが、どのように制御を転送するかを特定します。

kvm / QEMUの場合は、ホストとゲストの間でマウスとキーボードの占有権を切り替えるには、Ctrl - Altキーの組み合わせを使用します。ホストがキーボードを占有している場合でも、フォーカスがある時には、ゲストのコンソールにタイプすることができます、しかし、その逆もあります。マウスをクリックするだけで、マシンは、ホストまたはゲスト、マウスを占有していると表示されます。

ターミナルエミュレーション

最小限の仮想マシンでブートして、ターミナルエミュレータからターミナルセッションを使用して仮想マシンに接続することをお勧めします。Windowsでは、puttyのようなターミナルエミュレータを使用できます 。Linuxディストリビューションには、端末エミュレーションが含まれています。ターミナルエミュレータは、他のコンピュータプラットフォームもしばしば含んでいますので利用できます。

Unicodeの演習では、UTF-8文字およびシングルバイト文字のどちらか一方に切り替えることができるターミナルエミュレータが必要になります。または、それぞれ専用の2つのエミュレータが必要になるかもしれません。もし右から左へ書く言語を使用するつもりならば、双方向機能を備えたターミナルエミュレータが必要になります。

仮想化

ここで例として使用されている仮想化ソフトウェアはQEMUです。QEMUは、Windows、Linux など、多くの人気のコンピューティングプラットフォームで利用可能です。手順は、WindowsとLinuxホストの下で提供されています。Linuxホストでは kvmが好ましい選択です(kvmとQEMUは、非常によく似たユーザーインターフェイスを提供しています)。 VirtualBox OSEは、他で人気FOSSの仮想化アプリケーションです。独自の仮想化ソフトウェアもあります。ここでの例は、kvm/QEMUですが、あなたは任意の仮想化ソフトウェアを使用することができます。

演習は、Ubuntu Linux 11.10 のkvmを使用してテストされています。

ディスクフォーマット

GT.Mアカルチュレーション ワークショップは、仮想化ソフトウェアで動作する vmdk format ディスクイメージのファイルとして配布されます(例:ubuntu-11.10_gtmworkshop7.vmdk)、FOSSとプロプライエタリのの両方があり、そしてQEMU/kvmで動作するqcow2フォーマットのディスクイメージがあります。

仮想マシンの構成

仮想化ソフトウェアは、複数のIPアドレスを持っているホストのネットワーク接続(有線または無線)のそれら自身のIPアドレスか、より一般的なネットワークアドレス変換(NAT)を使用するかの、どちらで仮想マシンを構成します。後者の場合には、ホストのネットワーク接続は、それが外の世界に表現する1つのIPアドレスを持ちますが、各仮想マシンは、ホスト(ホストはちょうど自宅のWifiアクセスポイント/ルーターのように働く) の内のサブネットのIPアドレスを持っています。

アウトバウンドとインバウンドのネットワークアクセスのために、仮想マシンを設定する必要があります。アウトバウンドアクセスが仮想マシンのネットワーク接続のどちらかのタイプで作動させるためには設定は必要ないはずですが、NAT環境内のインバウンドのネットワークアクセスでは、仮想マシン上のサービスが応答する必要がある時に、各ポート用の仮想マシンに転送するために、ホスト上のTCPポートが必要になります。例えば、各仮想マシンは、着信接続用にポート22でリスニングのセキュアシェル(SSH)サーバを持っており、あなたの仮想マシン上のポート22へ、ホスト上のポート2222への転送を選択できます。

仮想マシンのネットワークを設定するには、仮想化ソフトウェアのユーザーマニュアルを参照してください。たとえば、Linuxホスト上で kvm を使用して、次のコマンドブーツに必要なポートフォワーディングを持つ vmdkKイメージ:

kvm -enable-kvm -cpu host -net nic -net user,hostfwd=tcp::2222-:22 -hda /Distrib/Ubuntu/ubuntu-11.10_gtmworkshop7.vmdk &

著作権、使用権など

GT.Mは、所有しているとFidelity Information Services, Inc.が所有し著作権で保護され 、はGNU Affero General Public Licenseのバージョン3 の条件の下でx86 GNU/Linuxプラットフォームで利用可能です。ソースおよびバイナリは、 Source Forge のGT.Mプロジェクトページからダウンロードすることができます 。

(いわゆる "FOIA VistA"と呼ばれる)VistAコアは、米国の自由な情報公開を介してパブリックドメインです。ソースおよびオブジェクトコードは、ハードドライブのイメージの1つを利用してください。上述したように、ご自身でVistAを理解できない方が、このワークショップを必要とすることを想定してます。

Linuxカーネルは、GNUユーティリティ、VistaにWorldVistA EHRの拡張機能とCD - ROM上の他のすべてのソフトウェアおよびハードドライブのイメージは、それぞれのFOSSのライセンスの下でFOSSのは、ご利用いただけます。著作権およびすべてのコンテンツの商標または登録商標は、それらの所有者によって開催されて承認されています。

はじめに

ターミナルエミュレータで、localhost 上のポート2222 へSSH接続を開始してください、そして、ユーザーID gtmuser、パスワード GT.M Rocks! (スペースや感嘆符を含む)でログインしてください。たとえば、Linux上で、次のコマンドを使用することができます: ssh -p 2222 -X gtmuser@localhost 、ゲスト上のポート22へフォワードされるホストのポート2222へユーザー名がgtmuserで接続します。このスクリーンショットは、Linuxホストからsshを使用して、仮想マシンにログインするターミナルセッションです。


イラスト1:sshの初期接続




注意:スクリーンショットは、最初の接続を示しています。接続に引き続き、以下詳細です:

$ ssh -X -p 2222 gtmuser@localhost
gtmuser@localhost's password:
Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686)

 * Documentation:  https://help.ubuntu.com/
Last login: Thu Nov 17 01:50:08 2011 from 10.0.2.2
gtmuser@gtmworkshop7:~$ 

ダウンロードしGT.Mをインストール

はじめに、Source Forgeのからx86プラットフォーム上の32ビットのGNU/Linux用のGT.Mをダウンロードします。現在のGT.MのリリースはV5.4-002Bであり、 /tmpなどのテンポラリディレクトリにダウンロードできます、そしてwgetのプログラムを起動して:wget -P /tmp http://sourceforge.net/projects/fis-gtm/files/GT.M-x86-Linux/V5.4-002B/gtm_V54002B_linux_i686_pro.tar.gz

そして、テンポラリディレクトリを作成し、そこに tarball の内容を解凍します。

gtmuser@gtmworkshop7:~$ mkdir /tmp/tmp
gtmuser@gtmworkshop7:~$ cd /tmp/tmp
gtmuser@gtmworkshop7:/tmp/tmp$ tar zxf ../gtm_V54002B_linux_i686_pro.tar.gz
gtmuser@gtmworkshop7:/tmp/tmp$ 

/usr/lib/fis-gtm/V5.4-002B_x86のディレクトリに GT.M をインストールします。これは root として実行する必要があります。

gtmuser@gtmworkshop7:/tmp/tmp$ sudo ./configure
[sudo] password for gtmuser: 
                     GT.M Configuration Script
Copyright 2009, 2011 Fidelity National Information Services, Inc. Use of this
software is restricted by the provisions of your license agreement.

What user account should own the files?(bin) root
What group should own the files?(bin) root
Should execution of GT.M be restricted to this group?(y or n) n
In what directory should GT.M be installed?/usr/lib/fis-gtm/V5.4-002B_x86

Directory /usr/lib/fis-gtm/V5.4-002B_x86 does not exist. Do you wish to create it as part of
this installation?(y or n) y

Installing GT.M....

Should unicode support be installed?(y or n) y
Should an ICU version other than the default be used?(y or n) n

All of the GT.M MUMPS routines are distributed with uppercase names.
You can create lowercase copies of these routines if you wish, but
to avoid problems with compatibility in the future, consider keeping
only the uppercase versions of the files.

Do you want uppercase and lowercase versions of the MUMPS routines?(y or n)y

Creating lowercase versions of the MUMPS routines.
./CHK2LEV.m --->  ./chk2lev.m
./CHKOP.m --->  ./chkop.m
./GENDASH.m --->  ./gendash.m

...

./_UCASE.m --->  ./_ucase.m
./_UTF2HEX.m --->  ./_utf2hex.m
./_XCMD.m --->  ./_xcmd.m

Compiling all of the MUMPS routines. This may take a moment.


GTM>
%GDE-I-GDUSEDEFS, Using defaults for Global Directory 
        /usr/lib/fis-gtm/V5.4-002B_x86/gtmhelp.gld

GDE> 
GDE> 
GDE> 
%GDE-I-VERIFY, Verification OK

%GDE-I-GDCREATE, Creating Global Directory file 
        /usr/lib/fis-gtm/V5.4-002B_x86/gtmhelp.gld

GTM>
%GDE-I-GDUSEDEFS, Using defaults for Global Directory 
        /usr/lib/fis-gtm/V5.4-002B_x86/gdehelp.gld

GDE> 
GDE> 
GDE> 
%GDE-I-VERIFY, Verification OK

%GDE-I-GDCREATE, Creating Global Directory file 
        /usr/lib/fis-gtm/V5.4-002B_x86/gdehelp.gld

Installation completed. Would you like all the temporary files
removed from this directory?(y or n) y
gtmuser@gtmworkshop7:/tmp/tmp$ 

GT.Mは今インストールされ、動作しています。

GT.Mを実行する

デフォルトの環境

GT.Mでは、セットアップするためにいくつかの環境変数が必要です。仮想マシンでは、適切なデフォルト値を設定し、GT.Mを正しく使用するために必要なスクリプトが付属しています。ファイルは、適切なデフォルト値を設定するために /usr/lib/fis gtm/V5.4 002B_x86/gtmprofile を sourceコマンドができ、または、GT.M.を実行するためにgtmのスクリプトを単に実行することができますす。それが既に存在していない場合は、デフォルト環境にのみ作成されます。

gtmuser@gtmworkshop7:~$ source /usr/lib/fis-gtm/V5.4-002B_x86/gtmprofile
%GDE-I-GDUSEDEFS, Using defaults for Global Directory 
        /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.gld

GDE> 
%GDE-I-EXECOM, Executing command file /usr/lib/fis-gtm/V5.4-002B_x86/gdedefaults

GDE> 
%GDE-I-VERIFY, Verification OK

%GDE-I-GDCREATE, Creating Global Directory file 
        /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.gld
Created file /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.dat
%GTM-I-JNLCREATE, Journal file /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now ON
gtmuser@gtmworkshop7:~$ 

gtmprofile を source することは、GT.Mを実行するgtm スクリプトへのエイリアスとしてgtmも定義します(それについては後ほど説明します)。

gtmuser@gtmworkshop7:~$ alias gtm
gtm='/usr/lib/fis-gtm/V5.4-002B_x86/gtm'
gtmuser@gtmworkshop7:~$ gtm
GTM>

今、対話的にコマンドを実行することができる GT.Mの"ダイレクトモード" にいます。次に例を示します。

GTM>set ^Capital("USA")="Washington"

GTM>set ^Capital("India")="New Delhi"

GTM>set ^Capital("Jordan")="Amman"

コマンドは、プロセス間で共有されているデータベース更新を実行します。もし新しいターミナルセッションを開始するならば、新しいGT.Mプロセスが始まり、そして、それは ^Capital( キーと値の関連付ける)"グローバル変数" をdumpするために要求することを、見ることができます。halt コマンドは、Linuxのシェルに戻ることを表示します。

GTM>zwrite ^Capital
^Capital("India")="New Delhi"
^Capital("Jordan")="Amman"
^Capital("USA")="Washington"
GTM>halt
gtmuser@gtmworkshop7:~$

GT.Mの動作は、環境変数の数によって制御されます。私たちの演習では、 gtmprofileスクリプトが、自動的に環境変数の数をセットします:

gtmuser@gtmworkshop7:~$ env | grep gtm
gtm_repl_instance=/home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.repl
gtm_log=/tmp/fis-gtm/V5.4-002B_x86
gtm_prompt=GTM>
gtm_retention=42
gtmver=V5.4-002B_x86
USER=gtmuser
gtm_icu_version=4.2
gtmgbldir=/home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.gld
MAIL=/var/mail/gtmuser
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/fis-gtm/V5.4-002B_x86
gtmroutines=/home/gtmuser/.fis-gtm/V5.4-002B_x86/o(/home/gtmuser/.fis-gtm/V5.4-002B_x86/r /home/gtmuser/.fis-gtm/r) /usr/lib/fis-gtm/V5.4-002B_x86
PWD=/home/gtmuser
gtmdir=/home/gtmuser/.fis-gtm
HOME=/home/gtmuser
gtm_principal_editing=EDITING
LOGNAME=gtmuser
gtm_tmp=/tmp/fis-gtm/V5.4-002B_x86
gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
gtmuser@gtmworkshop7:~$ 

GT.Mデータベースは、システムのクラッシュ後にリカバーできるように構成することもできます。即座に仮想マシン"電源を切るには、仮想マシンのコンソールウィンドウの右上隅の"X"をクリックすることで、すぐにクラッシュをシミュレーションできます。その後ブートし、gtmZWRite ^Capital コマンドを使用し、データベース内のデータが無傷でそのまま残っていることを確認します。

ツリープログラムは、デフォルトGT.M環境がホームディレクトリに作成されていることを示しています。スクリーンショットは、ツリー カラー出力を示しています。




以下の詳細で、これを取得するでしょう。

UTF-8モード

GT.Mでは、Unicode または ISO/IEC-10646を使って設定して、国際文字を実装するアプリケーションを書くことができます(2つの規格は互いに追跡しあいます)。ターミナルエミュレータで仮想マシンへの接続は、UTF-8文字セットをサポートするように構成されました。新鮮なターミナルセッションで、次のコマンドを実行します(利用するターミナルエミュレータのレンダリング方法に応じて、非印刷文字がここの画面からのセッションでは異なって見える場合があります):

gtmuser@gtmworkshop7:~$ export gtm_chset=UTF-8 LC_CTYPE=en_US.utf8
gtmuser@gtmworkshop7:~$ source /usr/lib/fis-gtm/V5.4-002B_x86/gtmprofile
gtmuser@gtmworkshop7:~$ gtm
GTM>write $zchset
UTF-8
GTM>for i=1040:16:1072 write !for j=0:1:15 write $char(i+j)," "

А Б В Г Д Е Ж З И Й К Л М Н О П
Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
а б в г д е ж з и й к л м н о п
GTM>

注意:Unicodeサポートは、ターミナルエミュレータがUnicodeを有効にするような追加のインフラストラクチャを必要とし、そして、言語的にも文化的にも正しい順序でソートされる名前などの文字列を、確実に書き出すためのカスタム照合モジュールを必要とするでしょう。

以下の演習では、Unicodeで使用するための環境をセットアップします。

基本

GT.Mを使用するために、最小に必要なもの:

ユーザードキュメント

GT.Mのユーザードキュメントは、マニュアルと技術情報で構成されています。マニュアルは、定期的に更新され、技術情報は、よりタイムリーな方法で利用され更新され、ユーザードキュメントとして提供しています。現在のGT.Mドキュメントは、GT.Mドキュメントサイトからオンラインで入手だけでなく、このCDのローカルコピーにもあります。すべての現時点のGT.Mドキュメントは、インターネットからアクセスでき、 GT.Mのホームページに移動し、ユーザードキュメントのタブをクリックします。

GT.Mドキュメントは、マニュアル、技術情報、推奨手法、アドバイスで構成されています。:

ファイルシステムのルーチン

GT.Mのルーチンはファイルシステム内のシンプルなファイルで、それらはデータベースに存在しません。GTM>プロンプトからルーチンを編集することができます。GT.Mを開始し、GTM>プロンプトで 、zedit "welcome"とタイプし、ENTERキーを押します。これは、/home/gtmuser/.fis-gtm/V5.4-002B_x86/r/welcome.m ファイルで、^hello のソースルーチンをviエディタ編集が開始します。5つキーを連続に押すことで、ESCAPE : q ! ENTER、ファイルを変更せずにviを終了します。

注意:vi は常にファイルの末尾に改行を置きますが、他のエディタではない場合があります。 GT.Mのプログラムファイルは、常に改行で終了する必要があります。

GT.Mの哲学は、堅牢で、スケーラブルで、M言語のトランザクション処理のデータベースとコンパイラを提供すべきことに集中し、そして、RESTにおける基となるオペレーティングシステムでは、ツールと機能を利用することです。基になるオペレーティング環境に拡張機能があるたびに、GT.Mはそれらからの恩恵を受けることができ、したがって強力なのです。伝統的なMの実装では、カタツムリの背中に乗ったシェルのように、それらの周りの環境を運ぶため、GT.MへのMプログラマのマイグレーションにとって少し不快なことがしょう。

GT.Mが、まだ対話的な直接モードを提供している真のコンパイラであるにもかかわらず、対話的なMコマンドを実行するときに見たように、- GT.Mは、単にコンパイルし、それぞれの行を実行します。

演習 - コンパイルとリンク

この演習の目的は、ルーチンのコンパイルとリンクを理解することです。find .fis-gtm -iname hello.[mo] コマンドを使用して、デフォルトのGT.M環境は、"hello"と呼ばれるプログラムを持っていないことを確認します。

gtmuser@gtmworkshop7:~$ find .fis-gtm -iname hello.[mo]
gtmuser@gtmworkshop7:~$ 

GT.Mの中からも、同じ操作を実行することができます

GTM>ZSYSTEM "find .fis-gtm -iname hello.[mo]"
GTM>

or

GTM>do SILENT^%RSEL("hello") zwrite %ZR
%ZR=0

GTM>

そこには、ルーチンをしていた、応答は次のようになります。

GTM>do SILENT^%RSEL("hello") zwrite %ZR    
%ZR=1
%ZR("hello")="/home/gtmuser/.fis-gtm/r/"

GTM>

もしデフォルトのviエディタの簡潔なコマンドに慣れていないならば、好みのエディタをインストールすることができます。仮想マシンにインストールされている2つの他のエディタは jed や fte です。

gtmuser@gtmworkshop7:~$ export EDITOR=`which jed`
gtmuser@gtmworkshop7:~$ gtm
GTM>

ルーチン ^hello を実行することをGT.Mに指示し、そして、エラーを報告することに注意してください:

GTM>Do ^hello
%GTM-E-ZLINKFILE, Error while zlinking "hello"
%GTM-E-FILENOTFND, File hello not found
GTM>

GT.M内で、エディタを起動するために ZEDit "hello" を使用してください。シンプルな "Hello, World" プログラムを作成します。今すぐ(GT.M内で、以前のコマンドを呼び出すために矢印キーを使用することができます)ソースファイルが存在していることに注意してください。

GTM>do SILENT^%RSEL("hello") zwrite %ZR
%ZR=1
%ZR("hello")="/home/gtmuser/.fis-gtm/V5.4-002B_x86/r/"

GTM>do SILENT^%RSEL("hello","OBJ") zwrite %ZR
%ZR=0

GTM>

これで、プログラムを実行します - 期待どおりに実行します。

GTM>do ^hello
Hello, World

GTM>

今、オブジェクトファイルを持つことを今確認するには、find コマンドを実行してください。do ^hello と入力して実行すると、GT.Mは動的に自動的に、オブジェクトプログラムに対してソースプログラムをコンパイルします 。

[GT.Mはコンパイラですので、実行時だけでなく、コンパイル時にもエラーメッセージを生成することができることに注意してください。VistAなどのようなアプリケーションを実際にコンパイルする時は、GT.Mではなく他のMの実装にとって正規なコード行によって引き起こされるエラーメッセージが数百行もある可能性があります。これらの行はVistAでは保護されており、適切なMの実装でのみ実行される条件文の中にあるので、何も心配は無いです。]

この場合では、ファイルのタイムスタンプを取得します。

GTM>do SILENT^%RSEL("hello") zwrite %ZR
%ZR=1
%ZR("hello")="/home/gtmuser/.fis-gtm/V5.4-002B_x86/r/"

GTM>do SILENT^%RSEL("hello","OBJ") zwrite %ZR
%ZR=1
%ZR("hello")="/home/gtmuser/.fis-gtm/V5.4-002B_x86/o/"

GTM>

ファイルのタイムスタンプを取得してみましょう:

GTM>zsystem "find .fis-gtm -name hello.[mo] -exec ls -l {} \;"
-rw-rw-r-- 1 gtmuser gtmuser 401 2011-11-07 12:05 .fis-gtm/V5.4-002B_x86/o/hello.o
-rw-rw-r-- 1 gtmuser gtmuser 33 2011-11-07 11:19 .fis-gtm/V5.4-002B_x86/r/hello.m

GTM>

今、zedit "hello"プログラムを編集して変更し、例えば、代わりに"Aloha, World"と表示するならば、保存してください。再度、do ^helloを実行すると、GT.Mは、まだ、"Hello, World"と表示することに注意してください。GT.Mが既にそのアドレス空間にリンクされている helloモジュールを持っているので、もし新しいバージョンがある場合でも、チェックするためにいつでも消去しません。これは、"上書き保護(clobber protection)" です。GT.Mの機能です。

たとえ既にそのアドレス空間にリンクされていても、helloを再リンクするためにGT.Mに今すぐ指示を、zLink "hello"と実行します。続いて、do ^helloと実行すると、今は"Aloha, World" と表示することに注意してください 。ソースファイルが新しいことを確認し、GT.Mは新しいオブジェクトファイルを作成していることを確認します。

GTM>zedit "hello"

GTM>do ^hello
Hello,world

GTM>zlink "hello"

GTM>do ^hello
Aloha, world

GTM>zsystem "find .fis-gtm -name hello.[mo] -exec ls -l {} \;"
-rw-rw-r-- 1 gtmuser gtmuser 405 2011-11-07 12:09 .fis-gtm/V5.4-002B_x86/o/hello.o
-rw-rw-r-- 1 gtmuser gtmuser 34 2011-11-07 12:08 .fis-gtm/V5.4-002B_x86/r/hello.m

GTM>

編集したルーチンの古いバージョンを実行すると、驚くことを回避するために、GT.Mでは、どのように動的コンパイルとリンクが動作していることを理解することが重要です

$zroutines ISVは、ルーチンを見つけるためにGT.Mへ指示します:

GTM>write $zroutines
/home/gtmuser/.fis-gtm/V5.4-002B_x86/o(/home/gtmuser/.fis-gtm/V5.4-002B_x86/r /home/gtmuser/.fis-gtm/r) /usr/lib/fis-gtm/V5.4-002B_x86
GTM>

プロセスの起動時に、$zroutinesは、環境変数 $gtmroutines から初期化されますが、GT.Mプロセス内から変更することができます。

GTM>set $zroutines=". "_$ztrnlnm("gtm_dist")

GTM>write $zroutines
. /usr/lib/fis-gtm/V5.4-002B_x86
GTM>write $ztrnlnm("gtmroutines")
/home/gtmuser/.fis-gtm/V5.4-002B_x86/o(/home/gtmuser/.fis-gtm/V5.4-002B_x86/r /home/gtmuser/.fis-gtm/r) /usr/lib/fis-gtm/V5.4-002B_x86
GTM>

ZEDit コマンドは、常に検索パス中の最初のソースディレクトリに、新しいルーチンを置きます。標準時で現在の日付と時刻を表示する新しいルーチンを作成するために使用します。上記 $zroutines に変更した後、新しく作成されたプログラムとオブジェクトファイルがカレントディレクトリ (.) で作成されている様子がわかります。

GTM>zedit "UTC"
GTM>zprint ^UTC
UTC ZSYstem "TZ=UTC date"
Quit
GTM>do ^UTC
Wed Sep  1 19:57:13 UTC 2010
GTM>zsystem "find . -name UTC\* -exec ls -l {} \;"
-rw-r--r-- 1 gtmuser gtmuser 377 2010-09-01 15:57 ./.fis-gtm/V5.4-002B_x86/o/UTC.o
-rw-r--r-- 1 gtmuser gtmuser 32 2010-09-01 15:57 ./.fis-gtm/V5.4-002B_x86/r/UTC.m

GTM>

プログラマガイドの $ZROutinesの使用方法 で詳細に説明しています。

演習 - アプリケーションにおけるデフォルト・ディレクトリ構造

tree -d .fis-gtmコマンドを使用して、.fis-gtm以下のデフォルト・ディレクトリ構造を見ます。それぞれのディレクトリの目的は何か?

グローバルディレクトリはグローバル変数をポイントします。

GT.M ルーチンはデータベース内では無くファイルシステムに属し、一方グローバル変数はデータベース内に属します。ルーチンは、グローバル変数と完全に独立しています。この点で、GT.Mは他のM実装とは異なります。

人物の名前が与えられたと仮定し、電話帳は与えられている電話番号から、その人物と時々上手にそれらの住所を見つけるための助けをしてくれます。同様に、Mグローバル変数名が与えられたと仮定し、グローバルディレクトリは、他の適切な情報だけでなく変数が属するその与えられているデータベースファイルによって、常駐GT.Mプロセスが変数を見つける助けをしてくれます。

グローバルディレクトリは、ISV $zgbldir によってポイントされているバイナリファイルです。 GDEユーティリティプログラムは、グローバルディレクトリをマネージメントするために使用されます(GT.M内部から do ^GDE、または、シェルから mumps -run ^GDE で呼び出されます)。[GDEへの入力はテキストファイルであることに注意してください。本番プロダクション稼働環境では、テキストファイルは、データベース構成を定義するために使用し、これらのテキストファイルは、バージョン管理下に置くことを、FISは推奨します。]

GT.Mでは、Mグローバル変数(Names または Name spaces)のセットは、Mグローバルに関連するプロパティを定義している Regions(領域) にマッピングされています。それぞれのRegion(領域)は、ファイルシステムに関連するプロパティを定義する Segment(セグメント)にマップされます。下図の例で考えてみましょう:




この例では、REST(REpresentational State Transfer)から分離するような4つのMグローバル変数があります(例えば、アプリケーション間で共有するグローバルの用途、または、保護の理由のため -- おそらく、爬虫類の学者は^Gharial(インドガビアル)^Jacare(ジャカレイ)のグローバルへのみアクセスでき、鳥類学者は^Hoopoe(ヤツガシラ)^Trogon(キヌバネドリ)のグローバルにのみアクセスできるるようにするために、それらには特別な情報が含まれているのでしょう )。これは、5つの空間名前Name Spaces を作成することで達成されます (この例のように、空間名前 name space は、単一の変数が含まれて、または、グローバル変数の範囲が含まれていることに注意してください。^Gharial (インドガビアル)を介して^Aで始まるすべて)。デフォルト(default) (*) の name spaceは常に存在します。

1つ以上のname spaces(ネームスペース)には、1つの Region(領域)がマップされます。1つのregion(領域)の内のすべてのグローバル変数は、最大レコード長やnull添字が許可できるかどうか等のグローバル変数プロパティの共通セットを共有します。このケースでは、^Gharial(インドガビアル)^Jacare(ジャカレイ)はregion(領域)REPTILESにマッピングされていて、ところが、 ^Hoopoe(ヤツガシラ)^Trogon(キヌバネドリ)はregion(領域) BIRDSにマッピングされています。 デフォルトのname space(ネームスペース) * DEFAULTと呼ばれる1つのregion(領域)にマッピングされています。

それぞれのregion(領域)は、1つのSegment(セグメント)へマッピングされています。1つのregion(領域)がMグローバル変数に属しているプロパティを定義するのと同様に、segment(セグメント)は、ファイル名、初期割り振り(allocation)、グローバルバッファ数など、その領域のデータベースファイルに属するプロパティを定義します。データベースファイルは、基になるオペレーティングシステムのファイルシステム内の1つの普通のファイルです。

それぞれのデータベースファイルは、単一のアクティブなジャーナルファイルを持つことができます。ジャーナルファイルは、ジャーナルファイルのチェーンを形成するために、以前のジャーナルファイルにリンクするします。

ISV $zgbldirは、グローバルディレクトリへGT.Mプロセスをポイントします。$ZGbldir は、プロセスの起動時に $gtmgbldir から初期化されますが、それは、実行中のプロセスによって変更することができます。

GTM>write $ztrnlnm("gtmgbldir")

/home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.gld
GTM>write $zgbldir

/home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.gld
GTM>

GDE(Global Directory Editor)は、グローバルディレクトリを操作するために使用されるプログラムです。 GDE自体はM言語で書かれており、$gtm_dist/mumps -run GDEにてシェルから呼び出すことができます (または、gtmエイリアスでgtm-run GDE)、または内部のダイレクトモードから、Do ^GDE

gtmuser@gtmworkshop7:~$ $gtm_dist/mumps -run GDE
%GDE-I-LOADGD, Loading Global Directory file
        /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.gld
%GDE-I-VERIFY, Verification OK


GDE>

name spaces(ネームスペース)と regions(領域) とsegments (セグメント)を確認するために、showコマンドを使用することができます。

GDE> show -name

         *** NAMES ***
 Global                             Region
 ------------------------------------------------------------------------------
 *                                  DEFAULT
GDE>

この場合では、唯一1つのname space(ネームスペース)があり、デフォルトです。唯一1つのregion(領域)もあり、デフォルトです。region(領域)とsegment(セグメント)の名前は、大文字と小文字は区別しませんが、しかし、M変数名が大文字と小文字が区別されるので、name spaces(ネームスペース)は大文字と小文字が区別されます。

GDE> show -region

                                *** REGIONS ***
                                 Dynamic                          Def    Rec   Key Null       Standard
 Region                          Segment                         Coll   Size  Size Subs       NullColl  Journaling
 ------------------------------------------------------------------------------------------------------------------
 DEFAULT                         DEFAULT                            0   4080   255 NEVER      Y         Y

                          *** JOURNALING INFORMATION ***
 Region                          Jnl File (def ext: .mjl)  Before Buff      Alloc Exten
 ---------------------------------------------------------------------------------------
 DEFAULT                         $gtmdir/$gtmver/g/gtm.mjl
                                                           Y       128        100   100

GDE>

注意:region(領域)パラメータは、 - 「GT.Mの管理および運用ガイド」で確認してください。1つのregion(領域)があるので、1つのsegment(セグメント)もあり、DEFAULT(デフォルト)と呼ばれます(region(領域)とsegment(セグメント)の名前が異なることがあります、それらを同じに保つことをお勧めします)。

GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 DEFAULT                         $gtmdir/$gtmver/g/gtm.dat
                                                     BG  DYN  4096       1000  1000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE>

$gtmdir$gtmver 環境変数では、どのようにデータベースファイルが定義されているかを知ります。これは、環境変数が定義されている限りは、システム上で発生する場合はどこでも、一つのグローバルディレクトリにデータベースファイルをポイントできることを、意味します。これは、グローバルディレクトリを共有し、しかし、別のデータベースファイルを持つための、2つのプロセスを可能にします。

重要:グローバルディレクトリ内のパラメータは、新しいデータベースファイルを作成するために mupip create にのみよって使われます。他の時には、グローバルディレクトリはデータベースファイルへグローバル変数名をマップするためのみに使用されます。それで、もしグローバルディレクトリを変更するならば、データベースファイルは変更されません。 もしデータベースファイル内のパラメータを変更するならば、データベースファイルを作成するために使用されるグローバルディレクトリを変更しない限り、次回はファイルを作成し、グローバルディレクトリ内の古いパラメータを使用するでしょう。

show mapコマンドは、グローバルディレクトリ内のデータベースファイルへnames(ネーム)のマッピングの良い可視化を提供します。

GDE> show -map

                                  *** MAP ***
   -  -  -  -  -  -  -  -  -  - Names -  -  - -  -  -  -  -  -  -
 From                            Up to                            Region / Segment / File(def ext: .dat)
 -----------------------------------------------------------------------------------------------------------------------------------
 %                               ...                              REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = $gtmdir/$gtmver/g/gtm.dat
 LOCAL LOCKS                                                      REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = $gtmdir/$gtmver/g/gtm.dat
GDE>

演習、 - 爬虫類の学者と鳥類学者のグローバルディレクトリを設定

シェルから起動します。 $gtmgbldir へ値を割り当てます、アカルチュレーション ワークショップで既存グローバルディレクトリを上書きしないようにして、それからGDEを呼び出します。

gtmuser@gtmworkshop7:~$ export gtmgbldir=/home/gtmuser/gtm.gld
gtmuser@gtmworkshop7:~$ $gtm_dist/mumps -run GDE
%GDE-I-GDUSEDEFS, Using defaults for Global Directory
        /home/gtmuser/gtm.gld

GDE>

必須ではありませんが、ボトムアップでグローバルディレクトリを構築することは概念的に便利かもしれません。- 最初にsegments(セグメント)を作成し、次にregions(領域)、そしてname spaces(ネームスペース)を作成します。最初に、より便利にパラメータを設定するためにデフォルト値を編集します - 直ぐに使える(out-of-box )のデフォルト値は、実験のために適しているので、実際には使用しません。テンプレートを使用して、複数の(regions)領域とsegments(セグメント)を作成するために必要な作業を軽減します。BIRDS(鳥)やREPTILS(爬虫類)に、異なるアクセスメソッドの使用することを通知します。

GDE> change -segment DEFAULT -block_size=4096 -allocation=1000 -extension=1000 -global_buffer_count=1000 -file_name=/home/gtmuser/gtm.dat
GDE> template -segment -access_method=bg -block_size=4096 -allocation=1000 -extension=1000 -global_buffer_count=1000
GDE> template -segment -access_method=mm -block_size=4096 -allocation=1000 -extension=1000 -global_buffer_count=1000
GDE> add -segment BIRDS -access_method=mm -file_name=/home/gtmuser/flap.dat
GDE> add -segment REPTILES -access_method=bg -file_name=/home/gtmuser/creep.dat
GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 BIRDS                           /home/gtmuser/flap.dat      MM  DYN  4096       1000  1000 DEFER
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
 DEFAULT                         /home/gtmuser/gtm.dat     BG  DYN  4096       1000  1000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
 REPTILES                        /home/gtmuser/creep.dat     BG  DYN  4096       1000  1000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE>

その後、segments(セグメント)にregions(領域)をマップできます。( -dynamic 修飾子で指定された)segment names(セグメントの名前)は変換されて大文字で表示されることを。通知します。

GDE> change -region DEFAULT -stdnull -key_size=255 -record_size=4080 -journal=(before,file="/home/gtmuser/gtm.mjl")
GDE> template -region -stdnull -key_size=255 -record_size=4080 -journal=nobefore
GDE> add -region BIRDS -dynamic=birds -journal=(nobefore,file="/home/gtmuser/flap.mjl")
GDE> add -region REPTILES -dynamic=reptiles -journal=(before,file="/home/gtmuser/creep.mjl")
GDE> show -region

                                *** REGIONS ***
                                 Dynamic                          Def    Rec   Key Null       Standard
 Region                          Segment                         Coll   Size  Size Subs       NullColl  Journaling
 ------------------------------------------------------------------------------------------------------------------
 BIRDS                           BIRDS                              0   4080   255 NEVER      Y         Y
 DEFAULT                         DEFAULT                            0   4080   255 NEVER      Y         Y
 REPTILES                        REPTILES                           0   4080   255 NEVER      Y         Y

                          *** JOURNALING INFORMATION ***
 Region                          Jnl File (def ext: .mjl)  Before Buff      Alloc Exten
 ---------------------------------------------------------------------------------------
 BIRDS                           /home/gtmuser/flap.mjl            N       128        100   100

 DEFAULT                         /home/gtmuser/gtm.mjl           Y       128        100   100

 REPTILES                        /home/gtmuser/creep.mjl           Y       128        100   100

GDE>

今すぐregions(領域)へのname spaces(ネームスペース)にマップします。

GDE> add -name Gharial -region=reptiles
GDE> add -name Jacare -region=reptiles
GDE> add -name Hoopoe -region=birds
GDE> add -name Trogon -region=birds
GDE> show -name

         *** NAMES ***
 Global                             Region
 ------------------------------------------------------------------------------
 *                                  DEFAULT
 Gharial                            REPTILES
 Hoopoe                             BIRDS
 Jacare                             REPTILES
 Trogon                             BIRDS
GDE>

マップ全体を調べることがで、一貫性チェックを実行するには、GDEに問い合わせます。

GDE> show -map

                                  *** MAP ***
   -  -  -  -  -  -  -  -  -  - Names -  -  - -  -  -  -  -  -  -
 From                            Up to                            Region / Segment / File(def ext: .dat)
 -----------------------------------------------------------------------------------------------------------------------------------
 %                               Gharial                          REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = /home/gtmuser/gtm.dat
 Gharial                         Gharial0                         REG = REPTILES
                                                                  SEG = REPTILES
                                                                  FILE = /home/gtmuser/creep.dat
 Gharial0                        Hoopoe                           REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = /home/gtmuser/gtm.dat
 Hoopoe                          Hoopoe0                          REG = BIRDS
                                                                  SEG = BIRDS
                                                                  FILE = /home/gtmuser/flap.dat
 Hoopoe0                         Jacare                           REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = /home/gtmuser/gtm.dat
 Jacare                          Jacare0                          REG = REPTILES
                                                                  SEG = REPTILES
                                                                  FILE = /home/gtmuser/creep.dat
 Jacare0                         Trogon                           REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = /home/gtmuser/gtm.dat
 Trogon                          Trogon0                          REG = BIRDS
                                                                  SEG = BIRDS
                                                                  FILE = /home/gtmuser/flap.dat
 Trogon0                         ...                              REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = /home/gtmuser/gtm.dat
 LOCAL LOCKS                                                      REG = DEFAULT
                                                                  SEG = DEFAULT
                                                                  FILE = /home/gtmuser/gtm.dat
GDE> verify
%GDE-I-VERIFY, Verification OK


GDE>

GDEを終了して、グローバルディレクトリを作成します。その後、データベースファイルを作成するために、mupip createコマンドを使用できます。ジャーナルファイルが別々に作成する必要があることに注意してください。

GDE> exit
%GDE-I-VERIFY, Verification OK

%GDE-I-GDCREATE, Creating Global Directory file
        /home/gtmuser/gtm.gld
gtmuser@gtmworkshop7:~$ ls -l *.dat *.mjl
ls: *.dat: No such file or directory
ls: *.mjl: No such file or directory
gtmuser@gtmworkshop7:~$ $gtm_dist/mupip create
Created file /home/gtmuser/flap.dat
Created file /home/gtmuser/gtm.dat
Created file /home/gtmuser/creep.dat
gtmuser@gtmworkshop7:~$ ls -l *.dat *.mjl
ls: cannot access *.mjl: No such file or directory
-rw-rw-rw- 1 gtmuser gtmuser 4170240 2011-11-07 14:57 creep.dat
-rw-rw-rw- 1 gtmuser gtmuser 4170240 2011-11-07 14:57 flap.dat
-rw-rw-rw- 1 gtmuser gtmuser 4170240 2011-11-07 14:57 gtm.dat
gtmuser@gtmworkshop7:~$

そして、ジャーナリングをonにします。Separate(分離)コマンドは、ジャーナリングのタイプに応じて使用する必要があります - ジャーナリングのイメージ前(before)とイメージの前でない(no-before)。

gtmuser@gtmworkshop7:~$ $gtm_dist/mupip set -journal=nobefore -region BIRDS
%GTM-I-JNLCREATE, Journal file /home/gtmuser/flap.mjl created for region BIRDS with NOBEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region BIRDS is now ON
gtmuser@gtmworkshop7:~$ $gtm_dist/mupip set -journal=before -region REPTILES,DEFAULT
%GTM-I-JNLCREATE, Journal file /home/gtmuser/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now ON
%GTM-I-JNLCREATE, Journal file /home/gtmuser/creep.mjl created for region REPTILES with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region REPTILES is now ON
gtmuser@gtmworkshop7:~$ ls -l *.dat *.mjl
-rw-rw-rw- 1 gtmuser gtmuser 4170240 2011-11-07 14:59 creep.dat
-rw-rw-rw- 1 gtmuser gtmuser   69632 2011-11-07 14:59 creep.mjl
-rw-rw-rw- 1 gtmuser gtmuser 4170240 2011-11-07 14:58 flap.dat
-rw-rw-rw- 1 gtmuser gtmuser   69632 2011-11-07 14:58 flap.mjl
-rw-rw-rw- 1 gtmuser gtmuser 4170240 2011-11-07 14:59 gtm.dat
-rw-rw-rw- 1 gtmuser gtmuser   69632 2011-11-07 14:59 gtm.mjl
gtmuser@gtmworkshop7:~$

製品の本番環境では、テキストファイルにGDEコマンドを置くことと、ヒアドキュメントまたはGDEの@コマンドの使用でそれらを起動したりすることを勧めます。バージョン管理の下でテキストファイルを配置します。

$ZROUTINES と $ZGBLDIR 対 UCI と ボリュームセット(Volume set)

GT.Mの環境は、$ZROutines( $gtmroutines で初期化)と$Zgbldir( $gtmgbldir で初期化)により定義されています。UCIおよびボリュームセットのような他のM実装のコンセプトは、GT.M.には存在しません

ルーチンとデータベースが分離しているGT.Mは、現実世界の環境では、とりわけ、非常に強力です。柔軟性とは別に、この推奨は、防衛運転しないこととは違って、" 防衛的プログラミング (defensive programming)" の実践を可能にします。私達はエラーしやすい傾向が出始める人間ですので、守備の練習はエラーの確率を減少させます。

演習、 - 模擬的なASP環境をセットアップ

アプリケーションサービスプロバイダー(ASP)の環境では、同じアプリケーションコードは、サイトの数によって使用され、それぞれのサイトは、自身のデータベースを持っています。時には、データベースの部分は、ロケーションによっては、データ辞書や薬剤の処方の承認または売上税の税率の表のような、通常の運用では読み取り専用に基づいて一般的に使用できます。各サイトは、カスタムルーチンの小さなセット(small set)を持っていることもあります。GH(総合病院:General Hospital)とcc(がんセンター:Cancer Center)と呼ばれる2つの機関に提供するASPについて考えてみましょう。

ルーチンの大半は共有されている:

/var/opt/EHR/1.0/gh/r/var/opt/EHR/1.0/gh/V5.4-002B_x86/rに、GHのカスタムルーチンがあり、/var/opt/EHR/1.0/gh/V5.4-002B_x86/oにオブジェクトコードがある。

同様に、 /var/opt/EHR/1.0/cc/r/var/opt/EHR/1.0/cc/V5.4-002B_x86/rに、Cancer Centerのカスタムルーチンがあり、 /var/opt/EHR/1.0/cc/V5.4-002B_x86/o にオブジェクトコードがある。

$gtmroutinesは、何をGHのユーザのためにすべきか? 何をCCのユーザーにすべきか? GHユーザによって供給されるシェルスクリプトと、CCユーザによって供給される別のものを作成します。 [ シェルスクリプトは、 /var/opt/EHR/1.0/cc/V5.4-002B_x86 /var/opt/EHR/1.0/gh/V5.4-002B_x86 に属すことができます。.]

承認された国立医薬品ファイルは、^PSNDFグローバル変数にあり、両方の組織で共有されるユーザーのみにアクセスを参照してください。 データベースファイル/opt/EHR/1.0/V5.4-002B_x86/g/psndf.datにあります。 他のすべてのグローバル変数は、GHおよびCCに指定されているデータベースファイルにあります。それは、/var/opt/EHR/1.0/gh/V5.4-002B_x86/g/main.dat/var/opt/EHR/1.0/cc/V5.4-002B_x86/g/main.datです 。

まず、ディレクトリ構造を作成します。

gtmuser@gtmworkshop7:~$ sudo mkdir -p /opt/EHR/VOE10
gtmuser@gtmworkshop7:~$ sudo chown -R gtmuser.users /opt/EHR/VOE10
gtmuser@gtmworkshop7:~$ cd /opt/EHR/VOE10 ; mkdir -p r V5.4-002B_x86/r V5.4-002B_x86/o V5.4-002B_x86/g
gtmuser@gtmworkshop7:/opt/EHR/VOE10$ sudo mkdir -p /var/opt/EHR/VOE10
gtmuser@gtmworkshop7:/var/opt/EHR/VOE10$ sudo chown -R gtmuser.users /var/opt/EHR/VOE10
gtmuser@gtmworkshop7:/var/opt/EHR/VOE10$ cd /var/opt/EHR/VOE10 ; mkdir -p gh/r gh/V5.4-002B_x86/r gh/V5.4-002B_x86/o gh/V5.4-002B_x86/g
gtmuser@gtmworkshop7:/var/opt/EHR/VOE10$ mkdir -p cc/r cc/V5.4-002B_x86/r cc/V5.4-002B_x86/o cc/V5.4-002B_x86/g
gtmuser@gtmworkshop7:/var/opt/EHR/VOE10$ cd
gtmuser@gtmworkshop7:~$

$gtmgbldirは、何をGHのユーザのためにすべきか? 何をCCのユーザーにすべきか?以前に作成したコマンドファイルに、これらを追加します。 ヒアドキュメント、または、グローバルディレクトリを作成されるであろうGDEの@コマンドのどちらかでGDEに与えるコマンドのファイルを作成し、その後グローバルディレクトリを作成します。

mupip create コマンドで3つのデータベースファイルを作成します(覚えておいてください:データベースファイル/opt/EHR/1.0/V5.4-002B_x86/ g/psndf.dat は最初の mupip create によって作成され、そして、2番目の mupip create は、指定のデータベースファイルの設定を作成するだけでしょう)。

1つの環境では、グローバル変数 ^PSNDF^Xへ値を割り当てます。 他の環境では、^PSNDF の値を読み取ることが確認できます (つまり、これは共有されています)、しかし^X に値はありません (つまり、これは共有されていません)。

2番目の環境に、^Xに値を Set し、最初の環境で、その環境でセットアップした^X のオリジナルの値がまだ見えることが確認してください。

/opt/EHR/1.0/r に Hello, World”と書かれたプログラムABC.mを作成し、/var/opt/EHR/1.0/ghに“Hello, General Hospital”と書かれたプログラムを、/var/opt/EHR/1.0/ccに“Hello, Cancer Center”と叫んでいるプログラムを、この2つのプログラムを同じ名前 DEF.mで作成します。ABC.mの実行時に、どちらの環境のプロセスでも"Hello, World"と取得することを確認してください、そして、DEF.m を実行する時に、その環境に依存している、Hello, General Hospital”または“Hello, Cancer Center”のどちらかです。

特別でない起動またはシャットダウン

データベースファイルを開くための最初のプロセスは、必要とされるすべての共有メモリの制御構造のセットアップです。最後の一つに、それを破壊します。単一点障害やパフォーマンスのボトルネックや潜在的なセキュリティ脆弱性があることは、ルートとして実行しなければならないデーモンはありません。もしレプリケーションを使うならば、少なくとも1つのソースサーバープロセスは(下記参照)最初に起動しなければならない。

もしシステムがクラッシュした場合に、または、強制的にダウンした場合に、バックアップシステムを導かれる時:もしジャーナリング使用している場合、mupip journal -recover (またはレプリケーションが使用されている場合、mupip journal -rollback)は、データベースを回復するでしょう。もしジャーナリングが使用されていない場合は、mupip rundown -region "*" は、ファイルヘッダでデータベース制御構造をクリーンアップしますが、しかし、きれいにGT.Mプロセスを終了せずにコンピュータをシャットダウンすることの結果となるいかなる整合性エラーもFIXすることはできません。

[注意:もしジャーナリングを使用するならば、mupip rundown を使わないでください、mupip journal の操作でクラッシュした後には、データベースを復旧する計画を立ててください。]

GT.Mの環境変数

GT.Mの動作は、環境変数の数によって制御されます。 最も重要なものは、 $gtm_dist, $gtmroutines$gtmgbldir 、上に記載されています。 GT.Mに付属していて、実行されることよりもむしろ供給する必要があるgtmprofileファイル(shタイプのシェルの場合)は、適切なデフォルト値を提供することを試みます。 それを与える前にまたはその後のどちらかの環境変数をセッティングすることにより( gtmprofile は相互作用に対処しようと試みるため、前者が好まれます)、デフォルトの使用の代わりに自身の値を与えることができます。

それらがどのようにセットされているかを確認するために/usr/lib/fis-gtm/V5.4-002B_x86/gtmprofile ファイルをレビューしてください。あなたが理解できるかどうか、それらをセットして確認して、状態を研究してください。

システム管理者は、時にはそれらの環境で、gtmprofileをカスタマイズします (同様に gtmスクリプトも)。 代わりに、提供されている自身のファイルをセットアップし、そして、その中からgtmprofileを与えるためにセットアップします。

次の環境変数は、gtmprofileにより 明示的に設定されています。それを設定していないことを推奨しますが、しかし、 gtmprofileを設定していることでしょう。

可能であれば、もし設定していないならば、次のデフォルトがgtmprofileよって提供されます:

もし必要に応じて、UTF-8環境をセットアップするためにgtmprofile が必要ならば、 gtmprofile を与える前に、次のように設定すべきです:

GT.Mは、直接または間接的に、 gtmprofileによって扱われていない他の環境変数の数を使用します (それらは、gtmprofile に提供される前または後に、設定することができます)。これらは、GT.M管理および運用ガイドに記載されています。いくつかの価値があること:

セキュリティ

GT.Mは、とても安全に利用できるように最初から設計されています。[警告:絶対的な安全性は、この世界に存在しません。ブリッジの哲学と技術についての議論は、ブルース シュナイアーの暗号の秘密とウソ, ISBN 0-471-25311-1 がとてもお勧めです 。] もしファイルの所有権とアクセス権で許可されている場合のみ、GT.Mプロセスはデータベースファイルにアクセスできます。通常の操作では、スーパーユーザー(root)として操作するGT.Mのうち1つだけの小さなコンポーネントがあります - それは、 gtmsecshr ヘルパープロセスです。GT.Mのセキュリティモデルは、シンプルでよく理解できるように文書化されています。

GT.Mセキュリティ哲学と実装技術は掲示板を参照してください。

演習 - 所有権(オーナーシップ)とアクセス権(パーミッション)でアクセスをコントロール

最後の演習から環境変数を破棄して、新鮮なセッションを開始します。以下では、Linuxのファイル権限は、データベースへのフルアクセスが可能なgtmuser ユーザが使用する方法と、そこから読み取りするユーザーを利用可能にしながら、データベースを更新する別のユーザーを防止することについて注目します。この演習を開始します。

デフォルトのデータベースに読み書きができることを確認し、そして、world属性ではアクセスできないようにパーミッションを変更し、グループ内の他は読み取り専用のようにすることを、確認してください。

gtmuser@gtmworkshop7:~$ ls -l .fis-gtm/V5.4-002B_x86/g/gtm.dat
-rw-rw-rw- 1 gtmuser gtmuser 20587008 2011-11-07 14:29 .fis-gtm/V5.4-002B_x86/g/gtm.dat
gtmuser@gtmworkshop7:~$ chmod o-rw,g-w .fis-gtm/V5.4-002B_x86/g/gtm.dat
gtmuser@gtmworkshop7:~$ ls -l .fis-gtm/V5.4-002B_x86/g/gtm.dat
-rw-r----- 1 gtmuser gtmuser 20587008 2011-11-07 14:29 .fis-gtm/V5.4-002B_x86/g/gtm.dat
gtmuser@gtmworkshop7:~$ gtm

GTM>set ^X=1

GTM>zwrite ^X
^X=1

GTM>halt

また、グループ ユーザーのメンバである別のユーザーを作成します。usersuserは、gtmuserが所有するデータベースから読み取ることができるが、更新することはできないことを、見てください。

gtmuser@gtmworkshop7:~$ sudo useradd -g gtmuser -m staffuser
gtmuser@gtmworkshop7:~$ sudo su - staffuser
staffuser@gtmworkshop7:~$ pwd
/home/staffuser
staffuser@gtmworkshop7:~$ export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
staffuser@gtmworkshop7:~$ export gtmver=V5.4-002B_x86
staffuser@gtmworkshop7:~$ export gtmdir=/home/gtmuser/.fis-gtm
staffuser@gtmworkshop7:~$ export gtmgbldir=$gtmdir/$gtmver/g/gtm.gld
staffuser@gtmworkshop7:~$ $gtm_dist/mumps -dir

GTM>zwrite ^X
^X=1

GTM>set ^X=2
%GTM-E-DBPRIVERR, No privilege for attempted update operation for file: /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.dat

GTM>halt
staffuser@gtmworkshop7:~$ logout
gtmuser@gtmworkshop7:~$ sudo userdel staffuser
gtmuser@gtmworkshop7:~$ grep staffuser /etc/passwd
gtmuser@gtmworkshop7:~$ sudo rm -rf /home/staffuser

グループへのGT.M アクセスを制限するために、インストールオプションがあります。もしこのオプションを使用する場合、その指定したグループでは、GT.M.を使用できるようになります。

それは非常にのみ、ログインでき、アプリケーションが実行でき、ログアウトする、ユーザーIDを作成することは、とても簡単です。

演習 - 分離されたASP環境でシミュレーション

この演習では、WorldVistA EHRのフォー・スライス・トースター (Four Slice Toaster) MSC FileMan 1034 エディションにおける instructions を見てみましょう(お使いのブラウザで開きファイルをダウンロードする必要があるかもしれません)。また代わりに、WorldVistA project at Source Forgeへ移動し、" View all files " をクリックし、WorldVistA EHR VOE_ 1.0 を開き、次に、2008-06 Four Slice Toaster MSC FM 1034 を開き、WVEHRVOE10Release6-08Toaster4SliceMSCFM1034Readme.html ファイルをダウンロードしてください。また、ファイルWVEHRVOE10Release6-08Toaster4SliceMSCFM1034.zip をダウンロードし、解凍して、Readme のインストラクションにしたがってそれを開きます。

Login as vistaadmin / vistaadmin for administrator access.、、、、、、、、、、、、、、 管理者アクセス用 vistaadmin / vistaadmin で ログインしてください。クリニック P のユーザは、gtm グループ とclinicp グループのメンバーで、クリニックQユーザは gtm グループと clinicqグループのメンバーで、そして、どちらも他のデータベースへのアクセス権がないことに、注意してください。

ジャーナリング

データベースの整合性について問題にするならば、ジャーナルをする必要があります。逆に、システムのクラッシュのような厄介なイベントで万が一の場合にでも、削除されたり新たに再作成されるようなデータベースはジャーナルする必要はありません。

GT.Mのような、すべての高性能データベースのほとんどは、システムクラッシュのような予定外のイベントの後でも、データの整合性を復元しビジネスの継続性を提供するためにジャーナリングを使用します(いくつかのデータベースでは"logging:ロギング"と呼ばれています)。

ジャーナリングをオンにする2つのスイッチがあります。 ENable / DISable と ON/OFF 。ジャーナリングの Enabling または disabling (有効またはを無効)は、データベースへのアクセスとは別に自立(stand alone)している必要があります。ジャーナリングのon と offの切り替えは、データベースが使用されている時に行うことができます。

演習 - 既存のデータベースでジャーナリング

この演習では、仮想マシンのクラッシュを想定して、データベースを復旧します。最初に、既存のデータベース上でそれをやってみて; 次に、スクラッチ(scratch)からジャーナリングセットアップします。

まず、古いジャーナルファイルをクリーン アウト(一掃)します。使用中のメモリセグメントが共有されていないことを確認します。次に、GT.Mに移動し、データベース操作を実行し、新しい共有メモリセグメントがあることを確認してください。

gtmuser@gtmworkshop7:~$ rm -f .fis-gtm/V5.4-002B_x86/g/gtm.mjl_*
gtmuser@gtmworkshop7:~$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      natgtmuserh     status

gtmuser@gtmworkshop7:~$ /usr/lib/fis-gtm/V5.4-002B_x86/gtm

GTM>set ^X=$zdate($horolog,"MON DD, YEAR")

GTM>zwrite ^X ; opens database file and creates a shared memory segment
^X="NOV 07, 2011"

GTM>zsystem "ipcs -m"

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      natgtmuserh     status
0x00000000 458752     gtmuser         660        5713920    1


GTM>

今度は、コンソールウィンドウ右上の "X" をクリックして仮想マシンをkillします、そして再起動します。GT.Mに戻って、データがまだそこに存在することを確認します。(自動回復を実行する)GTMのスクリプト代わりに、mumpsを実行し、データベースにアクセスしてみてください。注意:そのオペレーションの一環としてリカバリを実行するので、この演習用の gtm スクリプトを実行しないでください。

gtmuser@gtmworkshop7:~$ source /usr/lib/fis-gtm/V5.4-002B_x86/gtmprofile
gtmuser@gtmworkshop7:~$ mumps -dir

GTM>zwrite ^X
%GTM-E-REQRUNDOWN, Error accessing database /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.dat.  Must be rundown on cluster node gtmworkshop.
%GTM-I-TEXT, Error with database control shmctl
%SYSTEM-E-ENO22, Invalid argument

GTM>zsystem "ls -l $gtmdir/$gtmver/g" ; notice we have a journal file
total 276
-rw-r----- 1 gtmuser gtmuser 20587008 2011-11-07 17:31 gtm.dat
-rw-rw-r-- 1 gtmuser gtmuser     1536 2011-11-02 18:49 gtm.gld
-rw-r----- 1 gtmuser gtmuser    69632 2011-11-07 17:31 gtm.mjl
-rw-r----- 1 gtmuser gtmuser    69632 2011-11-07 17:14 gtm.mjl_2011311171412

GTM>zsystem "ipcs -m" ; and there are no shared memory segments indicating an open database


------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      


GTM>zsystem "ls -lR $gtm_tmp" ; and no log files from the gtm script
/tmp/fis-gtm/V5.4-002B_x86:
total 0

GTM>halt

次に、ダイレクトに実行するmumpsの実行の代わりに実行するgtmスクリプトを試してみましょう。

gtmuser@gtmworkshop7:~$ gtm

GTM>zwrite ^X ; database access works
^X="NOV 07, 2011"

GTM>zsystem "ls -l $gtmdir/$gtmver/g" ; there are two new journal files
total 412
-rw-r----- 1 gtmuser gtmuser 20587008 2011-11-07 17:36 gtm.dat
-rw-rw-r-- 1 gtmuser gtmuser     1536 2011-11-02 18:49 gtm.gld
-rw-r----- 1 gtmuser gtmuser    69632 2011-11-07 17:35 gtm.mjl
-rw-r----- 1 gtmuser gtmuser    69632 2011-11-07 17:14 gtm.mjl_2011311171412
-rw-r----- 1 gtmuser gtmuser    69632 2011-11-07 17:35 gtm.mjl_2011311173125
-rw-r----- 1 gtmuser gtmuser    69632 2011-11-07 17:35 gtm.mjl_2011311173556

GTM>zsystem "ipcs -m" ; there is a shared memory segment for the open database file

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 65536      gtmuser    660        5726208    1 


GTM>zsystem "ls -lR $gtm_tmp" ; and log files from the commands in the gtm script
/tmp/fis-gtm/V5.4-002B_x86:
total 8
srwxrwxr-x 1 gtmuser gtmuser   0 2011-11-07 17:36 gtm_mutex000003B0
-rw-rw-r-- 1 gtmuser gtmuser 613 2011-11-07 17:35 gtmuser_20111107223555UTC_mupip_recover
-rw-rw-r-- 1 gtmuser gtmuser 333 2011-11-07 17:35 gtmuser_20111107223555UTC_mupip_set

GTM>halt

どのようにして回復されたのでしょうか?答えはgtmスクリプトにあります。

[参考]gtmuser@gtmworkshop:~$ cat `which gtm`
#!/bin/sh
#################################################################
#                                                               #
#       Copyright 2010 Fidelity Information Services, Inc       #
#                                                               #
#       This source code contains the intellectual property     #
#       of its copyright holder(s), and is made available       #
#       under a license.  If you do not know the terms of       #
#       the license, please stop and do not read further.       #
#                                                               #
#################################################################
if [ !-f "/usr/lib/fis-gtm/V5.4-002B_x86"/gtmprofile ] ; then echo Cannot find file "/usr/lib/fis-gtm/V5.4-002B_x86"/gtmprofile to source
else
    . "/usr/lib/fis-gtm/V5.4-002B_x86"/gtmprofile
    timestamp=`date -u +%Y%m%d%H%M%S`"UTC"
    ( cd `dirname $gtmgbldir` ; \
        $gtm_dist/mupip journal -recover -backward "*" 2>$gtm_tmp/"$USER"_$timestamp"_mupip_recover" && \
        $gtm_dist/mupip set -journal="on,before" -region "*" 2>$gtm_tmp/"$USER"_$timestamp"_mupip_set" && \
        find . -name \*.mjl_\* -mtime +$gtm_retention -exec rm -vf {} \; )
    if [ 0 = $# ] ; then
        $gtm_dist/mumps -direct
    else
        $gtm_dist/mumps $*
    fi
    ( cd `dirname $gtmgbldir` \
        $gtm_dist/mupip rundown -region "*" 2>$gtm_tmp/"$USER"_$timestamp"-"`date -u +%Y%m%d%H%M%S`"UTC_mupip_rundown" )
    find $gtm_tmp -name "$USER"_\* -mtime +$gtm_retention -exec rm -f {} \;
fi

gtmuser@gtmworkshop7:~$ 

mupip journal recoverコマンドが、リカバリを実行します。新しいジャーナルファイルが作成されると古いジャーナルファイル名が変更されることを、mupipコマンドの出力をレビューしてください。各々のジャーナルファイルには、その前にあったジャーナルファイルへのバック ポインタを持っています。gtm スクリプトは、$gtm_retention 環境変数により指定された日数より古い、現在以外(non-current)のジャーナルファイルとテンポラリファイルを削除します。

gtmuser@gtmworkshop7:~$ cat $gtm_tmp/gtmuser_20111107223555UTC_mupip_recover
%GTM-I-MUJNLSTAT, Initial processing started at Mon Nov  7 17:35:55 2011
%GTM-I-MUJNLSTAT, Backward processing started at Mon Nov  7 17:35:55 2011
%GTM-I-MUJNLSTAT, Before image applying started at Mon Nov  7 17:35:55 2011
%GTM-I-FILERENAME, File /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.mjl is renamed to /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.mjl_2011311173125
%GTM-I-MUJNLSTAT, Forward processing started at Mon Nov  7 17:35:55 2011
%GTM-S-JNLSUCCESS, Show successful
%GTM-S-JNLSUCCESS, Verify successful
%GTM-S-JNLSUCCESS, Recover successful
%GTM-I-MUJNLSTAT, End processing at Mon Nov  7 17:35:56 2011
gtmuser@gtmworkshop7:~$ cat $gtm_tmp/gtmuser_20111107223555UTC_mupip_set 
%GTM-I-FILERENAME, File /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.mjl is renamed to /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.mjl_2011311173556
%GTM-I-JNLCREATE, Journal file /home/gtmuser/.fis-gtm/V5.4-002B_x86/g/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now ON
gtmuser@gtmworkshop7:~$ 

アクションのジャーナリング アニメーションがここにあります:


ファイルシステムの設定に注意してみてください。

クラッシュ後のGT.Mリカバーにおける堅牢な操作は、ファイルシステムの堅牢なリカバリーを必要とします。もし一致するデータが書き込まれた後にのみ、メタデータがディスクに書き込まれていることを確認するためのオプションをファイルシステムが必要とするならば、それをセットすることを確認します。

演習 - スクラッチからのジャーナリング

ホームディレクトリにディレクトリを作成してください (例えば、 myApp) 。aA.datではAまたはaの文字で、そして、others.datでは他の文字で、始まるすべての変数をマップしているグローバルディレクトリを作成します。データベースファイルを作成します。次に、両方のファイルのビフォア・イメージ・ジャーナリングを有効にしONにします。プロセスを開始し、両方のデータベースを更新します。プロセスが開いている状態で、仮想マシンを強制終了します。仮想マシンを再起動し、データベースにアクセスできないことをあなた自身で見てください、その後に、(2つのデータベースファイルで構成される)データベースををリカバーすると、すぐにデータベースにアクセスできることを実演して示してください。

ヒント:

データベース レプリケーション

アプリケーションにおいて、ビジネスの継続性が可能な限り必要とされる時には、論理的なマルチサイトの構成を作成するビフォア イメージ ジャーナリングに加えて、データベースのレプリケーションを使用します。今日のGT.Mレプリケーションのメジャーな制限は、レプリケーション上に20,000kmの距離の制限がある(地球の円周は約40,000kmなので、複数の20,000km以上離れてデータセンターを配置することは困難です)。この例では、ケープタウン (南緯34°, 東経19°)、フィラデルフィア(北緯40°, 西経75°)、上海 (北緯31°, 東経122°) にあるデータセンターをシミュレートしましょう。 フィラデルフィアとケープタウンとは12,550km、フィラデルフィアと上海とは11,900km、そして、上海とケープタウンとは12,900kmです(資料引用:Great Circle Mapper グレートサークルマッパー )。

演習 - レプリケーション

レプリケーションはジャーナリングの上に構築するので、上記で作成した myApp ディレクトリを使用します。 $gtm_repl_instance$gtm_repl_instnameの2つの環境変数にさらに値を代入するシェルスクリプトenvで拡張します 。gtm_repl_instance は、レプリケーションされたインスタンスがレプリケーションの状態についての情報を格納する場所のレプリケーション インスタンス ファイルの名前で、そして、gtm_repl_instance はインスタンスの名前です。この場合、ダミーですが、しかし、インスタンスのコピーを作成するようにそれを変更します。

gtmuser@gtmworkshop7:~$ cat myApp/env
export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
export gtmgbldir=/home/gtmuser/myApp/gtm.gld
export gtm_log=/tmp/fis-gtm/V5.4-002B_x86
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/gtmuser/myApp/gtm.repl
export gtm_repl_instname=dummy
export gtmroutines="/home/gtmuser/myApp $gtm_dist"
export gtm_tmp=$gtm_log
mkdir -p $gtm_tmp
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip

レプリケーションとジャーナリングをオンにします。

gtmuser@gtmworkshop7:~$ mupip set -replication=on -region "*"
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011312170809
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/aA.mjl created for region AA with BEFORE_IMAGES
%GTM-I-PREVJNLLINKCUT, Previous journal file name link set to NULL in new journal file /home/gtmuser/myApp/aA.mjl created for database file /home/gtmuser/myApp/aA.dat
%GTM-I-JNLSTATE, Journaling state for region AA is now ON
%GTM-I-REPLSTATE, Replication state for region AA is now ON
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011312170809
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-PREVJNLLINKCUT, Previous journal file name link set to NULL in new journal file /home/gtmuser/myApp/gtm.mjl created for database file /home/gtmuser/myApp/gtm.dat
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now ON
%GTM-I-REPLSTATE, Replication state for region DEFAULT is now ON
gtmuser@gtmworkshop7:~$

myAppの内部で、以下のシェルスクリプトを作成し、それらを実行可能にします:

gtmuser@gtmworkshop7:~$ cat myApp/originating_stop 
#!/bin/sh
$gtm_dist/mupip replicate -source -shutdown -timeout=0
$gtm_dist/mupip rundown -region "*"
gtmuser@gtmworkshop7:~$ cat myApp/replicating_start 
#!/bin/sh
$gtm_dist/mupip replicate -source -start -passive -instsecondary=dummy -buffsize=1048576 -log=/home/gtmuser/myApp/source_dummy.log
$gtm_dist/mupip replicate -receive -start -listenport=3000 -buffsize=1048576 -log=/home/gtmuser/myApp/receive.log
gtmuser@gtmworkshop7:~$ cat myApp/replicating_stop
#!/bin/sh
$gtm_dist/mupip replicate -receive -shutdown -timeout=0
$gtm_dist/mupip replicate -source -shutdown -timeout=0
$gtm_dist/mupip rundown -region "*"
gtmuser@gtmworkshop7:~$ chmod +x myApp/{originating_stop,replicating_*}
gtmuser@gtmworkshop7:~$ ls -l myApp/{originating_stop,replicating_*}
-rwxrwxr-x 1 gtmuser gtmuser 101 2011-11-08 17:30 myApp/originating_stop
-rwxrwxr-x 1 gtmuser gtmuser 239 2011-11-08 17:31 myApp/replicating_start
-rwxrwxr-x 1 gtmuser gtmuser 157 2011-11-08 17:31 myApp/replicating_stop
gtmuser@gtmworkshop7:~$ 

ディレクトリをきれいに保つために、古い世代のジャーナルファイルを削除できます:

gtmuser@gtmworkshop7:~$ ls -l myApp/*.mjl_*
-rw-rw-rw- 1 gtmuser gtmuser 69632 2011-11-08 17:08 myApp/aA.mjl_2011312170523
-rw-rw-rw- 1 gtmuser gtmuser 69632 2011-11-08 17:08 myApp/aA.mjl_2011312170809
-rw-rw-rw- 1 gtmuser gtmuser 69632 2011-11-08 17:08 myApp/gtm.mjl_2011312170523
-rw-rw-rw- 1 gtmuser gtmuser 69632 2011-11-08 17:08 myApp/gtm.mjl_2011312170809
gtmuser@gtmworkshop7:~$ rm myApp/*.mjl_*
gtmuser@gtmworkshop7:~$ 

アカルチュレーション ワークショップ‎ の仮想マシンをシャットダウンし、アカルチュレーション ワークショップ‎ の3つのコピーを作ります、それは、 Philadelphia.vmdk, Shanghai.vmdkCapeTown.vmdkです 。ホストシステムでディスク容量が不足している場合は、代わりに、2つのコピーを作成しオリジナルのubuntu-11.10_gtmworkshop7.vmdkファイルの名前を変更します。

もし Linux上でQEMU/KVMでqcow2またはvmdk のディスクイメージを使用している場合は、ベースイメージが変更されないように、かつ、すべての変更が新しいディスクイメージに行くようになるように、ディスクイメージをベースイメージから作成できるきるようにする機能を使用することができます。それがこの機能をサポートしているかどうかを確認するには、仮想化ソフトウェアをチェックしてください。ホスト上(シャットダウンゲスト付き)で、次のコマンドを実行します - あなたのPC上でQEMU/KVMのバージョンに応じて、正確なコマンドが異なる場合があります。

$ qemu-img create -f vmdk -o backing_file=ubuntu-11.10_gtmworkshop7.vmdk CapeTown.vmdk
Formatting 'CapeTown.vmdk', fmt=vmdk size=8589934592 backing_file='ubuntu-11.10_gtmworkshop7.vmdk' compat6=off
$ qemu-img create -f vmdk -o backing_file=ubuntu-11.10_gtmworkshop7.vmdk Philadelphia.vmdk
Formatting 'Philadelphia.vmdk', fmt=vmdk size=8589934592 backing_file='ubuntu-11.10_gtmworkshop7.vmdk' compat6=off
$ qemu-img create -f vmdk -o backing_file=ubuntu-11.10_gtmworkshop7.vmdk Shanghai.vmdk
Formatting 'Shanghai.vmdk', fmt=vmdk size=8589934592 backing_file='ubuntu-11.10_gtmworkshop7.vmdk' compat6=off
$

3つの仮想マシンを起動します。各仮想マシンは、ホストから転送するための2つのポートが必要です。1つは、各仮想マシン上のポート22へ転送されるsshアクセス用で、もう1つは、各仮想マシン上のポート3000に転送されるレプリケーション用です(つまり、3つのインスタンス用に全ホスト上に合計6個のポートがあります)。 ここの例では、ケープタウン(Cape Town) に 2221 と4000、フィラデルフィア(Philadelphia) に2222 と 5000、上海(Shanghai) に2223と6000 のホストのポートを使用しいます。ここで与えられたコマンドは、Linux上のkvmを使用し - ホスト上の仮想化に適切なコマンドを使用してください。

kvm -enable-kvm -cpu host -net nic -net user,hostfwd=tcp::2221-:22,hostfwd=tcp::4000-:3000 -hda CapeTown.vmdk&
kvm -enable-kvm -cpu host -net nic -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::5000-:3000 -hda Philadelphia.vmdk&
kvm -enable-kvm -cpu host -net nic -net user,hostfwd=tcp::2223-:22,hostfwd=tcp::6000-:3000 -hda Shanghai.vmdk&

複数のマシンでの作業をしている時の混乱を避けるために、そのロケーションにGT.Mワークショップの各マシンの名前を変更します。ここの例は、ケープタウン(CapeTown)マシンです。フィラデルフィア(Philadelphia)もShanghai(上海)も同様に行う必要があります。名前の変更を有効にするために、gtmworkshopcapetown 変更するために、rootユーザで /etc/hosts/etc/hostnameファイルを編集する必要があり、そして、再起動してください。

gtmuser@capetown:~$ cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       capetown

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
gtmuser@capetown:~$ cat /etc/hostname
capetown
gtmuser@capetown:~$ 

また、接続されている各セッションのマシン名を表示するためにホスト上のターミナルエミュレータ上のwindow / tabのラベルを変更しておくとよいでしょう。例:




各マシン上で(オペレータのエラーの確率を減らすために)より現実的にそれをするために、 "ローカル" のタイムゾーンを指定するために、sudo dpkg-reconfigure tzdataを実行します。フィラデルフィア(Philadelphia)はニューヨーク(New York)を選択し、ケープタウンはヨハネスブルクを選択してください。

それぞれのマシン上で、各インスタンスのmyApp/envを編集して、 export gtm_repl_instname=dummyexport gtm_repl_instance=/home/gtmuser/myApp/gtm.replの行を、そのインスタンスのインスタンスファイル名に変更します。たとえば、ケープタウン(Cape Town )のインスタンスは:

gtmuser@capetown:~$ cat myApp/env 
export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
export gtmgbldir=/home/gtmuser/myApp/gtm.gld
export gtm_log=/tmp/fis-gtm/V5.4-002B_x86
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/myApp/capetown.repl
export gtm_repl_instname=CapeTown
export gtmroutines="/home/gtmuser/myApp $gtm_dist"
export gtm_tmp=$gtm_log
mkdir -p $gtm_tmp
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@capetown:~$

次に、各インスタンス上で、レプリケーションのインスタンスファイルを作成します。

gtmuser@capetown:~$ ls -l myApp/*.repl
ls: cannot access myApp/*.repl: No such file or directory
gtmuser@capetown:~$ source myApp/env 
gtmuser@capetown:~$ mupip replicate -instance_create
gtmuser@capetown:~$ ls -l myApp/*.repl
-rw-rw-r-- 1 gtmuser gtmuser 1536 2011-11-10 00:47 myApp/capetown.repl
gtmuser@capetown:~$  

オリジナルのインスタンスとしてフィラデルフィア(Philadelphia)の設定を起動し、レプリケーションするセカンダリのロールでケープタウン(Cape Town)と上海(Shanghai)を起動します。3つのインスタンス上で、次のコマンドは、任意の順序で実行することができます。

レプリケーション インスタンスとして上海(Shanghai)をスタートします。

gtmuser@shanghai:~$ myApp/replicating_start 
Thu Nov 10 06:56:40 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@shanghai:~$ 

レプリケーション インスタンスとしてケープタウン(Cape Town)をスタートします。

gtmuser@capetown:~$ myApp/replicating_start
Thu Nov 10 00:57:33 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@capetown:~$

ケープタウン(Cape Town)と上海(Shanghai)へレプリケーションするオリジナルのインスタンスとして、フィラデルフィア(Philadelphia)をスタートしてください(仮想マシンに別のレプリケーションインスタンスが到達するホスト上のポートの使用に注意してください)。

gtmuser@philadelphia:~$ mupip replicate -source -start -instsecondary=CapeTown -secondary=10.0.2.2:4000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_CapeTown.log
Wed Nov  9 17:59:39 2011 : Initiating START of source server for secondary instance [CapeTown]
gtmuser@philadelphia:~$ mupip replicate -source -start -instsecondary=Shanghai -secondary=10.0.2.2:6000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_Shanghai.log
Wed Nov  9 18:00:35 2011 : Initiating START of source server for secondary instance [Shanghai]
gtmuser@philadelphia:~$

フィラデルフィア(Philadelphia)のGT.Mプロセスを起動し、データベースの更新を実行します:

gtmuser@philadelphia:~$ mumps -dir

GTM>set ^Weather("Philadelphia",$Piece($Horolog,",",1),$Piece($Horolog,",",2))="Rainy"

データがケープタウン(Cape Town) と上海(Shanghai)でレプリケートされていることを確認します。両方のインスタンスで次のように実行します:

gtmuser@shanghai:~$ mumps -dir

GTM>zwrite ^Weather
^Weather("Philadelphia",62404,64970)="Rainy"

GTM>

上海(Shanghai)を停止し、ケープタウン(Cape Town)はそのまま残します(システムメンテナンスやネットワーク停止をシミュレートしてみます)。

gtmuser@shanghai:~$ myApp/replicating_stop 
Signalling immediate shutdown
Thu Nov 10 07:04:29 2011 : Initiating shut down
Thu Nov 10 07:04:30 2011 : Receive pool shared memory removed
Thu Nov 10 07:04:30 2011 : Receive pool semaphore removed
Thu Nov 10 07:04:30 2011 : Signalling shutdown immediate
Thu Nov 10 07:04:30 2011 : Initiating SHUTDOWN operation on source server pid [867] for secondary instance [dummy]
Thu Nov 10 07:04:30 2011 : Waiting for upto [180] seconds for the source server to shutdown
Thu Nov 10 07:04:31 2011 : Journal pool shared memory removed
Thu Nov 10 07:04:31 2011 : Journal pool semaphore removed
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/aA.dat successfully rundown
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/gtm.dat successfully rundown
gtmuser@shanghai:~$ 

フィラデルフィア(Philadelphia)で、他の更新を作成してみます。

GTM>set ^Weather("Philadelphia",$Piece($Horolog,",",1),$Piece($Horolog,",",2))="Sunny"

ケープタウン(Cape Town)で更新されていることを確認します。

GTM>zwrite ^Weather
^Weather("Philadelphia",62404,64970)="Rainy"
^Weather("Philadelphia",62404,66663)="Sunny"

GTM>

しかし、上海(Shanghai)ではレプリケートされません。

GTM>zwrite ^Weather
^Weather("Philadelphia",62404,64970)="Rainy"

GTM>

レプリケート インスタンスとして上海(Shanghai)をリスタートします、そして、上海(Shanghai)でレプリケーションがアクティブでない時のオリジナル インスタンスの更新に追いつくことを確認します。

gtmuser@shanghai:~$ myApp/replicating_start 
Thu Nov 10 07:33:47 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@shanghai:~$ mumps -dir

GTM>zwrite ^Weather
^Weather("Philadelphia",62404,64970)="Rainy"
^Weather("Philadelphia",62404,66663)="Sunny"

GTM>

今、仮想マシンのコンソールウィンドウの "X" をクリックしてフィラデルフィア(Philadelphia )の想定外停止をシミュレートしてみます、ホスト上のプロセスのkill -9、または他の方法として、仮想マシンの電源を切ります。上海(Shanghai) が新しいオリジナルのインスタンスで、ケープタウン(Cape Town) がそのレプリケーションインスタンスであることを確認します。[ 制御の切り替え/ 計画停止では、オリジナルの最初のプライマリをダウンさせることは、オリジナルのプライマリインスタンスが同時に2つ発生しないことを確認するのに役立ちます。]

レプリケートのインスタンスとして上海(Shanghai)を停止し、オリジナルのインスタンスとして上海(Shanghai)を起動します。あなたがフィラデルフィア(Philadelphia)へレプリケートするソースサーバのプロセスを立ち上ができることに注意してください - フィラデルフィア(Philadelphia) が起動したときに、接続を行います。

gtmuser@shanghai:~$ myApp/replicating_stop
Signalling immediate shutdown
Thu Nov 10 07:41:49 2011 : Initiating shut down
Thu Nov 10 07:41:50 2011 : Receive pool shared memory removed
Thu Nov 10 07:41:50 2011 : Receive pool semaphore removed
Thu Nov 10 07:41:50 2011 : Signalling shutdown immediate
Thu Nov 10 07:41:50 2011 : Initiating SHUTDOWN operation on source server pid [885] for secondary instance [dummy]
Thu Nov 10 07:41:50 2011 : Waiting for upto [180] seconds for the source server to shutdown
Thu Nov 10 07:41:52 2011 : Journal pool shared memory removed
Thu Nov 10 07:41:52 2011 : Journal pool semaphore removed
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/aA.dat successfully rundown
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/gtm.dat successfully rundown
gtmuser@shanghai:~$ mupip replicate -source -start -instsecondary=CapeTown -secondary=10.0.2.2:4000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_CapeTown.log
Thu Nov 10 07:42:36 2011 : Initiating START of source server for secondary instance [CapeTown]
gtmuser@shanghai:~$ mupip replicate -source -start -instsecondary=Philadelphia -secondary=10.0.2.2:5000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_Philadelphia.log
Thu Nov 10 07:43:20 2011 : Initiating START of source server for secondary instance [Philadelphia]
gtmuser@shanghai:~$ 

ケープタウン( Cape Town)とフィラデルフィア(Philadelphia)の両方とも、それらが上海(Shanghai)へセカンダリのインスタンスになる前に、rollback fetchresync (再同期取得によるロールバック)を実行する必要があります。最初にケープタウン(Cape Town)(フィラデルフィア(Philadelphia) はクラッシュしてダウンしていますしているので、それらローカルタイムゾーンの時刻を示すため、時間が非常に異なって見えることに注意してください)。

gtmuser@capetown:~$ myApp/replicating_stop
Signalling immediate shutdown
Thu Nov 10 01:46:06 2011 : Initiating shut down
Thu Nov 10 01:46:07 2011 : Receive pool shared memory removed
Thu Nov 10 01:46:07 2011 : Receive pool semaphore removed
Thu Nov 10 01:46:07 2011 : Signalling shutdown immediate
Thu Nov 10 01:46:07 2011 : Initiating SHUTDOWN operation on source server pid [1010] for secondary instance [dummy]
Thu Nov 10 01:46:07 2011 : Waiting for upto [180] seconds for the source server to shutdown
Thu Nov 10 01:46:09 2011 : Journal pool shared memory removed
Thu Nov 10 01:46:09 2011 : Journal pool semaphore removed
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/aA.dat successfully rundown
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/gtm.dat successfully rundown
gtmuser@capetown:~$ mupip journal -rollback -backward -fetchresync=3000 -losttrans=/home/gtmuser/myApp/Unreplic_Trans_Report_`date +%Y%m%d%H%M%S`.txt "*"
%GTM-I-MUJNLSTAT, Initial processing started at Thu Nov 10 01:46:40 2011
%GTM-I-MUJNLSTAT, FETCHRESYNC processing started at Thu Nov 10 01:46:40 2011
Thu Nov 10 01:46:40 2011 : Assuming primary supports multisite functionality. Connecting using multisite communication protocol.
Thu Nov 10 01:46:40 2011 : Waiting for a connection...
Thu Nov 10 01:46:41 2011 : Connection established, using TCP send buffer size 16384 receive buffer size 87380
Thu Nov 10 01:46:41 2011 : Connection information:: Local: 10.0.2.15:3000 Remote: 10.0.2.2:36568
Thu Nov 10 01:46:41 2011 : Sending REPL_FETCH_RESYNC message with seqno 3 [0x3]
Thu Nov 10 01:46:41 2011 : Received REPL_NEED_INSTANCE_INFO message from primary instance [Shanghai]
Thu Nov 10 01:46:41 2011 : Sending REPL_INSTANCE_INFO message
Thu Nov 10 01:46:41 2011 : Received REPL_NEED_TRIPLE_INFO message for seqno 3 [0x3]
Thu Nov 10 01:46:41 2011 : Sending REPL_TRIPLE_INFO1 message with seqno 1 [0x1]
Thu Nov 10 01:46:41 2011 : Sending REPL_TRIPLE_INFO2 message with seqno 1 [0x1]
Thu Nov 10 01:46:41 2011 : Triple Sent with Start Seqno = 1 [0x1] : Root Primary = [Philadelphia] : Cycle = [1]
Thu Nov 10 01:46:41 2011 : Received REPL_RESYNC_SEQNO message
Thu Nov 10 01:46:41 2011 : Received RESYNC SEQNO is 3 [0x3]
%GTM-I-MUJNLSTAT, Backward processing started at Thu Nov 10 01:46:41 2011
%GTM-I-RESOLVESEQNO, Resolving until sequence number 0x0000000000000003
%GTM-I-MUJNLSTAT, Before image applying started at Thu Nov 10 01:46:41 2011
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011313002048
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314014608
%GTM-I-MUJNLSTAT, Forward processing started at Thu Nov 10 01:46:42 2011
%GTM-I-FILECREATE, Lost transactions extract file /home/gtmuser/myApp/Unreplic_Trans_Report_20111110014640.txt created
%GTM-I-RLBKJNSEQ, Journal seqno of the instance after rollback is 3 [0x0000000000000003]
%GTM-S-JNLSUCCESS, Show successful
%GTM-S-JNLSUCCESS, Verify successful
%GTM-S-JNLSUCCESS, Rollback successful
%GTM-I-MUJNLSTAT, End processing at Thu Nov 10 01:46:42 2011
gtmuser@capetown:~$ myApp/replicating_start
Thu Nov 10 01:46:59 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@capetown:~$ 

レプリケートされていないトランザクション ファイルがトランザクションのロールバックが無いことに注意してください:

gtmuser@capetown:~$ cat myApp/Unreplic_Trans_Report_20111110014640.txt 
GDSJEX05 ROLLBACK SECONDARY CapeTown
02\62405,6368\4\1010\0
03\62405,6368\4\1010\0\3

gtmuser@capetown:~$ 

今、そのリカバリーをシミュレートするためにフィラデルフィア(Philadelphia )を再起動します。システムが起動したとき(他のデータベースアクセスを実行する前に)に、ロールバック フェッチ リシンクロ (rollback fetchresync) を行います。

gtmuser@philadelphia:~$ mupip journal -rollback -backward -fetchresync=3000 -losttrans=/home/gtmuser/myApp/Unreplic_Trans_Report_`date +%Y%m%d%H%M%S`.txt "*"
%GTM-I-MUJNLSTAT, Initial processing started at Wed Nov  9 18:53:00 2011
%GTM-I-MUJNLSTAT, FETCHRESYNC processing started at Wed Nov  9 18:53:00 2011
Wed Nov  9 18:53:00 2011 : Assuming primary supports multisite functionality. Connecting using multisite communication protocol.
Wed Nov  9 18:53:00 2011 : Waiting for a connection...
Wed Nov  9 18:53:00 2011 : Connection established, using TCP send buffer size 16384 receive buffer size 87380
Wed Nov  9 18:53:00 2011 : Connection information:: Local: 10.0.2.15:3000 Remote: 10.0.2.2:49063
Wed Nov  9 18:53:00 2011 : Sending REPL_FETCH_RESYNC message with seqno 3 [0x3]
Wed Nov  9 18:53:00 2011 : Received REPL_NEED_INSTANCE_INFO message from primary instance [Shanghai]
Wed Nov  9 18:53:00 2011 : Sending REPL_INSTANCE_INFO message
Wed Nov  9 18:53:00 2011 : Received REPL_NEED_TRIPLE_INFO message for seqno 3 [0x3]
Wed Nov  9 18:53:00 2011 : Sending REPL_TRIPLE_INFO1 message with seqno 1 [0x1]
Wed Nov  9 18:53:00 2011 : Sending REPL_TRIPLE_INFO2 message with seqno 1 [0x1]
Wed Nov  9 18:53:00 2011 : Triple Sent with Start Seqno = 1 [0x1] : Root Primary = [Philadelphia] : Cycle = [1]
Wed Nov  9 18:53:00 2011 : Received REPL_RESYNC_SEQNO message
Wed Nov  9 18:53:00 2011 : Received RESYNC SEQNO is 3 [0x3]
%GTM-I-MUJNLSTAT, Backward processing started at Wed Nov  9 18:53:00 2011
%GTM-I-RESOLVESEQNO, Resolving until sequence number 0x0000000000000003
%GTM-I-MUJNLSTAT, Before image applying started at Wed Nov  9 18:53:00 2011
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011312172048
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011313183109
%GTM-I-MUJNLSTAT, Forward processing started at Wed Nov  9 18:53:01 2011
%GTM-I-FILECREATE, Lost transactions extract file /home/gtmuser/myApp/Unreplic_Trans_Report_20111109185300.txt created
%GTM-I-RLBKJNSEQ, Journal seqno of the instance after rollback is 3 [0x0000000000000003]
%GTM-S-JNLSUCCESS, Show successful
%GTM-S-JNLSUCCESS, Verify successful
%GTM-S-JNLSUCCESS, Rollback successful
%GTM-I-MUJNLSTAT, End processing at Wed Nov  9 18:53:01 2011
gtmuser@philadelphia:~$ myApp/replicating_start
Wed Nov  9 18:53:15 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@philadelphia:~$ 

次に、上海(Shanghai)でデータベースを更新してみます。

GTM>set ^Weather("Shanghai",$Piece($Horolog,",",1),$Piece($Horolog,",",2))="Stormy"

ケープタウン(Cape Town)とフィラデルフィア(Philadelphia)の両方にレプリケートされていることを確認してください。

GTM>zwrite ^Weather
^Weather("Philadelphia",62404,64970)="Rainy"
^Weather("Philadelphia",62404,66663)="Sunny"
^Weather("Shanghai",62406,2715)="Stormy"

演習をきれいに終了するには、3つのすべてのインスタンスをシャットダウンします。上海(Shanghai)でオリジナルのインスタンスを停止。

gtmuser@shanghai:~$ myApp/originating_stop
Fri Nov 11 00:47:24 2011 : Signalling shutdown immediate
Fri Nov 11 00:47:24 2011 : Initiating SHUTDOWN operation on source server pid [896] for secondary instance [CapeTown]
Fri Nov 11 00:47:24 2011 : Initiating SHUTDOWN operation on source server pid [898] for secondary instance [Philadelphia]
Fri Nov 11 00:47:24 2011 : Waiting for upto [180] seconds for the source server to shutdown
Fri Nov 11 00:47:25 2011 : Journal pool shared memory removed
Fri Nov 11 00:47:25 2011 : Journal pool semaphore removed
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/aA.dat successfully rundown
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/gtm.dat successfully rundown
gtmuser@shanghai:~$

そして、ケープタウン(Cape Town)とフィラデルフィア(Philadelphia)のレプリケーションのインスタンスで、myApp/replicating_stopを実行してレプリケーションを停止します。

gtmuser@philadelphia:~$ myAppSignalling immediate shutdown
Thu Nov 10 11:50:38 2011 : Initiating shut down
Thu Nov 10 11:50:39 2011 : Receive pool shared memory removed
Thu Nov 10 11:50:39 2011 : Receive pool semaphore removed
Thu Nov 10 11:50:39 2011 : Signalling shutdown immediate
Thu Nov 10 11:50:39 2011 : Initiating SHUTDOWN operation on source server pid [862] for secondary instance [dummy]
Thu Nov 10 11:50:39 2011 : Waiting for upto [180] seconds for the source server to shutdown
Thu Nov 10 11:50:40 2011 : Journal pool shared memory removed
Thu Nov 10 11:50:40 2011 : Journal pool semaphore removed
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/aA.dat successfully rundown
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/gtm.dat successfully rundown
gtmuser@philadelphia:~$

レプリケーションとバックログ

理想的な世界では、オリジナルのインスタンスはバックログを持って一度もダウンしないことです。しかし現実の世界では、レプリケートされない更新のバックログを持った状態でダウンする可能性があります。ビジネスの継続性を提供するためには、オリジナルのインスタンスがダウンする時には、以前の古いレプリケーションのインスタンスが、利用可能なアプリケーションを維持しながら新しいオリジナルとして立ち上がらなければなりません。 旧プライマリが新セカンダリとして立ち上がる時には、バックログの一部分が残っている更新を取り扱う必要があります。GT.Mは、継続的に利用されるアプリケーションを作成するために必要とされるフック(留め金?)を提供しますが、しかし、アプリケーション側で、これらのフックを活用する必要があります。次の2つのインスタンスの例を検討してみてください( 記号 P: 100 は、プライマリとして動作しているサイトの更新番号100番がコミットされていることを意味します):

ケープタウン(Cape Town)

上海(Shanghai)

P:100 (プライマリの更新番号100番)

S: 95 ( セカンダリ:5個の更新が残っているバックログ )

Crashes(クラッシュが発生)

P: 95 (こちら側がオリジナルのインスタンスになり、処理を開始し、全体構成の運用を続ける)

リペアされバックアップが運ばれてくる

P: 120(プロセスが先にそれを移動。トランザクションの矛盾)



上記のような状況を是正する必要があります。なぜなら、ケープタウン(Cape Town)の96番から100番の更新(トランザクション)は、上海(Shanghai)の更新96番から100番とは異なっているからです。この是正には、GT.Mのパートとアプリケーション ソフトウェアのパートがあります。GT.Mのパートは、mupip journal -rollback -fetchresync コマンドを使って、旧オリジナル上でトランザクションをロールバックします。これらのロールバックされた更新( “unreplicated(非レプリケート)” または “lost(失われた)” )は、ファイル内に配置され、そして、アプリケーションロジックにより再処理(reprocessing) / 調停(reconciliation) を経て、新しいオリジナルのインスタンスへ送信する必要があります。

ケープタウン(Cape Town)

上海(Shanghai)

S: 95(ロールバックされたデータベース ;非レプリケートトランザクションファイル内で 、96番から100番を更新)

P: 120

S: 120( レプリケーションが一度再開すると、上海(Shanghai)に追いつく)

P: 120(非レプリケートのトランザクションファイルを受信する)

S: 125(非レプリケートトランザクションは、再処理の後に巻き戻ります)

P: 125(非レプリケートのトランザクションの処理の方が先に移動してます)



少し複雑にするために、上記の例にフィラデルフィア(Philadelphia)を追加します。ケープタウン(Cape Town)がクラッシュする際に考慮すべき2つのケースがあります:

演習 - レプリケーションとバックログ

この演習では、(上記の例の5つの更新より小さい)バックログを使用してレプリケーションをシミュレートします。オリジナルのインスタンスとしてケープタウン(Cape Town)で開始し、レプリケートのインスタンスとしてフィラデルフィア(Philadelphia)と上海(Shanghai)へレプリケートをします。 ケープタウン(Cape Town)は、最も最近にはセカンダリのインスタンスになっていたので、上海(Shanghai)とフィラデルフィア(Philadelphia)では mupip journal -rollback -fetchresyncで始める必要があります。

オリジナルのインスタンスとしてケープタウン(Cape Town)をスタートします。

gtmuser@capetown:~$ mupip replicate -source -start -instsecondary=Philadelphia -secondary=10.0.2.2:5000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_Philadelphia.log
Thu Nov 10 19:01:51 2011 : Initiating START of source server for secondary instance [Philadelphia]
gtmuser@capetown:~$ mupip replicate -source -start -instsecondary=Shanghai -secondary=10.0.2.2:6000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_Shanghai.log
Thu Nov 10 19:02:04 2011 : Initiating START of source server for secondary instance [Shanghai]
gtmuser@capetown:~$ 

フィラデルフィア(Philadelphia)(そして上海(Shanghai)でも)で fetchresync 操作を実行し、次にレプリケーションを開始します。レプリケーションの健全性とレプリケーションのバックログの状況を知らせてもらうためにGT.Mに要求することができます。

gtmuser@philadelphia:~$ mupip journal -rollback -backward -fetchresync=3000 -losttrans=/home/gtmuser/myApp/Unreplic_Trans_Report_`date +%Y%m%d%H%M%S`.txt "*"
%GTM-I-MUJNLSTAT, Initial processing started at Thu Nov 10 12:03:02 2011
%GTM-I-MUJNLSTAT, FETCHRESYNC processing started at Thu Nov 10 12:03:02 2011
Thu Nov 10 12:03:02 2011 : Assuming primary supports multisite functionality. Connecting using multisite communication protocol.
Thu Nov 10 12:03:02 2011 : Waiting for a connection...
Thu Nov 10 12:03:03 2011 : Connection established, using TCP send buffer size 16384 receive buffer size 87380
Thu Nov 10 12:03:03 2011 : Connection information:: Local: 10.0.2.15:3000 Remote: 10.0.2.2:51018
Thu Nov 10 12:03:03 2011 : Sending REPL_FETCH_RESYNC message with seqno 4 [0x4]
Thu Nov 10 12:03:03 2011 : Received REPL_NEED_INSTANCE_INFO message from primary instance [CapeTown]
Thu Nov 10 12:03:03 2011 : Sending REPL_INSTANCE_INFO message
Thu Nov 10 12:03:03 2011 : Received REPL_NEED_TRIPLE_INFO message for seqno 4 [0x4]
Thu Nov 10 12:03:03 2011 : Sending REPL_TRIPLE_INFO1 message with seqno 3 [0x3]
Thu Nov 10 12:03:03 2011 : Sending REPL_TRIPLE_INFO2 message with seqno 3 [0x3]
Thu Nov 10 12:03:03 2011 : Triple Sent with Start Seqno = 3 [0x3] : Root Primary = [Shanghai] : Cycle = [1]
Thu Nov 10 12:03:03 2011 : Received REPL_RESYNC_SEQNO message
Thu Nov 10 12:03:03 2011 : Received RESYNC SEQNO is 4 [0x4]
%GTM-I-MUJNLSTAT, Backward processing started at Thu Nov 10 12:03:03 2011
%GTM-I-RESOLVESEQNO, Resolving until sequence number 0x0000000000000004
%GTM-I-MUJNLSTAT, Before image applying started at Thu Nov 10 12:03:03 2011
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011313185301
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314115040
%GTM-I-MUJNLSTAT, Forward processing started at Thu Nov 10 12:03:04 2011
%GTM-I-FILECREATE, Lost transactions extract file /home/gtmuser/myApp/Unreplic_Trans_Report_20111110120302.txt created
%GTM-I-RLBKJNSEQ, Journal seqno of the instance after rollback is 4 [0x0000000000000004]
%GTM-S-JNLSUCCESS, Show successful
%GTM-S-JNLSUCCESS, Verify successful
%GTM-S-JNLSUCCESS, Rollback successful
%GTM-I-MUJNLSTAT, End processing at Thu Nov 10 12:03:04 2011
gtmuser@philadelphia:~$ myApp/replicating_start
Thu Nov 10 12:06:10 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@philadelphia:~$ mupip replicate -receiver -checkhealth
PID 910 Receiver server is alive
PID 911 Update process is alive
gtmuser@philadelphia:~$ mupip replicate -receiver -showbacklog
0 : number of backlog transactions received by receiver server and yet to be processed by update process
3 : sequence number of last transaction received from Source Server and written to receive pool
3 : sequence number of last transaction processed by update process
gtmuser@philadelphia:~$ 

また、オリジナルのインスタンス、ケープタウン(Cape Town)上で、レプリケーションの健全性とバックログをチェックすることができます。注意:あなたが求める詳細なレプリケーション接続についての指定がなければ、すべての情報を取得します。

gtmuser@capetown:~$ mupip replicate -source -checkhealth
Thu Nov 10 20:37:07 2011 : Initiating CHECKHEALTH operation on source server pid [1090] for secondary instance name [Philadelphia]
PID 1090 Source server is alive in ACTIVE mode
Thu Nov 10 20:37:07 2011 : Initiating CHECKHEALTH operation on source server pid [1092] for secondary instance name [Shanghai]
PID 1092 Source server is alive in ACTIVE mode
gtmuser@capetown:~$ mupip replicate -source -showbacklog
Thu Nov 10 20:37:24 2011 : Initiating SHOWBACKLOG operation on source server pid [1090] for secondary instance [Philadelphia]
0 : backlog number of transactions written to journal pool and yet to be sent by the source server
3 : sequence number of last transaction written to journal pool
3 : sequence number of last transaction sent by source server
Thu Nov 10 20:37:24 2011 : Initiating SHOWBACKLOG operation on source server pid [1092] for secondary instance [Shanghai]
0 : backlog number of transactions written to journal pool and yet to be sent by the source server
3 : sequence number of last transaction written to journal pool
3 : sequence number of last transaction sent by source server
gtmuser@capetown:~$ 

ケープタウン(Cape Town)でグローバルの更新をしてみます。

GTM>set ^Weather("Cape Town",$Piece($Horolog,",",1),$Piece($Horolog,",",2))="Snowing"

フィラデルフィア(Philadelphia)と上海(Shanghai)でレプリケートを確認します。

GTM>ZWRite ^Weather
^Weather("Cape Town",62405,74316)="Snowing"
^Weather("Philadelphia",62404,64970)="Rainy"
^Weather("Philadelphia",62404,66663)="Sunny"
^Weather("Shanghai",62406,2715)="Stormy"

最初に上海(Shnghai)でレプリケーションをシャットダウンし、次にケープタウン(Cape Town)でグローバルの更新を行い、バックログの障害をシミュレートします。上海(Shanghai)で:

gtmuser@shanghai:~$ myApp/replicating_stop
Signalling immediate shutdown
Fri Nov 11 02:40:38 2011 : Initiating shut down
Fri Nov 11 02:40:39 2011 : Receive pool shared memory removed
Fri Nov 11 02:40:39 2011 : Receive pool semaphore removed
Fri Nov 11 02:40:39 2011 : Signalling shutdown immediate
Fri Nov 11 02:40:39 2011 : Initiating SHUTDOWN operation on source server pid [941] for secondary instance [dummy]
Fri Nov 11 02:40:39 2011 : Waiting for upto [180] seconds for the source server to shutdown
Fri Nov 11 02:40:40 2011 : Journal pool shared memory removed
Fri Nov 11 02:40:40 2011 : Journal pool semaphore removed
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/aA.dat successfully rundown
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/gtm.dat successfully rundown
gtmuser@shanghai:~$ 

ケープタウン(Cape Town)で:

GTM>set ^Weather("Cape Town",$Piece($Horolog,",",1),$Piece($Horolog,",",2))="Blizzards"

GTM>zsystem "$gtm_dist/mupip replicate -source -showbacklog"
Thu Nov 10 20:42:36 2011 : Initiating SHOWBACKLOG operation on source server pid [1090] for secondary instance [Philadelphia]
0 : backlog number of transactions written to journal pool and yet to be sent by the source server
5 : sequence number of last transaction written to journal pool
5 : sequence number of last transaction sent by source server
Thu Nov 10 20:42:36 2011 : Initiating SHOWBACKLOG operation on source server pid [1092] for secondary instance [Shanghai]
1 : backlog number of transactions written to journal pool and yet to be sent by the source server
5 : sequence number of last transaction written to journal pool
4 : sequence number of last transaction sent by source server

GTM>

注意:上海(Shanghai)へのバックログがありますが、フィラデルフィア(Philadelphia)へはありません。フィラデルフィア(Philadelphia)でのレプリケーションをシャットダウンし、ケープタウン(Cape Town)上での他の更新を確認します。フィラデルフィア(Philadelphia)へ1、そして、上海(Shanghai)へ2のバックログがあることを確認します。

フィラデルフィア(Philadelphia)で:

gtmuser@philadelphia:~$ myApp/replicating_stop
Signalling immediate shutdown
Thu Nov 10 14:43:05 2011 : Initiating shut down
Thu Nov 10 14:43:06 2011 : Receive pool shared memory removed
Thu Nov 10 14:43:06 2011 : Receive pool semaphore removed
Thu Nov 10 14:43:06 2011 : Signalling shutdown immediate
Thu Nov 10 14:43:06 2011 : Initiating SHUTDOWN operation on source server pid [908] for secondary instance [dummy]
Thu Nov 10 14:43:06 2011 : Waiting for upto [180] seconds for the source server to shutdown
Thu Nov 10 14:43:07 2011 : Journal pool shared memory removed
Thu Nov 10 14:43:07 2011 : Journal pool semaphore removed
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/aA.dat successfully rundown
%GTM-I-MUFILRNDWNSUC, File /home/gtmuser/myApp/gtm.dat successfully rundown
gtmuser@philadelphia:~$ 

ケープタウン(Cape Town)で:

gtmuser@capetown:~$ mumps -dir

GTM>set ^Weather("Cape Town",$Piece($Horolog,",",1),$Piece($Horolog,",",2))="Cloudy"

GTM>zwrite ^Weather
^Weather("Cape Town",62405,74316)="Snowing"
^Weather("Cape Town",62405,74509)="Blizzards"
^Weather("Cape Town",62405,78542)="Cloudy"
^Weather("Philadelphia",62404,64970)="Rainy"
^Weather("Philadelphia",62404,66663)="Sunny"
^Weather("Shanghai",62406,2715)="Stormy"

GTM>zsystem "$gtm_dist/mupip replicate -source -showbacklog"
Thu Nov 10 21:50:21 2011 : Initiating SHOWBACKLOG operation on source server pid [1090] for secondary instance [Philadelphia]
1 : backlog number of transactions written to journal pool and yet to be sent by the source server
6 : sequence number of last transaction written to journal pool
5 : sequence number of last transaction sent by source server
Thu Nov 10 21:50:21 2011 : Initiating SHOWBACKLOG operation on source server pid [1092] for secondary instance [Shanghai]
2 : backlog number of transactions written to journal pool and yet to be sent by the source server
6 : sequence number of last transaction written to journal pool
4 : sequence number of last transaction sent by source server

GTM>

ケープタウン(Cape Town) をクラッシュしてみます。あなたはフィラデルフィア(Philadelphia)または上海(Shanghai)のどちらかへ運ぶことを選択できます。もしあなたが、新しいプライマリを作成してインスタンスをレプリケートすることについて決定する時間がないならば、最も便利な方を選択してください。もしあなたが決定するまでの時間があるならば、DSEを使ってデータベースファイルヘッダーにある“Region Seqno”フィールドを見て、さらに先のいづれかの1つを参照できます(複数領域(multi-region)のデータベース内で、レプリケートされたすべての領域を見る必要があり、そして最大値を取ります)。

フィラデルフィア(Philadelphia)の場合(ノート:DSEコマンドのfind -regionを使用):

gtmuser@philadelphia:~$ $gtm_dist/dse


File    /home/gtmuser/myApp/aA.dat
Region  AA

DSE> dump -fileheader

File            /home/gtmuser/myApp/aA.dat
Region          AA
Date/Time       10-NOV-2011 14:52:59 [$H = 62405,53579]
  Access method                          BG  Global Buffers                1000
  Reserved Bytes                          0  Block size (in bytes)         4096
  Maximum record size                  4080  Starting VBN                   129
  Maximum key size                      255  Total blocks            0x00001392
  Null subscripts                     NEVER  Free blocks             0x00001384
  Standard Null Collation              TRUE  Free space              0x00000000
  Last Record Backup     0x0000000000000001  Extension Count              10000
  Last Database Backup   0x0000000000000001  Number of local maps            10
  Last Bytestream Backup 0x0000000000000001  Lock space              0x00000028
  In critical section            0x00000000  Timers pending                   0
  Cache freeze id                0x00000000  Flush timer            00:00:01:00
  Freeze match                   0x00000000  Flush trigger                  938
  Current transaction    0x0000000000000002  No. of writes/flush              7
  Maximum TN             0xFFFFFFFFE3FFFFFF  Certified for Upgrade to        V5
  Maximum TN Warn        0xFFFFFFFF73FFFFFF  Desired DB Format               V5
  Master Bitmap Size                    112  Blocks to Upgrade       0x00000000
  Create in progress                  FALSE  Modified cache blocks            0
  Reference count                         1  Wait Disk                        0
  Journal State               [inactive] ON  Journal Before imaging        TRUE
  Journal Allocation                   2048  Journal Extension             2048
  Journal Buffer Size                   128  Journal Alignsize             2048
  Journal AutoSwitchLimit           8386560  Journal Epoch Interval         300
  Journal Yield Limit                     8  Journal Sync IO              FALSE
  Journal File: /home/gtmuser/myApp/aA.mjl
  Mutex Hard Spin Count                 128  Mutex Sleep Spin Count         128
  Mutex Spin Sleep Time                2048  KILLs in progress                0
  Replication State                      ON  Region Seqno    0x0000000000000004
  Zqgblmod Seqno         0x0000000000000003  Zqgblmod Trans  0x0000000000000002
  Endian Format                      LITTLE  Commit Wait Spin Count          16
  Database file encrypted             FALSE
DSE> find -region
List of global directory:       


File    /home/gtmuser/myApp/aA.dat
Region  AA

File    /home/gtmuser/myApp/gtm.dat
Region  DEFAULT
DSE> find -region=DEFAULT

File    /home/gtmuser/myApp/gtm.dat
Region  DEFAULT

DSE> dump -fileheader

File            /home/gtmuser/myApp/gtm.dat
Region          DEFAULT
Date/Time       10-NOV-2011 14:54:59 [$H = 62405,53699]
  Access method                          BG  Global Buffers                1000
  Reserved Bytes                          0  Block size (in bytes)         4096
  Maximum record size                  4080  Starting VBN                   129
  Maximum key size                      255  Total blocks            0x00001392
  Null subscripts                     NEVER  Free blocks             0x00001382
  Standard Null Collation              TRUE  Free space              0x00000000
  Last Record Backup     0x0000000000000001  Extension Count              10000
  Last Database Backup   0x0000000000000001  Number of local maps            10
  Last Bytestream Backup 0x0000000000000001  Lock space              0x00000028
  In critical section            0x00000000  Timers pending                   0
  Cache freeze id                0x00000000  Flush timer            00:00:01:00
  Freeze match                   0x00000000  Flush trigger                  938
  Current transaction    0x0000000000000007  No. of writes/flush              7
  Maximum TN             0xFFFFFFFFE3FFFFFF  Certified for Upgrade to        V5
  Maximum TN Warn        0xFFFFFFFF73FFFFFF  Desired DB Format               V5
  Master Bitmap Size                    112  Blocks to Upgrade       0x00000000
  Create in progress                  FALSE  Modified cache blocks            0
  Reference count                         1  Wait Disk                        0
  Journal State               [inactive] ON  Journal Before imaging        TRUE
  Journal Allocation                   2048  Journal Extension             2048
  Journal Buffer Size                   128  Journal Alignsize             2048
  Journal AutoSwitchLimit           8386560  Journal Epoch Interval         300
  Journal Yield Limit                     8  Journal Sync IO              FALSE
  Journal File: /home/gtmuser/myApp/gtm.mjl
  Mutex Hard Spin Count                 128  Mutex Sleep Spin Count         128
  Mutex Spin Sleep Time                2048  KILLs in progress                0
  Replication State                      ON  Region Seqno    0x0000000000000006
  Zqgblmod Seqno         0x0000000000000003  Zqgblmod Trans  0x0000000000000004
  Endian Format                      LITTLE  Commit Wait Spin Count          16
  Database file encrypted             FALSE
DSE> exit
gtmuser@philadelphia:~$ 

そして上海(Shanghai)で:

gtmuser@shanghai:~$ $gtm_dist/dse

File    /home/gtmuser/myApp/aA.dat
Region  AA

DSE> dump -fileheader

File            /home/gtmuser/myApp/aA.dat
Region          AA
Date/Time       11-NOV-2011 03:58:49 [$H = 62406,14329]
  Access method                          BG  Global Buffers                1000
  Reserved Bytes                          0  Block size (in bytes)         4096
  Maximum record size                  4080  Starting VBN                   129
  Maximum key size                      255  Total blocks            0x00001392
  Null subscripts                     NEVER  Free blocks             0x00001384
  Standard Null Collation              TRUE  Free space              0x00000000
  Last Record Backup     0x0000000000000001  Extension Count              10000
  Last Database Backup   0x0000000000000001  Number of local maps            10
  Last Bytestream Backup 0x0000000000000001  Lock space              0x00000028
  In critical section            0x00000000  Timers pending                   0
  Cache freeze id                0x00000000  Flush timer            00:00:01:00
  Freeze match                   0x00000000  Flush trigger                  938
  Current transaction    0x0000000000000002  No. of writes/flush              7
  Maximum TN             0xFFFFFFFFE3FFFFFF  Certified for Upgrade to        V5
  Maximum TN Warn        0xFFFFFFFF73FFFFFF  Desired DB Format               V5
  Master Bitmap Size                    112  Blocks to Upgrade       0x00000000
  Create in progress                  FALSE  Modified cache blocks            0
  Reference count                         1  Wait Disk                        0
  Journal State               [inactive] ON  Journal Before imaging        TRUE
  Journal Allocation                   2048  Journal Extension             2048
  Journal Buffer Size                   128  Journal Alignsize             2048
  Journal AutoSwitchLimit           8386560  Journal Epoch Interval         300
  Journal Yield Limit                     8  Journal Sync IO              FALSE
  Journal File: /home/gtmuser/myApp/aA.mjl
  Mutex Hard Spin Count                 128  Mutex Sleep Spin Count         128
  Mutex Spin Sleep Time                2048  KILLs in progress                0
  Replication State                      ON  Region Seqno    0x0000000000000004
  Zqgblmod Seqno         0x0000000000000001  Zqgblmod Trans  0x0000000000000002
  Endian Format                      LITTLE  Commit Wait Spin Count          16
  Database file encrypted             FALSE
DSE> find -region=DEFAULT

File    /home/gtmuser/myApp/gtm.dat
Region  DEFAULT

DSE> dump -fileheader

File            /home/gtmuser/myApp/gtm.dat
Region          DEFAULT
Date/Time       11-NOV-2011 03:59:38 [$H = 62406,14378]
  Access method                          BG  Global Buffers                1000
  Reserved Bytes                          0  Block size (in bytes)         4096
  Maximum record size                  4080  Starting VBN                   129
  Maximum key size                      255  Total blocks            0x00001392
  Null subscripts                     NEVER  Free blocks             0x00001382
  Standard Null Collation              TRUE  Free space              0x00000000
  Last Record Backup     0x0000000000000001  Extension Count              10000
  Last Database Backup   0x0000000000000001  Number of local maps            10
  Last Bytestream Backup 0x0000000000000001  Lock space              0x00000028
  In critical section            0x00000000  Timers pending                   0
  Cache freeze id                0x00000000  Flush timer            00:00:01:00
  Freeze match                   0x00000000  Flush trigger                  938
  Current transaction    0x0000000000000006  No. of writes/flush              7
  Maximum TN             0xFFFFFFFFE3FFFFFF  Certified for Upgrade to        V5
  Maximum TN Warn        0xFFFFFFFF73FFFFFF  Desired DB Format               V5
  Master Bitmap Size                    112  Blocks to Upgrade       0x00000000
  Create in progress                  FALSE  Modified cache blocks            0
  Reference count                         1  Wait Disk                        0
  Journal State               [inactive] ON  Journal Before imaging        TRUE
  Journal Allocation                   2048  Journal Extension             2048
  Journal Buffer Size                   128  Journal Alignsize             2048
  Journal AutoSwitchLimit           8386560  Journal Epoch Interval         300
  Journal Yield Limit                     8  Journal Sync IO              FALSE
  Journal File: /home/gtmuser/myApp/gtm.mjl
  Mutex Hard Spin Count                 128  Mutex Sleep Spin Count         128
  Mutex Spin Sleep Time                2048  KILLs in progress                0
  Replication State                      ON  Region Seqno    0x0000000000000005
  Zqgblmod Seqno         0x0000000000000001  Zqgblmod Trans  0x0000000000000002
  Endian Format                      LITTLE  Commit Wait Spin Count          16
  Database file encrypted             FALSE
DSE> exit
gtmuser@shanghai:~$ 

領域番号の最大の Seqno は 6(フィラデルフィア(Philadelphia) のDEFAULT 領域)ですので、それは好ましい新しいオリジナルのプライマリインスタンスです。このように、それを新しいオリジナルのプライマリになります。

gtmuser@philadelphia:~$ mupip replicate -source -start -instsecondary=Shanghai -secondary=10.0.2.2:6000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_Shanghai.log
Thu Nov 10 15:02:01 2011 : Initiating START of source server for secondary instance [Shanghai]
gtmuser@philadelphia:~$ mupip replicate -source -start -instsecondary=CapeTown -secondary=10.0.2.2:4000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_CapeTown.log
Thu Nov 10 15:02:28 2011 : Initiating START of source server for secondary instance [CapeTown]
gtmuser@philadelphia:~$ 

上海(Shanghai)では、mupip journal -rollback -fetchresync 操作を実行し、レプリケートのインスタンスとして動作を開始します。

gtmuser@shanghai:~$ mupip journal -rollback -backward -fetchresync=3000 -losttrans=/home/gtmuser/myApp/Unreplic_Trans_Report_`date +%Y%m%d%H%M%S`.txt "*"
%GTM-I-MUJNLSTAT, Initial processing started at Fri Nov 11 04:03:17 2011
%GTM-I-MUJNLSTAT, FETCHRESYNC processing started at Fri Nov 11 04:03:17 2011
Fri Nov 11 04:03:17 2011 : Assuming primary supports multisite functionality. Connecting using multisite communication protocol.
Fri Nov 11 04:03:17 2011 : Waiting for a connection...
[参考]Thu Nov 10 01:46:41 2011 : Connection established, using TCP send buffer size 16384 receive buffer size 87380
Thu Nov 10 01:46:41 2011 : Connection information:: Local: 10.0.2.15:3000 Remote: 10.0.2.2:36568
Thu Nov 10 01:46:41 2011 : Sending REPL_FETCH_RESYNC message with seqno 3 [0x3]
Thu Nov 10 01:46:41 2011 : Received REPL_NEED_INSTANCE_INFO message from primary instance [Shanghai]
Thu Nov 10 01:46:41 2011 : Sending REPL_INSTANCE_INFO message
Thu Nov 10 01:46:41 2011 : Received REPL_NEED_TRIPLE_INFO message for seqno 3 [0x3]
Thu Nov 10 01:46:41 2011 : Sending REPL_TRIPLE_INFO1 message with seqno 1 [0x1]
Thu Nov 10 01:46:41 2011 : Sending REPL_TRIPLE_INFO2 message with seqno 1 [0x1]
Thu Nov 10 01:46:41 2011 : Triple Sent with Start Seqno = 1 [0x1] : Root Primary = [Philadelphia] : Cycle = [1]
Thu Nov 10 01:46:41 2011 : Received REPL_RESYNC_SEQNO message
Thu Nov 10 01:46:41 2011 : Received RESYNC SEQNO is 3 [0x3]
%GTM-I-MUJNLSTAT, Backward processing started at Thu Nov 10 01:46:41 2011
%GTM-I-RESOLVESEQNO, Resolving until sequence number 0x0000000000000003
%GTM-I-MUJNLSTAT, Before image applying started at Thu Nov 10 01:46:41 2011
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011313002048
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314014608
%GTM-I-MUJNLSTAT, Forward processing started at Thu Nov 10 01:46:42 2011
%GTM-I-FILECREATE, Lost transactions extract file /home/gtmuser/myApp/Unreplic_Trans_Report_20111110014640.txt created
%GTM-I-RLBKJNSEQ, Journal seqno of the instance after rollback is 3 [0x0000000000000003]
%GTM-S-JNLSUCCESS, Show successful
%GTM-S-JNLSUCCESS, Verify successful
%GTM-S-JNLSUCCESS, Rollback successful
%GTM-I-MUJNLSTAT, End processing at Thu Nov 10 01:46:42 2011
gtmuser@capetown:~$ <f2>myApp/replicating_start</f2>
Thu Nov 10 01:46:59 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@capetown:~$ 

フィラデルフィア(Philadelphia )で更新を実行し、ケープタウン(Cape Town)へのバックログがあることを確認します( 実際の数が正しくない可能性があります、なぜならば、ケープタウン(Cape Town)は最近フィラデルフィア(Philadelphia)へのレプリケートインスタンスではなかったからです)、しかし、上海(Shanghai)へのバックログはありません。

gtmuser@philadelphia:~$ mumps -dir

GTM>set ^Weather("Philadelphia",$Piece($Horolog,",",1),$Piece($Horolog,",",2))="Heat Wave"

GTM>zsystem "$gtm_dist/mupip replicate -source -showbacklog" 
Thu Nov 10 15:06:08 2011 : Initiating SHOWBACKLOG operation on source server pid [945] for secondary instance [CapeTown]
4 : backlog number of transactions written to journal pool and yet to be sent by the source server
6 : sequence number of last transaction written to journal pool
2 : sequence number of last transaction sent by source server
Thu Nov 10 15:06:08 2011 : Initiating SHOWBACKLOG operation on source server pid [941] for secondary instance [Shanghai]
0 : backlog number of transactions written to journal pool and yet to be sent by the source server
6 : sequence number of last transaction written to journal pool
6 : sequence number of last transaction sent by source server

GTM>

ケープタウン(Cape Town)のマシンをすぐにブートして、fetchresyncを実行します:

gtmuser@capetown:~$ source myApp/env
gtmuser@capetown:~$ mupip journal -rollback -backward -fetchresync=3000 -losttrans=/home/gtmuser/myApp/Unreplic_Trans_Report_`date +%Y%m%d%H%M%S`.txt "*"
%GTM-I-MUJNLSTAT, Initial processing started at Thu Nov 10 22:13:56 2011
%GTM-I-MUJNLSTAT, FETCHRESYNC processing started at Thu Nov 10 22:13:56 2011
Thu Nov 10 22:13:56 2011 : Assuming primary supports multisite functionality. Connecting using multisite communication protocol.
Thu Nov 10 22:13:56 2011 : Waiting for a connection...
Thu Nov 10 22:13:57 2011 : Connection established, using TCP send buffer size 16384 receive buffer size 87380
Thu Nov 10 22:13:57 2011 : Connection information:: Local: 10.0.2.15:3000 Remote: 10.0.2.2:47583
Thu Nov 10 22:13:57 2011 : Sending REPL_FETCH_RESYNC message with seqno 7 [0x7]
Thu Nov 10 22:13:57 2011 : Received REPL_NEED_INSTANCE_INFO message from primary instance [Philadelphia]
Thu Nov 10 22:13:57 2011 : Sending REPL_INSTANCE_INFO message
Thu Nov 10 22:13:57 2011 : Received REPL_NEED_TRIPLE_INFO message for seqno 7 [0x7]
Thu Nov 10 22:13:57 2011 : Sending REPL_TRIPLE_INFO1 message with seqno 4 [0x4]
Thu Nov 10 22:13:57 2011 : Sending REPL_TRIPLE_INFO2 message with seqno 4 [0x4]
Thu Nov 10 22:13:57 2011 : Triple Sent with Start Seqno = 4 [0x4] : Root Primary = [CapeTown] : Cycle = [1]
Thu Nov 10 22:13:57 2011 : Received REPL_RESYNC_SEQNO message
Thu Nov 10 22:13:57 2011 : Received RESYNC SEQNO is 6 [0x6]
%GTM-I-MUJNLSTAT, Backward processing started at Thu Nov 10 22:13:57 2011
%GTM-I-RESOLVESEQNO, Resolving until sequence number 0x0000000000000006
%GTM-I-MUJNLSTAT, Before image applying started at Thu Nov 10 22:13:57 2011
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011314190359
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314214908
%GTM-I-MUJNLSTAT, Forward processing started at Thu Nov 10 22:13:58 2011
%GTM-I-FILECREATE, Lost transactions extract file /home/gtmuser/myApp/Unreplic_Trans_Report_20111110221356.txt created
%GTM-I-RLBKJNSEQ, Journal seqno of the instance after rollback is 6 [0x0000000000000006]
%GTM-S-JNLSUCCESS, Show successful
%GTM-S-JNLSUCCESS, Verify successful
%GTM-S-JNLSUCCESS, Rollback successful
%GTM-I-MUJNLSTAT, End processing at Thu Nov 10 22:13:58 2011
gtmuser@capetown:~$ cat /home/gtmuser/myApp/Unreplic_Trans_Report_20111110221356.txt 
GDSJEX05 ROLLBACK PRIMARY CapeTown
05\62405,78542\7\1107\0\6\0\0\^Weather("Cape Town",62405,78542)="Cloudy"

gtmuser@capetown:~$ 

非レプリケートのトランザクションファイルは意義のあるコンテンツを持っていることに注意してください - ケープタウン(Cape Town)はオリジナルのインスタンスなった時には、更新は作られましたが、しかし、レプリケートはされていません。このファイルには、現在フィラデルフィア(Philadelphia)の新しいオリジナルのインスタンスによって処理する必要があります。

レプリケーション インスタンスとしてケープタウン(Cape Town)をすぐにスタートします:

gtmuser@capetown:~$ myApp/replicating_start
Thu Nov 10 22:16:18 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@capetown:~$ 

注意:フィラデルフィア(Philadelphia)は今はバックログがないことを報告します:

GTM>zsystem "$gtm_dist/mupip replicate -source -showbacklog"
Thu Nov 10 15:17:00 2011 : Initiating SHOWBACKLOG operation on source server pid [945] for secondary instance [CapeTown]
0 : backlog number of transactions written to journal pool and yet to be sent by the source server
6 : sequence number of last transaction written to journal pool
6 : sequence number of last transaction sent by source server
Thu Nov 10 15:17:00 2011 : Initiating SHOWBACKLOG operation on source server pid [941] for secondary instance [Shanghai]
0 : backlog number of transactions written to journal pool and yet to be sent by the source server
6 : sequence number of last transaction written to journal pool
6 : sequence number of last transaction sent by source server

GTM> 

もしアプリケーションが、レプリケートされていないトランザクションを処理する$ZQGBLMOD() 関数を使用している場合は、すべてのオリジナルインスタンスからレプリケートされていないトランザクションを処理した後に実行するmupip replicate source losttncomplete コマンドの詳細については、論理的なマルチサイトレプリケーション技術情報を参照してください。

バックアップ

アプリケーションが実行されていない時のバックアップは簡単です - データベースファイルをコピーするだけです。[ ただし覚えておいていただきたいことは、コピーはデータベースファイルヘッダーにある同じジャーナルファイルの名前を持つでしょう、そして、システムは潜在的に、同じジャーナルファイルを指している2つのデータベースファイルが存在します。オリジナルのデータベースファイルとして、同じコンピュータシステム上で、そのファイルを使用する前に、ジャーナリングを無効にし、必要に応じて、それを再び有効にします(単にジャーナルファイルの切替えはしないでください)。]

アプリケーションが正常に動作している時のバックアップは、(バックアップアクティビティの入出力負荷を増大するコースを除いて)、アプリケーションに影響を与えることなくGT.Mで簡単に行え、そして、バックアップを達成することができる2つの方法は、一つはGT.Mを使わない方法で、もう一方はGT.Mを使う方法です:

演習 – バックアップ

いずれかのインスタンスで行う作業は、最後にオリジナルのインスタンスであったいずれかのインスタンスで作業してください(それは本当は問題ではないが、常に mupip journal rollback fetchresyncステップで開始されるので、最後にオリジナルのインスタンスであったことに拘わらず、レプリケートのインスタンスとして、いつも他のインスタンスを立てることができます; この場合、例はフィラデルフィア(Philadelphia) をあらわします)。

バックアップを置くディレクトリを作成します: mkdir backup

そのインスタンスのmyAppディレクトリで、アップデートが作成されるファイルXYZ.mで、GT.MプログラムXYZを作成します。例えば:

XYZ    Set (^a,^b)=0
       For  Do
       . Hang 0.1
       . Tstart ()
       .   Set r=$Random(2147483646)
       .   Set ^a($horolog)=^a-r
       .   Set ^b($horolog)=^b+r
       . Tcommit
       Quit

(注)グローバル変数 ^a^b は異なったデータベースファイルに入りますが、トランザクション処理を使用することは、領域間のACID特性を提供します。

もしソースサーバーが実行しているソースサーバーが無いならば、レプリケートされた環境のデータベースがあるまで、 少なくとも一つを起動し、例えば: mupip replicate -source -start -instsecondary=Shanghai -secondary=10.0.2.2:6000 -buffsize=1048576 -log=/home/gtmuser/myApp/source_Shanghai.log [アップデートが許可される前に、少なくとも1つのソースサーバーが実行されているレプリケートされた環境が必要です。確実に2番目のソースサーバーを起動することができます。 - あるいは、下記の Replication Briefly Revisited (レプリケーションを簡単に再訪)の演習にあるように、後でそれを起動することができます]。

シェルからバックグラウンドプロセスとしてプログラムを起動します: mumps -run XYZ </dev/null 1>/dev/null 2>&1 &

プログラム実行中のジャーナルファイルが増大していることを示していることに注意してください:

gtmuser@philadelphia:~$ ls -l myApp/*.mjl
-rw-rw-rw- 1 gtmuser gtmuser 77824 2011-11-10 15:35 myApp/aA.mjl
-rw-rw-rw- 1 gtmuser gtmuser 77824 2011-11-10 15:35 myApp/gtm.mjl
gtmuser@philadelphia:~$ ls -l myApp/*.mjl
-rw-rw-rw- 1 gtmuser gtmuser 77824 2011-11-10 15:35 myApp/aA.mjl
-rw-rw-rw- 1 gtmuser gtmuser 81920 2011-11-10 15:35 myApp/gtm.mjl
gtmuser@philadelphia:~$ ls -l myApp/*.mjl
-rw-rw-rw- 1 gtmuser gtmuser 86016 2011-11-10 15:35 myApp/aA.mjl
-rw-rw-rw- 1 gtmuser gtmuser 86016 2011-11-10 15:35 myApp/gtm.mjl
gtmuser@philadelphia:~$ 

データベース全体のバックアップを取ります("包括的バックアップ"):

gtmuser@philadelphia:~$ mupip backup -nojournal "*" backup/
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011314153705
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/aA.mjl created for region AA with BEFORE_IMAGES
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314153705
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for database file backup//aA.dat is now DISABLED
%GTM-I-JNLSTATE, Journaling state for database file backup//gtm.dat is now DISABLED
DB file /home/gtmuser/myApp/aA.dat backed up in file backup//aA.dat
Transactions up to 0x000000000000020E are backed up.
DB file /home/gtmuser/myApp/gtm.dat backed up in file backup//gtm.dat
Transactions up to 0x0000000000000214 are backed up.


BACKUP COMPLETED.

gtmuser@philadelphia:~$ 

変更されているデータベースの一部分のバックアップを取ります("バイトストリーム" バックアップ)。最後にデータベース全体をバックアップした以降に変更されているこれらのデータベースブロックだけをバックアップするには、 -since=database 修飾子を使用することに注意してください:

gtmuser@philadelphia:~$ mupip backup -bytestream -since=database "*" backup/aA`date +%Y%m%d%H%M%S`.bck,backup/gtm`date +%Y%m%d%H%M%S`.bck
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011314153900
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/aA.mjl created for region AA with BEFORE_IMAGES
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314153900
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
MUPIP backup of database file /home/gtmuser/myApp/aA.dat to backup/aA20111110153859.bck
DB file /home/gtmuser/myApp/aA.dat incrementally backed up in file backup/aA20111110153859.bck
4 blocks saved.
Transactions from 0x000000000000020E to 0x000000000000044F are backed up.
MUPIP backup of database file /home/gtmuser/myApp/gtm.dat to backup/gtm20111110153859.bck
DB file /home/gtmuser/myApp/gtm.dat incrementally backed up in file backup/gtm20111110153859.bck
4 blocks saved.
Transactions from 0x0000000000000214 to 0x0000000000000455 are backed up.


BACKUP COMPLETED.

gtmuser@philadelphia:~$ ls -l backup/
total 992
-rw-rw-rw- 1 gtmuser gtmuser    90624 2011-11-10 15:39 aA20111110153859.bck
-rw-rw-rw- 1 gtmuser gtmuser 20587008 2011-11-10 15:37 aA.dat
-rw-rw-rw- 1 gtmuser gtmuser    90624 2011-11-10 15:39 gtm20111110153859.bck
-rw-rw-rw- 1 gtmuser gtmuser 20587008 2011-11-10 15:37 gtm.dat
gtmuser@philadelphia:~$ 

変更を持つデータベースの一部分のバイトストリーム バックアップをそれ以上にしてください。 - 多くは必要に応じて( 最終のバイトストリーム バックアップ以降に変更されたこれらのブロックのみをバックアップするために、-since=bytestream 修飾子の使用することに注意してください):

gtmuser@philadelphia:~$ mupip backup -bytestream -since=bytestream "*" backup/aA`date +%Y%m%d%H%M%S`.bck,backup/gtm`date +%Y%m%d%H%M%S`.bck
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011314154301
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/aA.mjl created for region AA with BEFORE_IMAGES
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314154301
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
MUPIP backup of database file /home/gtmuser/myApp/aA.dat to backup/aA20111110154300.bck
DB file /home/gtmuser/myApp/aA.dat incrementally backed up in file backup/aA20111110154300.bck
6 blocks saved.
Transactions from 0x000000000000044F to 0x0000000000000913 are backed up.
MUPIP backup of database file /home/gtmuser/myApp/gtm.dat to backup/gtm20111110154300.bck
DB file /home/gtmuser/myApp/gtm.dat incrementally backed up in file backup/gtm20111110154300.bck
6 blocks saved.
Transactions from 0x0000000000000455 to 0x0000000000000919 are backed up.


BACKUP COMPLETED.

gtmuser@philadelphia:~$

必要に応じて多くの追加バイトストリーム バックアップを取ってください。先行して行ったバイトストリーム バックアップ以後の更新をバックアップする必要があることを、それぞれの場合には指定しています。

gtmuser@philadelphia:~$ mupip backup -bytestream -since=bytestream "*" backup/aA`date +%Y%m%d%H%M%S`.bck,backup/gtm`date +%Y%m%d%H%M%S`.bck
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011314154356
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/aA.mjl created for region AA with BEFORE_IMAGES
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314154356
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
MUPIP backup of database file /home/gtmuser/myApp/aA.dat to backup/aA20111110154356.bck
DB file /home/gtmuser/myApp/aA.dat incrementally backed up in file backup/aA20111110154356.bck
6 blocks saved.
Transactions from 0x0000000000000913 to 0x0000000000000A25 are backed up.
MUPIP backup of database file /home/gtmuser/myApp/gtm.dat to backup/gtm20111110154356.bck
DB file /home/gtmuser/myApp/gtm.dat incrementally backed up in file backup/gtm20111110154356.bck
6 blocks saved.
Transactions from 0x0000000000000919 to 0x0000000000000A2B are backed up.


BACKUP COMPLETED.

gtmuser@philadelphia:~$

納得して落ち着いたところで、データベースを更新する mumps プロセスは終了します:

gtmuser@philadelphia:~$ ps -ef | grep mumps | grep -v grep
gtmuser   1074   756 10 15:35 pts/0    00:01:01 /usr/lib/fis-gtm/V5.4-002B_x86/mumps -run XYZ
gtmuser@philadelphia:~$ mupip stop 1074
STOP issued to process 1074
gtmuser@philadelphia:~$ 

最終的なバックアップを取り、^a^bの値に注意してください(そして、それらはまだゼロにまとめられていることを確認してください)。最終的な復元を行った後に、バックアップから復元された値が、これらの値と同じであることを確認します。

gtmuser@philadelphia:~$ mupip backup -bytestream -since=bytestream "*" backup/aA`date +%Y%m%d%H%M%S`.bck,backup/gtm`date +%Y%m%d%H%M%S`.bck
%GTM-I-FILERENAME, File /home/gtmuser/myApp/aA.mjl is renamed to /home/gtmuser/myApp/aA.mjl_2011314154829
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/aA.mjl created for region AA with BEFORE_IMAGES
%GTM-I-FILERENAME, File /home/gtmuser/myApp/gtm.mjl is renamed to /home/gtmuser/myApp/gtm.mjl_2011314154829
%GTM-I-JNLCREATE, Journal file /home/gtmuser/myApp/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
MUPIP backup of database file /home/gtmuser/myApp/aA.dat to backup/aA20111110154828.bck
DB file /home/gtmuser/myApp/aA.dat incrementally backed up in file backup/aA20111110154828.bck
4 blocks saved.
Transactions from 0x0000000000000A25 to 0x0000000000000B83 are backed up.
MUPIP backup of database file /home/gtmuser/myApp/gtm.dat to backup/gtm20111110154828.bck
DB file /home/gtmuser/myApp/gtm.dat incrementally backed up in file backup/gtm20111110154828.bck
4 blocks saved.
Transactions from 0x0000000000000A2B to 0x0000000000000B89 are backed up.


BACKUP COMPLETED.

gtmuser@philadelphia:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
62405,56706 -2026531582 2026531582 0
gtmuser@philadelphia:~$ 

さて今から、バックアップの復元を作業をします。最初のバックアップ(データベースバックアップ)が完了し、すぐに実行できる(ready-to-run)データベースを提供します。後続のバイトストリームバックアップは、mupip restoreコマンドを使用してデータベースのバックアップを適用することができます。

バックアップを復元する環境を作成します。もしシンプルに作成した backupディレクトリを使うならば、それは最も簡単にできます。新しいシェルのセッションでの作業は、myApp/envmyApp/gtm.gldbackup ディレクトリへコピーし、それらを編集します。[ グローバルディレクトリは、データベースを作成するためだけに使用されているので、backupの中のグローバル ディレクトリ ファイルの領域(region)で、デフォルトのジャーナルファイル名を変更する理由がないことに注意してください。それにもかかわらず、そのグローバルディレクトリが、新しいデータベースファイルを作成するために将来使用されるかもしれないので、グローバルディレクトリを正しくしておくことは健康的に良いことです。]

gtmuser@philadelphia:~$ cp myApp/{env,gtm.gld} backup/
gtmuser@philadelphia:~$ fte myApp/env 
gtmuser@philadelphia:~$ cat backup/env
export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
export gtmgbldir=/home/gtmuser/backup/gtm.gld
export gtm_log=/tmp/fis-gtm/V5.4-002B_x86
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/gtmuser/backup/philadelphia.repl
export gtm_repl_instname=Philadelphia
export gtmroutines="/home/gtmuser/backup $gtm_dist"
export gtm_tmp=$gtm_log
mkdir -p $gtm_tmp
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@philadelphia:~$ source backup/env
gtmuser@philadelphia:~$ mumps -run GDE
%GDE-I-LOADGD, Loading Global Directory file 
        /home/gtmuser/backup/gtm.gld
%GDE-I-VERIFY, Verification OK


GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 AA                              /home/gtmuser/myApp/aA.dat  BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
 DEFAULT                         /home/gtmuser/myApp/gtm.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE> change -segment AA -file=/home/gtmuser/backup/aA.dat
GDE> change -segment DEFAULT -file=/home/gtmuser/backup/gtm.dat
GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 AA                              /home/gtmuser/backup/aA.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
 DEFAULT                         /home/gtmuser/backup/gtm.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE> show -region

                                *** REGIONS ***
                                 Dynamic                          Def    Rec   Key Null       Standard
 Region                          Segment                         Coll   Size  Size Subs       NullColl  Journaling
 ------------------------------------------------------------------------------------------------------------------
 AA                              AA                                 0   4080   255 NEVER      Y         Y
 DEFAULT                         DEFAULT                            0   4080   255 NEVER      Y         Y

                          *** JOURNALING INFORMATION ***
 Region                          Jnl File (def ext: .mjl)  Before Buff      Alloc Exten
 ---------------------------------------------------------------------------------------
 AA                              /home/gtmuser/myApp/aA.mjl        Y       128       2048  2048

 DEFAULT                         /home/gtmuser/myApp/gtm.mjl    Y       128       2048  2048

GDE> change -region AA -journal=file=/home/gtmuser/backup/aA.mjl
GDE> change -region DEFAULT -journal=file=/home/gtmuser/backup/gtm.mjl
GDE> show -region

                                *** REGIONS ***
                                 Dynamic                          Def    Rec   Key Null       Standard
 Region                          Segment                         Coll   Size  Size Subs       NullColl  Journaling
 ------------------------------------------------------------------------------------------------------------------
 AA                              AA                                 0   4080   255 NEVER      Y         Y
 DEFAULT                         DEFAULT                            0   4080   255 NEVER      Y         Y

                          *** JOURNALING INFORMATION ***
 Region                          Jnl File (def ext: .mjl)  Before Buff      Alloc Exten
 ---------------------------------------------------------------------------------------
 AA                              /home/gtmuser/backup/aA.mjl       Y       128       2048  2048

 DEFAULT                         /home/gtmuser/backup/gtm.mjl   Y       128       2048  2048

GDE> exit
%GDE-I-VERIFY, Verification OK

%GDE-I-GDUPDATE, Updating Global Directory file 
        /home/gtmuser/backup/gtm.gld
gtmuser@philadelphia:~$ 

^a と^b の最後のグローバルノードの値が等しく、そして、反対になっていることを確認してください(トランザクション処理の値を示す):

gtmuser@philadelphia:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
62405,56224 -2124406191 2124406191 0
gtmuser@philadelphia:~$ 

一つ一つを復元するであろうバイトストリームバックアップのファイル名に注意してください。

gtmuser@philadelphia:~$ ls -l backup/*.bck
-rw-rw-rw- 1 gtmuser gtmuser 90624 2011-11-10 15:39 backup/aA20111110153859.bck
-rw-rw-rw- 1 gtmuser gtmuser 98816 2011-11-10 15:43 backup/aA20111110154300.bck
-rw-rw-rw- 1 gtmuser gtmuser 98816 2011-11-10 15:43 backup/aA20111110154356.bck
-rw-rw-rw- 1 gtmuser gtmuser 86528 2011-11-10 15:48 backup/aA20111110154828.bck
-rw-rw-rw- 1 gtmuser gtmuser 90624 2011-11-10 15:39 backup/gtm20111110153859.bck
-rw-rw-rw- 1 gtmuser gtmuser 98816 2011-11-10 15:43 backup/gtm20111110154300.bck
-rw-rw-rw- 1 gtmuser gtmuser 98816 2011-11-10 15:43 backup/gtm20111110154356.bck
-rw-rw-rw- 1 gtmuser gtmuser 86528 2011-11-10 15:48 backup/gtm20111110154828.bck
gtmuser@philadelphia:~$ 

最初のバイトストリーム バックアップ( since=database修飾子を使用して)を復元してください、^a と^b の値をチェックしてください:

gtmuser@philadelphia:~$ mupip restore backup/aA.dat backup/aA20111110153859.bck 

RESTORE COMPLETED
5 blocks restored
gtmuser@philadelphia:~$ mupip restore backup/gtm.dat backup/gtm20111110153859.bck 

RESTORE COMPLETED
5 blocks restored
gtmuser@philadelphia:~$ 

新しい ^a^b の値を確認してください:タイムスタンプは、最初のバイトストリームのバックアップ(since=database付き)が復元された前に、データベースのそれより以前にあり、^a^bの中のノードの値がゼロをまだ追加することに注意してください。

gtmuser@philadelphia:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
62405,56339 -409750439 409750439 0
gtmuser@philadelphia:~$ 

2番目のバイトストリームバックアップ(since=bytestream修飾子で最初に)をリストアしてください、そして値をチェックしてください。追加のバイトストリームバックアップを繰り返してください。 最終の値が、myAppの中の最後の値と同じであることに注意してください。

gtmuser@philadelphia:~$ mupip restore backup/aA.dat backup/aA20111110154300.bck 

RESTORE COMPLETED
7 blocks restored
gtmuser@philadelphia:~$ mupip restore backup/gtm.dat backup/gtm20111110154300.bck 

RESTORE COMPLETED
7 blocks restored
gtmuser@philadelphia:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
62405,56580 -690269483 690269483 0
gtmuser@philadelphia:~$ mupip restore backup/aA.dat backup/aA20111110154356.bck 

RESTORE COMPLETED
7 blocks restored
gtmuser@philadelphia:~$ mupip restore backup/gtm.dat backup/gtm20111110154356.bck 

RESTORE COMPLETED
7 blocks restored
gtmuser@philadelphia:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
62405,56635 -733572328 733572328 0
gtmuser@philadelphia:~$ mupip restore backup/aA.dat backup/aA20111110154828.bck 

RESTORE COMPLETED
4 blocks restored
gtmuser@philadelphia:~$ mupip restore backup/gtm.dat backup/gtm20111110154828.bck 

RESTORE COMPLETED
4 blocks restored
gtmuser@philadelphia:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
62405,56706 -2026531582 2026531582 0
gtmuser@philadelphia:~$ 

復元されたバックアップを持つ環境で、 ^a と^b の終了時点の値が、正確にオリジナルのデータベースと同じであることに注意してください。また、^a と ^b の値は、常にグローバル変数は、トランザクション処理を示し、異なるデータベースに存在するにもかかわらずゼロを追加します。

簡便に巻き戻すレプリケーション

バックアップ演習中のケープタウン(Cape Town)と上海(Shanghai)を無視してきたが、完全なログを作成しています。ここでは、フィラデルフィア(Philadelphia)でmyApp環境でバックログ レポートは:[ もしバックアップをリストアするために、同じシェルセッションを使用している場合は、オリジナルの環境の環境変数を取得するsource myApp/env が必要です。]

gtmuser@philadelphia:~$ mupip replicate -source -showbacklog
Thu Nov 10 17:55:23 2011 : Initiating SHOWBACKLOG operation on source server pid [945] for secondary instance [CapeTown]
2946 : backlog number of transactions written to journal pool and yet to be sent by the source server
2952 : sequence number of last transaction written to journal pool
6 : sequence number of last transaction sent by source server
Thu Nov 10 17:55:23 2011 : Initiating SHOWBACKLOG operation on source server pid [941] for secondary instance [Shanghai]
2946 : backlog number of transactions written to journal pool and yet to be sent by the source server
2952 : sequence number of last transaction written to journal pool
6 : sequence number of last transaction sent by source server
gtmuser@philadelphia:~$ 

上海(Shanghai)をブートし、^a^b についてデータベースの状態をチェックしてください - ^aのノードが定義されていないのでエラーが表示されます。

gtmuser@shanghai:~$ source myApp/env
gtmuser@shanghai:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
 
%GTM-E-NULSUBSC, Null subscripts are not allowed for region: AA
%GTM-I-GVIS,            Global variable: ^a("")
%GTM-I-RTSLOC,          At M source location %XCMD+3^%XCMD
gtmuser@shanghai:~$ 

その後、myApp/replicating_start スクリプトを実行し、上海(Shanghai)が追いつくこと通知してください。

gtmuser@shanghai:~$ myApp/replicating_start 
Fri Nov 11 07:12:07 2011 : Initiating START of source server for secondary instance [dummy]
gtmuser@shanghai:~$ mumps -run %XCMD 'set x=$order(^a(""),-1) write x," ",^a(x)," ",^b(x)," ",^a(x)+^b(x),!'
62405,56706 -2026531582 2026531582 0
gtmuser@shanghai:~$

今、フィラデルフィア(Philadelphia)は、上海(Shanghai)のゼロバックログを示していますが、しかし、それでもケープタウン(CapeTown)のために大規模なバックログを持っていることに注意してください。

gtmuser@philadelphia:~$ mupip replicate -source -showbacklog
Thu Nov 10 18:13:12 2011 : Initiating SHOWBACKLOG operation on source server pid [945] for secondary instance [CapeTown]
2946 : backlog number of transactions written to journal pool and yet to be sent by the source server
2952 : sequence number of last transaction written to journal pool
6 : sequence number of last transaction sent by source server
Thu Nov 10 18:13:12 2011 : Initiating SHOWBACKLOG operation on source server pid [941] for secondary instance [Shanghai]
0 : backlog number of transactions written to journal pool and yet to be sent by the source server
2952 : sequence number of last transaction written to journal pool
2952 : sequence number of last transaction sent by source server
gtmuser@philadelphia:~$ 

潔くインスタンスをシャットダウンします。

ユニコード(ISO/IEC-10646)

GT.Mは、Unicodeを用いて国際文字セットをサポートしています。mumpsプロセスは、MモードとUTF-8モードのどちらかで動作することができ、これらモードは環境変数 gtm_chsetにより指定され、プロセスが開始されプロセスの寿命が尽きるまで不変です。

Mモードにおけるプロセスは、ASCII(Mモード)としてエンコードされる $Char(0) から $Char(127)までの文字で、シングルバイト文字として文字列を解釈します。Mモード環境でGT.Mプロセスは、$Char(128)から$Char(255)の文字は解釈しません。アプリケーションは、選択する任意の解釈を自由に使用し、そして、ISO-8859変異体は一般的に使用されています。バイトの文字列と文字の文字列とを区別しません、そして、すべてのバイトは有効な文字とします。不正なまたは非正規の文字概念は、不合理な結論です。

UTF-8モードにおけるデフォルトによるプロセスは、UTF-8(UTF-8モード)を使用してエンコードされるマルチバイト文字として文字列を解釈します。バイトのシーケンスは、標準では定義されてなくて、不正な文字と見なされます。プロセスは、バイトのシーケンスとして文字列を解釈することもでき、そして、文字のシーケンスとしてよりもバイトのシーケンスとして見なす時は、同じ文字列が異なったプロパティ(その長さなど)を持つことができます。

トリガが利用されている場合を除き、この解釈はプロセスのレベルにあります:データベースは、バイナリデータとして文字列を扱い、それらがエンコードする方法を気にしません。そのため、同じデータベースに、 MモードとUTF-8モードの両方で動作する mumps プロセスによって同時にアクセスできる可能性があります。Mupipとその他のプロセスは、この区別にが関係ありません。もしデータベースがトリガを持っている場合、トリガはコードをコンパイルされるので、データベースを使用するすべてのプロセスは、同じモードを持つ必要があります。

プロセスのモードは、gtm_chset 環境変数によって制御されます。もしそれが設定されていない場合、または、"UTF-8"以外の値ならば、プロセスはMモードで動作します。プロセス内の ISV $ZCHsetは、モードをテストするために利用できます。

UTF-8モードで動作するプロセスでは、以下の環境が必要とされます:

locale コマンドは、利用可能なロケールのリストを提供します:

gtmuser@gtmworkshop7:~$ locale -a
C
POSIX
en_US.utf8
gtmuser@gtmworkshop7:~$ 

追加のUTF - 8ロケールを生成するために localedef コマンドを使用することができます - この例では、ヨルダンでの使用としてアラビア語のUTF-8ロケールが生成されます。

gtmuser@gtmworkshop7:~$ sudo localedef -f UTF-8 -i ar_JO ar_JO.utf8
gtmuser@gtmworkshop7:~$ locale -a
C
POSIX
ar_JO.utf8
en_US.utf8
gtmuser@gtmworkshop7:~$

対話的な使用方法については、ターミナルエミュレータは、UTF-8モードで文字を表示するように設定する必要があります ; それ以外では、非常に混乱することになります。

この演習では、2つのセッションがあり、一つはUTF-8モードでのmumpsプロセスで、もう一つは、Mモードでmumpsプロセスを使用します。 utf8demoディレクトリとその内の2つの環境ファイル、utf8demo/env_mutf8demo/env_utf8 を、次のように作成してください:

gtmuser@gtmworkshop7:~$ cat utf8demo/env_m
export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
export gtmgbldir=/home/gtmuser/utf8demo/gtm.gld
export gtm_log=/tmp/fis-gtm/V5.4-002B_x86
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/utf8demo/gtm_repl
export gtm_repl_instname=dummy
export gtmroutines="/home/gtmuser/utf8demo $gtm_dist"
export gtm_tmp=$gtm_log
mkdir -p $gtm_tmp
unset gtm_chset
export gtm_prompt="GTM>"
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@gtmworkshop7:~$ cat utf8demo/env_utf8 
export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86/utf8
export gtmgbldir=/home/gtmuser/utf8demo/gtm.gld
export gtm_log=/tmp/fis-gtm/V5.4-002B_x86
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/utf8demo/gtm_repl
export gtm_repl_instname=dummy
export gtmroutines="/home/gtmuser/utf8demo $gtm_dist"
export gtm_tmp=$gtm_log
mkdir -p $gtm_tmp
export gtm_icu_version=`icu-config --version | cut -d . -f 1,2`
export LC_CTYPE=`locale -a | grep -i utf | head -1`
export gtm_chset=UTF-8
export gtm_prompt="UTF8>"
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@gtmworkshop7:~$ 

以前と同じように、グローバルディレクトリとデータベースファイルを作成します。今だけは、GDEのユーティリティプログラムの動作が同じであることを見ることができるように、UTF-8のセッションでこれを行います。

gtmuser@gtmworkshop7:~$ source utf8demo/env_UTF8
gtmuser@gtmworkshop7:~$ mumps -run GDE
%GDE-I-GDUSEDEFS, Using defaults for Global Directory
        /home/gtmuser/utf8demo/gtm.gld

GDE> @/usr/lib/fis-gtm/V5.4-002B_x86/utf8/gdedefaults
%GDE-I-EXECOM, Executing command file /usr/lib/fis-gtm/V5.4-002B_x86/utf8/gdedefaults

GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 DEFAULT                         $gtmdir/$gtmver/g/gtm.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE> change -segment DEFAULT -file=/home/gtmuser/utf8demo/gtm.dat
GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 DEFAULT                         /home/gtmuser/utf8demo/gtm.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE> exit
%GDE-I-VERIFY, Verification OK

%GDE-I-GDCREATE, Creating Global Directory file
        /home/gtmuser/utf8demo/gtm.gld
gtmuser@gtmworkshop7:~$ mupip create
Created file /home/gtmuser/utf8demo/gtm.dat
gtmuser@gtmworkshop7:~$ 

ダイレクトモードのプロンプトが属しているモードの混乱を避けるためにgtm_prompt 環境変数を使用します。

gtmuser@gtmworkshop7:~$ mumps -dir

UTF8>write $zchset
UTF-8
UTF8>for i=0:1:255 set ^Ch(i)=$char(i)

UTF8>for i=0:16:240 write !for j=0:1:15 write ^Ch(i+j)," : "

 :  :  :  :  :  :  :  : :        : 
 : 
    : 
 :  :  : 
 :  :  :  :  :  :  :  : ▒ :  : ▒ : :  :  :  :  : 
  : !: " : # : $ : % : & : ' : ( : ) : * : + : , : - : . : / : 
0 : 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : : : ; : < : = : > : ?: 
@ : A : B : C : D : E : F : G : H : I : J : K : L : M : N : O : 
P : Q : R : S : T : U : V : W : X : Y : Z : [ : \ : ] : ^ : _ : 
` : a : b : c : d : e : f : g : h : i : j : k : l : m : n : o : 
p : q : r : s : t : u : v : w : x : y : z : { : | : } : ~ :  : 
 :  :  :  :  :  :  :  :  :  :  :  :  :  :  :  : 
 :  :  :  :  :  :  :  :  :  :  : :  :  :  :  : 
 : ¡ : ¢ : £ : ¤ : ¥ : ¦ : § : ¨ : © : ª : « : ¬ :  : ® : ¯ : 
° : ± : ² : ³ : ´ : µ : ¶ : · : ¸ : ¹ : º : » : ¼ : ½ : ¾ : ¿ : 
À : Á : Â : Ã : Ä : Å : Æ : Ç : È : É : Ê : Ë : Ì : Í : Î : Ï : 
Ð : Ñ : Ò : Ó : Ô : Õ : Ö : × : Ø : Ù : Ú : Û : Ü : Ý : Þ : ß : 
à : á : â : ã : ä : å : æ : ç : è : é : ê : ë : ì : í : î : ï : 
ð : ñ : ò : ó : ô : õ : ö : ÷ : ø : ù : ú : û : ü : ý : þ : ÿ : 
UTF8>halt
gtmuser@gtmworkshop7:~$ 

あなたがUTF-8モードで設定された文字を、Mモードでシェルを開始し、Mモードで表示してみてください( ISO-8859-1などのシングルバイトのエンコーディングに対応するために、あなたのターミナルエミュレータを設定してください):

gtmuser@gtmworkshop7:~$ mumps -dir

GTM>write $zchset
M
GTM>for i=0:16:240 write !for j=0:1:15 write ^Ch(i+j)," : "

 :  :  :  :  :  :  :  : :        : 
 : 
    : 
 :  :  : 
 :  :  :  :  :  :  :  : ▒ :  : ▒ : :  :  :  :  : 
  : !: " : # : $ : % : & : ' : ( : ) : * : + : , : - : . : / : 
0 : 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : : : ; : < : = : > : ?: 
@ : A : B : C : D : E : F : G : H : I : J : K : L : M : N : O : 
P : Q : R : S : T : U : V : W : X : Y : Z : [ : \ : ] : ^ : _ : 
` : a : b : c : d : e : f : g : h : i : j : k : l : m : n : o : 
p : q : r : s : t : u : v : w : x : y : z : { : | : } : ~ :  : 
 :  :  :  :  :  :  :  :  :  :  :  :  :  :  :  : 
 :  :  :  :  :  :  :  :  :  :  : Â:  :  :  :  : 
 : ¡ : ¢ : £ : ¤ : ¥ : ¦ : § : ¨ : © : ª : « : ¬ :  : ® : ¯ : 
° : ± : ² : ³ : ´ : µ : ¶ : · : ¸ : ¹ : º : » : ¼ : ½ : ¾ : ¿ : 
à : à : à : à : à : à : à : à : à : à : à : à : à : à : à : à : 
à : à : à : à : à : à : à : à : à : à : à : Ã: à : à : à : à : 
à : á : â : ã : ä : å : æ : ç : è : é : ê : ë : ì : à : î : ï : 
ð : ñ : ò : ó : ô : õ : ö : ÷ : ø : ù : ú : û : ü : ý : þ : ÿ : 
GTM>Halt
gtmuser@gtmworkshop7:~$ 

文字列の長さが異なっていることを知っておいてください。 UTF-8モードのプロセスは、すべてを長さ1としてレポートし、一方でMモードのプロセスは、長さを2としてレポートします。

UTF8>For i=0:16:240 Write !For j=0:1:15 Write $Length(^Ch(i+j))," : "

1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
UTF8>

GTM>for i=0:16:240 write !for j=0:1:15 write $length(^Ch(i+j))," : "

1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
GTM>

ただし、両方とも$Length()関数の代わりに$Zlength()関数を使用すると、バイト単位で同じ文字列の長さをレポートします。

UTF8>For i=0:16:240 Write !For j=0:1:15 Write $ZLength(^Ch(i+j))," : "

1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
UTF8>

そして:

GTM>For i=0:16:240 Write !For j=0:1:15 Write $ZLength(^Ch(i+j))," : "

1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 : 1 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 : 2 :
GTM>

Unicodeは、唯一の文字エンコーディングを提供することを忘れないでください。UTF-8でエンコードされた文字列の順序は、言語的または文化的に、あなたの言語対して正しく修正されない場合があります。たとえば、中国語の名前は、簡略化か、または、トラディショナルな中国語のスクリプトのどちらかで使用するUTF-8文字でエンコードすることができますが、言語的に文化的に適切な名前の順序(例えば、北京の電話帳など)は、ラテンスクリプトを使うように、ピンインの順序になります。正しい順序で文字列を格納するためにGT.Mを使用するには、照合モジュールを提供する追加の要件があるかもしれません。

データベース暗号化

この演習に進む前に、GT.Mデータベース暗号化の限界とアーキテクチャを理解することが重要です: GT.M自身は一切の暗号化ソフトウェアは含めれていません、また、暗号化を実行しません - GPG(GNUプライバシーガード)とOpenSSLとのインターフェイスに対してレファレンス(参照)プラグインというプラグイン アーキテクチャを持ちます。鍵の管理と配布は、データベース暗号化自体よりもはるかに難しい問題であることも忘れないでください。

以下の演習では、GT.Mの能力をさらに高める、リファレンスの実装とGPGについて示します。演習の多くは、リファレンス(参照)プラグインについての記述です。 - 隠れているものに何が起こるかを理解できるように、詳細についてここで繰り返しましょう。鍵を安全に管理するために必要で、事実上、暗号化の三つの層があることに注意してください:

2人のユーザー存在し、Helen は管理者で鍵を配布します。Philはノーマルなデータベースユーザーです。ファイルを復号化し、そして、共通暗号の鍵へのアクセスを取得するために、プロセスに必要な秘密鍵は、GPGキーリングにあります。Phil と Helenは、それぞれ公開鍵と秘密鍵のペアを生成し、そして、自身の公開鍵を交換する必要があります。

この演習では、公開鍵と秘密鍵のペアの作成は、仮想マシン(または別のホスト上の)を実行しているホスト上で実行する必要があることに、注意してください。GT.Mワークショップの仮想マシンは、矛盾のないGPGにとって十分なエントロピー(均質)(ランダム)を生成しません、そして、正常に鍵ペアを生成します。生成されたキーペアは、仮想マシンへ転送する必要があります。

以下の演習では、Linuxホスト上でGPGを使用します。Windowsまたは他のホストでのGPGのためのコマンドは、同様なものがあります。もし、ホスト上の個別のユーザーIDが、シミュレートされたPhil と Helen のユーザーに対して利用でいない場合は、別のGPGキーリングを指定するように1つのユーザーIDで、環境変数 $GNUPGHOME を使用することができます。Helen GPG キーリングは、ホスト上に常存在し、仮想マシンへそれをプッシュする必要がないことに注意してください。

ホスト上で Helen と Phil のGPGキーリングを作成します。GPGで利用可能な機能のために、リファレンス(参照)プラグインは非対称暗号化方式として排他的にRSAを使用しているので、非対称キーは2つの手順で生成する必要があることに注意してください。最初に Helen.

$ export GNUPGHOME=~/.helengnupg
$ mkdir $GNUPGHOME
$ chmod go-rx $GNUPGHOME
$ gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: keyring `/home/gtmuser/.philgnupg/secring.gpg' created
gpg: keyring `/home/gtmuser/.philgnupg/pubring.gpg' created
Please select what kind of key you want:
   (1) DSA and Elgamal (default)
   (2) DSA (sign only)
   (5) RSA (sign  only)
Your selection?5
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want?(2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for?(0)
Key does not expire at all
Is this correct?(y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Helen Keymaster
Email address: helen.keymaster@gt.m
Comment: Demo for GT.M Workshop
You selected this USER-ID:
    "Helen Keymaster (Demo for GT.M Workshop) <helen.keymaster@gt.m>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?O
You need a Passphrase to protect your secret key.

Enter passphrase: (use a passphrase of your choice)
Repeat passphrase:

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy!(Need 280 more bytes)
......+++++
..+++++
gpg: /home/gtmuser/.helengnupg/trustdb.gpg: trustdb created
gpg: key 40736E89 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/40736E89 2009-12-15
      Key fingerprint = 579E 6342 1856 F9E5 EFA9  ECAE D039 66C8 4073 6E89
uid                  Helen Keymaster (Demo for GT.M Workshop) <helen@gt.m>

Note that this key cannot be used for encryption.  You may want to use
the command "--edit-key" to generate a subkey for this purpose.
$ gpg --edit-key helen@gt.m
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  2048R/40736E89  created: 2009-12-15  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
[ultimate] (1). Helen Keymaster (Demo for GT.M Workshop) <helen@gt.m>

Command> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Helen Keymaster (Demo for GT.M Workshop) <helen@gt.m>"
2048-bit RSA key, ID 40736E89, created 2009-12-15

Enter passphrase:
Please select what kind of key you want:
   (2) DSA (sign only)
   (4) Elgamal (encrypt only)
   (5) RSA (sign only)
   (6) RSA (encrypt only)
Your selection?6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want?(2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for?(0)
Key does not expire at all
Is this correct?(y/N) y
Really create?(y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy!(Need 74 more bytes)
...+++++
+++++

pub  2048R/40736E89  created: 2009-12-15  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  2048R/6CC824A4  created: 2009-12-15  expires: never       usage: E
[ultimate] (1). Helen Keymaster (Demo for GT.M Workshop) <helen@gt.m>

Command> save
$

Helen の キーリングは暗号と署名の両方のためのRSA鍵を持っています。次に、Philのキーリングを作ります。

$ export GNUPGHOME=~/.philgnupg
$ mkdir $GNUPGHOME
$ chmod go-rx $GNUPGHOME
$ gpg --gen-key
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: keyring `/home/gtmuser/.philgnupg/secring.gpg' created
gpg: keyring `/home/gtmuser/.philgnupg/pubring.gpg' created
Please select what kind of key you want:
   (1) DSA and Elgamal (default)
   (2) DSA (sign only)
   (5) RSA (sign only)
Your selection?5
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want?(2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for?(0)
Key does not expire at all
Is this correct?(y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Phil Keyuser
Email address: phil@gt.m
Comment: Demo for GT.M Workshop
You selected this USER-ID:
    "Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?o
You need a Passphrase to protect your secret key.

Enter passphrase: (use a passphrase of your choice)
Repeat passphrase:

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy!(Need 284 more bytes)
..+++++
..+++++
gpg: /home/gtmuser/.philgnupg/trustdb.gpg: trustdb created
gpg: key 72DFCE93 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/72DFCE93 2009-12-15
      Key fingerprint = 6DDA 1679 8BE6 E3A3 67B7  16B7 6F1B DEC1 72DF CE93
uid                  Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>

Note that this key cannot be used for encryption.  You may want to use
the command "--edit-key" to generate a subkey for this purpose.
$ gpg --edit-key phil@gt.m
gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  2048R/72DFCE93  created: 2009-12-15  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
[ultimate] (1). Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>

Command> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>"
2048-bit RSA key, ID 72DFCE93, created 2009-12-15

Enter passphrase:

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy!(Need 84 more bytes)
...........+++++
+++++

pub  2048R/72DFCE93  created: 2009-12-15  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  2048R/95884D50  created: 2009-12-15  expires: never       usage: E
[ultimate] (1). Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>

Command> save
$

ゲストにホストから PhilのGPG キーリングを移動する必要があります。もしホストが有効な適切なサービスを持つならば、sshなどで、仮想マシンからのキーリングを取りだすことができます(この例で、gtmuserは、Phil のキーリングを作成するために使用されるホスト上のユーザIDです)。

gtmuser@gtmworkshop7:~$ scp -r gtmuser@10.0.2.2:.philgnupg .
gtmuser@10.0.2.2's password:
gtmuser@gtmworkshop7:~$

もしホストが有効なssh サービスを持っていないならば、代替として sshまたはscpクライアント(Windows上でWinSCPなど )は、ゲストにホストからの Philのキーリングを送り出すことができます。この例はLinux上でscpを使用しています。

$ scp -r -P 2222 .philgnupg gtmuser@localhost:./
gtmuser@localhost's password: 
pubring.gpg                                   100% 2398     2.3KB/s   00:00    
random_seed                                   100%  600     0.6KB/s   00:00    
secring.gpg                                   100% 2574     2.5KB/s   00:00    
trustdb.gpg                                   100% 1280     1.3KB/s   00:00    
$ 

仮想マシンに Philのキーリングをコピーしたら、GPGで想定されているそれらのものになるように、ディレクトリのパーミッションを設定する必要があります。そうでないと、不十分なセキュリティについての苦情が表示されます。また、.philgnupg ディレクトリの名前を .gnupg へ変更することができます : mv .philgnupg .gnupg ; chmod -R go-rwx .gnupg

ホスト上でHelenの公開鍵をエクスポートし、GT.M アカルチュレーション ワークショップ‎ 仮想マシンのゲストに転送します。これは、ホストから押し出されているファイルを示していますが、ゲストから取りだすこともできます。

$ gpg --armor --output helen.publickey.txt --export helen@gt.m
$ scp -P 2222 helen.publickey.txt gtmuser@localhost:./
gtmuser@localhost's password:
helen.publickey.txt                                  100% 1743     1.7KB/s   00:00
$

ゲストで、Philのキーリングへ Helenの公開キーをインポートします。Helenはホスト上でそれをインポートできるように、Philの公開鍵をエクスポートはします。

gtmuser@gtmworkshop7:~$ export GNUPGHOME=~/.philgnupg
gtmuser@gtmworkshop7:~$ gpg --import helen.publickey.txt
gpg: key 40736E89: public key "Helen Keymaster (Demo for GT.M Workshop) <helen@gt.m>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
gtmuser@gtmworkshop7:~$ gpg --armor --output phil.publickey.txt --export phil@gt.m
gtmuser@gtmworkshop7:~$

ホスト上の HelenのGPGキーリングに、Phil公開鍵をインポートします。共通暗号としてPhilのキーを後で確実に送信するために、 Helenに必要な鍵交換を完了します。また、Helen と Phil は、彼らの公開鍵を必要とするかもしれない誰かのために pgp.mit.edu などの キーサーバーへ、彼らの公開鍵をアップロードすることができます。ファックスや電話などのように、中間者攻撃 (man-in-the-middle attack、MITM と略記) からそれらを守るために、さまざまなチャネルを介してそれら公開鍵のフィンガープリントを直接交換すべきです。

$ scp -P 2222 gtmuser@localhost:phil.publickey.txt ./
gtmuser@localhost's password:
phil.publickey.txt                                   100% 1738     1.7KB/s   00:00
$ gpg --import phil.publickey.txt
gpg: key 72DFCE93: public key "Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
$

Helenは手動で共通暗号用の32バイトのキーを生成することができますが、GPGやその他のツール使用して真のランダムなキーを利用したほうがよいです(たとえば、 http://www.random.org )。これはワークショップだけのものですので、鍵生成のパフォーマンスをスピードアップすることとホストからのエントロピーを排出しないようにすることを、ここでの一つはキーの強度を使用し、二つは、実際のアプリケーションで使用する値です。このキーは、Philの公開鍵で暗号化され、Helenの秘密鍵で署名されます。その後、ゲストにキーを押し出してください。

$ gpg --gen-random 1 32 | gpg --encrypt --recipient phil@gt.m --sign --armor >gtm_workshop_key.txt

You need a passphrase to unlock the secret key for
user: "Helen Keymaster (Demo for GT.M Workshop) <helen@gt.m>"
2048-bit RSA key, ID 40736E89, created 2009-12-15

Enter passphrase:

gpg: 95884D50: There is no assurance this key belongs to the named user

pub  2048R/95884D50 2009-12-15 Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>
 Primary key fingerprint: 6DDA 1679 8BE6 E3A3 67B7  16B7 6F1B DEC1 72DF CE93
      Subkey fingerprint: 190E A578 8C8C 380E DEB1  7862 55B8 5E61 9588 4D50

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway?(y/N) y
$ scp -P 2222 gtm_workshop_key.txt gtmuser@localhost:./
gtmuser@localhost's password:
gtm_workshop_key.txt                                 100% 1005     1.0KB/s   00:00
$

GT.M アカルチュレーション ワークショップのゲストで、enc ディレクトリを作成し、環境を設定するenvファイルを作成します。ご希望の場合は、env ファイルを別のディレクトリからコピーし、適応させるように編集します。また、gtm_dbkeys 環境変数を指定してマスタキーファイルを作成します。

gtmuser@gtmworkshop7:~$ mkdir enc
gtmuser@gtmworkshop7:~$ fte enc/env
gtmuser@gtmworkshop7:~$ cat enc/env
export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
export gtmgbldir=/home/gtmuser/enc/gtm.gld
export gtm_log=/tmp/fis-gtm/V5.4-002B_x86
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/enc/gtm_repl
export gtm_repl_instname=dummy
export gtmroutines="/home/gtmuser/enc $gtm_dist"
export gtm_tmp=$gtm_log
mkdir -p $gtm_tmp
export gtm_dbkeys=/home/gtmuser/enc/master_keys.txt
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@gtmworkshop7:~$ source enc/env
gtmuser@gtmworkshop7:~$

Helenからgtm_workshop_key.txt ファイルからデータベースキーファイルを作成します。

gtmuser@gtmworkshop7:~$ gpg --decrypt <gtm_workshop_key.txt | gpg --encrypt --armor --default-recipient-self --output enc/gtm.key

You need a passphrase to unlock the secret key for
user: "Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>"
2048-bit RSA key, ID 95884D50, created 2009-12-15 (main key ID 72DFCE93)

Enter passphrase:

gpg: encrypted with 2048-bit RSA key, ID 95884D50, created 2009-12-15
      "Phil Keyuser (Demo for GT.M Workshop) <phil@gt.m>"
gpg: Signature made Tue Dec 15 23:50:42 2009 est using RSA key ID 40736E89
gpg: Good signature from "Helen Keymaster (Demo for GT.M Workshop) <helen@gt.m>"
gpg: WARNING: This key is not certified with a trusted signature!gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 579E 6342 1856 F9E5 EFA9  ECAE D039 66C8 4073 6E89
gtmuser@gtmworkshop7:~$

データベースファイルが暗号化することを指定するグローバルディレクトリを作成します。

gtmuser@gtmworkshop7:~$ mumps -run GDE
%GDE-I-GDUSEDEFS, Using defaults for Global Directory
        /home/gtmuser/enc/gtm.gld

GDE> change -segment default -encryption -file=/home/gtmuser/enc/gtm.dat
GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 DEFAULT                         /home/gtmuser/enc/gtm.dat   BG  DYN  1024        100   100 GLOB=1024
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=ON
GDE> change -region default -journal=(before,file="/home/gtmuser/enc/gtm.mjl")
GDE> show -region

                                *** REGIONS ***
                                 Dynamic                          Def    Rec   Key Null       Standard
 Region                          Segment                         Coll   Size  Size Subs       NullColl  Journaling
 ------------------------------------------------------------------------------------------------------------------
 DEFAULT                         DEFAULT                            0    256    64 NEVER      N         Y

                          *** JOURNALING INFORMATION ***
 Region                          Jnl File (def ext: .mjl)  Before Buff      Alloc Exten
 ---------------------------------------------------------------------------------------
 DEFAULT                         /home/gtmuser/enc/gtm.mjl         Y       128        100   100

GDE> exit
%GDE-I-VERIFY, Verification OK

%GDE-I-GDCREATE, Creating Global Directory file
        /home/gtmuser/enc/gtm.gld
gtmuser@gtmworkshop7:~$

データベースファイルを作成します。この環境で難読化されたGPG キーリング パスワードを使用してmupipを作成することを提供するために、パスワードと場所の入力を促すmumpsプロセスを中継して通じてmupipを起動する必要があることと、この環境においてパスワードを難読化することに、注意してください。

gtmuser@gtmworkshop7:~$ gtm_passwd="" mumps -dir

Enter Passphrase:

GTM>zsystem "$gtm_dist/mupip create"
Created file /home/gtmuser/enc/gtm.dat

GTM>halt
gtmuser@gtmworkshop7:~$

You can use DSE to verify that the file is encrypted.

gtmuser@gtmworkshop7:~$ $gtm_dist/dse dump -fileheader

File    /home/gtmuser/enc/gtm.dat
Region  DEFAULT


File            /home/gtmuser/enc/gtm.dat
Region          DEFAULT
Date/Time       16-DEC-2009 16:01:07 [$H = 61711,57667]
  Access method                          BG  Global Buffers                1024
  Reserved Bytes                          0  Block size (in bytes)         1024
  Maximum record size                   256  Starting VBN                   129
  Maximum key size                       64  Total blocks            0x00000065
  Null subscripts                     NEVER  Free blocks             0x00000062
  Standard Null Collation             FALSE  Free space              0x00000000
  Last Record Backup     0x0000000000000001  Extension Count                100
  Last Database Backup   0x0000000000000001  Number of local maps             1
  Last Bytestream Backup 0x0000000000000001  Lock space              0x00000028
  In critical section            0x00000000  Timers pending                   0
  Cache freeze id                0x00000000  Flush timer            00:00:01:00
  Freeze magtmuserh                   0x00000000  Flush trigger                  960
  Current transaction    0x0000000000000001  No. of writes/flush              7
  Maximum TN             0xFFFFFFFFE3FFFFFF  Certified for Upgrade to        V5
  Maximum TN Warn        0xFFFFFFFF73FFFFFF  Desired DB Format               V5
  Master Bitmap Size                    112  Blocks to Upgrade       0x00000000
  Create in progress                  FALSE  Modified cache blocks            0
  Reference count                         1  Wait Disk                        0
  Journal State                         OFF  Journal Before imaging        TRUE
  Journal Allocation                    100  Journal Extension              100
  Journal Buffer Size                   128  Journal Alignsize              128
  Journal AutoswitchLimit           8388600  Journal Epoch Interval         300
  Journal Yield Limit                     8  Journal Sync IO              FALSE
  Journal File: /home/gtmuser/enc/gtm.mjl
  Mutex Hard Spin Count                 128  Mutex Sleep Spin Count         128
  Mutex Spin Sleep Time                2048  KILLs in progress                0
  Replication State                     OFF  Region Seqno    0x0000000000000001
  Zqgblmod Seqno         0x0000000000000000  Zqgblmod Trans  0x0000000000000000
  Endian Format                      LITTLE  Commit Wait Spin Count          16
  Database file encrypted              TRUE
gtmuser@gtmworkshop7:~$

ジャーナリングをオンにし、いくつかの更新を行ってみます。

gtmuser@gtmworkshop7:~$ mupip set -journal="before,on" -region "*"
%GTM-I-JNLCREATE, Journal file /home/gtmuser/enc/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now ON
gtmuser@gtmworkshop7:~$ gtm_passwd="" mumps -dir

Enter Passphrase:

GTM>set ^Text="This should be encrypted in the database"

GTM>halt
gtmuser@gtmworkshop7:~$

データが、データベースファイルにもジャーナルファイルにも、実際にも表示されないことを確認してください。

gtmuser@gtmworkshop7:~$ strings enc/gtm.dat
GDSDYNUNX03
/home/gtmuser/enc/gtm.mjl
TUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
hgf(
\'&L
gtmuser@gtmworkshop7:~$ strings enc/gtm.mjl
GDSJNL18
;K)K
<K)K
/home/gtmuser/enc/gtm.dat
J)K=
J)KJ
J)KM
;K)KO
;K)K
;K)KD
;K)K
@UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
;K)K
<K)Kr
<K)Ku
<K)Kw
gtmuser@gtmworkshop7:~$

GT.M 協力者

これまでのところ、アカルチュレーション ワークショップは、コア コンセプトを中心に説明してきました。今は、コンセプトをまとめる時です。それをするために、その前任者よりもそれぞれ洗練され、GT.M上の Vistaアプリケーションのように、インストールのシリーズを通じて行くことでしょう。

VistAの知識がないことが想定されるか、または、アカルチュレーション ワークショップを必要とされるか - VistAは、単に、GT.M上のアプリケーションの構成を探求するために、自由に利用可能なサンプルアプリケーションとして使用しています。

VistAについて

アメリカ退役軍人部 (VA)は、世界最大の統合医療ネットワークのひとつとして動いています。米軍の退役軍人に質の高いケアを法的に義務付け提供し、それを繰り返し、提供するケアの品質だけでなく費用対効果をも認識されている。VistA は、VA によってヘルスケア インフォメーション システム (HIS) として開発されメンテナンスされています。ソフトウェアは、パブリックドメインで自由に利用可能なできます。多くのプロバイダは、コマーシャルベースでVistAをサポートし、そして、オンラインでアクティブなVistAコミュニティがあります 。

すべての医療機関にとって、VistAは、費用対効果の高いエンタープライズリソースプランニング(ERP)システムを提供することができます。医療情報学の分野での起源であるM言語は、医療ソフトウェアのデファクトスタンダードとなっていて、VistAは、ANSI / ISO標準プログラミング言語であるM言語(また、MUMPSをとして知られている)で書かれています。

GT.M アカルチュレーション ワークショップでは、GT.Mアプリケーションのサンプルとして、VistA風の World VistA EHR ® を使用し、そして、VistAは Source ForgeのWorldVistAプロジェクトからダウンロードすることができます。

VistAダウンロード

VistAを取得するには、ルーチンとグローバル変数の2つのアーカイブファイルをダウンロードする必要があります。まず、アーカイブファイルを格納するディレクトリを作成し、次に、そのディレクトリにファイルをダウンロードします。

gtmuser@gtmworkshop7:~$ sudo mkdir -p /Distrib/VistA
[sudo] password for gtmuser:
gtmuser@gtmworkshop7:~$ sudo chown gtmuser.gtmuser /Distrib/VistA/
gtmuser@gtmworkshop7:~$ wget -P /Distrib/VistA/ http://tinyurl.com/WVEHRVOE10Routines
[multiple lines of output have been suppressed here]
HTTP request sent, awaiting response... 200 OK
Length: 33432464 (32M) [application/x-gzip]
Saving to: `/Distrib/VistA/routines.tgz'

100%[==============================================================================>] 33,432,464   353K/s   in 79s

2010-09-10 16:46:01 (415 KB/s) - `/Distrib/VistA/routines.tgz' saved [33432464/33432464]
gtmuser@gtmworkshop7:~$ wget -P /Distrib/VistA/ http://tinyurl.com/WVEHRVOE10Globals
[multiple lines of output have been suppressed here]
HTTP request sent, awaiting response... 200 OK
Length: 140631465 (134M) [application/x-gzip]
Saving to: `/Distrib/VistA/globals.zwr.gz'

100%[==============================================================================>] 140,631,465  416K/s   in 5m 31s

2010-09-10 16:52:34 (415 KB/s) - `/Distrib/VistA/globals.zwr.gz' saved [140631465/140631465]

gtmuser@gtmworkshop7:~$ 

シンプルな環境

(上記の演習の環境のように)一つのディレクトリに - ソース、オブジェクト、グローバルディレクトリ、データベースとジャーナルファイル - 非常に単純な環境では、あなたが置いたすべてのものが1つです。しかし、実際のアプリケーションでは、これは急速に扱いにくくなる。

前述の単純な環境から最初のステップアップとして、親ディレクトリでシェルスクリプトを使って、ソースファイル、オブジェクトファイル、データベース用に別々のサブディレクトリを持つことです。注意:本番環境ではジャーナルファイルを別の場所に配置する必要があります。データベースとは異なったディスクのファイルシステム上、あるいは、理想的には独立したディスクコントローラ上などです。

VistAのディレクトリを作成します。グローバル変数用に、a g サブディレクトリを使用し 、オブジェクトファイル用に o サブディレクトリを使用し、ルーチン用に、r サブディレクトリを使用します。環境変数を設定するために、ソースファイルを作成します。グローバル変数をロードする場所として、グローバルディレクトリとデータベースファイルを作成します。

gtmuser@gtmworkshop7:~$ mkdir -p VistA/{g,o,r}
gtmuser@gtmworkshop7:~$ fte VistA/env
gtmuser@gtmworkshop7:~$ cat VistA/env
export gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86
export gtmgbldir=/home/gtmuser/VistA/gtm.gld
export gtm_log=/tmp/fis-gtm/V5.4-002B_x86
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/VistA/gtm_repl
export gtm_repl_instname=dummy
export gtmroutines="/home/gtmuser/VistA/o(/home/gtmuser/VistA/r) $gtm_dist"
export gtm_principal_editing="EDITING"
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@gtmworkshop7:~$ source VistA/env
gtmuser@gtmworkshop7:~$ mumps -run GDE
%GDE-I-GDUSEDEFS, Using defaults for Global Directory 
        /home/gtmuser/VistA/gtm.gld

GDE> @/usr/lib/fis-gtm/V5.4-002B_x86/gdedefaults
%GDE-I-EXECOM, Executing command file /usr/lib/fis-gtm/V5.4-002B_x86/gdedefaults

GDE> change -segment DEFAULT -file=/home/gtmuser/VistA/g/gtm.dat
GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 DEFAULT                         /home/gtmuser/VistA/g/gtm.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE> change -region DEFAULT -journal=file=/home/gtmuser/VistA/g/gtm.mjl
GDE> show -region 

                                *** REGIONS ***
                                 Dynamic                          Def    Rec   Key Null       Standard
 Region                          Segment                         Coll   Size  Size Subs       NullColl  Journaling
 ------------------------------------------------------------------------------------------------------------------
 DEFAULT                         DEFAULT                            0   4080   255 NEVER      Y         Y

                          *** JOURNALING INFORMATION ***
 Region                          Jnl File (def ext: .mjl)  Before Buff      Alloc Exten
 ---------------------------------------------------------------------------------------
 DEFAULT                         /home/gtmuser/VistA/g/gtm.mjl       Y       128       2048  2048

GDE> exit
%GDE-I-VERIFY, Verification OK

%GDE-I-GDCREATE, Creating Global Directory file 
        /home/gtmuser/VistA/g/gtm.gld
gtmuser@gtmworkshop7:~$ mupip create

Created file /home/gtmuser/VistA/g/gtm.dat
gtmuser@gtmworkshop7:~$ 

グローバル変数は、圧縮されたアーカイブ形式なので、一時ファイルに圧縮ファイルを抽出する場合やデータベースにアーカイブをロードするには、多くのディスクスペースを使用します。この一時的なスペースの必要性を回避するために、FIFO(名前付きパイプ)を使用できます。gzip プロセスはそのFIFOへ書き込み、そして、mumpip loadは gzip プロセスから読み取ります。

gtmuser@gtmworkshop7:~$ mkfifo /tmp/vistaglobals
gtmuser@gtmworkshop7:~$ gzip -d </Distrib/VistA/globals.zwr.gz >/tmp/vistaglobals &

[1] 5677
gtmuser@gtmworkshop7:~$ mupip load /tmp/vistaglobals 
GT.M MUPIP EXTRACT
10-AUG-2010  14:38:37 ZWR
Beginning LOAD at record number: 3

LOAD TOTAL              Key Cnt: 20337342  Max Subsc Len: 223  Max Data Len: 834
Last LOAD record number: 20337344

[1]+  Done                    gzip -d < /Distrib/VistA/globals.zwr.gz > /tmp/vistaglobals
gtmuser@gtmworkshop7:~$ rm /tmp/vistaglobals 
gtmuser@gtmworkshop7:~$ ls -lR VistA/
VistA:
total 4.0K
-rw-r--r-- 1 gtmuser gtmuser 240 2010-09-13 11:42 env
drwxr-xr-x 2 gtmuser gtmuser  32 2010-09-13 11:49 g
drwxr-xr-x 2 gtmuser gtmuser   1 2010-09-13 11:41 o
drwxr-xr-x 2 gtmuser gtmuser   1 2010-09-13 11:41 r

VistA/g:
total 421M
-rw-rw-rw- 1 gtmuser gtmuser 451M 2010-09-13 11:54 gtm.dat
-rw-r--r-- 1 gtmuser gtmuser 1.5K 2010-09-13 11:49 gtm.gld

VistA/o:
total 0

VistA/r:
total 0
gtmuser@gtmworkshop7:~$ 

データベースは 451MB あり、20,337,342個のグローバル変数のノードが含まれているので注意してください。次に、r ディレクトリにルーチンをアンパックできます。

gtmuser@gtmworkshop7:~$ tar zxvf /Distrib/VistA/routines.tgz -C VistA/
[many thousands of lines of output have been suppressed here]
r/DGPFLMT.m
r/PRSEDEL1.m
r/FBCTAU.m
gtmuser@gtmworkshop7:~$ ls VistA/r | wc
25163 25163 251422
gtmuser@gtmworkshop7:~$ 

これは、WorldVistA EHRが 25,163 のソースコード モジュールを持っていることを教えてくれます。イベントによるシステム クラッシュからデータベースをリカバーできるように、ジャーナリングをオンにできます。これは開発環境であっても便利です。 開発者は、環境を回復するために待たされることを好みません。ディスクは安価です!

gtmuser@gtmworkshop7:~$ mupip set -journal="before,on" -region DEFAULT
%GTM-I-JNLCREATE, Journal file /home/gtmuser/VistA/g/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now ON
gtmuser@gtmworkshop7:~$ ls -l VistA/g
total 430900
-rw-rw-rw- 1 gtmuser gtmuser 472031744 2010-09-13 12:01 gtm.dat
-rw-r--r-- 1 gtmuser gtmuser      1536 2010-09-13 11:49 gtm.gld
-rw-rw-rw- 1 gtmuser gtmuser

VistAを実行できます。VistAが動作することを自分自身を納得させるのに十分です。そして、終了します。

gtmuser@gtmworkshop7:~$ mumps -dir

GTM>set DUZ=1

GTM>do P^DI


VA FileMan 22.0


Select OPTION: ^
GTM>halt
gtmuser@gtmworkshop7:~$ 

必要に応じて、GT.Mは動的にモジュールをコンパイルすることに注意してください。

gtmuser@gtmworkshop7:~$ ls -l VistA/o
total 352
-rw-r--r-- 1 gtmuser gtmuser 18900 2010-09-13 12:03 DIALOG.o
-rw-r--r-- 1 gtmuser gtmuser  9059 2010-09-13 12:04 DIARB.o
-rw-r--r-- 1 gtmuser gtmuser 18107 2010-09-13 12:04 DIB.o
-rw-r--r-- 1 gtmuser gtmuser 15682 2010-09-13 12:03 DIC0.o
-rw-r--r-- 1 gtmuser gtmuser 10447 2010-09-13 12:03 DIC11.o
-rw-r--r-- 1 gtmuser gtmuser 24949 2010-09-13 12:03 DIC1.o
-rw-r--r-- 1 gtmuser gtmuser 16612 2010-09-13 12:03 DIC2.o
-rw-r--r-- 1 gtmuser gtmuser 16412 2010-09-13 12:04 DICATT2.o
-rw-r--r-- 1 gtmuser gtmuser 10372 2010-09-13 12:03 DICL.o
-rw-r--r-- 1 gtmuser gtmuser 19330 2010-09-13 12:03 DIC.o
-rw-r--r-- 1 gtmuser gtmuser 14901 2010-09-13 12:03 DICRW.o
-rw-r--r-- 1 gtmuser gtmuser 11564 2010-09-13 12:03 DICUIX1.o
-rw-r--r-- 1 gtmuser gtmuser 15624 2010-09-13 12:03 DICUIX2.o
-rw-r--r-- 1 gtmuser gtmuser 14650 2010-09-13 12:03 DICUIX.o
-rw-r--r-- 1 gtmuser gtmuser 16413 2010-09-13 12:03 DII.o
-rw-r--r-- 1 gtmuser gtmuser  7085 2010-09-13 12:03 DILF.o
-rw-r--r-- 1 gtmuser gtmuser 23032 2010-09-13 12:03 DILIBF.o
-rw-r--r-- 1 gtmuser gtmuser  2096 2010-09-13 12:03 DI.o
-rw-r--r-- 1 gtmuser gtmuser 10357 2010-09-13 12:03 DIQGU.o
-rw-r--r-- 1 gtmuser gtmuser 21554 2010-09-13 12:03 _DTC.o
-rw-r--r-- 1 gtmuser gtmuser 18558 2010-09-13 12:03 _ZOSV.o
gtmuser@gtmworkshop7:~$ 

プリ コンパイルされたルーチン

VistAは、異なったMUMPS実装の間で移植できるように書かれています。これは、すべてのMUMPS実装のために書かれているので、文法的に不正なコードが含まれていることが保証されていることを意味します。モジュールが動的にコンパイルされるように、STDERRに送信されるコンパイルエラーが生成されます。これらの当惑を見つける可能性があるので、すべてのモジュールを動的にコンパイルすることによって不正コードを防ぐことができます。

gtmuser@gtmworkshop7:~$ cd VistA/o
gtmuser@gtmworkshop7:~/VistA/o$ find ../r -name \*.m -print -exec $gtm_dist/mumps {} \;

理想的には、シンプルに mumps *.m コマンドでコンパイルしますが、25,163個のルーチンは、シェルで扱うことより長く、コマンドラインとなるでしょう。そこで、findコマンドを使用します。また、xargsコマンドを使用してもコンパイルすることができます。また、ソースモジュール数とオブジェクトモジュール数のカウントして、すべてのルーチンがコンパイルされたことを確認してください。

gtmuser@gtmworkshop7:~/VistA/o$ ls |wc
  25163   25163  251422
gtmuser@gtmworkshop7:~/VistA/o$ ls ../r|wc
  25163   25163  251422
gtmuser@gtmworkshop7:~/VistA/o$ 

モジュールを再コンパイルした後に、VistAを開始し実行できることを確認してください。

複数のGT.Mバージョン

GT.MオブジェクトファイルはGT.Mの各リリースに固有のものなので、例えば、V5.4-002BはV5.4-000Aによって生成されたオブジェクトファイルを使用することはできません。データベースのフォーマットはより安定しているとはいえ、1つのデータベースファイルは1個のGT.Mのプロセスでは同時に開くことができます。同じソースコードは、しかしながら、GT.Mリリース数に制限なく使用できます。また、単一のGT.Mリリース内であっても、同じソースコードは、MモードとUTF-8モードで実行中のプロセスで使用することができます。しかし、オブジェクトファイルは異なっています。単純な環境で実装されたディレクトリツリー構造は、GT.Mのソースモジュールのセットを使用する1つのモードだけで、唯一のGT.Mリリースオペレーティングシステムの処理することができます。

gtmuser@gtmworkshop7:~$ tree -d VistA/
VistA/
├── g
├── o
└── r

3 directories
gtmuser@gtmworkshop7:~$ 

ディレクトリ構造内で別のレイヤーを作成することにより、同じVistAのルーチンは、複数のGT.Mリリースで動作させることができます。例えば、私達が持っていたケースでは:

gtmuser@gtmworkshop7:~$ mkdir VistA/V5.4-002B_x86
gtmuser@gtmworkshop7:~$ mv VistA/{g,o} VistA/V5.4-002B_x86/
gtmuser@gtmworkshop7:~$ tree -d VistA/
VistA/
├── r
└── V5.4-002B_x86
    ├── g
    └── o

4 directories
gtmuser@gtmworkshop7:~$ 

単純に別の場所から、オブジェクト、ジャーナル、グローバルディレクトリ、データベースファイルを移動したことに、注意してください。ここでは、ファイルを移動する時のために、いくつかの規則があります:

上記の修正は、(それがグローバルディレクトリを指すので、環境ファイルを使用して開始して、それがデータベースファイルを指すので、次にグローバルディレクトリ):

gtmuser@gtmworkshop7:~$ mv VistA/env VistA/V5.4-002B_x86/
gtmuser@gtmworkshop7:~$ fte VistA/V5.4-002B_x86/env
gtmuser@gtmworkshop7:~$ cat VistA/V5.4-002B_x86/env
export gtmdir=/home/gtmuser/VistA
export gtmver=V5.4-002B_x86
export gtm_dist=/usr/lib/fis-gtm/$gtmver
export gtmgbldir=$gtmdir/$gtmver/g/gtm.gld
export gtm_log=/tmp/fis-gtm/$gtmver
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/VistA/gtm_repl
export gtm_repl_instname=dummy
export gtmroutines="$gtmdir/$gtmver/o($gtmdir/r) $gtm_dist"
export gtm_principal_editing="EDITING"
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@gtmworkshop7:~$ 

GT.Mのバージョンが複数の場所であるので、それは環境変数 $gtmdir に要約されることに注意してください。また、 /home/gtmuser/VistA は環境変数 $gtmdir に要約されることができます。環境変数を使用するにはグローバルディレクトリを変更することにより、グローバルディレクトリの移植性を高めるになります。

gtmuser@gtmworkshop7:~$ source VistA/V5.4-002B_x86/env
gtmuser@gtmworkshop7:~$ mumps -run GDE
%GDE-I-LOADGD, Loading Global Directory file
        /home/gtmuser/VistA/V5.4-002B_x86/g/gtm.gld
%GDE-I-VERIFY, Verification OK


GDE> change -segment DEFAULT -file=$gtmdir/$gtmver/g/gtm.dat
GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 DEFAULT                         $gtmdir/$gtmver/g/gtm.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE> change -region DEFAULT -journal=file=$gtmdir/$gtmver/g/gtm.mjl
GDE> show -region

                                *** REGIONS ***
                                 Dynamic                          Def    Rec   Key Null       Standard
 Region                          Segment                         Coll   Size  Size Subs       NullColl  Journaling
 ------------------------------------------------------------------------------------------------------------------
 DEFAULT                         DEFAULT                            0   4080   255 NEVER      Y         Y

                          *** JOURNALING INFORMATION ***
 Region                          Jnl File (def ext: .mjl)  Before Buff      Alloc Exten
 ---------------------------------------------------------------------------------------
 DEFAULT                         $gtmdir/$gtmver/g/gtm.mjl
                                                           Y       128       2048  2048

GDE> exit
%GDE-I-VERIFY, Verification OK

%GDE-I-GDUPDATE, Updating Global Directory file
        /home/gtmuser/VistA/V5.4-002B_x86/g/gtm.gld
gtmuser@gtmworkshop7:~$ 

データベースとジャーナル ポインタが正しくするために、ジャーナリングを無効にし再度有効にします。

gtmuser@gtmworkshop7:~$ mupip set -journal=disable -region DEFAULT
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now DISABLED
gtmuser@gtmworkshop7:~$ mupip set -journal="enable,on,before,file=$gtmdir/$gtmver/g/gtm.mjl" -region DEFAULT
%GTM-I-FILERENAME, File /home/gtmuser/VistA/V5.4-002B_x86/g/gtm.mjl is renamed to /home/gtmuser/VistA/V5.4-002B_x86/g/gtm.mjl_2010256150621
%GTM-I-JNLCREATE, Journal file /home/gtmuser/VistA/V5.4-002B_x86/g/gtm.mjl created for region DEFAULT with BEFORE_IMAGES
%GTM-I-JNLSTATE, Journaling state for region DEFAULT is now ON
gtmuser@gtmworkshop7:~$ 

そして、VistAは、再度新しいディレクトリ構造で使用するための準備ができます:

gtmuser@gtmworkshop7:~$ mumps -dir

GTM>set DUZ=1

GTM>do P^DI


VA FileMan 22.0


Select OPTION: ^
GTM>halt
gtmuser@gtmworkshop7:~$ 

GT.Mの他のバージョンのディレクトリを追加することができます。例えば、

gtmuser@gtmworkshop7:~$ mkdir -p VistA/V5.4-00{0A,1}_x86/{g,o}
gtmuser@gtmworkshop7:~$ tree -d VistA/
VistA/
├── r
├── V5.4-000A_x86
│ ├── g
│ └── o
├── V5.4-001_x86
│ ├── g
│ └── o
└── V5.4-002B_x86
    ├── g
    └── o

10 directories
gtmuser@gtmworkshop7:~$ 

これは、単純なアップグレードを容易にします。たとえば、V5.4-002BからV5.4-002(この記事執筆時は未発表)へ移行したい場合は、同じディレクトリ内のV5.4-002BとV5.4-002のサブディレクトリの間でぼレプリケーティングを使用して、ローリング アップグレードに影響を与える可能性があります。

マイナーな改善 - GT.Mのバージョンに依存するソース

一般的には、プログラムのソースコードは、GT.Mバージョンから独立しています。時折、変更されたソースコードで、GT.Mのバージョン強化のアドバンテージを活用することができます。このようなバージョンの特定のソースコードモジュールの r サブディレクトリによって、g と o のサブディレクトリを拡張することができます。もちろん、envファイルが適宜に更新されていない限り、GT.Mは決してバージョン特有のルーチンを見つけられないでしょう。

gtmuser@gtmworkshop7:~$ for i in VistA/V* ; do mkdir $i/r ; done
gtmuser@gtmworkshop7:~$ tree -d VistA/
VistA/
├── r
├── V5.4-000A_x86
│ ├── g
│ ├── o
│ └── r
├── V5.4-001_x86
│ ├── g
│ ├── o
│ └── r
└── V5.4-002B_x86
    ├── g
    ├── o
    └── r

13 directories
gtmuser@gtmworkshop7:~$ fte VistA/V5.4-002B_x86/env
gtmuser@gtmworkshop7:~$ cat VistA/V5.4-002B_x86/env
export gtmdir=/home/gtmuser/VistA
export gtmver=V5.4-002B_x86
export gtm_dist=/usr/lib/fis-gtm/$gtmver
export gtmgbldir=$gtmdir/$gtmver/g/gtm.gld
export gtm_log=/tmp/fis-gtm/$gtmver
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/VistA/gtm_repl
export gtm_repl_instname=dummy
export gtmroutines="$gtmdir/$gtmver/o($gtmdir/$gtmver/r $gtmdir/r) $gtm_dist"
export gtm_principal_editing="EDITING"
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@gtmworkshop7:~$ source VistA/V5.4-002B_x86/env
gtmuser@gtmworkshop7:~$ mumps -dir

GTM>write $zroutines
/home/gtmuser/VistA/V5.4-002B_x86/o(/home/gtmuser/VistA/V5.4-002B_x86/r /home/gtmuser/VistA/r) /usr/lib/fis-gtm/V5.4-002B_x86
GTM>halt
gtmuser@gtmworkshop7:~$ 

ローカルの変更を分離する

大規模なアプリケーションのインストールは、多くの場合、ローカルまたは修正を行っています。このような場合には、標準的なアプリケーションのディストリビューションからローカルパッチを分離することが重要です。これは、p サブディレクトリにこれらのルーチンを配置することと、標準ルーチンはそのまま残してある r サブディレクトリの先頭の p サブディレクトリを配置することが効果的に行うことができます。

gtmuser@gtmworkshop7:~$ for i in VistA/V* ; do mkdir $i/p ; done

gtmuser@gtmworkshop7:~$ tree -d VistA/

VistA/
├── r
├── V5.4-000A_x86
│ ├── g
│ ├── o
│ ├── p
│ └── r
├── V5.4-001_x86
│ ├── g
│ ├── o
│ ├── p
│ └── r
└── V5.4-002B_x86
    ├── g
    ├── o
    ├── p
    └── r

16 directories
gtmuser@gtmworkshop7:~$ fte VistA/V5.4-002B_x86/env
gtmuser@gtmworkshop7:~$ cat VistA/V5.4-002B_x86/env
export gtmdir=/home/gtmuser/VistA
export gtmver=V5.4-002B_x86
export gtm_dist=/usr/lib/fis-gtm/$gtmver
export gtmgbldir=$gtmdir/$gtmver/g/gtm.gld
export gtm_log=/tmp/fis-gtm/$gtmver
export gtm_principal_editing=EDITING
export gtm_repl_instance=/home/VistA/gtm_repl
export gtm_repl_instname=dummy
export gtmroutines="$gtmdir/$gtmver/o($gtmdir/$gtmver/p $gtmdir/$gtmver/r $gtmdir/p $gtmdir/r) $gtm_dist"
export gtm_principal_editing="EDITING"
alias mumps=$gtm_dist/mumps
alias mupip=$gtm_dist/mupip
gtmuser@gtmworkshop7:~$ 

今度は、/home/gtmuser/VistA/p ディレクトリへGT.Mでより良い動作となるようにそれを可能にすることを、VistAに対していくつかの変更を適用することにより、操作でこれを見ることができます。GT.Mアカルチュレーション ワークショップを得た同じ場所からファイル KSBVistAPatches.zip をダウンロードしてください、そして、/Distrib/VistA ディレクトリにそれを置いてください。次に、それを/home/gtmuser/VistA/p ディレクトリへ解凍します。

gtmuser@gtmworkshop7:~$ ls -l /Distrib/VistA/KSBVistAPatches.zip
-rw-r--r-- 1 gtmuser gtmuser 20530 2010-09-14 14:05 /Distrib//VistA/KSBVistAPatches.zip
gtmuser@gtmworkshop7:~$ unzip -d VistA/p /Distrib/VistA/KSBVistAPatches.zip
Archive:  /Distrib//VistA/KSBVistAPatches.zip
  inflating: VistA/p/XPDR.m
  inflating: VistA/p/XWBTCPM.m
  inflating: VistA/p/ZOSV2GTM.m
  inflating: VistA/p/_ZOSV2.m
  inflating: VistA/p/ZOSVGUX.m
  inflating: VistA/p/_ZOSV.m
  inflating: VistA/p/ZTMGRSET.m
gtmuser@gtmworkshop7:~$

次に、VistA/V5.4-002B_x86/o ディレクトリ内のオブジェクトファイルでコンパイルしてください。

gtmuser@gtmworkshop7:~$ cd VistA/V5.4-002B_x86/o
gtmuser@gtmworkshop7:~/VistA/V5.4-002B_x86/o$ mumps ../../p/*.m
gtmuser@gtmworkshop7:~/VistA/V5.4-002B_x86/o$

ローカルの変更でVistAを実行することができます。この場合において、変更の一つは、VistAのマイナーなバグ修正です:それは、むしろセパレータとしても、ディレクトリ名の一部として、括弧内のリストでソースディレクトリを分離するスペースを扱います。変更すると、パッチを適用する例として関数を実行する時には、それが正しくは、ディレクトリの括弧のリスト内にある場合でも、最初のソースディレクトリに新しいルーチンを置きます。この例では、^ZTMGRTSET 関数が実行されます。VistA/V5.4-002B/pディレクトリが最初は空であるが、その後、数10個のファイルを持つことに注意してください。

gtmuser@gtmworkshop7:~$ ls -l VistA/V5.4-002B_x86/p
total 0
gtmuser@gtmworkshop7:~$ mumps -dir

GTM>do ^ZTMGRSET


ZTMGRSET Version 8.0 Patch level **34,36,69,94,121,127,136,191,275,355**
HELLO!I exist to assist you in correctly initializing the current account.

This is namespace or uci EHR,EHR.
Should I continue?N//y
I think you are using GT.M (Unix)
Which MUMPS system should I install?1 = VAX DSM(V6), VAX DSM(V7)
2 = MSM-PC/PLUS, MSM for NT or UNIX
3 = Cache (VMS, NT, Linux), OpenM-NT
4 = Datatree, DTM-PC, DT-MAX
5 =
6 =
7 = GT.M (VMS)
8 = GT.M (Unix)
System: 8//

I will now rename a group of routines specific to your operating system.
Routine: ZOSVGUX      Loaded, Saved as %ZOSV
Routine:
Routine: ZIS4GTM      Loaded, Saved as %ZIS4
Routine: ZISFGTM      Loaded, Saved as %ZISF
Routine: ZISHGTM      Loaded, Saved as %ZISH
Routine: XUCIGTM      Loaded, Saved as %XUCI
Routine: ZISETGUX     Missing
Routine: ZOSV2GTM     Loaded, Saved as %ZOSV2
Routine: ZISTCPS      Loaded, Saved as %ZISTCPS

NAME OF MANAGER'S UCI,VOLUME SET: EHR,EHR//
The value of PRODUCTION will be used in the GETENV api.
PRODUCTION (SIGN-ON) UCI,VOLUME SET: EHR,EHR//
The VOLUME name must match the one in PRODUCTION.
NAME OF VOLUME SET: EHR//
The temp directory for the system: '/tmp/'//
^%ZOSF setup


Now to load routines common to all systems.
Routine: ZTLOAD       Loaded, Saved as %ZTLOAD
Routine: ZTLOAD1      Loaded, Saved as %ZTLOAD1
Routine: ZTLOAD2      Loaded, Saved as %ZTLOAD2
Routine: ZTLOAD3      Loaded, Saved as %ZTLOAD3
Routine: ZTLOAD4      Loaded, Saved as %ZTLOAD4
Routine: ZTLOAD5      Loaded, Saved as %ZTLOAD5
Routine: ZTLOAD6      Loaded, Saved as %ZTLOAD6
Routine: ZTLOAD7      Loaded, Saved as %ZTLOAD7
Routine: ZTM          Loaded, Saved as %ZTM
Routine: ZTM0         Loaded, Saved as %ZTM0
Routine: ZTM1         Loaded, Saved as %ZTM1
Routine: ZTM2         Loaded, Saved as %ZTM2
Routine: ZTM3         Loaded, Saved as %ZTM3
Routine: ZTM4         Loaded, Saved as %ZTM4
Routine: ZTM5         Loaded, Saved as %ZTM5
Routine: ZTM6         Loaded, Saved as %ZTM6
Routine: ZTMS         Loaded, Saved as %ZTMS
Routine: ZTMS0        Loaded, Saved as %ZTMS0
Routine: ZTMS1        Loaded, Saved as %ZTMS1
Routine: ZTMS2        Loaded, Saved as %ZTMS2
Routine: ZTMS3        Loaded, Saved as %ZTMS3
Routine: ZTMS4        Loaded, Saved as %ZTMS4
Routine: ZTMS5        Loaded, Saved as %ZTMS5
Routine: ZTMS7        Loaded, Saved as %ZTMS7
Routine: ZTMSH        Loaded, Saved as %ZTMSH
Routine: ZTER         Loaded, Saved as %ZTER
Routine: ZTER1        Loaded, Saved as %ZTER1
Routine: ZIS          Loaded, Saved as %ZIS
Routine: ZIS1         Loaded, Saved as %ZIS1
Routine: ZIS2         Loaded, Saved as %ZIS2
Routine: ZIS3         Loaded, Saved as %ZIS3
Routine: ZIS5         Loaded, Saved as %ZIS5
Routine: ZIS6         Loaded, Saved as %ZIS6
Routine: ZIS7         Loaded, Saved as %ZIS7
Routine: ZISC         Loaded, Saved as %ZISC
Routine: ZISP         Loaded, Saved as %ZISP
Routine: ZISS         Loaded, Saved as %ZISS
Routine: ZISS1        Loaded, Saved as %ZISS1
Routine: ZISS2        Loaded, Saved as %ZISS2
Routine: ZISTCP       Loaded, Saved as %ZISTCP
Routine: ZISUTL       Loaded, Saved as %ZISUTL
Routine: ZTPP         Loaded, Saved as %ZTPP
Routine: ZTP1         Loaded, Saved as %ZTP1
Routine: ZTPTCH       Loaded, Saved as %ZTPTCH
Routine: ZTRDEL       Loaded, Saved as %ZTRDEL
Routine: ZTMOVE       Loaded, Saved as %ZTMOVE
Want to rename the FileMan routines: No//y
Routine: DIDT         Loaded, Saved as %DT
Routine: DIDTC        Loaded, Saved as %DTC
Routine: DIRCR        Loaded, Saved as %RCR
Setting ^%ZIS('C')

Now, I will check your % globals...........
ALL DONE
GTM>halt
gtmuser@gtmworkshop7:~$ ls -l VistA/V5.4-002B_x86/p|wc
     57     450    3356
gtmuser@gtmworkshop7:~$

開発環境の作成

あなたがアプリケーションで作業する時、それを強化するかバグを修正するかのどちらかをするために、通常はアプリケーションのごく一部を変更します。 GT.Mで、あなたのプロジェクトの作業をするために、アプリケーション環境全体のコピーを作成する必要はありません。他と足並みが揃わないリスクを持って、他の開発者と同じ環境で作業する必要もありません。必要なのは、それらの$ZROUTINESの検索パスが、メインアプリケーション ルーチンを見つける前に開発ルーチンを見つけたように、プロセスを設定することです。もし、それは感覚、親の環境にマップされた残りのグローバルとデータベースの一部を行う場合や、さらに、 - あなたの仕事はグローバル変数への変更を伴う場合には、、、、データベースの独自のコピーをセットアップすることができます。もちろん、大規模なプロジェクトで、ご使用の環境の親は、親が自分自身を持つことができます。

運動を簡素化するために、V5.4-002B_x86以外のGT.Mのバージョン用のサブディレクトリを削除する - あなたは多分開発を行い、並行してGT.Mのバージョンを移行することができるが、それは複雑で一つのさらなる一歩です。

gtmuser@gtmworkshop7:~$ ls -l VistA/
total 2720
drwxr-xr-x 2 gtmuser gtmuser     56 2010-09-14 14:07 p
drwxr-xr-x 2 gtmuser gtmuser 405504 2010-09-13 13:51 r
drwxr-xr-x 6 gtmuser gtmuser     32 2010-09-14 11:49 V5.4-000A_x86
drwxr-xr-x 6 gtmuser gtmuser   4096 2010-09-14 11:54 V5.4-001_x86
drwxr-xr-x 6 gtmuser gtmuser     32 2010-09-14 11:49 V5.4-002B_x86
gtmuser@gtmworkshop7:~$ rm -rf VistA/V5.4-00{0A,1}_x86
gtmuser@gtmworkshop7:~$ ls -l VistA/
total 2720
drwxr-xr-x 2 gtmuser gtmuser     56 2010-09-14 14:07 p
drwxr-xr-x 2 gtmuser gtmuser 405504 2010-09-13 13:51 r
drwxr-xr-x 6 gtmuser gtmuser   4096 2010-09-14 11:54 V5.4-002B_x86
gtmuser@gtmworkshop7:~$

今すぐ、ファイル incinstall を、このアカルチュレーション ワークショップの同じ場所からVistA環境へコピーしてください、そして、実行ファイルinstallを作ってください。

gtmuser@gtmworkshop7:~$ ls -l VistA/
total 2732
-r--r--r-- 1 gtmuser gtmuser    894 2010-09-14 15:56 inc
-r-xr-x--x 1 gtmuser gtmuser   4416 2010-09-14 15:56 install
drwxr-xr-x 2 gtmuser gtmuser     56 2010-09-14 14:07 p
drwxr-xr-x 2 gtmuser gtmuser 405504 2010-09-13 13:51 r
drwxr-xr-x 6 gtmuser gtmuser   4096 2010-09-14 11:54 V5.4-002B_x86
gtmuser@gtmworkshop7:~$

同様に、VistA/V5.4-002B_x86 へ、ファイル wvehrstop, wvehrstart, run, newjnls, env をコピーしてください (はい、後者は、既ににそこにあるenv ファイルに上書きされます )。 wvehrstop, wvehrstart, run, newjnls を実行可能にします。また、新しい envファイルでVistA/V5.4-002B_x86の中に、env を置き換えてください。/usr/lib/fis-gtm/V5.4-002B_x86に、gtmと呼ばれるシンボリックリンクを作成します。

gtmuser@gtmworkshop7:~$ ls -l VistA/V5.4-002B_x86/
total 1816
-rw-r--r-- 1 gtmuser gtmuser    731 2010-09-14 16:56 env
drwxr-xr-x 2 gtmuser gtmuser     40 2010-09-14 17:31 g
lrwxrwxrwx 1 gtmuser gtmuser     29 2010-09-14 17:30 gtm -> /usr/lib/fis-gtm/V5.4-002B_x86
-r-xr-xr-x 1 gtmuser gtmuser    181 2010-09-14 16:04 newjnls
drwxr-xr-x 3 gtmuser gtmuser 208896 2010-09-14 17:31 o
drwxr-xr-x 2 gtmuser gtmuser   4096 2010-09-14 14:24 p
drwxr-xr-x 2 gtmuser gtmuser      1 2010-09-13 17:34 r
-r-xr-x--x 1 gtmuser gtmuser    340 2010-09-14 16:05 run
-r-xr-xr-x 1 gtmuser gtmuser    277 2010-09-14 16:14 wvehrstart
-r-xr-xr-x 1 gtmuser gtmuser    161 2010-09-14 16:14 wvehrstop
gtmuser@gtmworkshop7:~$

今すぐインストールスクリプトを使用してdevと呼ばれるVistAの子の環境を作成します。

gtmuser@gtmworkshop7:~$ VistA/install dev
Creating environment in dev as child of environment in /home/gtmuser/VistA
Default permission for development environment is for all to read and group to write - please alter as needed
gtmuser@gtmworkshop7:~$ ls -lR dev
dev:
total 16
-r--r--r-- 1 gtmuser gtmuser  894 2010-09-14 17:33 inc
-r-xr-x--x 1 gtmuser gtmuser 4416 2010-09-14 17:33 install
drwxrwxr-x 2 gtmuser gtmuser    1 2010-09-14 17:33 p
lrwxrwxrwx 1 gtmuser gtmuser   19 2010-09-14 17:33 parent -> /home/gtmuser/VistA
drwxrwxr-x 2 gtmuser gtmuser    1 2010-09-14 17:33 r
drwxrwxr-x 7 gtmuser gtmuser   88 2010-09-14 17:33 V5.4-002B_x86

dev/p:
total 0

dev/r:
total 0

dev/V5.4-002B_x86:
total 20
-r--r--r-- 1 gtmuser gtmuser 731 2010-09-14 17:33 env
drwxrwxr-x 2 gtmuser gtmuser   8 2010-09-14 17:33 g
lrwxrwxrwx 1 gtmuser gtmuser  36 2010-09-14 17:33 gtm -> /home/gtmuser/VistA/V5.4-002B_x86/gtm
-r-xr-xr-x 1 gtmuser gtmuser 181 2010-09-14 17:33 newjnls
drwxrwxr-x 2 gtmuser gtmuser   1 2010-09-14 17:33 o
drwxrwxr-x 2 gtmuser gtmuser   1 2010-09-14 17:33 p
drwxrwxr-x 2 gtmuser gtmuser   1 2010-09-14 17:33 r
-r-xr-x--x 1 gtmuser gtmuser 340 2010-09-14 17:33 run
drwxrwxr-x 2 gtmuser gtmuser   1 2010-09-14 17:33 tmp
-r-xr-xr-x 1 gtmuser gtmuser 277 2010-09-14 17:33 wvehrstart
-r-xr-xr-x 1 gtmuser gtmuser 161 2010-09-14 17:33 wvehrstop

dev/V5.4-002B_x86/g:
total 4
-r--r--r-- 1 gtmuser gtmuser 1536 2010-09-13 18:22 gtm.gld

dev/V5.4-002B_x86/o:
total 0

dev/V5.4-002B_x86/p:
total 0

dev/V5.4-002B_x86/r:
total 0

dev/V5.4-002B_x86/tmp:
total 0
gtmuser@gtmworkshop7:~$

今、dev環境を実行し、環境変数の値に注意してください。特に、使用されるデータベースが、どのように親のそれであるか。

gtmuser@gtmworkshop7:~$ dev/V5.4-002B_x86/run

GTM>write $zgbldir
/home/gtmuser/dev/V5.4-002B_x86/g/gtm.gld
GTM>write $zroutines
/home/gtmuser/dev/V5.4-002B_x86/o(/home/gtmuser/dev/V5.4-002B_x86/p /home/gtmuser/dev/V5.4-002B_x86/r /home/gtmuser/dev/p /home/gtmuser/dev/r) /home/gtmuser/dev/parent/V5.4-002B_x86/o(/home/gtmuser/dev/parent/V5.4-002B_x86/p /home/gtmuser/dev/parent/V5.4-002B_x86/r /home/gtmuser/dev/parent/p /home/gtmuser/dev/parent/r) /home/gtmuser/dev/V5.4-002B_x86/gtm
GTM>zsystem "env | grep gtm"
gtm_repl_instance=/home/gtmuser/dev/parent/V5.4-002B_x86/g/gtm.repl
gtm_log=/tmp/fis-gtm/V5.4-002B_x86
gtm_prompt=GTM>
gtm_retention=42
gtmver=V5.4-002B_x86
USER=gtmuser
gtm_icu_version=4.2
routines=/home/gtmuser/dev/V5.4-002B_x86/o(/home/gtmuser/dev/V5.4-002B_x86/p /home/gtmuser/dev/V5.4-002B_x86/r /home/gtmuser/dev/p /home/gtmuser/dev/r) /home/gtmuser/dev/parent/V5.4-002B_x86/o(/home/gtmuser/dev/parent/V5.4-002B_x86/p /home/gtmuser/dev/parent/V5.4-002B_x86/r /home/gtmuser/dev/parent/p /home/gtmuser/dev/parent/r)
gtmgbldir=/home/gtmuser/dev/V5.4-002B_x86/g/gtm.gld
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/fis-gtm/V5.4-002B_x86
MAIL=/var/mail/gtmuser
PWD=/home/gtmuser/dev/V5.4-002B_x86/tmp
gtmroutines=/home/gtmuser/dev/V5.4-002B_x86/o(/home/gtmuser/dev/V5.4-002B_x86/p /home/gtmuser/dev/V5.4-002B_x86/r /home/gtmuser/dev/p /home/gtmuser/dev/r) /home/gtmuser/dev/parent/V5.4-002B_x86/o(/home/gtmuser/dev/parent/V5.4-002B_x86/p /home/gtmuser/dev/parent/V5.4-002B_x86/r /home/gtmuser/dev/parent/p /home/gtmuser/dev/parent/r) /home/gtmuser/dev/V5.4-002B_x86/gtm
gtmdir=/home/gtmuser/dev/parent
HOME=/home/gtmuser
gtm_principal_editing=EDITING
LOGNAME=gtmuser
gtm_tmp=/tmp/fis-gtm/V5.4-002B_x86
gtm_dist=/usr/lib/fis-gtm/V5.4-002B_x86


GTM>do ^GDE
%GDE-I-LOADGD, Loading Global Directory file
        /home/gtmuser/dev/V5.4-002B_x86/g/gtm.gld
%GDE-I-VERIFY, Verification OK


GDE> show -segment

                                *** SEGMENTS ***
 Segment                         File (def ext: .dat)Acc Typ Block      Alloc Exten Options
 -------------------------------------------------------------------------------------------
 DEFAULT                         $gtmdir/$gtmver/g/gtm.dat
                                                     BG  DYN  4096       5000 10000 GLOB=1000
                                                                                    LOCK=  40
                                                                                    RES =   0
                                                                                    ENCR=OFF
GDE> quit
%GDE-I-NOACTION, Not updating Global Directory /home/gtmuser/dev/V5.4-002B_x86/g/gtm.gld
gtmuser@gtmworkshop7:~$

自分自身でさらなる研究を

"Hello, World" プログラムを作成するためにdev 環境でZEDITコマンドを使用してください、そして、それを実行可能なことを見せてください。今、VistAの親の環境でそのプログラムを実行してみてください、そして、それが存在しないことがわかります。

もしインストールスクリプトの--separate-globalsフラグを使用する場合に、何が起こるかを調べてください。環境変数が設定されているかどうかを確認するスクリプトを介して作業してください。

インストールスクリプトを調べ、それが子どもの環境を設定する方法を参照してください。

inserted by FC2 system