A Day In The Boy's Life -149ページ目

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

前回の「PostgreSQLの障害対策 - WAL編 - 」にて、WALでインスタンス障害への対応ができていることがわかりましたが、DB管理者から見ればより深刻なのはメディア障害の方です。


データファイルが壊れた、ディスク障害が発生してデータファイルの取出しが不可能になった、といった場合に先ほどのWALだけでは対応できません。

前回のバックアップファイルが残っていて、それ以降のトランザクション処理が全てWALセグメントファイルに含まれているのであれば復旧できるかもしれませんが、多くの場合はそのようなことはまれだと思います。


PostgreSQLのPITRは、Oracleのアーカイブログ運用と似ています。
バックアップ以降のWALセグメントファイルが残っていれば、それを適用させることで障害前の状態に復旧させることができます。


※ 障害前のどの状態まで戻せるかは、WALセグメントファイルに残っているトランザクション情報によります。


PITR機能を有効にするには、postgresql.confファイルに定義されている、archive_commandディレクティブを有効にし、適切なコマンドを指定する必要があります。


例えば、このように書きます。


archive_command = 'cp %p /var/log/arch/%f'

%pがWALセグメントファイルのフルパスが、%fはファイル名となり、上記のように書くと作成されたWALトランザクションファイルが/var/log/arch以下にも保存されるようになります。
Oracleのアーカイブログと違って、PostgreSQLの場合はWALトランザクションファイルをそのまま利用します。
設定ファイルを編集後は、PostgreSQLを再起動しておきます。


この設定が何を意味するのか確かめてみます。
わかりやすくするために、postgresql.confのarchive_timeoutディレクティブを下記のように編集し、PostgreSQLを再起動しておきます。


archive_timeout = 5

これは、指定の時間(秒)でWALトランザクションファイルを強制的に出力するためのオプションです。
(Oracleのように、ログスイッチを実行するためのSQLは存在しないようです)

まず、pg_xlogの中身を確認しておきます。


$ ls -o pg_xlog/
合計 16416
-rw-------  1 postgres 16777216  2月 17 13:30 000000010000000000000000
drwx------  2 postgres     4096  2月 17 13:30 archive_status

次に、適当にテーブルにデータを格納するなどのトランザクションを実行してみます。
すると、pg_xlogディレクトリとarchive_commandの中で指定したarchディレクトリの両方にログが出力されるようになっているのがわかります。


$ ls -o pg_xlog/
合計 65628
-rw-------  1 postgres 16777216  2月 17 13:35 000000010000000000000001
-rw-------  1 postgres 16777216  2月 17 13:35 000000010000000000000002
-rw-------  1 postgres 16777216  2月 17 13:35 000000010000000000000003
-rw-------  1 postgres 16777216  2月 17 13:36 000000010000000000000004
drwx------  2 postgres     4096  2月 17 13:36 archive_status

$ ls -o /var/log/arch/
合計 82032
-rw-------  1 postgres 16777216  2月 17 13:30 000000010000000000000000
-rw-------  1 postgres 16777216  2月 17 13:35 000000010000000000000001
-rw-------  1 postgres 16777216  2月 17 13:35 000000010000000000000002
-rw-------  1 postgres 16777216  2月 17 13:35 000000010000000000000003
-rw-------  1 postgres 16777216  2月 17 13:36 000000010000000000000004

そして、よく見ると「000000010000000000000000」というファイルは、archディレクトリにしか存在しません。
WALトランザクションファイルが指定の数を超えたので削除対象となり、削除を行う前にarchディレクトリに退避させていることがわかります。


つまり、このWALトランザクションファイルが、直近のトランザクションを記録したログ(Oracleで言うREDOログ)と、永続的に記録するためのログファイル(Oracleで言うアーカイブログ)の2つの意味を持たせていることになります。

ファイル名が同じ形式なため、どちらがどちらなのか区別が付かないのですが、archive_commandの中で指定した退避先がアーカイブログ、pg_xlogディレクトリにあるのがREDOログの役割となっています。


これで、インスタンス障害とメディア障害に対応できたログファイルを残すことができるようになりました。
次は、PITRを使ったオンラインバックアップの方法です。



Point In Time Recoveryを使うためのオンラインバックアップ


PITRでリカバリを行うためには、ある時点での物理的なバックアップファイルと、それを取得した以降のアーカイブログが必要となります。


