<?xml version="1.0" encoding="EUC-JP"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>rough justice</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/" />
    <link rel="self" type="application/atom+xml" href="http://www.esco-sb.jp/blog/roughjustice/atom.xml" />
   <id>tag:www.esco-sb.jp,2010:/blog/roughjustice//3</id>
    <link rel="service.post" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3" title="rough justice" />
    <updated>2008-06-30T04:40:04Z</updated>
    <subtitle>WEBアプリとかDBとか。</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type  3.2-ja-2</generator>
 
<entry>
    <title>10,000Hit御礼</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/06/10000hit.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=47" title="10,000Hit御礼" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.47</id>
    
    <published>2008-06-30T04:30:43Z</published>
    <updated>2008-06-30T04:40:04Z</updated>
    
    <summary>当ブログを立ち上げてから約2年半になりました。 おかげさまで今月10,000hi...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="others" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        当ブログを立ち上げてから約2年半になりました。
おかげさまで今月10,000hitを達成することができました。
この場を借りて御礼申し上げます。

元々当ブログは私の所属する組織の技術者及びパートナー企業の方々への
情報共有の場として設けたものですが、特に縛りを設けず広く公開
しているものです。

しかしながら上記の通り私、乃至は私を中心とするグループ間の情報共有を
達成することのみが目的であるため、広くご利用されることを想定して
コンテンツを作成・メンテナンスしておりません。

特に私事ですが最近開発現場を離れたことにより、記事が開発よりのものから
運用よりの内容へ変わってきております。
過去の記事、特にjava、struts、tomcatの情報は記事を書いた時点
（だいたい2年前）のものであり、現在から見ると古い情報となっております。
当然それらweb技術というものは確実に革新しており、またセキュリティホール等
不具合についても常に修正され続けております。

本ブログを閲覧される方はこれらリスクを踏まえてくださいますよう
お願いいたします。
*立さんやN*Tさん等、頻繁にご利用いただいていて感謝しておりますが、
技術者として当記事のみを鵜呑みにされることが無きようご注意くださいませ。
        
    </content>
</entry>
<entry>
    <title>Subversion/trac　プロジェクト作成</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/05/subversiontrac.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=46" title="Subversion/trac　プロジェクト作成" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.46</id>
    
    <published>2008-05-30T03:35:24Z</published>
    <updated>2008-05-30T03:36:06Z</updated>
    
    <summary> コピペ企画その２。 Subversion プロジェクトの作成方法 １．svna...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="others" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[コピペ企画その２。

<strong>Subversion プロジェクトの作成方法</strong>

１．svnadminコマンドでプロジェクト作成
# svnadmin create /var/svn/<font color="red">test_project</font>

２．アクセス権を変更して、httpd実行ユーザーからアクセス可能にする
# chown -R apache:apache /var/svn/<font color="red">test_project</font>

以降の操作は、subclipse/tortoisSVNからやった方が楽。（trunk/tags/branchesの作成も含めて）

<strong>TRAC プロジェクトの作成方法</strong>

１．trac-adminコマンドでプロジェクト作成
# trac-admin /var/trac/<font color="red">test_project</font> initenv

<blockquote>
Trac will first ask a few questions about your environment
in order to initalize and prepare the project database.

 Please enter the name of your project.
 This name will be used in page titles and descriptions.

Project Name [My Project]><font color="red">プロジェクト名を入力</font>
※上記までのプロジェクト名を略称とすれば、ここだけは正式名称
（例：initenvのプロジェクト名→「test_project」　Project Nameのプロジェクト名→「Test Project System」

 &nbsp;Please specify the connection string for the database to use.
 &nbsp;By default, a local SQLite database is created in the environment
 &nbsp;directory. It is also possible to use an already existing
 &nbsp;PostgreSQL database (check the Trac documentation for the exact
 &nbsp;connection string syntax).

Database connection string [sqlite:db/trac.db]><font color="red">Enterキーを入力</font>

Please specify the type of version control system,
By default, it will be svn.

If you don't want to use Trac with version control integration,
choose the default here and don't specify a repository directory.
in the next question.

Repository type [svn]><font color="red">svn</font>

Please specify the absolute path to the version control
repository, or leave it blank to use Trac without a repository.
You can also set the repository location later.

Path to repository [/path/to/repos]><font color="red">/var/svn/test_project</font>

Please enter location of Trac page templates.
Default is the location of the site-wide templates installed with Trac.

Templates directory [/opt/trac/share/trac/templates]><font color="red">Enterキーを入力</font>
</blockquote>

２．作成プロジェクトのアクセス権変更
# chown -R apache:apache /var/trac/test_project

３．リポジトリ文字コードをSJISに設定 + メール通知機能設定
vi /var/trac/<font color="red">test_project</font>/conf/trac.ini
<blockquote>
[trac]
default_charset = iso-8859-15
↓
default_charset = <font color="red">japanese.shift_jis </font>

[notification]
always_notify_owner = <font color="red">true</font>
always_notify_reporter = false
always_notify_updater = <font color="red">true</font>
mime_encoding = base64
smtp_always_bcc =
smtp_always_cc =
smtp_default_domain = <font color="red">メールドメイン（@抜き）</font>
smtp_enabled = <font color="red">true</font>
smtp_from = <font color="red">fromアドレス</font>
smtp_password =
smtp_port = 25
smtp_replyto = <font color="red">リプライアドレス</font>
smtp_server = localhost
smtp_subject_prefix = __default__
smtp_user =
use_public_cc = false
use_short_addr = false
use_tls = false
</blockquote>

httpdの再起動は不要

４．このサイトの管理者を設定
# trac-admin /var/trac/<font color="red">test_project</font> permission list <font color="red">sugi1149</font>

管理者にさせたいユーザーに、TRAC_ADMIN権限がなかったら追加。

# trac-admin /var/trac/<font color="red">test_project</font> permission add <font color="red">sugi1149</font> TRAC_ADMIN

もう一度
# trac-admin /var/trac/<font color="red">test_project</font> permission list <font color="red">sugi1149</font>
で、TRAC_ADMIN権限が付与されたことを確認

５．このサイトでのWebAdminプラグイン利用設定
vi /var/trac/<font color="red">test_project</font>/conf/trac.ini
<blockquote>
[components]
webadmin.* = enabled
</blockquote>
※末尾に追加する

６．resolution属性日本語化
# mkdir /opt/trac/sql
# cd /opt/trac/sql

# vi resolution.sql
<blockquote>
UPDATE enum SET name = '完了' where type = 'resolution' AND value = 1;
UPDATE enum SET name = 'チケットが誤り' where type = 'resolution' AND value = 2;
UPDATE enum SET name = '修正しない' where type = 'resolution' AND value = 3;
UPDATE enum SET name = '他のチケットと重複' where type = 'resolution' AND value = 4;
UPDATE enum SET name = '内容が再現できない' where type = 'resolution' AND value = 5;
</blockquote>

# sqlite3 /var/trac/<font color="red">test_project</font>/db/trac.db < resolution.sql

※その他日本語化はwebadminで。

７．httpd 再起動
# service httpd restart

これで、サイト管理者はログインするとWebAdminツールが使えるようになる。]]>
        
    </content>
