平成8年度 委託研究ソフトウェアの 成果ソフトウェア
|
(15) KLIC による並列アクテイブデータベース処理の実現
研究代表者:横田治夫 助教授
北陸先端科学技術大学院大学 情報科学研究科
[English page is here]
このソフトウェアは,独立した2つのソフトウェアから構成されています.
(1) parade (PARallel Active Database Engine) :
並列アクティブデータベースプロトタイプ
(2) fatpas (FAult Tolerant PArallel Software) :
耐故障並列ソフトウェアライブラリ
このプログラムは、さらに次の二つから構成されています。
(2-1) expand : KLICマクロ展開プログラム
(2-2) fts : 耐故障並列ソフトウェアライブラリ
【並列アクティブデータベースエンジン: Parade】
by
横田治夫 at JAIST (北陸先端科学技術大学院大学)
[用途]
広範囲のデータベース処理を前提にしており、動的な経営判断や株の
動向解析といったビジネス分野も対象にしているが、現バージョンは
まだ必ずしも安定していないため、実験的利用が望ましいと思われる。
サーバーの関係代数レベルのストリームインタフェースは、KLIC で
書かれたアプリケーションプログラムに対してデータベース利用をサ
ポートする。
[機能]
用意されたアクティブルールによって能動的にデータベースの内容を
チェックして条件を判断し、定められた動作を行うことを目標に作ら
れており、以下の機能を持つ。
- 効率良い動作のため、ネステッドトランザクションをサポートし
ており、子トランザクションのアボートは、親トランザクション
に影響を与えない。
- データの排他制御においては分散デッドロック検出を行い、処理
の集中を避けている。
- データベース操作は、関係データベース演算を基本としており、
水平分散されたデータに対して並列検索処理を行う。
- ユーザインタフェースは、インタラクティブな SQL クライアント
を複数持てるのと同時に、KLIC からの関係代数レベルのストリー
ムインタフェースも用意している。
- KL1プロセスのsuspend/resume機能を利用したルール処理機構によ
り、能動的なデータの更新・検索等をネステッドトランザクショ
ンの保護の下で効率よく実行できる。
[実行環境]
以下のマシン上とKLIC version 2.002の組み合わせ
- nCUBE2:nCX 5.105a 3.4.0 (要 nbsd, nsdisk)
- Sun: SunOS 4.1.3 (Solaris 1.1),SunOS 5.4 (Solaris 2.4)
- PC: 386 BSD (BSDI BSD/OS 2.0.1)
- NEWS: NEWS-OS 6.1.1
[ファイル構成]
- parade/
- COPYRIGHT
- Readme-E.html
- Readme-J.txt
- advertise-E.html
- advertise-J.html
- rdbhosts
- Makefile
- common/
- client/
- sqlclt/
- dict.kl1
- hostname.kl1
- parser.kl1
- sqlclt.kl1
- uif.kl1
- oqlclt/
- hostname.kl1
- paraio.kl1
- uif.kl1
- dict.kl1
- oqlclt.kl1
- parser.kl1
- server/
- access.kl1
- access1.kl1
- algebra.kl1
- create.kl1
- deadlock.kl1
- delete.kl1
- drop.kl1
- exec.kl1
- insert.kl1
- lock.kl1
- log.kl1
- node_io.kl1
- processor.kl1
- projection.kl1
- rdbserv.kl1
- selection.kl1
- trans.kl1
- rule.kl1
- btree/
- bt_add.kl1
- bt_del.kl1
- bt_del1.kl1
- bt_del2.kl1
- bt_del3.kl1
- bt_get.kl1
- bt_name.kl1
- bt_page.kl1
- bt_pagename.kl1
- bt_util.kl1
- btinit.dat
- btree.kl1
- coding/
- Makefile
- decoder.kl1
- encoder.kl1
- fastio.kl1
- util/
- Makefile
- util.kl1
- rel/
- Makefile
- attributes
- audit
- dept
- emp
- faculty
- relations.skel
- nrelations.skel
- rule
- newrel/
- doc/
- catalogue.tex
- papers.tex
- parade_doc.tex
- sun/
- client/
- sqlclt/
- Makefile
- oqlclt/
- Makefile
- javaQBE/
- readme
- index.html
- makefile
- DropPanel.java
- ScrollableTable.java
- GroupTable.java
- SelectPanel.java
- Attribute.java
- QbePanel.java
- Tag.java
- AttributePanel.java
- QbeSettingPanel.java
- TagTable.java
- AttributeTable.java
- QueryAttributes.java
- VStackLayout.java
- QueryCreate.java
- Client.java
- QueryData.java
- Communicate.java
- QueryDelete.java
- Const.java
- QueryDrop.java
- CreatePanel.java
- QueryInsert.java
- server/
- Makefile
- catalog.kl1
- socket/
- paraio.kl1
- socket.kl1
- ncube/
- client/
- Makefile
- server/
- Makefile
- catalog.kl1
- socket/
- paraio.kl1
- socket.kl1
[その他]
現在、開発途上です。
【KLICマクロ展開プログラム】
by
杉野栄二、横田治夫 at JAIST (北陸先端科学技術大学院大学)
[用途]
KL1ソースプログラムに対して加工を行ないたいときに、じゃまになる
KLICのマクロ表記をとりのぞきたいとき、
またKLICで記述されたプログラムをPIMへ移植したいときにも役立つ。
あるいは、KLICで記述されたマクロが どのように展開されるかを
確かめたいときに有効である。
[機能]
本プログラムは、KLICにおけるマクロ表記等を含むKL1プログラムを
ほぼプレーンなKL1プログラムに変換し、標準出力へ出力する。
[実行環境]
- KLIC (klic version 3.001 )
[ファイル構成]
- fatpas/
- expand/
- README.j
- README-j.html
- README.e
- README-e.html
- Makefile
- diff.kl1
- kl1cmp.kl1
- kl1cmp0.kl1
- macro.kl1
- main.kl1
- obj.kl1
- util.kl1
- write.kl1
- difftest
- test
[インストール方法]
必要に応じてMakefile を修正し、
make all で実行形式 kl1expand が作られる。
[使い方] 変換結果は、標準出力に出力される。
その1)ファイルから入力する場合
- % kl1expand File1 File2 ...
- 入力ファイル名は、***.kl1 の形であること。
その2)標準入力から入力する場合
- % cat hogehoge.kl1 | kl1expand user
- 入力ファイル名として 'user' を指定すれば、標準入力からプログラムを
読み込む。
[変換後のプログラムについて]
KLICのコンパイラを元にしているため、ガードのOR
- head :- (guard1 ; guard2) | body.
- の形はそのまま出力する。
・ モジュール宣言以下のコマンド
:- xxxxx.
は、モジュール内の述語定義の一番最後にまとめて出力される。
・ モジュール宣言前のコマンドは、モジュール宣言の前に出力される。
[KLICのバージョンアップに対応するヒント]
本プログラム対応版のKLICコンパイラ(compilerディレクトリ以下の *.kl1)を、
新版のコンパイラと比較して、それに対応するプログラムを変更する。
KLICのバージョンアップに対応するために、ファイル名モジュール名等
できるだけ保存するようにしてある。
対応するオリジナルのファイルとの共通部分の比較機能
% make cmp
も提供する。本プログラムの相違部分には、% IGNORE ... 等のコメントがあるが、
この比較機能はこの部分だけ無視して比較を行なうため、共通部分に変更が
あれば、この機能でわかる。
[試験]
本プログラム自身を展開した結果とオリジナルプログラムに対して、
klicでコンパイルした結果で比較した。
試験方法
- % kl1expand XXX.kl1 > tmp.kl1
- % klic -c XXX.kl1 tmp.kl1
- % cmp XXX.c tmp.c
試験結果
- main.kl1 ○
- write.kl1 ○
- util.kl1 △
- obj.kl1 △
- macro.kl1 △
- kl1cmp.kl1 ×
- ○は一致したもの、
- △はkl1cmp.kl1 中の tidy_clause を行なわないと一致する。
tidy_clauseは、変数名のつけかえ等を行なって
結果クローズの見栄えを良くするものである。
このため、変数の割り付け方が変わるものと思われる。
kl1cmp.kl1 のかわりに kl1cmp0.kl1を用いてコンパイルすると
tidy_clauseを行わない結果が得られる。
- ×は、述語のコンパイル順序が変わることによる。
クローズ内のif-then 表記マクロの展開によって、新たに生成
される述語の順序が オリジナルのコンパイラでは逆順になっている。
このため、内部で生成するテーブル、ラベル名等の割り付けが
異る。
変更履歴:
- klic (limited release version 2.004) コンパイラをもとに作成。
[Version 1.0] 1996.10.25 by
杉野栄二 (sugino@jaist.ac.jp)
ただし、klic (version 3.001)での動作を確認(1997.7.30) 。
- 1996.10.31 プリティプリントを変更
- orゴールの表記に段下げをつけた。
- ボディ変数と非変数のボディユニファイが
出ないようにした。(変数を非変数に置き換える)
- 1996.12.19 プリティプリントを修正
ボディで冗長なユニフィケーションが出ていたため。
- 1997.02.28 ガード組み込み述語の演算部分の表記を修正
(divide(A,B,C) -> C := A/B 等)
【耐故障並列ソフトウェアライブラリ】
by
杉野栄二、横田治夫 at JAIST (北陸先端科学技術大学院大学)
[用途]
一般の並列計算機上で、KL1プログラムの耐故障実行を実現する。
[機能]
サンプルプログラム ft_queen.kl1 のように
耐故障ソフトウェア化したKL1プログラムとリンクすることで、
耐故障実行を行う。
述語 distribution(Primary,Backup) : watchdog.kl1 で提供される
は、すべてのノードを二つに分け、それぞれで監視プロセス起動する。
それぞれのプロセスへのストリームをリストにしてPrimary, Backup
へ返す。
述語 copy(Args,Args1,Args2,Interrupt) : copy.kl1 で提供される
は、与えられた引数(変数を含む)Argsを複製し、Args1, Args2へ返す。
変数に対してはそれぞれプロセスが生成される、Argsの変数に
動的にユニファイされる値に対しては、対応するArgs1,Args2の変数に
ブロードキャストされる。 逆にArgs1, Args2へは同じ値がユニファイされる
ものとし、そのいずれかをArgsの対応する変数へ送る。
変数に対して生成されているプロセスは、
ストリーム Interruptへ fault が送られると ArgsとArgs2とをユニファイして
終了する。
[使い方]
ライブラリ watchdog.kl1、copy.kl1 および、
使用する環境に応じてncube.kl1 または sparc.kl1 、
それとユーザプログラム
(サンプルプログラムならば main.kl1 と ft_queen.kl1 )
をKLICでコンパイル、リンクして起動する。
% klic -v -dp -o dofts watchdog.kl1 copy.kl1 sparc.kl1 main.kl1 ft_queen.kl1
注)使用可能なノード数の総数が3個以上なければならない。
[実行環境]
- KLIC klic version 2.002
- nCUBE2:nCX 5.105a 3.4.0 または
- SunOS 4.1.3
[ファイル構成]
- fatpas/
- fts/
- README.j
% 日本語版 README
- README-j.html
% 本ファイル
- README.e
% 英語版 README
- README-e.html
% 英語版 html
- watchdog.kl1
% 監視プロセス
- copy.kl1
% プロセス複製
- ncube.kl1
% nCUBE2向けライブラリ
- sparc.kl1
% SPARC向けライブラリ
- === サンプルプログラム ===
- main.kl1
% サンプルプログラム 主ルーチン
- queen.kl1
% N-Queenプログラム
- ft_queen.kl1
% 耐故障化 N-Queenプログラム
- ft_queen_faulty.kl1
% 耐故障化 N-Queenプログラム エラーあり
- main-sim.kl1
% サンプルプログラム(その2)主ルーチン
- f_sim.kl1
% サンプルプログラム(その2)
- f_sim_faulty.kl1
% サンプルプログラム(その2)エラーあり
[実行例]
分散版KLICのトレース機能が利用できないため、バグが完全に
とりきれていない。 よって現在の版では、故障に対して完全に
実行継続できない。
サンプルプログラム(その2)については、ある程度の
継続動作が見られる。
1) コンパイル
- % make sparc
2) エラー無しの実行
- % ./dofts-s -p5 10 100d
- Leader [1]
- Leader [2]
- Backup Site Group : 2 4
- Primary Site Group : 1 3
- 30 [67,1]
<== プログラム出力 A (30), B ([67,1])
- Response time is 1359 msec
3) エラーありの実行
- amethyst[300]% ./dofts-sf -p5 10 100d
- Leader [1]
- Leader [2]
- Primary Site Group : 1 3
- Backup Site Group : 2 4
- BOMB! 3
<== Node 3 でexit
- 30 FAULT was detected on PRIMARY SITE!
<== 出力 A の後、故障検出
- FAULT was informed to BACKUP!
- BACKUP change to PRIMARY !!! REBIRTH (1) [4]
- REBIRTH (2) [4]
- ... REBIRTH ndet_replay [117,1]
<== 内部メッセージの後、出力 B
- ^Ckill tasks from io_server
<== 正常終了しないため ^C
耐故障化変換 プログラムは、未完成であるので、以下に耐故障化変換の指針を記す。
[耐故障化の指針]
1) 耐故障実行させたい部分を分離する。
ユーザプログラムは、main.kl1 と queen.kl1 に分離されており、
述語 queen:queen(N,Result) を耐故障実行する。
注) オリジナルのプログラムは、main.kl1 queen.kl1 だけで動作する。
2)耐故障実行させたい部分を次の手順で変更する。
2-1) 呼び出される一番上の述語を次の例のように変更する。
- % オリジナルの述語呼び出し
- queen(N,R) :-
- % 監視プロセス生成
- watchdog:distribution(Primary,Backup),
- % 次の述語へ引数を渡す
- queen_1({N,R},Primary,Backup) @ lower_priority(10).
- % プライマリとバックアップの主プロセスへのストリームを取り
- queen_1(Args,[PTop|Primary],[BTop|Backup]) :-
- % 引数を複製し、
- copy:copy(Args,Args1,Args2,Interrupt),
- % 割り込み線をマージし、
- Interrupt = {Interrupt1,Interrupt2}, Log = ack(Log1),
- % プライマリ、バックアップそれぞれへ
- % トップのゴールをフォークする
- PTop = {primary,queen,queen,Args1,Log,Signal,Interrupt1},
- BTop = {backup ,queen,queen,Args2,Log1,Signal,Interrupt2}.
2-2) トップゴールの呼び出し口を用意する。
呼び出し口は、モジュール exgoal に定義される。
上では、モジュール queen の述語 queen は、オリジナルのアリティが2
となっているので、以下の =-=-=-=- の間の2クローズが定義される。
- :- module exgoal.
-
- call_goal(Site,Module,Predicate,Args,Log,GSig,Raise)-SC :-
- call_goal_0(Site,Module,Predicate,Args,Log,GSig,Raise)-SC @ lower_priority.
- % =-=-=-=-
- call_goal_0(primary,queen,queen,{A,B},Log,GSig,Raise)-SC :-
- queen:queen_record(A,B,Log)+GSig+Raise-SC.
- call_goal_0(backup ,queen,queen,{A,B},Log,GSig,Raise)-SC :-
- queen:queen_replay(A,B,Log)+GSig+Raise-SC.
- % =-=-=-=-
- otherwise.
- call_goal_0(Type,Module,Method,Arguments,Log,GSignal,Raise)-SC :-
- klicio:klicio([stdout(normal(Out))]),
- variable:wrap((Type::Module:Method/Arguments), G),
- Out = [fwrite("Illegal goal invocation : "),
putwt(G), nl,fflush(_)],
- Raise = [].
2-3) 2-3 で定義した トップゴール に対応する述語を用意する。
(1) もとの述語に対して Instant Replay 変換する
- % Record Version
- queen_record(N,X,Log) :-
- current_node(_,All),
- queen_0_record(N,X,~(All-1),Log)@node(1).
-
- queen_0_record(4,X,A,Log) :- queen_record([1,2,3,4],[],[],X,A,Log).
- ....
-
- queen_record([P|U],C,L,I,PE,Log) :-
- Log = c1(Log1,Log2,Log3),
- TO:= (P mod PE)+1,
- throw_record(U,[P|C],L,I2,PE,TO,Log1),
- merge_record(I1,I2,I,Log2),
- append(U,C,N),
- c1_record(P,1,N,L,L,I1,PE,Log3).
-
- % Replay Version
- queen_replay(N,X,Log) :-
- current_node(_,All),
- queen_0_replay(N,X,~(All-1),Log)@node(1).
-
- queen_0_replay(4,X,A,Log) :- queen_replay([1,2,3,4],[],[],X,A,Log).
- ....
-
- queen_replay([P|U],C,L,I,PE,Log) :-
- Log = c1(Log1,Log2,Log3) |
- TO:= (P mod PE)+1,
- throw_replay(U,[P|C],L,I2,PE,TO,Log1),
- merge_replay(I1,I2,I,Log2),
- append(U,C,N),
- c1_replay(P,1,N,L,L,I1,PE,Log3).
(2) すべてのユーザ述語について引数を追加する
引数GSigは上位からの割り込み用であり、全ゴールにブロードキャストされる
ように、サブゴールにそのまま渡す。
引数Raiseはゴールからの割り出し用なので、サブゴールが複数あるような
場合には、mergeされるようにサブゴールのRaiseストリームから成る
ベクタをユニファイする。
サブゴールが一つだけなら、そのまま渡す。 サブゴールが存在しなければ、
[] とユニファイする。
引数組 SC は、ショートサーキットするだけのためなので、そのまま各ゴール
につけるだけである。
- % Record Version
- queen_record(N,X,Log)+GSig+Raise-SC :-
- current_node(_,All),
- queen_0_record(N,X,~(All-1),Log)+GSig+Raise-SC @node(1).
-
- queen_0_record(4,X,A,Log)+GSig+Raise-SC :-
- queen_record([1,2,3,4],[],[],X,A,Log)+GSig+Raise-SC.
- ....
-
- queen_record([P|U],C,L,I,PE,Log)+GSig+Raise-SC :-
- Raise = {Raise1,Raise2,Raise3,Raise4},
- Log = c1(Log1,Log2,Log3),
- TO:= (P mod PE)+1,
- throw_record(U,[P|C],L,I2,PE,TO,Log1)+GSig+Raise1-SC,
- merge_record(I1,I2,I,Log2)+GSig+Raise2-SC,
- append_record(U,C,N)+GSig+Raise3-SC,
- c1_record(P,1,N,L,L,I1,PE,Log3)+GSig+Raise4-SC.
(3) Record Versionでは、非決定的述語で Logのack待ち部分を挿入する
- queen_record([P|U],C,L,I,PE,ack(Log))+GSig+Raise-SC :-
- Raise = {Raise1,Raise2,Raise3,Raise4},
- Log = c1(Log1,Log2,Log3),
- TO:= (P mod PE)+1,
- throw_record(U,[P|C],L,I2,PE,TO,Log1)+GSig+Raise1-SC,
- merge_record(I1,I2,I,Log2)+GSig+Raise2-SC,
- append_record(U,C,N)+GSig+Raise3-SC,
- c1_record(P,1,N,L,L,I1,PE,Log3)+GSig+Raise4-SC.
- queen_record([],[_|_],_,I,ack(Log))+Sig+Raise-SC:-
- Raise=[],
- Log=c2(Ack),
- I=[].
(4) Record Version では、非決定的述語で ボディユニファイのところに
ack待ちを挿入する (出力コミット)
- queen_record([],[_|_],_,I,ack(Log))+Sig+Raise-SC:-
- Raise=[],
- Log=c2(Ack),
- output(Ack,I, [])-SC.
-
- output(Ack,X,Y)-SC :- wait(Ack) | X = Y.
(5) Replay Version では各述語の前に 割り込みチェック処理用の
クローズを挿入する
- % Replay Version
- queen_replay(A, B, Log)+GSig+Raise-SC :-
- (wait(Log) -> queen_replay_0(A, B, Log)+GSig+Raise-SC ;
- alternatively;
- GSig = [rebirth|GSig1] -> queen_record(A, B, _)+GSig1+Raise-SC).
- queen_replay_0(N,X,Log)+GSig+Raise-SC :-
- current_node(_,All),
- queen_0_replay(N,X,~(All-1),Log)+GSig+Raise-SC @node(1).
-
- queen_0_replay( 4,X,A,Log)+GSig+Raise-SC :-
- queen_replay([1,2,3,4],[],[],X,A,Log)+GSig+Raise-SC.
- ....
-
- queen_record([P|U],C,L,I,PE,Log)+GSig+Raise-SC :-
- Log = c1(Log1,Log2,Log3) |
- Raise = {Raise1,Raise2,Raise3,Raise4},
- TO:= (P mod PE)+1,
- throw_replay(U,[P|C],L,I2,PE,TO,Log1)+GSig+Raise1-SC,
- merge_replay(I1,I2,I,Log2)+GSig+Raise2-SC,
- append_replay(U,C,N)+GSig+Raise3-SC,
- c1_replay(P,1,N,L,L,I1,PE,Log3)+GSig+Raise4-SC.
- queen_replay([],[_|_],_,I,ack(Log))+Sig+Raise-SC:-
- Log=c2(Ack) |
- Raise=[],
- I=[].
(6) throw goal ('goal @ node(N)')は、すべて次のような割り出しに変える
- throw_record(A,B,C,D,E,F,Log)+GSig+Raise-SC :-
- Raise = [goal(primary,queen,queen,{A,B,C,D,E},Log)].
- throw_replay(A,B,C,D,E,F,Log)+GSig+Raise-SC :-
- Raise = [goal(primary,queen,queen,{A,B,C,D,E},Log)].
現在のバージョンでは、隣のノードへ勝手に投げるのでノード番号は
必要ない。
(7) throw goalするゴールに対応する入口を モジュールexgoalに追加する。
- call_goal_0(primary,queen,queen,{A,B,C,D,E},Log,GSig,Raise)-SC :-
- queen:queen_record(A,B,C,D,E,Log)+GSig+Raise-SC.
- call_goal_0(backup ,queen,queen,{A,B,C,D,E},Log,GSig,Raise)-SC :-
- queen:queen_replay(A,B,C,D,E,Log)+GSig+Raise-SC.
- ....
- otherwise.
- call_goal_0(Type,Module,Method,Arguments,Log,GSignal,Raise)-SC :-
- klicio:klicio([stdout(normal(Out))]),
- variable:wrap((Type::Module:Method/Arguments), G),
- Out = [fwrite("Illegal goal invocation : "),
putwt(G), nl,fflush(_)],
- Raise = [].
注)ft_queen.kl1 は、throw goalするゴールをc1に変え、
その他不必要な部分をオプティマイズしたものである。
[FTP]
www-admin@icot.or.jp