物理的なバックアップとは、データファイルのコピーを指しますが、単にコピーしただけではリカバリ時に使えません。
データファイルは常に更新がかかっているので、何時の時点で取られたバックアップなのか明確にし、それとアーカイブログをつき合わせて、どの時点以降をリカバリする必要があるのかを記録させていなければなりません。


まずは、バックアップファイルを取得します。

データファイルをオンラインでバックアップするには先ほど述べたように、まずバックアップを取ることの宣言をする必要があります。


template1=# SELECT pg_start_backup('bakcup');
 pg_start_backup
-----------------
 0/458368
(1 row)

これで、バックアップの宣言が行われます。
pg_start_backup関数で指定しているbackupという文字は単なるラベルですので、何を指定してもかまいません。
この間に、データファイル一式のコピーを取得しておきます。


$ cp -R /usr/local/pgsql/data/ /home/postgres/pg_data_backup/

コピーが完了したら、バックアップの終了宣言を行います。


template1=# SELECT pg_stop_backup();
 pg_stop_backup
----------------
 0/4583CC
(1 row)

これで、データファイルのバックアップが完了しました。
Oracleでオンラインバックアップを取るときのBEGIN BACKUPとEND BACKUP宣言と同じようなイメージですね。

もう一度ログファイルを覗いてみると


$ ls -o pg_xlog/
合計 82036
-rw------- 1 postgres 16777216 2月 17 14:20 000000010000000000000009
-rw------- 1 postgres      239 2月 17 14:20 000000010000000000000009.00019D2C.backup
-rw------- 1 postgres 16777216 2月 17 13:40 00000001000000000000000A
-rw------- 1 postgres 16777216 2月 17 13:45 00000001000000000000000B
-rw------- 1 postgres 16777216 2月 17 13:50 00000001000000000000000C
-rw------- 1 postgres 16777216 2月 17 13:55 00000001000000000000000D

.backupというファイルができています。
この中身は、


START WAL LOCATION: 0/9019D2C (file 000000010000000000000009)
STOP WAL LOCATION: 0/9019D90 (file 000000010000000000000009)
CHECKPOINT LOCATION: 0/9019D2C
START TIME: 2009-02-17 14:20:08 JST
LABEL: bakcup
STOP TIME: 2009-02-17 14:20:51 JST

のように、バックアップの開始時間と終了時刻、WALやチェックポイントの情報が記載されいます。
バックアップの終了宣言を行うと、強制的にログスイッチが行われ、アーカイブログが出力されます。



Point In Time Recoveryを使ったリカバリ


いよいよ大詰めですが、PITRを使った簡単なリカバリのテストをしてみたいと思います。
PITRを使ったリカバリは、特定時刻のDBの状態に戻すこともできますし、WALトランザクションファイルに記録されている最新の状態まで戻すこともできます。


まず、最初のDBの状態です。


testdb=# select no, to_char(date, 'YYYY/MM/DD HH24:MI:SS') from test_tab;
 no |       to_char
----+---------------------
  1 | 2009/02/17 18:12:50

この時点で、先ほどやったようにオンラインバックアップを取得しておきます。

新たに1つレコードを追加してみます。


testdb=# select no, to_char(date, 'YYYY/MM/DD HH24:MI:SS') from test_tab;
 no |       to_char
----+---------------------
  1 | 2009/02/17 14:19:10
  2 | 2009/02/17 14:32:32

ここから障害を起こしますが、障害を発生させる直前のトランザクション(先ほど投入したnoが2のデータ)が含まれるWALトランザクションファイルもバックアップしておきます。
でないと、障害直前に戻すことができません。


$ ls -o pg_xlog/
合計 32824
-rw-------  1 postgres 16777216  2月 17 18:14 000000010000000000000000
-rw-------  1 postgres      236  2月 17 18:14 000000010000000000000000.0044C270.backup
-rw-------  1 postgres 16777216  2月 17 18:29 000000010000000000000001
drwx------  2 postgres     4096  2月 17 18:14 archive_status

バックアップ以降にできた、「000000010000000000000001」のトランザクションファイルを別ディレクトリにコピーしておきます。

ここではバックアップ以降のトランザクションファイルが明らかなために個別にバックアップしていますが、不明な場合はpg_xlog全体をバックアップしておくことで問題ありません。


$ cp 000000010000000000000001 /home/backup/pg_xlog/

ここで、擬似的な障害としてデータファイルを全て削除してみます。


$ rm -Rf data/