</entry>
<entry>
    <title>CentOS5.1にSubversionとtracをインストール</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/05/centos51subversiontrac.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=45" title="CentOS5.1にSubversionとtracをインストール" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.45</id>
    
    <published>2008-05-27T10:05:45Z</published>
    <updated>2008-05-27T10:05:36Z</updated>
    
    <summary>ネタが無いので、自分のマシンの中から過去に作った資料を引っ張り出してコピペ。 n...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="others" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[ネタが無いので、自分のマシンの中から過去に作った資料を引っ張り出してコピペ。
<em>numeriサルベージ方式</em>

１．yumで必要なパッケージをインストール
 yum install httpd subversion mod_dav_svn mod_python mod_ssl

２．tracは別リポジトリからインストール
 # wget http://dag.wieers.com/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.i386.rpm
 # rpm -Uhv rpmforge-release-0.3.6-1.el5.rf.i386.rpm

 無用の混乱を避けるため、デフォルトでは有効にならないように設定ファイルを修正する

# vi /etc/yum.repos.d/rpmforge.repo
<blockquote>
enabled = 1
&nbsp;&nbsp;&nbsp;↓
enabled = 0&nbsp;&nbsp;&nbsp;←デフォルトでは有効にしない
</blockquote>

 RPM の署名を検証するためのキーを導入
 wget http://dag.wieers.com/packages/RPM-GPG-KEY.dag.txt
 rpm --import RPM-GPG-KEY.dag.txt
 yum --enablerepo=rpmforge install trac

３．Subversionの設定
 /etc/httpd/conf.d/subversion.conf
<blockquote>
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

&lt;Location /svn&gt;
 DAV svn
 SVNParentPath /var/svn

 AuthType Basic
 AuthName &quot;Authorization Realm&quot;
 AuthUserFile /etc/httpd/dav_trac_svn.passwd
 Require valid-user
&lt;/Location&gt;
</blockquote>

 /etc/httpd/conf.d/trac.conf
<blockquote>
&lt;Location /trac&gt;
 SetHandler mod_python
 PythonDebug On
 PythonHandler trac.web.modpython_frontend
 PythonOption TracEnvParentDir /var/trac
 PythonOption TracUriRoot /trac
 SetEnv PYTHON_EGG_CACHE /var/trac/.python-eggs
&lt;/Location&gt;

# authentication    : only login
&lt;LocationMatch &quot;^/trac/[^/]+/login&quot;&gt;
 AuthType Basic
 AuthName &quot;trac&quot;
 AuthUserFile /etc/httpd/dav_trac_svn.passwd
 Require valid-user
&lt;/LocationMatch&gt;
</blockquote>

４．Subversion、trac共通ユーザーアカウント作成
 # htpasswd -mc /etc/httpd/dav_trac_svn.passwd sugi1149

 「c」オプションはファイル作成のため。2人目以降は「-m」のみでOK

５．Subversion、trac のためのディレクトリ作成
 # mkdir /var/svn
 # chown -R apache:apache /var/svn
 # mkdir /var/trac
 # chown -R apache:apache /var/trac

６．日本語化のために一旦tracをアンインストール
 # yum -y remove trac

７．日本語版tracを展開
 # cp trac-0.10.4-ja-1.zip /tmp
 # cd /tmp
 # unzip trac-0.10.4-ja-1.zip
 # cd trac-0.10.4-ja-1
 # mkdir /opt/trac
 # python ./setup.py install --prefix=/opt/trac/

８．シンボリックリンクをはる
 # ln -s /opt/trac/bin/trac-admin /usr/bin/trac-admin
 # ln -s /opt/trac/bin/tracd /usr/bin/tracd
 # ln -s /opt/trac/lib/python2.4/site-packages/trac /usr/lib/python2.4/site-packages/trac
 # ln -s /opt/trac/share/man/man1/trac-admin.1 /usr/share/man/man1/trac-admin.1
 # ln -s /opt/trac/share/man/man1/tracd.1 /usr/share/man/man1/tracd.1
 # ln -s /opt/trac/share/trac /usr/share/trac

９．tracプラグイン利用の準備
 ez_setup.pyをインストール
 # cp ez_setup.py /tmp
 # cd /tmp
 # python ez_setup.py

１０．trac WebAdminプラグインのインストール
# cp TracWebAdmin-0.1.2dev_r4240-py2.4.egg /tmp
# cd /tmp
# easy_install TracWebAdmin-0.1.2dev_r4240-py2.4.egg

１１．httpd 起動
 # chkconfig httpd on
 # service httpd restart]]>
        
    </content>
</entry>
<entry>
    <title>基本スタンバイ・データベースを構築する＜その２　スタンバイサイト＞</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/04/post_6.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=44" title="基本スタンバイ・データベースを構築する＜その２　スタンバイサイト＞" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.44</id>
    
    <published>2008-04-25T00:11:21Z</published>
    <updated>2008-04-25T00:20:22Z</updated>
    
    <summary> ＜スタンバイサイト＞ まずはコールドバックアップした、 ・データファイル ・R...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="oracle" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[＜スタンバイサイト＞
まずはコールドバックアップした、
・データファイル
・REDOログファイル
・アーカイブログファイル
・パスワードファイル
を確認しましょう。

プライマリサイトで格納されていたディレクトリが、
スタンバイサイトでも「<font color="red"><b>完全に</b></font>」再現されるように
配置します。

スタンバイ用に作成した制御ファイルは、
プライマリでの制御ファイル配置ディレクトリと
同じ場所にでも置いておきましょう。
（異なっていてもかまいませんが）

プライマリで制御ファイルを多重化していた場合、
スタンバイサイトでもコピーして同数と
なるようにしましょう。

次に転送した初期化パラメータファイルです。
制御ファイルの配置ディレクトリ・名前を
変更していなければ特に変える必要は
ありません。
変更している場合は、パラメータファイルを
スタンバイ環境に合わせて修正しましょう。

<blockquote>
control_files = (
<font color="blue">E:\ORADATA\HOGEDB\CONTROL01.CTL,
E:\ORADATA\HOGEDB\CONTROL02.CTL,
E:\ORADATA\HOGEDB\CONTROL03.CTL</font>
)
</blockquote>

oradimコマンドでスタンバイデータベース用の
サービスを作成します。

<blockquote>
D:\> oradim -new -sid HOGEDB -startmode manual -srvcstart system
インスタンスが作成されました。
</blockquote>

コンピュータの再起動時に、インスタンスのみ開始されて
データベースが自動オープンしないようにします。

他、ORACLE_HOMEやORACLE_SIDの環境変数も
セットしておきましょう。

ではサービスを開始して、インスタンスを開始した後、
スタンバイ・データベースにnomountで接続しましょう。

<blockquote>
SQL> conn sys/パスワード as sysdba
アイドル・インスタンスに接続しました。

SQL> startup nomount pfile='転送したパラメータファイルのフルパス'
ORACLEインスタンスが起動しました。
･･･
･･･
</blockquote>

最後にスタンバイ・モードでマウントします。

<blockquote>
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
データベースが変更されました。
</blockquote>

これでスタンバイ環境の準備ができました。
早速プライマリサイトから転送したアーカイブ・ログファイルを
適用してみましょう。

<blockquote>
SQL> set autorecovery on
SQL> recover standby database;
</blockquote>

SQL Plusに対してautorecovery onを指定すると、
必要なアーカイブ・ログファイルを問い合わせ無しに
自動で適用します。

以後、プライマリサイトで作成されるアーカイブログは
全てスタンバイサイトへ転送し、上記のように
適用する必要があります。

<font color="red"><b>一つでもアーカイブログを消失してしまうと、
スタンバイサイトは意味がなくなってしまいます。</b></font>
（以降のログが適用できなくなり、データは
古いままとなります）

プライマリサイトでSPFILE運用をしていた場合、
スタンバイサイトでも揃えておいた方がよさそうですね。

<blockquote>
SQL> CREATE SPFILE='D:\***\spfile***.ora' FROM PFILE;
</blockquote>

サーバー再起動の際は、上記サービスの設定により、
インスタンス：開始　データベース：停止
の状態になります。

SPFILE運用であれば、
<blockquote>
SQL> conn sys/パスワード as sysdba
SQL> startup nomount
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
</blockquote>
のようにして、スタンバイ・データベースをマウントします。

スタンバイサイトはずっとマウント状態のまま運用します。

プライマリサイトが障害により使用不可となった場合、
スタンバイサイトをプライマリとして昇格させ、
読み書きができるようにします（アクティブ化）。

<blockquote>
SQL> ALTER DATABASE ACTIVATE STANDBY DATABASE;
SQL> shutdown immediate
SQL> startup
</blockquote>

一度アクティブにすると、スタンバイには戻せなくなります。

後はクライアントアプリケーション側の接続先を
全て昇格されたサーバーになるように設定すれば
完了です。
事前に手順をキチっと定めておかないと、
いざ障害発生という時に手違い/漏れが出ちゃいそうですね。
]]>
        
    </content>
