投稿日 2008年12月19日 金曜日 カテゴリ mysql 投稿者 sugimotoコメント(0) » 

MySQLを使っていて、次の2つの文字列比較

  • = で比較する場合
  • Likeで比較する場合

でバックスラッシュの入った文字列を検索する場合、で \ の数が違いました。

= で比較の場合、2重にすることでマッチする

mysql> select 'foo\\bar' = 'foo\\bar';
+-------------------------+
| 'foo\\bar' = 'foo\\bar' |
+-------------------------+
|                       1 |
+-------------------------+
1 row in set (0.00 sec)

= で比較の場合、4重にするとマッチしない

mysql> select 'foo\\bar' = 'foo\\\\bar';
+---------------------------+
| 'foo\\bar' = 'foo\\\\bar' |
+---------------------------+
|                         0 |
+---------------------------+
1 row in set (0.00 sec)

like で比較の場合、2重だとマッチしない

mysql> select 'foo\\bar' like '%\\%';
+------------------------+
| 'foo\\bar' like '%\\%' |
+------------------------+
|                      0 |
+------------------------+
1 row in set (0.00 sec)

like で比較の場合、4重だとマッチする

mysql> select 'foo\\bar' like '%\\\\%';
+--------------------------+
| 'foo\\bar' like '%\\\\%' |
+--------------------------+
|                        1 |
+--------------------------+
1 row in set (0.02 sec)

MySQLのマニュアルにありました。

注記 :MySQL は C エスケープ構文をストリングで使用するため ( 例えば、‘\n’ で改行文字を表現 ) 、LIKE ストリングで使用する ‘\’ はすべて二重にする必要があります。例えば、‘\n’ を検索するには、‘\\n’ と指定します。‘\’ の検索には、‘\\\\’ と指定します。これは、バックスラッシュがパーサによってストリップされ、そしてパターンのマッチが実行された時にもストリップされるため、ひとつのバックスラッシュを残してマッチさせるためです。( 例外 :パターン ストリングの最後では、バックスラッシュは ‘\\’ と指定できます。ストリングの末尾では、エスケープの後に連なるものがないため、バックスラッシュはそのもので独立することができます ) 。
投稿日 2008年4月21日 月曜日 カテゴリ mysql, rsync, CMS, MODx 投稿者 sugimotoコメント(3) » 

OpenGrooveの検索アプライアンスサーバ「zeera document search」の製品サイトはMODx CMSを利用して構築しています。

サイトの更新は

  1. 別に用意したテスト環境で更新
  2. 更新に問題がないか社内でチェック
  3. 本番環境に更新分を反映

という手順でやっているのですが、#3の反映作業は手作業にすると、手間がかかり、反映漏れが出るもとになります。

そこで、ssh, rsync, mysqldumpを使って、#3の手順を自動化し、更新分を確実に反映することにしました。

1. 反映の方法

自動化の方法の概要を簡単に説明すると以下の通りです。

- rsyncでディレクトリの同期

MODx CMSは、

   top --- manager
        +- assets

というディレクトリ構造をしていて、assetsにテンプレート,CSS,imageなどが保存されています。 逆にmanagerにはMODxのコアスクリプトと設定ファイルがあります。 そのため、assetsをrsyncで同期することにします。

- データベースの更新

MODx CMSはMySQLでデータを保存しています。 環境依存なデータはsite_settingsテーブルに集約されているため、このテーブル以外をコピーします。

- サーバ間の接続はSSHを使用する

自動化するためにパスフレーズなしの鍵をつくり、自動接続して本番環境にデータを転送します。

2. サーバの設定

自動化のためにテストサーバから本番サーバにSSHで接続するための環境を作ります。

- 鍵の作成

テストサーバで鍵を作成します。

> ssh-keygen -t rsa

パスフレーズを聞かれますが、入力せずにリターンキーを押し、パスフレーズなしで作成します。 出来上がった公開鍵は本番サーバに転送し、/home/[user]/.ssh/authorized_keysに入れておきます。

3. データベースの更新の設定

mysqldumpでテスト環境のデータベースをdumpして、本番環境にdumpデータを反映します。

まず、テスト環境のデータをコピーし、本番環境に反映するためのSQL文のファイルを生成するシェルスクリプトを用意します。

[dump_modx_data.sh]

#!/bin/bash
work_dir=/home/user/xxxxx
filename=dumpfile.dump
file_path=$work_dir$filename

echo "" > $file_path

# データを削除するSQL文をファイルに書き込み
echo "TRUNCATE TABLE active_users;" >> $file_path
...site_settings 以外のテーブルについて同じ

# データを INSERT するSQL文をファイルに書き込み
mysqldump -u [user] -p[password] [database] --no-create-info \
        --tables [テーブルを列挙] >> $file_path

これで、データベース反映用のSQLスクリプトがダンプされます。

4. データベース反映用のSQLスクリプトを本番サーバで実行する

次に、先ほどのシェルスクリプトで作成したデータベース反映用のSQLスクリプトを本番サーバで実行します。

[insert_dumpfile.sh]

#!/bin/bash
work_dir=/home/user/workdirectory
filename=dumpfile.dump
file_path=$work_dir$filename
#本番サーバで実行するシェルスクリプト
command=remote_commands.sh

#SQLスクリプトを本番サーバにコピー
scp $file_path remoteuser@remoteserver:/temporary/dir/.
#sshでログインしてSQLスクリプトを実行
ssh -l remoteuser remoteserver < $work_dir$command
#作業後に削除
rm -f $file_path

[remote_commands.sh] < 本番サーバー上で実行されるシェルスクリプト

#!/bin/bash
filename=/temporary/dir/dumpfile.dump
mysql -u [user] -p[password] [database] < $filename
rm -f $filename

5. rsync でディレクトリをコピーする

スタイルシートや、画像ファイルはデータベースには保存されていないので、rsyncでディレクトリの同期をして本番サーバに反映します。assets ディレクトリ全体を同期の対象にします。

[rsync_assets.sh]

#!/bin/bash
#rsyncコマンドでassetsディレクトリの同期
#削除されたファイルも反映する
#remoteディレクトリは親ディレクトリを指定する
rsync -a --delete --exclude "cache/docid_*.pageCache.php" /path/to/local remoteserver:/parent/path/to/remote    

6. 反映の実行

これまでに作成したシェルスクリプトを

  1. dump_modx_data.sh
  2. insert_dumpfile.sh
  3. rsync_assets.sh

の順に実行すると自動的にテストサーバーのデータが本番サーバーに反映されます。

3つのファイルを一つにまとめて、cronに登録しておけば、毎晩、自動的にテストサーバーのデータが本番サーバーに反映されます。