雑記

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|
2007|01|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|09|11|
2009|02|03|05|06|07|08|10|11|12|
2010|01|03|04|05|06|07|08|09|10|
2011|05|06|09|10|
2012|03|07|09|12|
2013|01|02|04|05|07|08|10|11|
2014|04|05|08|10|12|
2015|01|05|
2016|09|

2003-10-27 LISA初日

奇妙な空模様

朝起きると,でした.変だなと思いつつ会場に向かうと.その後,時間に余裕が出来たので,部屋に戻ってテレビを見ると山火事のニュースをやっていました.家屋等に被害が出たり,フリーウェイが封鎖されたりしているようです.屋外に出ると降ってきた灰が目やのどに入って辛い状況です.今(チュートリアル終了後)あらためてニュースを見ると,ほとんどのニュース局が中継していて,封鎖されている道路は増え,死者も出ているようです.風が狙ったようにサンディエゴの方向を向いているのはなぜ? あと,例のプロペラ機は煙と熱によって乱れるであろう気流の中ではたして飛べるのでしょうか?

サマータイム

朝,チュートリアルの会場に着くと人っ子一人いません.行きがけに灰まみれの車を見ていたので,その影響かと思ったのですが.昨日でサマータイム期間が終了しただけでした.11月1日に切り替えるわけではないんですね.切り替えを日曜日にしないと影響が大きいといわれれば納得ですが,誰も教えてくれないんだもんなぁ,って当然か.

往年の...

ニュースを見ようとチャンネルを回していたら,speed channelという局で1993年のF1イギリスGPを放送していたので,思わず見入ってしまいました.セナがラスト1週でガス欠し,プロスト教授が50勝目をあげたレースです.2位はキャメルカラーのレーシングスーツで身を包んだ,ベネトンのシューマッハ.さすがに若い.3位は同じくベネトンのパトレーゼ.こちらは懐かしい.今何をしているんでしょうか?

電気が...

昨日は気付かなかったのですが,結構頻繁に電気が一瞬暗くなります.山火事の影響か,普段からこうなのかは謎です.

Intrusion Detection and Prevention Systems

IDS/IPSの概要とシステムに潜む落とし穴といった内容でした.以下,メモ起こし.

  • チュートリアルでの侵入(Intrusion)の定義:ネットワーク and/or コンピュータのセキュリティに関するポリシーの侵害(policy violation)  ポリシー無き所に侵害なし.
  • NIDSを騙す.
    % stty erase R
    % rxRoxRoxRtxRkxRixRt
    % stty erase ^?
        
  • 「見たことの無いログ」が重要.
    • 見逃さない.
    • 積極的に集める.
  • false positive, false negative, noise/false alarms
  • 次世代:FW/IDS IPS.(疑問:false positiveが起きたらどうする?)
  • Endpoint IDSってanti-virusと何が違うの?(目から鱗)
  • MS WindowsはOS界のハニーポット説:-).
  • The Microscope Effect: the closer your view the smaller your field of vision
  • Burglar Alarms: 侵入後の不正な通信に対する警告.
  • 平常時のアクセス数を把握せよ.
  • IDSはどこに置く? トレードオフ.
  • 最近のスイッチはポートのcarbon-copy機能を持っているので気をつけよう.
  • "Artificial Ignorance":「見たことの無いログ」を記録するためのテクニック.
  • Computer Jounalistの誤解:自分を幸せにしてくれたシステムは,他人も幸せにしてくれる.
  • 危険信号:「(このシステムは)政府に採用されたが,詳細は述べられない」⇒「守秘契約をするから教えてくれ」と返そう.
  • その他の語彙:自分なりの訳
    • policy violation:ポリシーの侵害
    • (file) tamper detection:(ファイルの)改竄検知
    • anormaly:異常(protocol anormalyとか)
    • re-prioritize:優先順位の付け直し
    • Enterprise Security Management(ESM)
    • perimeter:(ネットワーク)境界
    • port-spanning:(スイッチの)ポートの結びつけ(?)