</entry>
<entry>
    <title>基本スタンバイ・データベースを構築する＜その１　プライマリサイト＞</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/04/post_5.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=43" title="基本スタンバイ・データベースを構築する＜その１　プライマリサイト＞" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.43</id>
    
    <published>2008-04-23T00:09:00Z</published>
    <updated>2008-04-23T00:22:58Z</updated>
    
    <summary> 基本スタンバイ〜にはいくつか前提条件があります。 ・スタンバイサイトのOrac...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="oracle" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[基本スタンバイ〜にはいくつか前提条件があります。

・スタンバイサイトのOracle Databaseは、プライマリサイトと
　同バージョン、同エディションであること。
　（パッチの適用状態も同じであること）
・OSについてもスタンバイ−プライマリ双方で
　同バージョン、同パッチ適用であること
・データベースはアーカイブ・ログモードであること
・スタンバイサイトのディスクは、プライマリサイトの
　データファイル・REDOログファイル等を全て同ディレクトリ階層で
　コピーできる容量があること。

今回試した環境は

プライマリ機：
Windows 2000 Server SP4
Oracle Database Standard Edition 10.2.0.2.0
データベース作成済み（アーカイブ・ログモード）
アーカイブ・ログファイルの出力先はフラッシュ・リカバリ領域

スタンバイ機：
Windows 2000 Server SP4
Oracle Database Standard Edition 10.2.0.2.0

です。

以降全てSYSユーザーにて作業していると
ご理解ください。

＜プライマリサイト＞
最初にオンラインREDOログに残っているトランザクションを
アーカイブログに吐き出しておきましょう。

<blockquote>
SQL> ALTER SYSTEM SWITCH LOGFILE;
システムが変更されました。
</blockquote>

ログをスイッチすれば、カレントだったREDOログが
アーカイブされます。

次にスタンバイサイト用の制御ファイルを作成します。

<blockquote>
SQL> ALTER DATABASE CREATE STANDBY CONTROLFILE AS 'D:\****.CTL';
データベースが変更されました。

SQL> ALTER SYSTEM SWITCH LOGFILE;
システムが変更されました。
</blockquote>

スタンバイ用の制御ファイルは必ず上記コマンドで
作成する必要があります。
<font color="red"><b>プライマリサイトで使用している制御ファイルを
スタンバイへ持っていっても使えません</b></font>のでお間違えなく。
ALTER DATABASE CREATE･･･文の「AS」以降で作成する
ファイルをフルパスで指定します。
場所はどこでもかまいません。
名前も何でもかまいません。（一般にはプライマリサイトの
制御ファイルとの混同・誤操作を避けるために、
プライマリとは別の名前を付けることを推奨されています）

スタンバイ用の制御ファイルを作成したら、念のため
もう一度ログスイッチをしておきます。

作成したスタンバイ用制御ファイルは、スタンバイ機へ
転送しておきましょう。後で使います。

次にデータベースをシャットダウンして、コールドバックアップ
をスタンバイサイトへ転送します。

<blockquote>
SQL> shutdown immediate
データベースがクローズされました。
･･･
･･･
</blockquote>

スタンバイサイトへ転送するのは
・データファイル
・REDOログファイル
・アーカイブログファイル
・パスワードファイル
です。

制御ファイルは先にスタンバイ用に作成したものを
使いますので、プライマリデータベースのものは
転送しません。

転送し終わったら、プライマリデータベースは
起動しておきましょう。

<blockquote>
SQL> startup
※（SPFILE運用の場合）
</blockquote>

また、プライマリのデータベースがSPFILE運用
である場合、テキストベースの初期化パラメータ
ファイルを作成して転送しておきましょう。

<blockquote>
SQL> CREATE PFILE='D:\init***.ORA' from spfile;
</blockquote>

テキストベースの初期化パラメータファイルを
使用していた場合はそれを転送します。

長くなったので今回はここまで。]]>
        
    </content>
</entry>
<entry>
    <title>基本スタンバイ・データベースを考える</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/04/post_4.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=42" title="基本スタンバイ・データベースを考える" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.42</id>
    
    <published>2008-04-22T06:31:06Z</published>
    <updated>2008-04-22T06:33:00Z</updated>
    
    <summary> 今回はOracle 基本スタンバイ・データベースについて 書いてみようと思いま...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="oracle" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        今回はOracle 基本スタンバイ・データベースについて
書いてみようと思います。
当機能はいわゆる「ディザスタリカバリ」「HA構成」の
範疇に入るもので、高可用性を提供します。

Oracleが提供する高可用性製品（機能）としては
Data Guardが有名ですが、今回これは取り上げません。
また、Data GuardはOracleサポート製品（機能）ですが、
基本スタンバイ〜は･･･？です。
あくまでData Guard導入前の検証用くらいに
捉えたほうが無難です。

基本スタンバイ〜も、Data Guardも基本的な
考え方は同じです。

本番データベースをプライマリサイトと位置付け、
別途データベースサーバーを用意し、スタンバイサイト
として設定します。
プライマリサイトで作成するアーカイブログファイルを
スタンバイサイトに転送し、同ファイルをスタンバイ
のデータベースに適用することにより、両サイトの
データ内容が同期されます。
（ということは、データベースはアーカイブログ・
モードである必要があります）
プライマリサイトに障害が発生した場合は、
スタンバイサイトをプライマリサイトに昇格させて、
以後本番データベースとして扱うわけです。
（フェイルオーバー）

基本スタンバイ〜とData Guardの違いは
大雑把にいうと以下の通り。

・プライマリからスタンバイへアーカイブログ転送
　Data Guardは自動、基本スタンバイ〜は手動
・スタンバイデータベースへのアーカイブログ適用
　Data Guardは自動、基本スタンバイ〜は手動
・障害発生時の自動フェイルオーバー
　Data Guardはあり（10gR2より）、基本スタンバイ〜は手動

と、まぁ、基本スタンバイ〜はなんでも人の手を
介する必要があるってことです。
手間を考えればスクリプトを自作することになるでしょう。

ちなみにData GuardはEnterprise Editionのオプション製品
であり、Databaseとは別にライセンスが必要となります。
プライマリ・スタンバイ双方にライセンスが必要と
なりますから、Data Guardでの最小構成では、

Database Enterprise Edition * 2 + Data Guard * 2

のライセンスが必要ということですね。
年間サポート料金もDatabaseとData Guardは別です。

対して基本スタンバイ〜は、Standard Editionから
利用できます。オプション機能ではないのでStdが
2台あれば構成できます。

ただし繰り返しますが、サポートの面を考えると
Data Guardの方が絶対に安心して使えます。

長くなりそうなので記事を分けます。
        
    </content>
