2009年10月アーカイブ

まだ、経過観察中ながら、異常傾向がみられなくなった。

テーブル単位での ignore だから、キャラクタセットの切り替えが(バイナリログからクエリを実行するスレーブサーバでは)本来期待するようには行われなかったという事だと思ってます。

そもそも、replicate-wild-ignore-table の使い方というか、使ってよい条件を満たせていなかったのかもしれません。元々、滅多に使わないテーブルに関する設定だったので、これで収まるならそれはそれでよいかな、といった所です。

本当に解決していたらうれしい限りです。

何が悪いのかよくわからない。

問題が発生したレコードのタイムスタンプとバイナリログを確認すると、replicate-wild-ignore-table でレプリケーション対象から外したテーブルへのクエリが実行された近辺だという事はわかりました。

また、バイナリログがローテーションされ、新しいバイナリログからレプリケーションする時には問題が解消されているらしき事もわかりました。

何かでスレーブサーバの SQL スレッドのキャラクタセットの設定がおかしくなり、バイナリログが変わって改めてキャラクタセットが設定されたために治ったのではなかろうかと疑っています。

問題発生の傾向が結構あからさまなので、その問題発生近辺のバイナリログをみれば、何が起きているのかすぐわかるかと思った訳ですが、いまいちよくわかりません。

ひとまず、「問題発生の傾向が結構あからさま」という事がわかっただけでも前進でしょうか。完全に不規則だったら、自分にはお手上げでした。

まずは replicate-wild-ignore-table をやめてみて、それでだめなら必要そうなログを記録して、再検討かなと思っています。

会社でそんな話を聞きましたが、自分の環境で全く気づかなかったのはなんでだろう?

Googole 経由で Leopard の頃の記事が見つかりました。
MacPorts でインストールした Ruby は遅いらしい - kwatchの日記

記事のテストを自分の環境でも試してみました。

# fib.rb
def fib(n)
  n <= 1 ? 1 : fib(n-1) + fib(n-2)
end

if __FILE__ == $0
  require 'benchmark'
  n = $N ? $N.to_i : 30
  Benchmark.benchmark do |x|
    x.report("fib(#{n})") do
      fib(n)
    end
  end
end
$ uname -a
Darwin imac.local 10.0.0 Darwin Kernel Version 10.0.0: Fri Jul 31 22:46:25 PDT 2009; root:xnu-1456.1.25~1/RELEASE_X86_64 x86_64
$ port installed ruby
The following ports are currently installed:
  ruby @1.8.7-p174_0+darwin+thread_hooks (active)
$ /usr/bin/ruby -v -s fib.rb -N=33
ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]
fib(33)  4.680000   0.010000   4.690000 (  5.324309)
$ /usr/local/bin/ruby -v -s fib.rb -N=33
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0], MBARI 0x6770, Ruby Enterprise Edition 20090928
fib(33)  3.970000   0.010000   3.980000 (  4.786717)
$ /opt/local/bin/ruby -v -s fib.rb -N=33
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
fib(33)  4.790000   0.010000   4.800000 (  5.772489)

とりあえず、参考記事ほどの差はありませんでした。

後は、Ruby Benchmark Suite を実行してみようと思いますが、結構な時間がかかる様なのでここまで。

テーブル名を実行時に取得しなければならないために、実行時にモデルクラスを生成してたら、無遠慮に Class.new してて失敗した件。

細かく説明しませんが、ユーザごとにテーブル定義を決定する様な仕組みを、以下のページでサンプルとして書いたように Class.new(ActiveRecord::Base) して実装していました。
KoshigoeBLOG: メタクラスってなんなんだすか?(1)

その発想(?)自体は別にどうという事でもありませんが、毎回 object_id の異なる同名クラスを作成してしまって問題を引き起こしていた事に気がつきました。何が問題かというと、永続的なプロセスの中で、何度も ActiveRecord::Base を継承した同名テーブルの(object_id の異なる)モデルクラスを作成してしまうと、GC されずにメモリに積み上がっていくという事です。

以下のコードの通り、ActiveRecord::Base を継承する度に、ActiveRecord::Base の @@subclasses[] に派生クラスが登録される様です。

module ActiveRecord
  ...
  class Base
    ...
    def self.inherited(child) #:nodoc:
      @@subclasses[self] ||= []
      @@subclasses[self] << child
      super
    end
    ...
end

