MySQLでレプリケーションのメモ

まずマスター側でバイナリログの出力と識別IDの設定

MySQLのmy.cnfを設定

    • 識別IDはほかとかぶらないようにする
[mysqld]
log-bin      ←バイナリログの設定
server-id=1  ←識別ID

MySQLを再起動

スレイブ側の識別IDを設定

[mysqld]
server-id=2  ←識別ID

マスター側と同じようにmy.cnfを変更したらMySQLを再起動

マスター側にレプリケーションの権限ユーザ作成

スレイブ側からマスター側に接続する時のユーザ

mysql> GRANT REPLICATION SLAVE ON *.* TO repl_user@99.999.99.999 IDENTIFIED BY 'repl_passwd';
                                                       ↑スレイブ側のIPを入れる
Query OK, 0 rows affected (0.01 sec)

マスター側のDBのバックアップ&スレイブ側にDBを展開

マスター側のMySQLのTBLへの書き込みをロック

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.01 sec)

マスター側のバイナリログの状態をメモ(File,Position)

mysql> SHOW MASTER STATUS;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000018 |    17263 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

マスター側DBをバックアップしてロック解除

    • 今回はオフラインバックアップ(バックアップの補足は最下部にメモ)
cd /var/lib/mysql/              ←MySQLのデータディレクトリ
tar cvf ~/xxxxx.tar xxxxx       ←xxxxxDBをアーカイブ
mysql> UNLOCK TABLES;           ←MySQLのTBLへの書き込みロックを解除

スレイブ側でアーカイブされたファイルを展開

         ↓マスター側のIPを入力
scp 99.999.99.999:/root/xxxxx.tar ./xxxxx.tar   ←スレイブ側でscpコマンド
cd /var/lib/mysql/                              ←MySQLのデータディレクトリ
※↓もし対象のDBが存在するなら消しておいたほうがいいかも
rm -r ./xxxxx
↓スレイブ側のMySQLのデータディレクトリに展開
tar xvf ./xxxxx.tar

レプリケーションの開始

マスターに接続するためのパラメータをスレイブ側に設定する

mysql> CHANGE MASTER TO
        MASTER_HOST='99.999.99.999',          ←マスターのホスト名orIPアドレス
        MASTER_USER='repl_user',              ←マスターで作成したレプリケーション権限ユーザ
        MASTER_PASSWORD='repl_passwd',        ←マスターで作成したレプリケーション権限ユーザのパス
        MASTER_LOG_FILE='mysqld-bin.000018',  ←マスターのバイナリログのFile
        MASTER_LOG_POS=17263;                 ←マスターのバイナリログのPosition

レプリケーションスタート

mysql> START SLAVE;

完了

補足

※注意:下記のような事があるとスレイブからマスタに接続できなかったりするので注意(接続できていないとエラーログに出力される)

    • マスターとスレイブのMySQL文字コード等の設定が違う
    • 別のDBを参照しマスターを更新などした場合に参照した別DBがスレイブにない

レプリケーションの停止

mysql> STOP SLAVE;

バイナリログの中身を表示

mysql> SHOW BINLOG EVENTS;

スレイブの状態を表示

mysql> SHOW SLAVE STATUS;

DBのバックアップについて簡単にメモ

MySQLデータのバックアップには大きく分けて2つある
1.オフラインバックアップ
オフラインバックアップはMySQLの書き込みをロックもしくはMySQLを停止させた状態でバックアップをとる

  • MySQLの書き込みをロック
# mysql> FLUSH TABLES WITH READ LOCK; ←MySQLの書き込みロック
# /etc/init.d/mysqld stop ←MySQLサーバ停止

対象のDBのMySQLデータディレクトリをバックアップする

  • これはcp,rsync,tar,gzip等でバックアップ

MySQLの書き込みロックを解除するもしくはMySQLサーバを開始する
2.オンラインバックアップ
オンラインバックアップはMySQLを止めずにバックアップを行う方法

  • mysqlhotcopy、mysqlsnapshot、mysqldump等の方法がある(下記例文)
# mysqlhotcopy -u ユーザID -p パスワード データベース名 /tmp
   ↑ISAMテーブルやMyISAMテーブルが対象
# ./mysqlsnapshot -u ユーザID -p パスワード -s /tmp --split -n 
   ↑すべてのISAMテーブルまたはMyISAMテーブルを、データベースごとに1つのtarファイルにまとめてバックアップ
下記DB全てをバックアップ
# mysqldump -u ユーザID -p パスワード -x --all-databases > /tmp/mysql.dump ←mysqldumpはすべての種類のMySQLテーブルで使用可
   ↑これが一番メジャーだが時間がかかりファイルサイズがでかくなる
# mysqldump -u ユーザID -p パスワード -x --all-databases | gzip > / tmp/mysql.dump.gz
   ↑このように出力をパイプしてgzipをかけると多少処理時間とサイズを減らすことができる

SQL Server 2005 Express Editionでテーブルとデータを移行のメモ