</entry>
<entry>
    <title>Oracle Textで全文検索</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/04/oracle_text.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=41" title="Oracle Textで全文検索" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.41</id>
    
    <published>2008-04-16T03:37:11Z</published>
    <updated>2008-04-16T03:48:55Z</updated>
    
    <summary> 以前PostgreSQLにおけるTsearch2を利用した全文検索を 試してみ...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="oracle" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[以前PostgreSQLにおけるTsearch2を利用した全文検索を
試してみました。
<a href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/03/tsearch2.php">Tsearch2で全文検索</a>

今回はOracleの「Oracle Text」機能を試してみたいと思います。
ちなみにOracle 10gの「Oracle Text」はdbcaを使用した場合、
標準インストールされる機能です。
（Ora8ではConText、8iではinterMedia Textという名称で
オプション機能でした）

OracleVer：10.2.0.2
DBキャラクタセット：JA16SJISTILDE

dbcaでデータベースを作成した場合、「CTXSYS」ユーザーが
作成されているはずです。（DBA_USERS表で確認しましょう）

Oracle Textが有効であるかも確認してみましょう。

<blockquote>
SQL> conn SYS/パスワード
SQL> SELECT COMP_NAME,STATUS,substr(VERSION,1,10) AS VER 
&nbsp;&nbsp;2 FROM DBA_REGISTRY 
&nbsp;&nbsp;3 WHERE COMP_ID = 'CONTEXT';

COMP_NAME    STATUS VER
------------ ------ -----------
Oracle Text  VALID  10.2.0.2.0


SQL>SELECT OBJECT_TYPE,OBJECT_NAME,STATUS 
&nbsp;&nbsp;2 FROM DBA_OBJECTS 
&nbsp;&nbsp;3 WHERE OWNER='CTXSYS' AND STATUS != 'VALID'
&nbsp;&nbsp;4 ORDER BY OBJECT_TYPE,OBJECT_NAME;

レコードが選択されませんでした。
</blockquote>

索引付けを行なう際の言語を、プリファレンスとして
作成します。プリファレンス名とレクサー（トークンを生成するアルゴリズム）を
引数に「ctx_ddl.create_preference」プロシージャを実行します。


<blockquote>
SQL> conn ユーザー名/パスワード
SQL> execute ctx_ddl.create_preference('hoge_lexer', 'JAPANESE_LEXER');
</blockquote>

「hoge_lexer」がプリファレンス名で、「JAPANESE_LEXER」が
指定する日本語レクサーです。
実行するユーザーには「CTXAPP」ロール権限が必要です。
権限が無い場合は付与してCTXSYSユーザーから付与して
あげましょう。

では検索用のテーブルを作成してみましょう。 

<blockquote>
SQL> CREATE TABLE TBL (
&nbsp;&nbsp;2 KEY NUMBER(2) PRIMARY KEY,
&nbsp;&nbsp;3 ORIGTEXT VARCHAR2(100)
&nbsp;&nbsp;4 );
</blockquote>

Tsearch2と違い、Oracle Textでは分かち書きして
トークンを作成してくれるので、分かち書き用（インデックス用）の
列は不要です。

データをINSERTします。

<blockquote>
INSERT INTO TBL VALUES(1,
'ルウム戦役で５隻の戦艦がシャア一人の為に撃破された…に、逃げろーッ！');
INSERT INTO TBL VALUES(2,
'このタイミングで戦闘を仕掛けたと言う事実は、古今例が無い。');
INSERT INTO TBL VALUES(3,
'そのために私のような女を大佐は拾って下さったんでしょう？');
INSERT INTO TBL VALUES(4,
'赤い色のＭＳ！シャアじゃないのか？');
INSERT INTO TBL VALUES(5,
'一年戦争開戦初期、1 月 15 日からサイド 5 (ルウム) にて行われた一大艦隊戦役'); 
INSERT INTO TBL VALUES(6,
'ｼｬｱが、MSに乗って輝いていたのは１stだけ。ms乗りとしては･･･'); 
COMMIT;
</blockquote>

索引を作ります。
INDEXTYPEに「CTXSYS.CONTEXT」を指定してテキスト索引であることを明示します。
PARAMETERSには、先に作成したプリファレンス名を指定します。

<blockquote>
CREATE INDEX WAKACHI_INDEX ON TBL(ORIGTEXT)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS('lexer hoge_lexer');
</blockquote>

お･･･。ちょい時間かかるな。

作成できたら実際に検索する前に、作成されたトークンを確認
してみましょう。
これは「DR$<インデックス名>$I」という索引表で確認できます。

<blockquote>
SQL> SELECT TOKEN_TEXT FROM DR$WAKACHI_INDEX$I ORDER BY TOKEN_TEXT;

TOKEN_TEXT
---------------------------
1
15
1ST
5
MS
(略)
サイド
シャア
シャア
タイミング
(略)
赤い
戦艦
戦争
(略)

79行が選択されました。
</blockquote>

よさげですね。

では実際に検索してみましょう。

<blockquote>
SQL> SELECT * FROM TBL WHERE CONTAINS(ORIGTEXT, 'シャア')>0;

KEY ORIGTEXT
--- ------------------------
&nbsp;&nbsp;1 ルウム戦役で５隻の戦艦がシャア一人の為に撃破された…に、逃げろーッ！
&nbsp;&nbsp;4 赤い色のＭＳ！シャアじゃないのか？
&nbsp;&nbsp;6 ｼｬｱが、MSに乗って輝いていたのは１stだけ。ms乗りとしては･･･
</blockquote>

「シャア」を含むKey「1」「4」「6」が検索されました。
ここで注目したいのは、半角カナ「ｼｬｱ」で登録したKey「6」も、
全角カナ「シャア」での検索にヒットすることです。
Oracleが「ゆれ」も解決してくれているわけですね。かしこい！

これはデータに全角/半角、大文字/小文字それぞれで登録した
「MS」（「ＭＳ」「ms」）についても同じことが言えます。
試してみてください。

また、Tsearch2で問題となった、トークンが分けられている複数の
単語を連結して検索する動作はどうなるのでしょう。
「ルウム戦役」というキーワードは「ルウム」と「戦役」に
分かち書きされるので、Tsearch2では「ルウム戦役」という
検索は工夫しないとできませんでした。

<blockquote>
SQL> SELECT * FROM TBL WHERE CONTAINS(ORIGTEXT, 'ルウム戦役')>0;

KEY ORIGTEXT
--- ------------------------
&nbsp;&nbsp;1 ルウム戦役で５隻の戦艦がシャア一人の為に撃破された…に、逃げろーッ！
</blockquote>

すごい！ Oracleかしこい！ さすが商用RDBMS！

なお、一度索引を作成した場合、その後テキスト検索対象列に
追加/更新/削除が発生しても、トークンは同期されません。

<blockquote>
SQL> INSERT INTO TBL VALUES(7,
&nbsp;&nbsp;2 '私は父ジオン・ズム・ダイクンの元に召されるであろう！！！'); 
SQL> COMMIT;

SQL> SELECT * FROM TBL WHERE CONTAINS(ORIGTEXT, 'ジオン')>0;
レコードが選択されませんでした。
</blockquote>

トークンを同期させるには
１．ctx_ddl.sync_indexプロシージャを実行
２．索引をREBUILD
する必要があります。

<blockquote>
SQL> execute ctx_ddl.sync_index('WAKACHI_INDEX');
PL/SQLプロシージャが正常に完了しました。

SQL> SELECT * FROM TBL WHERE CONTAINS(ORIGTEXT, 'ジオン')>0;

KEY ORIGTEXT
--- ------------------------
&nbsp;&nbsp;7 私は父ジオン・ズム・ダイクンの元に召されるであろう！！！
</blockquote>

他にCREATE INDEX文のオプションとして、「EVERY<interval-string>」
「ON COMMIT」を指定することにより自動同期化も可能なようですが、
トークンの作成はコストが高い処理なので、業務時間中の実行には
注意が要りそうですね。
（夜間バッチがベターかな？）]]>
        
    </content>
</entry>
<entry>
    <title>Winbind で完全に Samba と Active Directory を統合</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/03/winbind_samba_active_directory.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=40" title="Winbind で完全に Samba と Active Directory を統合" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.40</id>
    
    <published>2008-03-24T03:56:01Z</published>
    <updated>2008-03-27T01:57:22Z</updated>
    
    <summary> 先日、Sambaの認証をActive Directoryと統合しましたが、 今...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="others" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[先日、Sambaの認証をActive Directoryと統合しましたが、
今回はもう一歩先へ踏み込んでみたいと思います。

前回までの環境の場合、２つ問題点が残ります。

１．せっかくADと統合したのに、Samba機に対して
&nbsp;&nbsp;&nbsp;&nbsp;ADユーザーと同名のOSユーザーを作成しなければならない。

２．認証はADでも、ファイル・ディレクトリのアクセス権の制御は
&nbsp;&nbsp;&nbsp;&nbsp;Linuxユーザー・グループでおこなわれてしまう。


Windows機から作成したディレクトリのアクセス権を参照したところ。
<a href="http://www.esco-sb.jp/blog/roughjustice/images/20080319/1.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20080319/1.php','popup','width=425,height=416,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20080319/1-thumb.JPG" width="200" height="195" alt="" /></a>


なので今回は上２つを解消するのが目的です。
具体的にはユーザー・グループの情報もDCから頂いて、
Samba上での動作も全て一本化することです。

まず smb.conf に、Winbind認証のための設定をおこないます。
（前回設定部分の表記は省略）

/etc/samba/smb.conf
<blockquote>
allow trusted domains = no
idmap backend = rid:TEST-KEIRI-PDC=10000-50000
idmap uid = 10000-50000
idmap gid = 10000-50000
winbind cache time = 15
winbind separator = @
winbind use default domain = yes
template homedir = /home/%U
template shell = /bin/false
encrypt passwords = yes
obey pam restrictions = yes
</blockquote>


LinuxがWinbindを経由してActive Directoryから
アカウント情報（ユーザー・グループ）を
取得できるよう、nsswitch.conf を修正します。

/etc/nsswitch.conf
<blockquote>
passwd: files winbind #修正
shadow: files winbind #修正
group: files winbind #修正
</blockquote>


ユーザーにホームディレクトリを使用させる場合、
アクセス時に/home下にディレクトリが存在しなかったら、
自動で作成されるよう、system-auth を設定します。
ホームディレクトリを使用しない場合この設定は不要です。
（smb.confから[homes]の設定もとっぱらっちゃいましょう）

/etc/pam.d/system-auth
<blockquote>
session&nbsp;&nbsp;&nbsp;&nbsp;required&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pam_mkhomedir.so skel=/etc/skel umask=0022
</blockquote>


Winbindを起動します。自動起動の設定もしておきましょう。
sambaも再起動しておきましょう。
<blockquote>
# service winbind start（Enterキー）
# service winbind status（Enterキー）
winbind (pid xxxxx xxxxx) is running...
# chkconfig winbind on
# service smb restart
</blockquote>

設定は以上です。

まず、winbindが正常に動作しているか確認しましょう。
<blockquote>
wbinfo -t（Enterキー）
checking the trust secret via RPC calls succeeded
</blockquote>

では、ADに登録されているユーザーを取得できるか
確認してみましょう。
<blockquote>
# wbinfo -u（Enterキー）
administrator
guest
･･･
･･･
･･･
sugi1149
･･･
･･･
･･･
</blockquote>
ずらずらっと、ADのユーザーが表示されればOKです。

同様にグループも取得できるか確認してみましょう。
<blockquote>
# wbinfo -g（Enterキー）
domain computers
domain controlers
schema admins
･･･
･･･
domain admins
domain users
･･･
･･･
</blockquote>

ユーザーsugi1149が所属しているグループを確認してみましょう。
<blockquote>
# id sugi1149
uid=11108(sugi1149) gid=10513(domain users) 所属グループ=10513(domain users),14112(jyosys2)
</blockquote>

よさげですね。
Windowsからアクセスしてみると･･･お、入れましたね。
Linux側では一切 useradd コマンドが不要になったわけです。

試しにWindowsからファイルを1個こさえてプロパティを見てみると･･･
<a href="http://www.esco-sb.jp/blog/roughjustice/images/20080319/2.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20080319/2.php','popup','width=425,height=466,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20080319/2-thumb.JPG" width="200" height="219" alt="" /></a>


Linux端末からこのファイルを見てみると･･･
<blockquote>
# ls test_dir
合計 0
-rwxr--r-- 1 sugi1149 domain users 0&nbsp;&nbsp;3月&nbsp;&nbsp;19&nbsp;&nbsp;14:51&nbsp;&nbsp;新規テキスト ドキュメント.txt
</blockquote>]]>
        3月19日のエントリで作成した、Linuxユーザー「sugi1149」は、
