mysqlを稼動させたまま、複数テーブルのレプリケーションを行う。

社内で運用中のRailsアプリケーションでは、データベースをShardingして一つのmysql上に複数DBがのっかっている状態になっている。
このデータベースはmasterとslaveで分散させているのですが、slaveの負荷が高くなってきた為にslaveの数を増やすことになりました。

その為にmasterのdumpをとってslaveに流してやります。--flush-logオプションをつければあるタイミングでbin-logを移動してくれるので、レプリケーション先でMASTER_FILE_LOGを新しいbin-logを指定してやればいいのです。

master-db

master-dbでのファイルの位置を確認し、dumpを取ります。

 mysql> show master status;
+----------------+-----------+--------------+------------------+
| File           | Position  | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+-----------+--------------+------------------+
| log-bin.000061 | 119120300 |              | mysql            |
+----------------+-----------+--------------+------------------+
 mysqldump --skip-lock-tables --flush-log --single-transaction --user=root --password --database database-1 database-2 database-3 | gzip -c > database_dump_`date +%Y%m%d_%H%M`.gz

で、log-binファイルを確認する。

 sudo ls -l mysql/var/log-bin
(省略)
-rw-rw---- 1 mysql staff     56193 2010-12-17 13:10 log-bin.000057
-rw-rw---- 1 mysql staff 109617173 2010-12-17 15:02 log-bin.000058
-rw-rw---- 1 mysql staff  26931166 2010-12-17 15:15 log-bin.000059
-rw-rw---- 1 mysql staff 135276244 2010-12-17 16:02 log-bin.000060
-rw-rw---- 1 mysql staff 120524056 2010-12-17 16:39 log-bin.000061
-rw-rw---- 1 mysql staff   5468112 2010-12-17 16:41 log-bin.000062
-rw-rw---- 1 mysql staff    137097 2010-12-17 16:41 log-bin.000063
-rw-rw---- 1 mysql staff   4438152 2010-12-17 16:42 log-bin.000064

なんと、log-binファイルが想定以上に移動している。

どうやら一緒に指定しても、dumpを取るdatabase毎にflushしちゃってるみたい。これだと、slaveのレプリケーションを64から開始しようとしても62に含まれるdatabase-1に対するクエリ、63に含まれるdatabase-1, 2に対するクエリが実行されていないことになってしまう。そこで、取ったdumpと共にlog-binファイルからもクエリを実行してやる必要がある。

以下のファイルをslaveにコピーする。

 scp database_dump_YYYYmmdd_HHMM.gz slave-db:/tmp
 sudo cp mysql/var/log-bin/log-bin.000062 /tmp/
 sudo cp mysql/var/log-bin/log-bin.000063 /tmp/
 sudo chmod +r /tmp/log-bin.00006*
 for log in 62 63
   scp /tmp/log-bin.0000${log} parkgree-db-slave-03:/tmp
slave-db

slaveを止めて、データベースを作り直す。

mysql> stop slave
for db in {1..3}
  mysql -uroot -p -e'drop database database-'$db
for db in {1..3}
  mysql -uroot -p -e'create database database-'$db

masterの位置を設定しなおす。

 mysql> CHANGE MASTER TO
 mysql> MASTER_LOG_FILE='log-bin.000064',
 mysql> MASTER_LOG_POS=0;

dumpファイルを実行する

gunzip -c /tmp/database_dump_YYYYmmdd_HHMM.gz | mysql -uroot -p

忘れずにbinlogファイルを読み込む

 mysqlbinlog --database=database-1 log-bin.000062 | mysql -uroot -p database-1
 mysqlbinlog --database=database-1 log-bin.000063 | mysql -uroot -p database-1
 mysqlbinlog --database=database-2 log-bin.000063 | mysql -uroot -p database-2

で、slaveを再開する。

mysql> start slave

DBが同期されていることが確認出来ればOKです。

max connection数を調べる

起動してからの最大値を調べる。チューニングの時に重宝。

mysqladmin -uroot -p extended-status | egrep '(Max|Thread_)'