ついでにPostgreSQL関連のプロセスも強制終了しておきます。


ここからがリカバリです。

まず、データファイルのバックアップを元の位置に戻します。


$ cp -R ~/pg_data_backup/ ./data/

このバックアップしたデータファイルに含まれるWALトランザクションログは不要ですので削除し、先ほどバックアップしておいたWALトランザクションファイルをリストアします。
戻した後は、このようになっています。


$ ls -o pg_xlog/
合計 16416
-rw-------  1 postgres 16777216  2月 17 18:37 000000010000000000000001
drwx------  2 postgres     4096  2月 17 18:37 archive_status

次に、リストア用の設定ファイルを作成します。
テンプレートが、shareディレクトリ以下に含まれていますので、それをdataディレクトリコピーします。


$ cd /usr/local/pgsql/share/

$ cp recovery.conf.sample ../data/recovery.conf

適当なエディタでrecovery.confを開き、restore_commandディレクティブにアーカイブログのパスを指定して、pg_xlogへリストアするように指定ます。


restore_command = 'cp /var/log/arch/%f %p'

編集が完了した後は、PostgreSQLを起動します。

そして、DBの内容を確認してみると・・・


testdb=# select no, to_char(date, 'YYYY/MM/DD HH24:MI:SS') from test_tab;
 no |       to_char
----+---------------------
  1 | 2009/02/17 18:12:50
  2 | 2009/02/17 18:29:26

リストアされていることがわかります。


では、次にPITRの言葉が示すとおり、特定時間へのリストを試してみます。

先ほどのtest_tabテーブルへ、もう1レコード追加します。


testdb=# select no, to_char(date, 'YYYY/MM/DD HH24:MI:SS') from test_tab;
 no |       to_char
----+---------------------
  1 | 2009/02/17 18:12:50
  2 | 2009/02/17 18:29:26
  3 | 2009/02/17 18:52:37

先ほどと同様に擬似的な障害を発生させても良いですが、特定時間のDBの状態に戻す場合は、むしろ人為的なミスなどによる場合がおいでしょうから、今回は普通にDBを停止させて、18時30分の時点(noが2のデータ投入直後)に戻してみます。


まず、DBを正常に停止させ、先ほど同様にpg_xlog内にあるWALトランザクションファイルをバックアップしておきます。


$ pg_ctl stop

$ cp -R pg_xlog /home/backup/

次に、dataディレクトリを削除し、前回バックアップしておいたファイルをリストアします。


$ rm -Rf data/

$ cp -R ~/pg_data_backup/ ./data/

同様にrecovery.confをdataディレクトリに作成し、restore_commandディレクティブを編集しておきます。
ただ、前回のものに加え、recovery_target_timeディレクティブを下記のように指定し、どの時点まで戻すのかを明示しておきます。


recovery_target_time = '2009-02-17 18:30:00 JST'

上記では、カラムnoが2のデータを投入した直後の時間帯を指定しています。


これで準備が整いましたので、PostgreSQLを起動させます。
その後、テーブルを確認してみたところ・・・


testdb=# select no, to_char(date, 'YYYY/MM/DD HH24:MI:SS') from test_tab;
 no |       to_char
----+---------------------
  1 | 2009/02/17 18:12:50
  2 | 2009/02/17 18:29:26

意図どおりに18時30分時点のDBの状態にリストアされていることがわかります。
DB起動時のログからも、どの時点にリストアしたのかを確認することができます。


LOG:  database system was interrupted at 2009-02-17 18:13:37 JST
LOG:  starting archive recovery
LOG:  restore_command = "cp /var/log/arch/%f %p"
LOG:  recovery_target_time = 2009-02-17 18:30:00+09
LOG:  restored log file "000000010000000000000000.0044C270.backup" from archive
LOG:  restored log file "000000010000000000000000" from archive
LOG:  checkpoint record is at 0/44C270
LOG:  redo record is at 0/44C270; undo record is at 0/0; shutdown FALSE
LOG:  next transaction ID: 0/626; next OID: 24576
LOG:  next MultiXactId: 1; next MultiXactOffset: 0
LOG:  automatic recovery in progress


上記のように、18時30分時点まで戻そうとしているのがわかりますね。
また、その時点までに必要なアーカイブログを適用してリストアしているのもわかります。


このように、PostgreSQLでもWALとPITRの機能をうまく使えば、障害に強いDBを構築することができます。