本稿の前に削除してあるものとします。
    </content>
</entry>
<entry>
    <title>Samba3.0 を Active Directoryドメイン に参加させる</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2008/03/samba30_active_directory.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=39" title="Samba3.0 を Active Directoryドメイン に参加させる" />
    <id>tag:www.esco-sb.jp,2008:/blog/roughjustice//3.39</id>
    
    <published>2008-03-19T02:47:50Z</published>
    <updated>2009-02-04T02:58:36Z</updated>
    
    <summary> 今回はLinuxにインストールされているSamba3.0を、 既存Active...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="others" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[今回はLinuxにインストールされているSamba3.0を、
既存Active Directoryドメインのメンバにする検証です。
Sambaが既存ADドメインに参加することにより、
Sambaサーバーへの認証をADと一本化するのが狙いです。
つまりADドメインに参加できるユーザーは、自動的に
Sambaにアクセスできる、ということですね。

＜Linux側＞
OS:CentOS5.1
Samba：3.0.28-1（ディストリ同梱 + yumでアップデート）
FQDN:sugi1149-li-01.test.co.jp

＜ActiveDirectory＞
ドメイン名：test.co.jp
ドメインNetBIOS名：TEST-KEIRI-PDC
タイプ：Windows2000ネィティブ
DC機FQDN：test-keiri.test.co.jp
DC機OS：Windows 2000 Server

事前準備といたしましては、色々名前解決が必要になってきますので、
Linux機のリゾルバを、DC機と同じDNSサーバーを指定するようにしておきます。

resolv.conf
<blockquote>
search test.co.jp
namaserver 172.16.1.1
</blockquote>

また、ADではKerberos認証が機能するため、クライアント（Linux機）と
サーバー（DC機）の時刻が同期している必要があります。
ま、NTPでよろ。


次、Kerberos認証のために /etc/krb5.conf を編集します。

/etc/krb5.conf
<blockquote>
（略）
[libdefaults]
default_realm = TEST.CO.JP #変更

（略）

[realms]
#追加
TEST.CO.JP = {
&nbsp;&nbsp;&nbsp;&nbsp;kdc = test-keiri.test.co.jp
}
#他のはコメントアウト
（略）

[domain_realm]
#追加
.test.co.jp = TEST.CO.JP
test.co.jp = TEST.CO.JP
#他のはコメントアウト
（略）
</blockquote>

Kereros Realm名（ADドメイン名）は必ず大文字でなければなりません。
DC名は小文字。FQDNで。
[domain_realm]のとこが、ADドメイン名とKereros Realm名の
マッピング箇所となります。
ここもKereros Realm名は大文字です。


次、/etc/samba/smb.conf を編集します。

/etc/samba/smb.conf
<blockquote>
[global]
&nbsp;&nbsp;&nbsp;&nbsp;workgroup = TEST-KEIRI-PDC
&nbsp;&nbsp;&nbsp;&nbsp;dos charset = CP932
&nbsp;&nbsp;&nbsp;&nbsp;unix charset = UTF-8
&nbsp;&nbsp;&nbsp;&nbsp;display charset = UTF-8
&nbsp;&nbsp;&nbsp;&nbsp;socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
&nbsp;&nbsp;&nbsp;&nbsp;veto files = /lost+found/aquota.group/.bash*/.canna/.gtkrc/.ssh/
&nbsp;&nbsp;&nbsp;&nbsp;hide files = /lost+found/aquota.group/.bash*/.canna/.gtkrc/.ssh/
&nbsp;&nbsp;&nbsp;&nbsp;realm = TEST.CO.JP
&nbsp;&nbsp;&nbsp;&nbsp;security = ADS
&nbsp;&nbsp;&nbsp;&nbsp;password server = test-keiri.test.co.jp
&nbsp;&nbsp;&nbsp;&nbsp;disable netbios = Yes
&nbsp;&nbsp;&nbsp;&nbsp;local master = No
&nbsp;&nbsp;&nbsp;&nbsp;domain master = No
&nbsp;&nbsp;&nbsp;&nbsp;hosts allow = 127., 172.16.
&nbsp;&nbsp;&nbsp;&nbsp;cups options = raw
[homes]
&nbsp;&nbsp;&nbsp;&nbsp;comment = Home Directories
&nbsp;&nbsp;&nbsp;&nbsp;read only = No
&nbsp;&nbsp;&nbsp;&nbsp;browseable = No
</blockquote>

注意すべきは、「netbios name」のエントリをコメントアウトすることです。
「netbios name」が設定されていると動作しない場合があるようです。
（詳細未確認）

「workgroup」には、ADドメインのNetBIOS名を指定します。
「realm」にADドメイン名を指定します。大文字が無難。
「security」にADSを指定。これでADのKerberos認証となります。


最後に、/etc/hosts を編集します。

/etc/hosts
<blockquote>
127.0.0.1 sugi1149-li-01.test.co.jp sugi1149-li-01 localhost.localdomain localhost
</blockquote>
ここで自ホストのFQDNを指定しておかないと、後述のAD接続でエラーとなりました。


ここまで準備ができたら、ADドメインに参加してみましょう。
まず、特権ユーザー（Administrator）でADにアクセスしてチケットを
発行してもらいます。

<blockquote>
# kinit administrator@TEST.CO.JP（Enterキー）
Password for administrator@TEST.CO.JP:XXXXXX
</blockquote>

「Password for administrator@TEST.CO.JP:」とパスワードの入力を
求められますので、続けてAdministratorのパスワードを入力して
Enterキーを押します。
適切なパスワードの場合、画面には何も表示されません。
間違ってると怒られます。

チケットが取得できたら晴れてADドメインに参加できます。

<blockquote>
# net ads join -S test-keiri.test.co.jp -U administrator%XXXXXX（Enterキー）
Using short domain name -- TEST-KEIRI-PDC
Joined 'SUGI1149-LI-01' to realm 'TEST.CO.JP'
</blockquote>


やりました。DC機の「Active Directory ユーザーとコンピュータ」の
「Computers」で確認すると、しっかりLinux機が追加されている筈です。

2009/02/04&nbsp;追記

DC機がWindows Server 2003の場合、
<blockquote>
 net <strong>rpc</strong> join ･･･
</blockquote>
にしないと参加できませんでした。



Windows側からアクセスをおこなうADユーザーのために、Linux機に
OSユーザーを用意しておく必要があります。

<blockquote>
# useradd -m sugi1149
</blockquote>

上記例は、「sugi1149」をOSユーザーとして登録しています。
勿論「sugi1149」は、既にActive Directory側でもユーザーとして
存在しているものとします。（sugi1149@test.co.jp）
「-m」オプションは、/home下にHOMEディレクトリを作成する
オプションです。
smb.confの[homes]設定に対応ですね。

ユーザー設定はこれだけ。認証はADでおこなわれるので、
OSユーザーに対してパスワード設定（passwd）の必要はありません。
当然、smbpasswdファイルの登録なんかも要りません。


これで全部完了！
ADドメインに属するWindowsマシンから、設定済みユーザー
（上記例：sugi1149@test.co.jp）でログオンして、
そのままSambaサーバにアクセスすると･･･
ユーザー名/パスワードを求められることなく入れます。
ふーーー。長かった。]]>
        
    </content>
