MongoDBのリカバリ

MongoDBのデーモンが走っているときにサーバが落ちてしまったときのリカバリ手順

もしMongoデーモンを以下のようなコマンドで走らせていれば

# ./mongod --dbpath=/tmp/db/ --fork --logpath=/var/ --logappend
/tmp/db/mongod.lock

というパスでロックファイルができているのでこれを削除します。
そしてrepairオプションをつけてもう一度mongodを起動します。

# ./mongod --repair --dbpath /tmp/db/

すると以下のように標準出力にざーっとログが流れます。

Sun Oct 31 19:58:30 MongoDB starting : pid=3892 port=27017 dbpath=/tmp/db/ 64-bit 
Sun Oct 31 19:58:30 db version v1.6.3, pdfile version 4.5
Sun Oct 31 19:58:30 git version: 278bd2ac2f2efbee556f32c13c1b6803224d1c01
Sun Oct 31 19:58:30 sys info: Linux domU-12-31-39-06-79-A1 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_41
Sun Oct 31 19:58:30 [initandlisten] ****
Sun Oct 31 19:58:30 [initandlisten] ****
Sun Oct 31 19:58:30 [initandlisten] need to upgrade database test with pdfile version 4.5, new version: 4.5
Sun Oct 31 19:58:30 [initandlisten]      starting upgrade
Sun Oct 31 19:58:30 [initandlisten]  test repairDatabase test
Sun Oct 31 19:58:30 allocating new datafile /tmp/db/$tmp_repairDatabase_0/test.ns, filling with zeroes...
Sun Oct 31 19:58:30 done allocating datafile /tmp/db/$tmp_repairDatabase_0/test.ns, size: 16MB,  took 0.032 secs
Sun Oct 31 19:58:30 allocating new datafile /tmp/db/$tmp_repairDatabase_0/test.0, filling with zeroes...
Sun Oct 31 19:58:31 done allocating datafile /tmp/db/$tmp_repairDatabase_0/test.0, size: 64MB,  took 0.155 secs
Sun Oct 31 19:58:31 allocating new datafile /tmp/db/$tmp_repairDatabase_0/test.1, filling with zeroes...
Sun Oct 31 19:58:31 [initandlisten] building new index on { _id: 1 } for test.users
Sun Oct 31 19:58:31 [initandlisten] done for 1 records 0.034secs
Sun Oct 31 19:58:31 done allocating datafile /tmp/db/$tmp_repairDatabase_0/test.1, size: 128MB,  took 0.274 secs
Sun Oct 31 19:58:31 [initandlisten] finished checking dbs
Sun Oct 31 19:58:31 dbexit: 

Sun Oct 31 19:58:31 [initandlisten] shutdown: going to close listening sockets...
Sun Oct 31 19:58:31 [initandlisten] shutdown: going to flush oplog...
Sun Oct 31 19:58:31 [initandlisten] shutdown: going to close sockets...
Sun Oct 31 19:58:31 [initandlisten] shutdown: waiting for fs preallocator...
Sun Oct 31 19:58:31 [initandlisten] shutdown: closing all files...
Sun Oct 31 19:58:31     closeAllFiles() finished

Sun Oct 31 19:58:31 [initandlisten] shutdown: removing fs lock...
Sun Oct 31 19:58:31 dbexit: really exiting now

再度、通常通りmongodを起動します。

# ./mongod --dbpath=/tmp/db/ --fork --logpath=/var/mongodb.log --logappend

これでなんとか元通り。

The free lunch is over.

"The free lunch is over"という言葉を見かけました。
初耳だったので早速調べてみる、これからの時代を生きるにあたって何が終わってしまったのか。
フリーランチというのは直訳で「タダ飯」ということですが、プログラミング的には
どうやら自分の書いたコードのパフォーマンス向上をCPUのスペックが上がっていくのただを指をくわえて待っていればよかった時代が終わったということのようです。
要因はCPUアーキテクチャの変化であるようです。ヘテロジニアスマルチコアに変化していくことで今までのようにはいかなくなったということでしょうか。
もともとPCの構成は全体からみると例外的であるという話は自分も感じていましたが、PCが売れていた期間は例外的であってもよかったのでしょう。
でも現在ですらIntelAMDが作っていたPC向けプロセッサの流れがARMなどが展開するモバイル端末向けの低消費電力を売りにした流れに押されているのは明らかです。
結果としてマルチコアに最適なコードを書かないとよいアプリケーションは作れないということでしょうか。
しかしありがたいのはHaskellOCamlなどの関数型言語PythonRubyといった新しいLL、混合型のScalaなど、良いツールはすでに揃っています。
肩肘張らずに新しいことを初めて少しずつでも自分のものにしていきたいものです。

