2009年6月22日月曜日

SQLiteで"unable to open database file"エラー

SQLite+PHPで簡単なアプリ作っていたら
「unable to open database file」というエラーが出ました。。
和訳すると「データベースファイルを開く事ができない」です。
エラーメッセージ内にあるパスには確かにデータベースファイル「XX.db」はあるのに。。

ということで、ファイルのパーミッションを変えて見ましたが変わらず。

ということで、ファイルの置かれたディレクトリのパーミッションを変えたらいけた!

以上どぇす。

2009年6月10日水曜日

MySQLでレプリケーション

Webアプリケーションを作成していて、MySQLサーバの負荷が高くなってきた場合、
・サーバスペックUP
・アプリケーションプログラム修正
・クエリ見直し
など色々対処方法はあるかと思います。
ま、一番言いのはサーバスペックUPだと思うのですが、どうしようもないくらい負荷が高くなった場合はMySQLサーバを複数台用意して、負荷を分散させましょう!
という事で、今日はMySQLの機能としてあるレプリケーション(Master-Slave)のやり方を簡単にメモ。

MySQLのレプリケーションはMaster側でバイナリログを取得していないといけないので
[Master]
# vim /etc/my.cnf
[mysqld]
server-id = 1 ←サーバIDはSlave側と重複しないように!
log-bin=mysql-bin ←バイナリログ取得
expire_logs_days=15 ←バイナリログ保存期間(任意)
binlog-do-db=[DB名] ←特定のデータベースのみバイナリログ取得(任意)
とします。
次にMasterに対しSlave側からアクセスできる新規ユーザを作成します。
[Master]
mysql> GRANT REPLICATION SLAVE ON *.* TO slave_user@192.168.0.2(Slave_IP);

では、Master側のデータをSlaveへ移動させます。
[Master]
mysql> FLUSH TABLES WITH READ LOCK;
でDBが更新されないようロックします。
Master側のバイナリログ状態を確認
[Master]
mysql> SHOW MASTER STATUS;
+-----------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-----------------+----------+--------------+------------------+
| mysql-bin.000001| 112 | | |
+-----------------+----------+--------------+------------------+
1 row in set (0.00 sec)
この「File」と「Position」の値はメモっておきます。コピー中にデータの更新があった場合にこのPositionからの同期をさせるためです。
MySQLのデータコピーをします。
[Master]
# tar cvf master.tar /usr/local/mysql/data/[DB名dir]

MySQLのロックを解除します。
[Master]
mysql> UNLOCK TABLES;


次にSlave側の設定です。
まず先ほど圧縮したMySQLのデータを展開します。
[Slave]
# cd /usr/local/mysql/data
# tar xvf master.tar
次にSlaveのmy.cnfの設定です。
[Slave]
# vim /etc/my.cnf
[mysqld]
server-id = 2 ←Master側と重複しないように!
read-only ←Slave側は更新しないように設定。SUPER権限を持つユーザのみが更新クエリを実行できる。
replicate-do-db = [DB名] ←指定したDBだけレプリケートする場合(任意)
Masterへ接続する設定を書いてもOK(?)です。
[Slave]
# vim /etc/my.cnf
master-host = 192.168.0.1 ←MasterIP
master-user = slave_user ←REPLICATION SLAVE権限を持つユーザ
と、my.cnfに書いても良いか、直接DBをイジった方が早い。
[Slave]
mysql> CHANGE MASTER TO
MASTER_HOST = '192.168.0.1',
MASTER_USER = 'slave_user',
MASTER_LOG_FILE = 'mysql-bin.000001', ←バイナリログ名
MASTER_LOG_POST = 112; ←先ほどメモったPositionの値
でOKです。
ではレプリケーション開始します。
[Slave]
mysql> SLAVE START;
ちなみに終了のときは
[Slave]
mysql> SLAVE STOP;
です。
めっちゃ簡単ですけど、もしSlaveが落ちて自動再起動とかなった場合にSLAVE STARTってっ誰がやるんだろ。。

2009年6月9日火曜日

MySQLを同一サーバ上に複数起動

どうも、俺です。
今日はMySQLを一つのサーバ内に複数起動する方法を超簡単にメモします。
OSはLinuxです。
そして、すでにデフォルトポート3306でのMySQLは起動しているものとします。
# netstat -tpln | grep mysql
tcp 0 0.0.0.0:3306 0.0.0.0:* LISTEN 30029/mysqld

まず、新しいmy.cnfを作成します。
# vim /etc/my.3307.cnf
[client]
port = 3307
socket = /tmp/mysql.3307.sock
[mysqld]
pid-file = /usr/local/mysql/var.3307/mysqld.3307.pid
datadir = /usr/local/mysql/var.3307
port = 3307
socket = /tmp/mysql.3307.sock
もう一つのMySQLはポート3307で起動するものとします。
次にmysql_install_dbを打ちます。
# mysql_install_db --defaults-file=/etc/my.3307.cnf --user=mysql
で/etc/my.3307.cnfを指定します。

では、MySQL起動します。
# /usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.3307.cnf & 
で起動できます。
このポート3307のMySQLへログインするには
# mysql --socket=/tmp/mysql.3307.sock
とソケットを指定すればOKです。

以上!!