</entry>
<entry>
    <title>Symantec Backup Execのプレ・ポストコマンド</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/12/symantec_backup_exec.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=38" title="Symantec Backup Execのプレ・ポストコマンド" />
    <id>tag:www.esco-sb.jp,2007:/blog/roughjustice//3.38</id>
    
    <published>2007-12-06T02:33:22Z</published>
    <updated>2007-12-06T02:38:52Z</updated>
    
    <summary> あんまりにもネタがないので、今回はマイナーなお話を。 先日Symantec社の...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="others" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[あんまりにもネタがないので、今回はマイナーなお話を。

先日Symantec社のバックアップ製品「Symantec Backup Exec」を
利用する機会がありました。
スケジュール化されたバックアップジョブを実行してくれる
まぁありがちな製品なのですが、今回の要件は「バックアップの
前後にある処理をおこない、その成否により以降の処理続行を
制御する・またログを残す」というものでした。

要するに事前処理成功の場合のみバックアップ開始。
バックアップ成功の場合事後処理開始。
事前処理・バックアップ・事後処理それぞれの成否ログを残す、
というのが要件なわけです。

「Symantec Backup Exec」には「プレコマンド」「ポストコマンド」
という機能が事前・事後処理用に用意されており、
ここで外部プログラムを指定できます。
また外部プログラムの戻り値を判断してログを残したり、
以降の処理続行・中断を制御してくれます。

おぉいいじゃんいいじゃんと思ったのですが･･･
この戻り値というのが「OSのリターンコード(ERRORLEVEL)」じゃ
ないといけないんですねー。

外部プログラムはVisual Basicで作成するつもりだったのですが、
VBって終了時にこれ戻せないんですよ。

悩むこと数分。「そういえばVB Scriptってリターンコード戻せる
んじゃなかったっけ？」

というわけでプレ・ポストコマンド用のVBアプリケーション（.exe）を
COMオブジェクト(ActiveX DLL）に作り直し、
VB Scriptファイル（.vbs）を作成してその中からCOMオブジェクトを
ロード・実行するようにしました。
COMオブジェクトの処理内で判断した成否は、パラメータとして
(setter/getterじゃなくてlet/getだっけ？）vbsが取得し、
そのままvbsファイルのリターンコードに指定します。
<blockquote>
WScript.Quit(リターンコード)
</blockquote>

あとは「Symantec Backup Exec」でプレ・ポストコマンドとして
このvbsファイルを指定すれば･･･

だめでした。vbsファイルを実行可能ファイルと判断してくれないみたい。
え〜、と思いつつさらにバッチファイル（.bat）を作成し、
この中からvbsファイルを実行し、vbsファイルのリターンコードを
そのままバッチファイルのリターンコードにします。
で、「Symantec Backup Exec」でプレ・ポストコマンドとして
バッチファイルを指定･･･
やっと動作しました。成否判断も
COMオブジェクト→vbsファイル→バッチファイル→Backup Exec
と正しく伝わっています。
やれやれ。]]>
        
    </content>
</entry>
<entry>
    <title>jstat + visualgc でリモートホストを監視</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/07/jstat_visualgc.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=37" title="jstat + visualgc でリモートホストを監視" />
    <id>tag:www.esco-sb.jp,2007:/blog/roughjustice//3.37</id>
    
    <published>2007-07-20T02:35:13Z</published>
    <updated>2007-07-20T02:41:46Z</updated>
    
    <summary> 2007年04月09日「jvmstatでTomcat(JVM)の監視」の記事に...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="java" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[<a href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/04/jvmstattomcatjvm.php" target="_blank">2007年04月09日「jvmstatでTomcat(JVM)の監視」の記事</a>について、
コメント欄でも触れましたが、若干内容に誤りがありました。
jvmstatは、jstatと名前を変えてJ2SE5.0に組み込まれました。
同時に、jvmstatに関連するツール群もJ2SE5.0に組み込まれました。
ただしvisualgcのみ組み込まれなかったため、利用したい場合は
別途jstatを入手して、visualgcのみ使用する、といった形になります。

<table border="1">
  <tbody>
    <tr>
      <th>jvmstatツールでの名称</th>
      <th>J2SE5.0での名称</th>

    </tr>
    <tr>
      <td>jvmstat</td>
      <td>jstat</td>
    </tr>
    <tr>
      <td>jvmps</td>

      <td>jps</td>
    </tr>
    <tr>
      <td>perfagent</td>
      <td>jstatd</td>
    </tr>
    <tr>

      <td>visualgc</td>
      <td>（対応無し）</td>
    </tr>
  </tbody>
</table>

それではjstatとvisualgcを使って、リモートホストのTOMCATを監視してみましょう。
まずは「監視される側（TOMCATの動作する側）」のホストの準備をおこないます。

visualgcへ監視内容を通知するデーモンプログラム（エージェント）「jstatd」を
実行します。jstatdを起動するには「ポリシーファイル」が必要です。
ポリシーファイルでは厳密なセキュリティポリシーを定義することができますが、
今回は簡単に全てを許可するポリシーとします。
（外部公開ホスト等では絶対にこの設定ではダメです）

<blockquote>
grant {
&nbsp;&nbsp;&nbsp;&nbsp;permission java.security.AllPermission;
};
</blockquote>
ファイル名は仮に「all.policy」とでもして、適当な所に保存します。

保存したらjstatdを起動します。プロンプトからポリシーファイルを保存したパスに
移動して以下のコマンドを実行します。
<blockquote>
jstatd -J-Djava.security.policy=all.policy
</blockquote>
エージェントなので、実行すると終了するまで（Ctrl + Cキーを押すまで）
プロンプトはそのままとなります。

では次に「監視する側」のホストの準備をおこないましょう。

visualgcを使うので、まだjvmstatツール群をインストールしていない場合は、
<a href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/04/jvmstattomcatjvm.php" target="_blank">2007年04月09日の記事</a>の要領で、ダウンロード・展開・
環境変数パスの設定を行ってください。

次にリモートホストで起動しているTOMCATのプロセスIDを調べましょう。
（事前にリモートホストでjstatdが起動している必要があります）
<blockquote>
jps -l &lt;リモートホストアドレス&gt;
</blockquote>

TOMCATは「Bootstrap」が含まれる行でしたね。
リモートホストに対してjpsを実行するとパッケージ名も表示されますね。
<a href="http://www.esco-sb.jp/blog/roughjustice/images/20070720/11.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20070720/11.php','popup','width=828,height=497,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20070720/1-thumb.jpg" width="200" height="120" alt="" /></a>

あとはプロセスIDとリモートホストアドレスを指定してvisualgcを実行するだけです。
<blockquote>
visualgc &lt;プロセスID&gt;@&lt;リモートホストアドレス&gt;
</blockquote>

<a href="http://www.esco-sb.jp/blog/roughjustice/images/20070720/2.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20070720/2.php','popup','width=679,height=356,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20070720/2-thumb.jpg" width="200" height="104" alt="" /></a>]]>
        
    </content>
</entry>
<entry>
    <title>jvmstatでTomcat(JVM)の監視</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/04/jvmstattomcatjvm.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=36" title="jvmstatでTomcat(JVM)の監視" />
    <id>tag:www.esco-sb.jp,2007:/blog/roughjustice//3.36</id>
    
    <published>2007-04-09T08:16:13Z</published>
    <updated>2007-04-09T08:20:21Z</updated>
    
    <summary>jvmstatというツールでTomcat状況を監視してみましょう。 jvmsta...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="java" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[jvmstatというツールでTomcat状況を監視してみましょう。
jvmstatはSUN Microより公開されているJVMのパフォーマンス情報（主にGC関連）をリアルタイムにモニタリングできるツールです。
さらに付属のvisualgcというツールでは、動作中のJavaVM のヒープメモリの状況をグラフィカルに表示することができます。
リモートホストの監視も付属のperfagentツールで可能だそうですが、今回はローカルマシンのTomcatの監視方法のみ説明します。

<a href="http://java.sun.com/performance/jvmstat/">公開サイト</a>より「jvmstat-3_0.zip」をダウンロードします。
展開すると「jvmstat」というディレクトリができるのでお好みの場所に移動します。
（スペースを含むパスではないほうがいいみたいです）

環境変数で&lt;&lt;jvmstatディレクトリの移動先&gt;&gt;\batにパスを通します。

準備はこれでOK。

visualgcの表示手順は以下のようにします。
１．Tomcatを起動する
２．コマンドプロンプトで「jps」と入力しEnterキーを押す
３．「Bootstrap」の行と、その数字（プロセスID)を見る
４．「visualgc&nbsp;プロセスID」と入力しEnterキーを押す