WALトランザクションファイルやアーカイブログを冗長化することができない、アーカイブログの出力方法がシェルを使っており信頼性にかける(失敗したときの対処ができない)、などと幾つか弱点はあると感じましたが、そのような点をうまくカバーすれば大規模なDBにも利用できると思います。





PostgreSQLバックアップ3分クッキング 」で書いたように、PostgreSQLは非常に簡単なバックアップとリカバリ方法を兼ね備えていますが、これだけでは障害直前のデータに復旧することができないなどの問題点があります。


pg_dumpコマンドによるバックアップは、あくまでもコマンド実行時点でのDBのスナップショットであるため、コマンド発行以降のトランザクション情報は含まれていません。

トランザクションごとにpg_dumpコマンドを発行することは非現実的であるため、障害に強いDBを構築するにはその他の方法で障害直前までのデータを復旧する手段を用意しておく必要があります。


ここでは、PostgreSQLで用意されているWALとPoint In Time Recovery(PITR)の機能をうまく使って、障害に強いDBを構築する方法を書いてみたいと思います。

なお、エントリがかなり長くなったので2回に分けて書いています。

Point In Time Recovery(PITR)については、後編の「PostgreSQLの障害対策 - Point In Time Recovery編 - 」を参照してください。



WALって何だ?


WAL(Write Ahead Logging)は、ログ先行書き込みという日本語訳からわかるように、トランザクションの処理の内容をデータファイルに反映する前に、ログファイル(WALセグメントファイル)に書き出そうという動きをさせるものです。

詳しくは、こちらの記事がとても参考になります。


WALとは(Write Ahead Logging) @ InterDB


PostgreSQL7.1以降、WALはデフォルトで有効になっています。
このWALセグメントファイルは、データファイルを格納しているディレクトリ(PGDATA)以下にある、pg_xlogというディレクトリに出力されます。


$ ls -la pg_xlog/
合計 16416
drwx------  3 postgres postgres     4096  2月 16 11:30 .
drwx------ 10 postgres postgres     4096  2月 16 13:23 ..
-rw-------  1 postgres postgres 16777216  2月 16 11:35 000000010000000000000000
drwx------  2 postgres postgres     4096  2月 16 11:30 archive_status

データファイルに問題が起きた場合でも、このログファイルを使って復旧させることができるのがWALの特徴になります。
OracleのREDOログファイルに相当する機能ですね。


ってことで、WALセグメントファイルはインスタンス障害に特化したものということになります。
というのも、OracleのREDOログファイル同様にWALセグメントファイルも循環方式となっており、ある一定のタイミングで上書きされてしまいます。

吐き出されるWALセグメントファイルの数は、マニュアルによると


WALセグメントファイルは常に少なくとも1つあり、また、通常は(2 + checkpoint_completion_target)×checkpoint_segments + 1より多くはありません。

とあります。

一時的にこの数を超えることはあるようですが、この数の上限以下になるように不要なWALセグメントファイルを削除する動きをするようです。



WALセグメントファイルを使ってインスタンス障害に対応できるか実験


ってことで、実施にインスタンス障害を起こしてみて、復旧できるのかを試してみたいと思います。

ここではtestdbにある、test_tabテーブルに対してのトランザクション実行中にインスタンス障害を起こしてみます。
まず、ちゃんと復旧できたかを確認とるために、DBのデータファイルの位置を把握しておきます。


$ psql testdb

testdb=# select datname,oid from pg_database;
  datname  |  oid
-----------+-------
 postgres  | 10819
 testdb    | 16384
 template1 |     1
 template0 | 10818

PostgreSQLは、1テーブルに付き1データファイルという構造を持っています。
なので、test_tabのテーブルのデータファイル名を調べます。


testdb=# select relname , relfilenode from pg_class where relname = 'test_tab';
 relname  | relfilenode
----------+-------------
 test_tab |       16390

次に、実際のデータファイルの位置と状態も確認しておきます。


$ ls -la data/base/16384/16390
-rw------- 1 postgres postgres 8192  2月 16 18:34 data/base/16384/16390

では、実際にデータを投入して、チェックポイントを実行してみます。


testdb=# insert into test_tab values (1, 'hoge');
INSERT 0 1

testdb=# checkpoint;

ファイルのタイムスタンプが書き換わっていることからも、チェックポイントによってログバッファの内容がデータファイルへ書き込まれたことがわかります。


$ ls -la data/base/16384/16390
-rw------- 1 postgres postgres 8192  2月 16 18:42 data/base/16384/16390