未だ Rails の事をよくわかっていないのでこれ以上は(少なくとも今は)書きませんが、今までだいぶ浮かれポンチな事をしていたな、と。

でも、すっきりして一安心です。

irb で readline.bundle が _system_free で Symbol not found がどうこうとか。

インストール(コンパイル)は、installer で Bus error になったので、ドキュメントにある手作業コンパイルでやりました。
Ruby Enterprise Edition Features Guide

$ wget http://rubyforge.org/frs/download.php/64475/ruby-enterprise-1.8.7-20090928.tar.gz
$ tar xvzf ruby-enterprise-1.8.7-20090928.tar.gz
$ PREFIX=/usr/local
$ cd ruby-enterprise-1.8.7-20090928/source/distro/google-perftools-*
$ ./configure --prefix=$PREFIX --disable-dependency-tracking
$ make libtcmalloc_minimal.la
#sudo mkdir -p $PREFIX/lib
#sudo rm -f $PREFIX/lib/libtcmalloc_minimal*.so*
#sudo cp -Rpf .libs/libtcmalloc_minimal*.bundle* $PREFIX/lib/
$ cd ../..
$ ./configure --prefix=$PREFIX --enable-shared --enable-pthread
$ gcc -dynamiclib system_allocator.c -install_name @rpath/libsystem_allocator.dylib -o libsystem_allocator.dylib
$ sudo install libsystem_allocator.dylib $PREFIX/lib/
$ make PRELIBS="-Wl,-rpath,$PREFIX/lib -L$PREFIX/lib -ltcmalloc_minimal"
$ sudo make install

# 始まりの行は、".libs/libtcmalloc_minimal*.bundle*"が見つからず実行してません。ここはコンパイルに失敗したら省略しとけ的に解釈して飛ばしました。

ruby で Ruby スクリプトファイルを実行する事はできましたが、irb が readline.bundle がらみで終了してしまいます。

irb(main):001:0> puts 'hoge'
dyld: lazy symbol binding failed: Symbol not found: _system_free
  Referenced from: /usr/local/lib/ruby/1.8/i686-darwin10.0.0/readline.bundle
  Expected in: flat namespace

dyld: Symbol not found: _system_free
  Referenced from: /usr/local/lib/ruby/1.8/i686-darwin10.0.0/readline.bundle
  Expected in: flat namespace

[1]    54039 trace trap  /usr/local/bin/irb

ひとまず、Realine を疑って /usr/local にインストール。

$ wget ftp://ftp.gnu.org/gnu/readline/readline-6.0.tar.gz
$ tar xvzf readline-6.0.tar.gz
$ cd readline-6.0
$ ./configure --prefix=/usr/local
$ make
$ sudo make install

REE を改めてコンパイル。configure から make までの間はよく理解していません。

$ cd ~/tmp/ruby-enterprise-1.8.7-20090928/source
$ make clean
$ ./configure --prefix=$PREFIX --enable-shared --enable-pthread --with-readline-dir=/usr/local
$ gcc -dynamiclib system_allocator.c -install_name @rpath/libsystem_allocator.dylib -o libsystem_allocator.dylib
$ sudo install libsystem_allocator.dylib $PREFIX/lib/
# Makefile の LIBS 行の修正
$ make PRELIBS="-Wl,-rpath,$PREFIX/lib -L$PREFIX/lib -ltcmalloc_minimal"

残念ながら、今度は make で Bus error になりました。configure に --with-readline-dir を与えてみましたが、unrecognized という警告が出てしまい、確認すると configure のオプションに --with-readline-dir は見当たりません。参考記事の通り、installer を使う事にしました。
Snow LeopardにRuby Enterprise Editionを入れる - おもしろWEBサービス開発日記

$ cd ~/tmp/ruby-enterprise-1.8.7-20090928
$ sudo ./installer -a /usr/local --no-tcmalloc -c --with-readline-dir=/usr/local -c --enable-shared -c --enable-pthread
$ /usr/local/bin/irb
irb(main):001:0> puts 'hoge'
hoge
=> nil
irb(main):002:0> 

という訳で、 irb も無事動きました。

ほか、gem や rails および passenger についてはまだ試してません。


ひょっとして、インストールは REE 専用のディレクトリ下におさめる様にして、あれこれ独立しておいておくべきなんですかね…?

プロフィール

このアーカイブについて

このページには、2009年10月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2009年9月です。

次のアーカイブは2009年11月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。