おおよそのコネクション数はこんな感じで見積もれる。

最大コネクション数 = 1台のWebサーバのプロセス数 * Web サーバ台数 * DBサーバに載せられてるDB数

tcpflowを使ってパケット監視

何かトラブルが起こったとき、アプリケーションのログを見るよりもパケット直接見た方が早いってばあちゃんが言ってた。

参考:http://www.slideshare.net/takafumionaka/ss-5852561
とあるアプリの開発運用(トラブルシュート)

Debian環境で使う。

まずはインストール

sudo aptitude install tcpflow

tcpflowのヘルプを見る。

usage: tcpflow [-chpsv] [-b max_bytes] [-d debug_level] [-f max_fds]
          [-i iface] [-w file] [expression]

		-b: max number of bytes per flow to save
		-c: console print only (don't create files)
		-C: console print only, but without the display of source/dest header
		-d: debug level; default is 1
		-e: output each flow in alternating colors
		-f: maximum number of file descriptors to use
		-h: print this help message
		-i: network interface on which to listen
		(type "ifconfig -a" for a list of interfaces)
		-p: don't use promiscuous mode
		-r: read packets from tcpdump output file
		-s: strip non-printable characters (change to '.')
		-v: verbose operation equivalent to -d 10
		expression: tcpdump-like filtering expression
  • c を忘れると大変なことになるので忘れないといいと思います。

監視するネットワークアダプタを探す。

ifconfig -a

で、監視

sudo tcpflow -c port 80 -i lo

80番ポートでアクセスするとログが流れるので、監視成功する。

gitをインストールする

会社では主にDebian環境、自宅ではCentOS環境を使っている。

殆どCUI環境で作業をしているのでアプリの開発なんかは問題ないのですが、
環境設定なんかは手作業で移すのはだるすぎる。

なので、もういっそgithubを使って
どこでも自由にDL出来る様にしちゃおう、という試み。

The world’s leading software development platform · GitHub

ついでに、お互いの環境での操作方法なんかもまとめてしまえ。

CentOSにインストール

リポジトリyum設定ファイルに追加する
#dag
[dag]
name=DagRPM Repository for Redhat EL5
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=1
enabled=1
gpgkey=http://dag.wieers.com/packages/RPM-GPG-KEY.dag.txt
yumでインストール
install -y install 

Debianにインストール

リポジトリをapt設定ファイルに追加する
  • /etc/apt/sources.list
deb http://ftp.jp.debian.org/debian/ lenny main non-free
aptitudeでインストール
aptitude -y install git-core

(続くよ。)

centosにruby1.9.2とrails3.0.3をインストールする

公式からダウンロードするです。
http://www.ruby-lang.org/ja/:ruby

cd /usr/local/src
wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p0.tar.gz
tar zxf ruby-1.9.2-p0.tar.gz
cd ruby-1.9.2-p0
./configure
make
make install

centosはまだ動作検証されていないらしいので、何か変なことがおこるかも。

で、このままrailsをインストールする。

gem install rails

`gem_original_require': no such file to load -- zlib (LoadError)

ありゃ。

cd ext/zlib/
ruby extconf.rb --with-zlib-include=/usr/include -with-zlib-lib=/usr/lib

エラー。zlibないらしい。

yum install zlib

既にインストールされてるって言われる…。

yum list | grep zlib

で、検索。zlib-develってのがそれっぽいのでインストール。

yum install zlib-devel
ruby extconf.rb --with-zlib-include=/usr/include -with-zlib-lib=/usr/lib
make
make install

いけたいけた。

gem install rails

よし、railsいじろー。

Rails3でscaffold

Rails3になってコマンドが変わっていたのでメモしてきます。

ブログっぽいのを想定して作ってきます。

以下はRAILS_ROOTにて実行。
まずは記事のCRUDを揃える。

config/database.ymlを確認したら、scaffoldする。

rails g scaffold article title:string body:string
rake db:migrate

おー。全部railsで出来る様になってるのね。

DBが出来ているのを確認した。