では、次のトランザクションを開始して、この途中にインスタンス障害を起こしてみます。


testdb=# insert into test_tab values (2, 'foo');
INSERT 0 1

で、この間にpostmasterのプロセスをKILLしてみる。
この後、検索とかをしみると・・・。


testdb=# select * from test_db;
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

ってことで、PostgreSQLが異常終了した状態です。
ちなみに、先ほどのデータファイルのタイムスタンプをもう一度確認してみると・・・


# ls -la data/base/16384/16390
-rw------- 1 postgres postgres 8192  2月 16 18:42 data/base/16384/16390

と、変わりが無いことからもログバッファの内容がデータファイルに書き込まれていないことがわかります。

では、PostgreSQLを起動させ、メディアリカバリが自動的に行われるかを確認してみます。


$ pg_ctl start
pg_ctl: another server might be running; trying to start server anyway
LOG:  database system was interrupted at 2009-02-16 18:42:14 JST
LOG:  checkpoint record is at 0/457EB0
LOG:  redo record is at 0/457EB0; undo record is at 0/0; shutdown FALSE
LOG:  next transaction ID: 0/649; next OID: 24582
LOG:  next MultiXactId: 1; next MultiXactOffset: 0
LOG:  database system was not properly shut down; automatic recovery in progress
LOG:  redo starts at 0/457EF8
LOG:  record with zero length at 0/458090
LOG:  redo done at 0/458068
LOG:  database system is ready
server starting

起動後に、testdbにつなげてSELECT文を実行してみると。


$ psql testdb

testdb=# select * from test_tab;
 no | name
----+------
  1 | hoge
  2 | foo
(2 rows)

2行目のnameがfooのデータを投入した時点でインスタンス障害が起こり、データファイルに反映されていない状態なのにWALセグメントファイルによってリカバリされていることがわかります。
ちなみにデータファイルのタイムスタンプを確認してみても、PostgreSQLを起動した時間帯と一致します。


# ls -la data/base/16384/16390
-rw------- 1 postgres postgres 8192 2月 16 18:50 data/base/16384/16390

WALセグメントファイル自体は、特に意識的に使うことはないのですが、このようなPostgreSQLがデータの整合性を保つために役立てていることがわかります。





借りているファーストサーバ にて、PEARを使ったPHPプログラムを書こうと思ったのですが、デフォルトでは入っていない模様。

ってことで、PEARをインストールして使えるまでの設定ログです。


ここでは、「レンタルサーバーのファーストサーバ設定あれこれ 」で書いたのと同様の環境(VPS(仮想専用サーバー)、CentOS5)で試しています。



PEARのインストール


デフォルトの状態では、PEARがインストールされていないようなので、まず始めにpearコマンドをインストールする必要があります。


※ PHPの設定情報(phpinfo)を覗いてみると、「--without-pear」オプションが指定されてインストールされているようです。

  ただ、PEARは独立したPHPのプログラムですので、PHPを再インストールしなくても追加することはできます。


インストールには、管理用システムであるParalles Power Panelから行うのがもっとも簡単です。


※ yumを使ってインストールすることもできますが、デフォルトの状態ではyumコマンドは使えませんし、管理用の

  Paralles Power Panelにてパッケージ類が管理されているため、そちらを使ったほうがサーバー管理上は安全です。


まず、Paralles Power Panelへログインし、左メニューの「パッケージ」を開きます。

次に、中ほどにある「新しいパッケージのインストール」ボタンをクリックし、表示される「名前」欄にpearとでも入力してパッケージを検索、「php-pear」と出てきたら、それにチェックを入れて「インストール」ボタンからインストールができます。


インストールできたかの確認は、サーバーへSSHで接続して


# which pear
/usr/bin/pear

と、pearコマンドのパスが確認できていれば問題ありません。



PEARの必要パッケージのインストール


これは、一般的なPEARの使い方のお話になりますが、PEARをインストールしてもデフォルトでは基本的な幾つかのPEARパッケージのみですので、自分が使いたいパッケージがない場合、後からインストールする必要が出てきます。
PEARパッケージのインストール方法は、

# pear install HTTP


のように、installオプションの後に必要なパッケージ名を指定することでできます。

(上記の場合は、PEARのHTTPパッケージ)


ただ、ファーストサーバ上で初めてパッケージを追加しようとしたら、