SQL Server 2005 Express Editionで別のSQL Server 2005 Express Editionにテーブルのコピー
1.まず移行元のSQL ServerGUIを開いてオブジェクトエクスプローラの対象のデータベースの上で右クリックし[タスク]→[スクリプトの生成]をクリック
2.スクリプト生成ウィザードが開く。次へを押してデータベースを選択する。
3.スクリプトオプションを選択する。
4.オブジェクトの種類を選択でテーブルにチェックする。
5.テーブルの選択で対象のテーブルをチェックする。
6.出力オプションで「スクリプトをファイルに保存」を指定してファイル名等をセットして完了を押す。
7.作成されたスクリプトを移行先のSQL Serverで実行しテーブルを作成する。これでテーブルの作成完了。
8.SQL Server 2005 Express EditionではGUIからのデータのエクスポートができないみたいなのでbcpユーティリティを利用しコマンドラインより実行する。
9.移行元のコマンドラインで下記を実行しcsvを作成する。

C:\>bcp データベース名.dbo.テーブル名 out ファイルを保存するパス -c -U ユーザ名 -P パスワード -t "," -T -S サーバ名
※引数の詳細は'bcp /?'を実行すると見れるのでそっちで確認

10.上記で作成されたデータのファイルを移行先に保存して移行先のコマンドラインで下記を実行しcsvを取り込む。

C:\>bcp データベース名.dbo.テーブル名 in 取り込むファイルのパス -c -U ユーザ名 -P パスワード -t "," -T -S サーバ名

下記例

データのエクスポート
C:\>bcp databasename.dbo.tablename out c:\tablename.csv -c -U sa -P ******* -t "," -T -S servername
データのインポート
C:\>bcp databasename.dbo.tablename in c:\tablename.csv -c -U sa -P ******* -t "," -T -S servername

以下参考
bcpユーティリティの引数や構文の説明
http://msdn.microsoft.com/ja-jp/library/ms162802.aspx

cakephpとsql server 2005(日本語)

cakephpSQL Server 2005 Express Editionを使おうとしてはまったのでメモ
cakephpSQL Server 2005 Express Editionが使えるそうなので使うことにした。
まずc:\xampp\apache\binのntwdblib.dllのバージョンをチェックして古い場合は置き換える

  • 2000.2.8.0はNGらしい
  • 落としてくる場所はいくつかあった。自分が落としたところはhttp://webzila.com/?wz=dll

<追記>
c:\xampp\phpの下も置き換える
database.phpの設定

var $default = array('driver' => 'mssql',
                     'connect' => 'mssql_connect',
                     'host' => 'サーバ名称もしくはIP',
                     'login' => '※ユーザID',
                     'password' => '※パスワード',
                     'database' => '※データベース名',
                     'prefix' => '');

cakephpの画面を見てみると

DBにつながったのでテーブルの中身を参照してみたら下記のエラー(エラー?)が出力された

Query: SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
Warning: SQL Error: データベース コンテキストが 'xxxxx' に変更されました。_
 in C:\xampp\htdocs\cake\cake\libs\model\datasources\dbo_source.php on line 440

なんかエラーっぽくないエラーがでました。
ちなみにこのエラーはモデルが読み込まれるときにでているみたいでした

とりあえずQuery:の後に書いてあるSQL文をコピーしてSQL Serverのクエリ実行をやってみたら正常に実行されました

とゆうことはcakephpの問題っぽいのでソースを追っかける…
結果

  • 上記で出力されたWarningはQueryが実行されたときのWarningではない(モデルを読み込んだときに残ってしまったメッセージ)
  • SQLを実行するときにC:\xampp\htdocs\cake\cake\libs\model\dbo\dbo_mssql.php内のlastError()関数からエラーを拾ってくるがこの関数で特定の文字列が入っていた場合スルーするような処理がありました。

下記cakephp1.1と1.2です

  //cakephp1.1.19.6305
  function lastError() {
    $error = mssql_get_last_message($this->connection);

    if ($error) {                      //↓英語
      if (strpos(strtolower($error), 'changed database') === false) {
        return $error;
      }
    }
    return null;
  }

  //1.2.0.7296 RC2
  function lastError() {
    $error = mssql_get_last_message($this->connection);

    if ($error) {            //↓ドイツ語?     ↓英語
      if (!preg_match('/contesto di database|changed database/i', $error)) {
        return $error;
      }
    }
    return null;
  }

日本語には対応していませんでした
とりあえず「データベース コンテキストが」の文字列をスルーするようにしてみる

  //cakephp1.1のlastError()を下記に変更
  function lastError() {
    $error = mssql_get_last_message($this->connection);

    $wkwkerror  = mb_convert_encoding($error,'UTF-8','SJIS');
    if ($error) {
      if (!preg_match('/contesto di database|changed database/i', $wkwkerror)) {
        if (!preg_match('/データベース コンテキストが(.*)に変更されました/', $wkwkerror)) {
          return $wkwkerror;
        }
      }
    }
    return null;
  }
※注意:このファイル自体がUTF-8の場合です。SJISであれば文字エンコードの処理がいらない。

ちゃんとテーブルの内容を参照する事ができました

まとめ

  • cakephpSQL Server 2005 Express Editionを使う場合は英語のやつを使えば問題ないはず(試してないので断言はできません)
  • 日本語のSQL Server 2005 Express Editionを使うのであればdbo_mssql.phpを編集する必要がある
    • とりあえずやってみたら動いたというレベルなので弊害があるかもです。
  • cakephp1.1系は英語、cakephp1.2系は英語とドイツ語のSQL Server 2005 Express Editionに対応してるっぽい(ちなみに試してません)

当方とりあえず日本語のSQL Server 2005 Express Editionで引き続き開発予定です。