homebrewでMySQLがインストールされた環境でmysql2 gemをbundle installする方法

毎回ハマるのでメモしておきます。

まずMySQLがインストールされている場所を特定します。

brew info mysql55

そうするとそれっぽいディレクトリ情報が表示されるので、次にRailsプロジェクト配下の.bundle/configに以下のように追記します。

BUNDLE_BUILD__MYSQL2: '--with-mysql-lib=/usr/local/opt/mysql55/lib --with-mysql-dir=/usr/local/opt/mysql55 --with-mysql-config=/usr/local/opt/mysql55/bin/mysql_config --with-mysql-include=/usr/local/opt/mysql55/include/mysql'

上記の設定値は環境によって違うと思うので、brew infoした結果で書き換えてください。

ハマったのはwith-mysql-includeオプションのところ。includeディレクトリの下にもう一階層(ここではmysqlディレクトリ)があったことに気づかず、30分以上悩みました。。

SSH経由でMySQLの準同期レプリケーションを行う方法

SSHで暗号化された通信経路でMySQLの準同期レプリケーションを行うための方法を紹介します。今回使用したMySQLのバージョンは5.5.30です。

 

1. マスタとスレーブと間でSSH経由で通信ができるようにする

レプリケーションの設定に入る前に、マスタDBがあるサーバー(以降、マスタと表記)とそのレプリケーション先のDBがあるサーバー(以降、スレーブと表記)の間の通信がちゃんとできるか確認しましよう。

 

------- スレーブでやること ----------
まず、以下のコマンドを実行してSSHポートフォワーディングによってスレーブの10000ポートからマスタの3306ポートにアクセスできるようにします。
ssh -f -N -C -L 10000:localhost:3306 user01@master.tamurasouko.com -p 22

上記のコマンドで下図のようなポートフォワーディングを実現しています。このコマンドの詳細についてはこちらのメモを参考にしてください。
ssh_master_and_slave

 

-------マスタでやること ----------
次に、マスタDBにMySQLクライアントで接続し、以下のコマンドでレプリケーション用のユーザを作成します。
mysql> GRANT REPLICATION SLAVE ON *.* TO slave_user@'localhost' IDENTIFIED BY 'slave_password';

上記のコマンドにはちょっとしたポイントがあります。それはユーザ(slave_user)のホストlocalhostにしている点です。

変だとおもいませんか?マスタに接続してレプリケーションを行うのは外部サーバーのスレーブなのに、マスタへの接続に使用するユーザのホストをスレーブではなく、localhost、つまりマスタ自身にしているところが一見おかしいように思えます。

このような設定にしているのはSSHのポートフォワーディングを利用しているためです。ポートフォワーディングはスレーブのlocalhostから通信を「転送」しているため、その通信を受け取ったマスタもlocalhostからの通信だな、と判断するわけです。(たぶん。このあたりの理解はあやしいです。)

レプリケーション用のユーザの作成が完了したら、以下のコマンドをMySQLクライアントで実行して作成したユーザをDBMSに反映させます。
mysql> FLUSH PRIVILEGES;

 

------- スレーブでやること ----------
ここまで設定が終わったら、スレーブからマスタにポートフォワーディングで接続できるか以下のコマンドを実行して確認します。
mysql -u slave_user -p -h 127.0.0.1 --port=10000

問題なく実行できればOKです。

 

2. 準同期レプリケーションのための設定をする

マスタ・スレーブ間の通信ができることを確認したところで、レプリケーションの設定をMySQLの設定ファイル(/etc/my.cnf)に記述していきます。設定はマスタ、スレーブそれぞれ行う必要があります。以下の設定を追記したらMySQLサーバーを両方とも再起動してください。

マスタのmy.cnf

# サーバーID
server-id=10

# バイナリーログファイルを生成
log-bin
# ログの保持を保証する期間
expire_logs_days=14

# レプリケーションプラグイン(マスタ用)を読み込む
plugin-load=rpl_semi_sync_master=semisync_master.so