WARNING: running in safe mode requires that all files created be the same uid as the current script. PHP reports this script is uid: 0, and current user is: root
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
sh: /cpp: No such file or directory
pear/HTTP requires PEAR Installer (version >= 1.7.1), installed version is 1.4.9
No valid packages found
install failed


のようなエラーメッセージが表示されたため、とりあえず言われているようにチャネルのアップデートを実行します。


# pear channel-update pear.php.net
WARNING: running in safe mode requires that all files created be the same uid as the current script. PHP reports this script is uid: 0, and current user is: root
Retrieving channel.xml from remote server
Update of Channel "pear.php.net" succeeded

次に、これまた怒られているPEARのバージョンが低いって問題を解決するために、PEAR関連パッケージを一括でアップデートさせます。


# pear upgrade-all

そして、HTTPパッケージのインストールをリトライしてみると、うまくいきました。



ファーストサーバでPEARを利用してみる


で、最大の難関となるのがここ。

PEARが使える状態となり、「いざ!」と思いプログラムに組み込んでみたら・・・


Warning: require_once() [function.require-once]: open_basedir restriction in effect. File(HTTP/Client.php) is not within the allowed path(s): (/var/www/vhosts/localhost.localdomain/httpdocs:/tmp) in /var/www/vhosts/localhost.localdomain/httpdocs/hoge.php on line 3


というようなエラーメッセージが。

調べてみたところ、仮想用ソフトウェアであるPLESKが、php.iniのopen_basedirの値を強制的に上書きして、開くことができるファイルパスを限定してしまっているようです。

PLESKが勝手にApacheに組み込む設定ファイル(httpd.include)を見てみると


<IfModule mod_php5.c>
php_admin_flag engine on
php_admin_flag safe_mode on
php_admin_value open_basedir "/var/www/vhosts/localhost.localdomain/httpdocs:/tmp"
</IfModule>

というように、PHPのopen_basedirオプションを強制的にセットしています。

このオプションにPEARパッケージがインストールされているパスを追加すれば動きそうなのですが、このファイル自体を編集することが禁じられている(このファイルの先頭に「このファイルを編集するなよ、編集した場合、どうなってもしらないからね」的な注釈がついている)ため、安全性をとるなら選択肢としては下記の2択に。


1. ドキュメントルートであるhttpdocsディレクトリ以下にPEARをインストールする

2. /tmp以下にPEARをインストールする


1.は外部からプログラムが実行可能となるのはさすがにリスクが大きいので、2.のtmpディレクトリ以下にPEARをインストールする方法で対処してみたいと思います。


とりあえず、動くかどうかの確認だけであれば、手っ取り早く


1. PEARがインストールされているディレクトリを丸ごと/tmpへコピー(/tmp/pear)

2. php.iniのinclude_pathに、/tmp/pearを追加


で、確認できます。(要Apache再起動)


ただ、このままだとPEARを更新・追加した場合に、インストールディレクトリへ格納される、/tmpは定期的に掃除されるため、PEARパッケージが消える可能性がある、などの問題があります。

って事で、余計な作業になってしまうのですが、上記2点を回避するための対策を。



- PEARパッケージのインストールディレクトリの変更


現在のインストールディレクトリを確認する場合は、


# pear config-show
-snip-
PEAR directory php_dir /usr/share/pear

にて、確認できます。

php_dirがインストールディレクトリを指定するオプションになっていますので、この値を変更します。


# pear config-set php_dir /tmp/pear


- /tmpディレクトリからの定期削除を回避する


/tmpディレクトリ以下に置かれたファイルやディレクトリは定期的に削除されますが、これはtmpwatchコマンドによって実行されています。


※ 詳細は、以前に書いた「不要なファイルやディレクトリを削除できる「tmpwatch」コマンド 」を参照してください。


ですので、そのtmpwatchコマンドの対象から、今回の/tmp/pearディレクトリを除外しておくことで回避できます。


/usr/sbin/tmpwatch -x /tmp/.X11-unix -x /tmp/.XIM-unix -x /tmp/.font-unix \
-x /tmp/.ICE-unix -x /tmp/.Test-unix -x /tmp/pear 240 /tmp
(略)

最後に、-xオプションつきでPEARのディレクトリを指定しておくことで、削除対処のディレクトリから除外されます。



ちょっと無理やりなPEARを使う方法ではありますが、どうしても使いたい場合は今回のような方法でしか、PLESK環境下では利用できなさそうです。