<a href="http://www.esco-sb.jp/blog/roughjustice/images/20070409/3.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20070409/3.php','popup','width=668,height=481,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20070409/3-thumb.jpg" width="200" height="144" alt="" /></a>

プロセスIDはWindowsの場合、タスクマネージャでも確認できますが、複数のJVMが立ち上がっている場合判別できません。eclipseもTomcatも「イメージ名」は「java.exe」とか「javaw.exe」になってしまいます。

jpsコマンドでは、プロセスIDとともに起動クラス名が表示されるので、Tomcatの起動クラス、つまり「Bootstrap」が判別できます。
それとjpsコマンドはjvmstatに含まれるツールではなく、J2SE5.0に含まれるツールです。

visualgcが起動できれば以下のように３つのウィンドウが表示されるはずです。
<a href="http://www.esco-sb.jp/blog/roughjustice/images/20070409/4.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20070409/4.php','popup','width=901,height=800,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20070409/4-thumb.jpg" width="200" height="177" alt="" /></a>

左上のウィンドウは「Visual GC Window」です。JVMのヒープ空間を<b>Eden、Survivor0 (S0)、Survivor1 (S1)、Old </b>に分けて表示してくれます。

右上のウィンドウは「Graph Window」です。時系列に沿った Eden、S0、S1、Old、Perm の使用済みメモリサイズの グラフが表示されます。
他にGC が Java の実行を停止していた時間と、 GC の回数なども表示されます。

下のウィンドウは「Survivor Age Histogram Window」です。オブジェクトの年齢・寿命を測る目安らしいですが･･･よくわからん。

「<b>世代別GC</b>」とかでググって勉強しませう。]]>
        
    </content>
</entry>
<entry>
    <title>jconsoleでTomcat(JVM)の監視</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/04/jconsoletomcatjvm.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=35" title="jconsoleでTomcat(JVM)の監視" />
    <id>tag:www.esco-sb.jp,2007:/blog/roughjustice//3.35</id>
    
    <published>2007-04-09T07:49:45Z</published>
    <updated>2007-04-09T07:52:20Z</updated>
    
    <summary> 今回はJavaの監視ツールで、Tomcat利用時の状況表示をおこなってみようと...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="java" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[今回はJavaの監視ツールで、Tomcat利用時の状況表示をおこなってみようと思います。
J2SE 5.0には、アプリケーションの状態などを監視／管理する（monitoring and management）ための
ツールが含まれています。

そのうちのひとつがjconsoleです。J2SE5.0は監視する側、される側双方のマシンに必要です。
（１台のマシンで完結する場合は当然そのマシンにJ2SE5.0がインストールされていればいいです）

まず監視される側のJavaアプリケーションの起動引数に以下の設定をします。

<blockquote>
-Dcom.sun.management.jmxremote.port=ポート番号
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
</blockquote>

リモート監視ではjconsoleから接続する際にポート番号の指定が必要になるため、
上記のようにポート番号を指定します。wellknownポートでなければなんでも良いと思います。
また、デフォルトでSSLとパスワード認証が有効になっているため、これを無効にします。

eclipse+Sysdeo Tomcatプラグイン環境がある場合は以下のように指定・起動します。
１．一度Sysdeo TomcatプラグインでTomcatを起動する
２．すぐにTomcatを終了する
３．eclipseのメニュー[実行]-[構成および実行]を選択してダイアログを開く
４．左側ツリーの[Javaアプリケーション]-[Tomcat 5.x]を選択する
５．右側の「引数」タブを開く
６．「VM引数」の末尾に上記引数３行を追加する。
７．「実行」ボタンを押してTomcatを起動する

これで監視される側の準備はOKです。

次に監視する側の操作です。
１．コマンドプロンプトで「jconsole」と入力してEnterキーを押す
（JAVA_HOME\binにパスは通っていますね？）
２．「リモート」タブを開く
３．「ホストまたはIP」に対象マシンのアドレスを入力する
４．「ポート」は上記で設定したポート番号を入力する
５．「ユーザー名」「パスワード」は入力無し
６．「接続」ボタンを押す

監視対象がローカルマシンの場合、「ホストまたはIP」を「127.0.0.1」としてもいいでしょう。

<a href="http://www.esco-sb.jp/blog/roughjustice/images/20070409/1.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20070409/1.php','popup','width=900,height=750,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20070409/1-thumb.jpg" width="200" height="166" alt="" /></a>

<a href="http://www.esco-sb.jp/blog/roughjustice/images/20070409/2.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20070409/2.php','popup','width=900,height=750,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20070409/2-thumb.jpg" width="200" height="166" alt="" /></a>

わりとおおざっぱな監視内容ではありますが、J2SEに含まれているツールとしては
十分ではないでしょうか。]]>
        
    </content>