# このサーバーをレプリケーションのマスタに指定
rpl_semi_sync_master_enabled=1
# スレーブから応答が帰ってこない場合の待ち時間を指定(ミリ秒)
rpl_semi_sync_master_timeout=1000

 

スレーブのmy.cnf

# サーバーID(※マスタより大きな値を設定)
server-id = 11

# レプリケーションプラグイン(スレーブ用)を読み込む
plugin-load=rpl_semi_sync_slave=semisync_slave.so

# このサーバーをレプリケーションのスレーブに指定
rpl_semi_sync_slave_enabled=1

 

3. データのコピーとログ位置を確認する

レプリケーションを始める前にマスタとスレーブのデータが同一である必要があります。そのためにマスタDBの全データをダンプ(別ファイルに書き出すこと)し、そのダンプデータをスレーブにコピーします。

 

------- マスタでやること ----------
まず、マスタのDBがこのコピー作業中に変更されないようにMySQLクライアントから以下のコマンドを実行し、ロックします。
mysql> FLUSH TABLES WITH READ LOCK;

この状態で以下のコマンドをシェルから実行し、マスタDBの全データをダンプします。
mysqldump -u root --password='root_password' --all-databases --master-data --events > all_dump.db

また、このときのバイナリーログの位置を以下のコマンドをMySQLクライアント上で実行して取得します。このログ位置はスレーブにてレプリケーションマスタを設定するときに使用します。(後述します)
mysql> SHOW MASTER STATUS;

ここまでの作業が終わったら、以下のコマンドでロックを解除します。
mysql> UNLOCK TABLES;

ここまでがマスタ側での作業です。

 

------- スレーブでやること ----------
次に、マスタDBのダンプデータをSFTPなどを用いてスレーブにもってきます。そして以下のコマンドを実行してスレーブDBにマスタDBのデータを投入します。
mysql -u root ---password='root_password' < all_dump.db

 

4. スレーブにレプリケーション先を設定する

------- スレーブでやること ----------
マスタとスレーブのデータが同一になったところで、スレーブにレプリケーション元のマスタを設定します。スレーブで以下のコマンドを実行します。
mysql> CHANGE MASTER TO master_host='localhost', master_port=10000, master_user='slave_user', master_password='slave_password', master_log_file='mysqld-bin.000001', master_log_pos=2530

SSHポートフォワーディングによってマスタに接続するため、コマンドのmaster_hostやmaster_portの値は上記のようになります。また、前節においてマスタでSHOW MASTER STATUSコマンドを実行して得られたログ位置をmaster_log_posの値として設定しています。

 

5. レプリケーション開始

------- スレーブでやること ----------
スレーブで以下のコマンドを実行すれば準同期レプリケーションが開始されます。
mysql> START SLAVE;

 

6. レプリケーションが行われているか確認

------- スレーブでやること ----------
実際にマスタを更新してデータがスレーブにも更新されるか見て確認してもいいですが、以下のコマンドをスレーブ側で実行して確認することもできます。(両方やっておけば確実です)
mysql> SHOW SLAVE STATUS\G

上記のコマンドを実行すると、Slave_IO_RunningSlave_SQL_Runningという項目が表示されます。これらがどちらもYesになっていればOKです。

 

環境

CentOS 6.4
MySQL 5.5.30
openSSL 1.0.0

 

 

SSHのポートフォワーディングでMySQLに接続する方法

SSHポートフォワーディング(トンネリング)を利用して、外部サーバーで稼働しているMySQLデータベースに接続する方法を紹介します。

 

SSHポートフォワーディングとは

ssh_portforwarding

SSHポートフォワーディングの仕組みがわかってしまえば、今回の話は簡単です。要は上図のように、SSHによって確立された通信経路を利用してクライアントの10000ポートをサーバーの3306ポートにマッピングするわけです。

つまり、このポートフォワーディングが行われているときにクライアントのローカルの10000ポートに接続すれば、サーバーの3306ポートに接続していると変わらないというわけです。