本日のツッコミ(全1件) [ツッコミを入れる]

- mak-y [山火事の影響受けてるのか・・・ 体調は大丈夫か? 過去10年で最悪とかって言ってたけど。。。 こちらでの扱いはすでに..]


2013-10-27

PostgreSQLでリストアに失敗したときの対処法

PostgreSQL 9.2でバージョンアップした訳でもないのにリストアに失敗するという不可解な現象に遭遇しました。今後も無いとは限らないので、備忘のためにメモ。

Drupalを運用しているサイトで

% pg_dump -Fc -b -U #{DB_USER} #{DB} > #{DB}.pg_dump

でダンプしたデータを、(作業で不具合が出て(^^;)

% pg_restore -C -U #{DB_USER} -d postgres #{DB}.pg_dump

でリストアしようとしたところ、

pg_restore: [アーカイバ(db)] TOC処理中にエラーがありました:
pg_restore: [アーカイバ(db)] TOCエントリ4637; 2606 62213193 CONSTRAINT variable_pkey pgsqlのエラーです
pg_restore: [アーカイバ(db)] could not execute query: ERROR:  could not create unique index "variable_pkey"
DETAIL:  Key (name)=(menu_expanded) is duplicated.
   コマンド: ALTER TABLE ONLY variable
    ADD CONSTRAINT variable_pkey PRIMARY KEY (name);

というエラーが。この種のエラーは過去にも数度経験していて、これまではdropdbとpg_restoreを再実行すると何事も無かったかのように成功していたのですが、なぜか今回は再現性があって、かなり焦りました。

エラーの解読

まずは上の{=呪文=}エラーを解読しなければなりません。理解できてから改めて読むと修正に必要な情報がすべて書かれているんですが、1行目の"TOC"の時点で意味不明で戦々恐々です。

で、解読の経緯ははしょりますが、
  • pg_dump/pg_restoreではバックアップデータを細かな処理単位で管理している
  • この管理されている単位の一覧がTOCとなり、「TOCエントリ」は個別の処理をさす

ということらしく、そこが理解できるとあとは結構スムーズで、上記エラーメッセージは

  • "4637; ..."番の処理でエラーが発生した
  • そのエラー内容は"variable_pkey"という名前のunique制約付きインデックス生成の失敗
  • 詳細:"name"フィールドで"menu_expand"という値のエントリが重複している
  • 実行しようとしたコマンドは"ALTER TABE ONLY ..."

という内容であることが分かりました。ここまで理解できればなんとか手作業で修正できそうです。

エラーが発生した処理の確認

まずは上記エラーが発生した処理を念のため確認します。 最初にエラーメッセージに表示されているTOCエントリ

4637; 2606 62213193 CONSTRAINT variable_pkey pgsql

という1行だけのテキストファイルを適当な名前(err_toc.txt)で作成します。

pg_restoreで-L(大文字のエル)オプションを使って上記ファイルを指定すると、その処理の内容を確認できます。

% pg_restore  -L err_toc.txt #{DB}.pg_dump
--
-- PostgreSQL database dump
--

SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;

SET search_path = public, pg_catalog;

SET default_tablespace = '';

--
-- Name: variable_pkey; Type: CONSTRAINT; Schema: public; Owner: pgsql; Tablespace: 
--

ALTER TABLE ONLY variable
    ADD CONSTRAINT variable_pkey PRIMARY KEY (name);


--
-- PostgreSQL database dump complete
--

前処理がついていますが、エラーメッセージにある"ALTER TABLE ONLY ..."です。

データベースの修復

マニュアルを見る限りではpg_restoreは途中で処理に失敗しても残りのTOCを継続して処理するようなのですが、気分の問題としてひとまずエラーがない状況で最大限DBを復旧させます。

まずpg_resotreでは-l(小文字のエル)オプションでTOCを取得できるので、これをテキストに書き出します。

% pg_restore -l #{DB}.pg_dump > toc.txt

このtoc.txtをエディタで開いてエラーとなった"4637; ..."のTOCエントリの行をコメントアウトします。

% vim toc.txt
  :
{~#adf:;~}4637; 2606 62213193 CONSTRAINT public variable_pkey pgsql
  :

行頭にセミコロンを付けて保存したら、今度は先ほどの-Lオプションを使ってDBに接続してリストアします。

% pg_restore --disable-triggers -C -U pgsql -d postgres #{DB}.pg_dump -L toc.txt

これで今回はエラーなくリストアできました。なお、処理の内容によってはエラーより後の処理で不具合が出る可能性もあるので、toc.txtをエラー前とエラー後に分割して、

  1. エラー前の処理までのリストア
  2. エラーへの対策とエラーが発生した処理の実行
  3. エラー後の処理のリストア

という順番で修復する必要があるかもしれません。今回はPRIMARY KEY制約の付加だけなので、他の処理はすべて実行してしまっても大丈夫でしょう。

エラーの修復

DBに接続してエラーの状況を確認します。エラーメッセージから"variable"というテーブルのname = 'menu_expanded'というデータのエラーだと分かるので、見てみます。が、その前にvariableテーブルはDrupalのオブジェクトを保存するためのテーブルなので、その内容をdrushコマンドをつかって確認しておきます。

% drush vget menu_expanded
menu_expanded: Array
(
)

どうやら空の配列のようです。次にDBに接続してテーブルの内容を確認します。

% psql -U pgsql #{DB}
DB=# SELECT * FROM variable WHERE name = 'menu_expanded';
     name      | value  
---------------+--------
 menu_expanded | a:0:{}
 menu_expanded | a:0:{}
(2 行)

なぜか全く同じ内容のエントリが2つあるので、削除してしまいます。

DB=# DELETE FROM variable WHERE name = 'menu_expanded';
DELETE 2

削除されている事を確認します。

DB=# SELECT * FROM variable WHERE name = 'menu_expanded';
 name | value 
------+-------
(0 行)

ここで直接INSERT文を発行して上記データを登録しても良いのですが、Drupalでは1文字でもtypoがあるとNULL扱いになってしまうので、こちらもdrushを使います。

=# \q
% drush eval "variable_set('menu_expanded', array());"

データを確認します。

% psql -U pgsql #{DB}
DB=# SELECT * FROM variable WHERE name = 'menu_expanded';
     name      | value  
---------------+--------
 menu_expanded | a:0:{}
(1 行)

これでデータは修正できたはずですので、最初の方で作ったerr_toc.txtを使ってエラーの出ていた処理を再実行します。-vオプションを付けると冗長な出力をしてくれます。-Cオプションを付けたり接続先のDBを間違えたりしないよう気をつけましょう。

% pg_restore --disable-triggers -U pgsql -d #{DB} #{DB}.pg_dump -v -L err_toc.txt
pg_restore: リストアのためにデータベースに接続しています
pg_restore: CONSTRAINT variable_pkeyを作成しています
pg_restore: CONSTRAINT variable_pkey用の所有者と権限を設定しています

念のため、確認します。

% psql -U pgsql DB
DB=# \d variable
                       テーブル "public.variable"
  列   |           型           |                 修飾語                 
-------+------------------------+----------------------------------------
 name  | character varying(128) | not null default ''::character varying
 value | text                   | not null
インデックス:
    "variable_pkey" PRIMARY KEY, btree (name)

DB=# \q

"name"がPRIMARY KEYとしてインデックスに表示されているので、正しく修復できた事が分かります。

基本的にはエラーが出なくなるまでこの作業の繰り返しです。

参考

http://d.hatena.ne.jp/naga_sawa/20120918/1347967306

-----