</entry>
<entry>
    <title>Javaでのわかち書き - senライブラリ</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/03/java_sen.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=34" title="Javaでのわかち書き - senライブラリ" />
    <id>tag:www.esco-sb.jp,2007:/blog/roughjustice//3.34</id>
    
    <published>2007-03-30T06:04:41Z</published>
    <updated>2007-03-30T09:31:17Z</updated>
    
    <summary> お次はJavaでわかち書きをする方法を説明します。 わかち書きにはSenという...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="java" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[お次はJavaでわかち書きをする方法を説明します。

わかち書きにはSenというライブラリを利用します。
Sen は、Java で実装された形態素解析器で、工藤拓さんによりオープンソース(LGPL)で開発されている形態素解析器MecabをJavaへポーティングしたライブラリ、だそうです。

<a href="https://sen.dev.java.net/servlets/ProjectDocumentList?folderID=755&expandFolder=755&folderID=0">Sen配布ページ</a>から「sen-1.2.2.1.zip」をダウンロードして解凍します。

この中にはわかち書きのための辞書は含まれておらず、自分で作成する必要があります。
辞書の作成のためには「Apache Ant」と「Active　Perl」が必要です。

Antは<a href="http://ant.apache.org/">ApacheAntプロジェクトサイト</a>から「apache-ant-1.7.0-bin.zip」をダウンロードします。
Active Perlは<a href="http://aspn.activestate.com/ASPN/Downloads/ActivePerl/">ActiveStateサイト</a>から「ActivePerl-5.8.8.820-MSWin32-x86-274739.msi」をダウンロードします。

Antはダウンロードしたファイルを解凍して、&lt;&lt;Antの解凍先&gt;&gt;\apache-ant-1.7.0\bin にパスを通しておきます。
Active PerlはMSI形式のインストーラーなので、普通にインストールできます。

また、辞書データはネットから自動的にダウンロードされるため、インターネット接続環境が必要です。プロキシの指定が必要な場合、&lt;&lt;senの解凍先&gt;&gt;\dic ディレクトリの「build.xml」を事前に編集しておきます。
build.xmlをエディタで開き、ファイル先頭辺り、
&lt;property name="***" value="***" /&gt;
が連なっている末行に
<blockquote>
&lt;property name="proxy.host" value="プロキシサーバーのアドレス" /&gt;
</blockquote>
を記述します。

準備ができたらプロンプトを立ち上げ、カレントディレクトリが&lt;&lt;senの解凍先&gt;&gt;\dic となるように移動します。

<blockquote>
D:\sen-1.2.2.1\dic> ant -Dperl.bin=&lt;&lt;Perlのインストール先&gt;&gt;\bin\perl.exe
</blockquote>
上記コマンドを実行すると辞書が作成されます。

さてさてようやっとJavaプログラムです。
eclipseでプロジェクトを作成し、「sen.jar」と「commons-logging.jar」にクラスパスを設定します。
また「icu4j_3_4_4.jar」にもクラスパスを設定します。（cu4jはIBMが提供しているJavaライブラリで、<a href="http://www.icu-project.org/download/">配布サイト</a>で入手できます。）

<blockquote>
<font color="#990066"><b>package</b></font> sen;

<font color="#990066"><b>import</b></font> java.io.IOException;
<font color="#990066"><b>import</b></font> java.util.ArrayList;

<font color="#990066"><b>import</b></font> com.ibm.icu.text.Normalizer;

<font color="#990066"><b>import</b></font> net.java.sen.StringTagger;
<font color="#990066"><b>import</b></font> net.java.sen.Token;

<font color="#990066"><b>public class</b></font> SenTest {

&nbsp;&nbsp;&nbsp;&nbsp;<font color="#990066"><b>public static void</b></font> main(String[] args) <font color="#990066"><b>throws</b></font> IllegalArgumentException, IOException{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.setProperty(<font color="#0000FF">"sen.home", "D:/sen-1.2.2.1"</font>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringTagger&nbsp;tagger = StringTagger.getInstance();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String str = args[0];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Token[] token = tagger.analyze(str);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String convToken = "";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayList <String>wakati = <font color="#990066"><b>new</b></font> ArrayList();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#990066"><b>for</b></font> (<font color="#990066"><b>int</b></font> i = 0; i < token.<font color="#0000FF">length</font>; i++) {
<font color="#339966">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(token[i].getBasicString() + "("
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ token[i].getTermInfo() + ")");</font>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;convToken = Normalizer.normalize(token[i].getBasicString().toUpperCase(), Normalizer.<font color="#0000FF">NFKC</font>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#990066"><b>if</b></font> (!wakati.contains(convToken))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wakati.add(convToken);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#990066"><b>for</b></font> (String result : wakati){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.<font color="#0000FF">out</font>.println(result);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</blockquote>

実行引数の文字列をわかち書きして、コンソールに出力するプログラムです。
System.setPropertyでsenの展開先を指定します。
tagger.analyzeでわかち書きされたTokenオブジェクト配列が返されます。
token[要素].getBasicString()でわかち書きされた文字を取得できます。
Normalizer.normalizeはicu4jのメソッドで、文字の「ゆれ」を統一します。
ここではtoUpperCase()と組み合わせることで、「英数字は大文字半角・カタカナは全角」となるようにしています。全文検索キーワードに収めるキーワードの「ゆれ」を統一しておくことで、検索時に全角・半角・大文字・小文字いずれでも検索できるようにするためです。
重複したキーワードを取得しないように、!wakati.containsでチェックしています。

このサンプルではコンソール出力していますが、実際は「
DB更新時のキーワード列に収めるデータ」と「検索時に検索条件をわかち書きするため」に使用することになります。]]>
        
    </content>
</entry>
<entry>
    <title>Tsearch2で全文検索</title>
    <link rel="alternate" type="text/html" href="http://www.esco-sb.jp/blog/roughjustice/archives/2007/03/tsearch2.php" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.esco-sb.jp/mt/mt-atom.cgi/weblog/blog_id=3/entry_id=33" title="Tsearch2で全文検索" />
    <id>tag:www.esco-sb.jp,2007:/blog/roughjustice//3.33</id>
    
    <published>2007-03-30T04:49:37Z</published>
    <updated>2007-04-05T09:37:05Z</updated>
    
    <summary> ほぼ1年ぶりの更新となってしまいました。 今回はPostgreSQLにおける全...</summary>
    <author>
        <name>たけし</name>
        
    </author>
            <category term="postgresql" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.esco-sb.jp/blog/roughjustice/">
        <![CDATA[ほぼ1年ぶりの更新となってしまいました。
今回はPostgreSQLにおける全文検索機能として、Tsearch2を利用する方法を解説します。
インストールについて昔はえらくめんどくさかったのですが、Postgresの最新版（07/03/30現在 Ver8.2.3）ではTsearch2が同梱されているためとっても簡単になっています。

Windows版での説明です。

<a href="http://www.postgresql.jp/">公式サイト</a>から「postgresql-8.2.3-1-ja.zip」をダウンロード・展開して、「postgresql-8.2-ja.msi」を実行します。

インストーラーでは、「ようこそ」-「注意事項」-「インストールオプション」-「サービス構成」-「クラスタの初期化」-「手続き言語」までは通常の手順で進めます。

次の「貢献モジュールを可能にする」で、一番右の列にある「Tsearch2」のチェックをONにします。

<a href="http://www.esco-sb.jp/blog/roughjustice/images/20070330/1.php" onclick="window.open('http://www.esco-sb.jp/blog/roughjustice/images/20070330/1.php','popup','width=506,height=385,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.esco-sb.jp/blog/roughjustice/images/20070330/1-thumb.jpg" width="200" height="152" alt="" /></a>

あとは先に進んでインストールを完了させるだけ。簡単！！すばらしい！！

では検索用のテーブルを作成してみましょう。

<blockquote>
CREATE TABLE tbl (
key numeric(2) primary key,
origtext TEXT,
wakachi TSVECTOR
);

CREATE INDEX wakachi_index ON tbl USING gin (wakachi);
</blockquote>

「wakachi」列には検索キーワードを格納する列です。
列のタイプは「TSVECTOR」とします。

「wakachi」列に対してインデックス「wakachi_index」を作成します。
「USING gin」はインデックスのタイプを指定しています。
gin は汎用転置インデックスです。

データを投入しましょう。「origtext」列には元の文書を、「wakachi」列にはわかち書きされたキーワードを投入します。Tsearch2自体にはわかち書きする機能はないそうなので、ここではわかち書きが既に為されているという前提でINSERTします。（javaでわかち書きする方法は別エントリで説明します）

<blockquote>
insert into tbl values(1,
'ルウム戦役で５隻の戦艦がシャア一人の為に撃破された…に、逃げろーッ！',
'ルウム 戦役 で 5 隻 の 戦艦 が シャア 一 人 為 に 撃破 する れる た ... 、 逃げ ろ ーッ !');
insert into tbl values(2,'
このタイミングで戦闘を仕掛けたと言う事実は、古今例が無い。',
'この タイミング で 戦闘 を 仕掛ける た と 言う 事実 は 、 古今 例 が 無い 。');
insert into tbl values(3,
'そのために私のような女を大佐は拾って下さったんでしょう？',
'その ため に 私 の よう だ 女 を 大佐 は 拾う て 下さる た ん です う ?');
insert into tbl values(4,
'赤い色のＭＳ！シャアじゃないのか？',
'赤い 色 の M S ! シャア じゃ ない か ?');
insert into tbl values(5,
'一年戦争開戦初期、1 月 15 日からサイド 5 (ルウム) にて行われた一大艦隊戦役',
'一 年 戦争 開戦 初期 、 1 月 15 日 から サイド 5 ( ルウム ) にて 行う れる た 一大 艦隊 戦役');
</blockquote>

わかち書きしたキーワードは、半角スペースを空けて登録します。

で、検索してみましょう。

<blockquote>
SELECT key,origtext FROM tbl WHERE 'シャア'::TSQUERY @@ wakachi;
</blockquote>

「シャア」を含むkey「1」「4」が検索されるはずです。
複数のキーワードでも検索できます。

<blockquote>
SELECT key,origtext FROM tbl WHERE 'シャア&赤い'::TSQUERY @@ wakachi;
</blockquote>

「シャア」と「赤い」を両方含むkey「4」のみが検索されます。
ちなみにAND検索は「&」，OR検索は「|」を区切りに使います。

ただしこれだけではまだ不十分です。たとえば「ルウム戦役」というキーワードで検索したい場合、わかち書きされたキーワードは「ルウム」と「戦役」に分けられています。
よって

<blockquote>
SELECT key,origtext FROM tbl WHERE 'ルウム戦役'::TSQUERY @@ wakachi;
</blockquote>

ではヒットしません。検索する場合は、「検索キーワードも事前にわかち書きしておく」のが鉄則です。SQL文もちょっと工夫します。

<blockquote>
SELECT key,origtext
FROM (
SELECT *
FROM tbl 
WHERE 'ルウム&戦役'::TSQUERY @@ wakachi OFFSET 0
) AS findtbl
WHERE origtext LIKE '%ルウム戦役%'
</blockquote>

検索前に「ルウム戦役」をわかち書きして「ルウム」と「戦役」を取得しておきます。
副問い合わせの中側では「ルウム&戦役」でAND検索するようにします。
これだけだと「ルウム」「戦役」の両方を含む行が全て（key「1」と「5」）返されてしまいます。行いたいのは「ルウム戦役」の検索ですから、副問い合わせの外側で「WHERE origtext LIKE '%ルウム戦役%'」とさらに絞り込んでkey「1」が返るようになります。

「OFFSET 0」はプランナに必ずインデックスを使用することを強制させる意味合いをもちます。
（「PostgreSQL + Tsearch2 日本語化パッチによる日本語全文検索システム構築手順」寺本純司　NTT サイバースペース研究所OSS コンピューティングプロジェクトより）

いやぁ便利な世の中になったもんです。]]>
        
    </content>
</entry>

</feed> 