しかも、このとき通信経路はSSHによって暗号化されおり、また接続先のポートがファイアウォール等で閉じられていたとしてもSSHのポートさえ開いていれば利用可能という非常に使い勝手がよい仕組みになっています。

 

ポートフォワーディングを実行する

では、さっそくSSHポートフォワーディングをやってみましょう。以下のコマンドを実行してください。
ssh -f -N -C -L 10000:localhost:3306 user01@xxx.tamurasouko.com -p 22

上記のコマンドを解説します。まずの"-L 10000:localhost:3306"の部分ですが、これはローカルの10000ポートを接続先サーバーの3306ポートにマッピングする、という指定です。次に、"user01@xxx.tamurasouko.com -p 22"の部分では、xxx.tamurasouko.comというサーバーの22ポートにユーザ名user01で接続する、という指定です。この22というポートはSSHの接続を待ち受けているサーバーのポート番号になります。
また、オプションの意味はそれぞれ以下の通りです。

オプション 説明
-f このポートフォワーディングをバックグラウンドで実行する。(必須
-N SSHトンネリングのみに使用する。(必須
-C データを圧縮して送る。

尚、ポートフォワーディングを停止したい場合はps aux|grep sshコマンドで当該プロセスを探し、killすればいいだけです。

 

外部サーバーのMySQLに接続する

外部サーバーの3306ポートでMySQLが通信を受け付け、かつ上記のポートフォワーディングが行われている場合、クライアントは次のコマンドで外部サーバーのMySQLに接続できます。
mysql -u root -p -h 127.0.0.1 --port=10000

portオプションでポートフォワーディングの窓口として設定したローカルの10000番ポートを指定すれば外部サーバーで稼働しているMySQLに接続することができます。

ちなみに"-h 127.0.0.1"を指定していないとうまくフォワーディング できませんでした。-hオプションは接続先を指定するオプションですが、上記の例ではローカルホストの10000ポートを窓口としてサーバーの3306ポートに接続しているわけですから、明示的に接続先がローカルホストであることを示す必要があります。

 

以上になります。今回はMySQLサーバーへに接続でしたが、SSHのポートフォワーディングは他にもいろいろ応用ができそうですね。
⇒ 応用例:[SSH経由でMySQLの準同期レプリケーションを行う]

 

環境

CentOS 6.4
MySQL 5.5.30
openSSL 1.0.0

 

よく使うNginxの設定

Nginxの設定ファイル(*.conf)の書き方をいつも忘れてしまうので、メモを残しておきます。

▼基本設定

http {
    ...

    # "you should increase server_names_hash_bucket_size"というエラーが出た時の対応
    server_names_hash_bucket_size  64;

    # 最大アップロードサイズを設定
    client_max_body_size 32m;

    # serverの設定は個別ファイルから読み込むようにする
    include /opt/nginx/conf/conf.d/*.conf;

    ...
}

 

▼リダイレクト(URL書き換え)

server {
  # 80番ポートにアクセスしてきたらSSL通信用のURLにリダイレクト
  listen 80;
  server_name xxx.tamurasouko.com;
  rewrite ^(.*) https://xxx.tamurasouko.com$1 permanent;
}

 

環境

Nginx 1.2.6

 

Monitによるサーバー監視

Monitというモニタリングソフトを使ってみました。導入も設定も簡単でした。

 

インストール

yumを使えば簡単です。以下のコマンドを実行すればインストールは完了です。
sudo yum install monit

 

基本設定

/etc/monit.confファイルに以下の設定を記述するだけで、問題なく動作します。

# 120秒ごとに監視を行う
set daemon  120
# アラートメールの送信サーバーを指定(※Gmailを使用する場合の例)
set mailserver smtp.gmail.com port 587 username "あなたのGmailアドレス" password "あなたのパスワード" using tlsv1
# Webブラウザからモニタリング状況を確認できるようにする
set httpd port 2812 and
    allow admin:monit

上記の5行目の設定によって、"http://[Monitが動作しているサーバーのアドレス]:2812"というURLにアクセスすることでモニタリング状況がWebブラウザから確認できます。このときユーザIDをパスワードを求められますが、それぞれ"admin"と"monit"と入力すればログインできます。

 

起動・終了

yumを使ってインストールした場合、Monitをデーモンとして起動するスクリプトが/etc/init.d配下にあるので、このスクリプトを利用します。
起動: sudo /etc/init.d/monit start
終了: sudo /etc/init.d/monit stop

 

監視設定

以下は「www.tamurasouko.comというWebサーバーの80番ポートに接続できるか監視を行い、できなければアラートメールを送信する」という設定の例です。この設定は/etc/monit.confに記述しても動きますが、個別設定用に/etc/monit.dというディレクトリが準備されているので、そこに別ファイルとして保存したほうが管理しやすいと思います。

check host www.tamurasouko.com with address www.tamurasouko.com
      if failed port 80 protocol http
      then alert

 

環境

CentOS 6.3

 

Vimでよく使うコマンド

ファイルを開く :e [ファイルのパス]
単語の削除 diw
画面の水平分割 :sp
画面の垂直分割 :vs
画面間の移動 Ctrl + w & [hjkl]
次の画面に移動 Ctrl + w & w
タブの新規作成 :tabnew 
右のタブに移動 gt
左のタブに移動 gT
指定したタブに移動 タブ番号 + gt
タブを閉じる :tabclose 
置換時に改行を入れる :%s/置換対象文字列/^M/g (※^M は Ctrl+v & Ctrl+m で入力)
バッファの(今まで開いた画面の)履歴表示 :ls またはbuffers
バッファの読み込み :b [バッファ番号] または :buffer [バッファ番号]

 

ファイル間の横断検索

vimgrep [検索対象文字列] [検索範囲]

例)"create_user"という文字列をRubyファイルから再帰的に検索する例
vimgrep create_user **/*.rb

また検索直後に:cwとすると検索結果を一覧できる。

参考:http://qiita.com/yuku_t/items/0c1aff03949cb1b8fe6b

 

gitでよく使うコマンド・設定

操作コマンド

目的・内容 コマンド
ファイル等をgitの管理外にする git rm --cached [ファイル名/ディレクトリ名]
リモートブランチの情報を更新し、既に消されたリモートブランチを非表示にする git fetch --prune
ブランチを削除する git branch -d [ブランチ名]
新しいブランチを作成し、その新しいブランチに移動する git checkout -b [新しいブランチ名]
リモートブランチを元に新しいブランチを作る git branch [新しいブランチ名] origin/[分岐元のブランチ名]
ブランチ間の差分を見る git diff branch_a branch_b
リモートレポジトリのURLを確認する git remote -v
リモートレポジトリの登録を解除する git remote remove [レポジトリ名]
コミットを打ち消す git revert [コミット識別子]
リモートブランチの内容でリセットする git reset -- hard staging/master
特定のファイルの変更履歴を見る git log --follow -p filename [ファイルパス]
コミットの変更内容を見る git log -p [コミット番号]

 

設定

目的・内容 コマンド
出力を色付けする git config --global color.ui true

 

 

 

Sqlite3のコマンドラインツールの使い方

▼コマンドラインツールの起動
sqlite3 [データベースファイル名]
引数に指定したデータベースファイルがない場合は新規作成される。既に存在するデータベースファイルを指定した場合には、そのファイルに格納されているデータを開く。

 

▼コマンドラインツールの終了
.quit
先頭にドット「.」を付けるのを忘れないように。

 

▼テーブルの一覧を取得
SELECT name FROM sqlite_master WHERE TYPE = 'table';

 

▼データの登録
INSERT INTO [テーブル名] ([カラム名1], [カラム名2], ...) VALUES ([値1], [値2], ...)
例)INSERT INTO users (user_id, name) VALUES(1, 'Tamura');

 

▼日付型を取り扱う
以下の例のように「YYYY-MM-DD」形式で指定すればよい。DATE関数で括るれば間違いない。
例)SELECT * FROM receipts WHERE date_of_issue = DATE('2013-03-01') ;