CentOS 5.5 上にRuby 1.9.2 RC2 インストール

以下のサイトを参考にしながらバージョンを1.9.2に置き換えると問題なくインストールできました。

How to Install Ruby 1.9 on CentOS 5

# yum groupinstall 'Development Tools'
# yum install readline-devel
# cd /usr/local/src
# wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-rc2.tar.bz2
# tar xzvf ruby-1.9.2-rc2.tar.bz2
# cd ruby-1.9.2-rc2
# ./configure && make
# make install

あとはシンボリックリンクを張ります。

# ln -s /usr/local/bin/ruby /usr/bin/ruby192

Ruby 1.8.5と共存させたかったので、今回は'ruby192'と別名にしました。


次にrubygemsの設定。
Download RubyGemsからTGZファイルをダウンロード。

そしてページに書いてあるようにセットアップ。

# ruby setup.rb


zlibがないと怒られたので
CentOSにRubyOnRailsをセットアップを参考にzlibのコンパイルと設定。

これでなんとかなりました。

Rubyメモ

2バイト文字が混じったテキストを読もうとしたときに以下のエラー

in `scan': invalid byte sequence in UTF-8 (ArgumentError)

UNICODE形式のテキスト

エンコードを指定したい

Ruby1.9ではKCODEが使えなくなった
どうすればいいかは以下
http://d.hatena.ne.jp/maluboh/20080222/p1

1.9での文字エンコーディング関連は以下
http://d.hatena.ne.jp/rubyco/20060318/charcount


文字列のマッチングを行うときに、面倒くさいのでupcaseかdowncaseで揃える。

s = "I love Ruby"

s1 = s.upcase #=> "I LOVE RUBY"
s2 = s.downcase #=> "i love ruby"

Arrayから重複要素を取り除く
array.uniq

パラメータをSQLiteで管理するための移行作業

今までテキストデータで管理していた諸々のパラメータですが、思い切ってSQLiteで管理できるように改良しました。開発が進むにつれてキャラクタやオブジェクトが増えてくると、テキストデータで管理するような単純な方法はつらいし自前でパーサーも書かないといけないのでコード量も増えます。

VC++ & DXライブラリの環境なので以下のサイトを参考に"lib"コマンドでLIBファイルとDLLファイルを作成しました。

SQLite Vesion 3 DLL版 を呼び出すC/C++アプリケーションの構築
http://hp.vector.co.jp/authors/VA002803/sqlite/capi3dll.htm

現状、RPGのようにパラメータが頻繁に書き換わることはないので、PupSQLiteというツールでGUI上からテーブル・データ作成を終わらせてしまって、プログラムからはそれをSELECT文で読み込むといった具合です。今はまだコレで充分。

Pup's Atelier
https://www.eonet.ne.jp/~pup/

パラメータは外部に置いておき、いつでもロードできるようにするというのは途中の実装が面倒くさいですが、一度作ってしまえばリターンはとても大きいと思います。Game Programming Gems Vol.1 の一番最初に書かれていることですね。

一つ予想もしなかった箇所でバグが出ていますが、それが終われば前のエントリで挙げていたパターンのひとつ、Proxyパターンを実装して描画コストを下げたいと思います。

ゲーム最適化のために勉強したいデザインパターン

Factory Method
Flyweight
Proxy

どれも基本中の基本のものだけど、特に生成系はしっかり押さえないと3D-TPSならすぐに30FPS下回ってカクカクになる。問題に直面しない限り、基本をしっかり勉強しようという考えに至らないのがまたなんとも……。

大学で研究をしたり、趣味で絵を描いたりしていると、なんだか感覚や考え方が変になってくることがある。たとえば絵を描く時にありがちなんだけど、人は描けてもそれ以外のものが描けない、あるいは空間の中で共存させることができないという悩みがある。いろんな練習方法や技法があるけれど、ものとものの接点だけに注目したらどうかと考えるようになって、頭から離れなくなってしまった。だってそうじゃないか、床と椅子は椅子の脚の部分が接地しているから椅子になりえるのであってそれが空間じゃないのか、人の腰と椅子が接地するからこそ、座っているという動作が生まれるんじゃないのか。こんな考え方で絵を描くのも面白いかもしれない。上手くいくか分らないけどね。

で、そうしていると感覚がずれてきて、身の周りのものがネットワークにしか見えなくなってくる。家具や街の電灯、自転車、樹木、なんでも他のものと接地することで存在していて、リンクしているんだと、少しだけ嬉しくなった。