Y's note

Web技術・プロダクトマネジメント・そして経営について

本ブログの更新を停止しており、今後は下記Noteに記載していきます。
https://note.com/yutakikuchi/

Mysqlの起動に関するメモ

Mac OS Xでの設定

今回はMacOS10.6.5での設定を行いました。
UnixLinuxとの違いはあると思いますが、多少は参考になるかもしれません。

自動起動設定

起動
/Library/StartupItems/MySQLCOM/MySQLCOM start
停止
/Library/StartupItems/MySQLCOM/MySQLCOM stop

起動/停止

起動
sudo mysqld_safe
停止
mysqladmin -u root -p shutdown
起動確認
mysqladmin ping
mysqld is alive

rootのpassword設定

これはまず最初にやるべき事ですね。
空passwordはセキュリティ上よろしく無いので、rootのパスワードを変更します。

mysqladmin -u root password 新しいパスワード

my.cnf

初期設定時だと/etc/my.cnfが存在しないので、特定のフォルダからコピーをします。

sudo cp  /usr/local/mysql-5.1.39-osx10.5-x86/support-files/my-medium.cnf /etc/my.cnf

必要に応じて上のファイルをカスタマイズする必要があります。
my.cnfを変更した場合はmysqlを再起動する必要があります。

my.cnfのチューニング

log-slow-queries,long-query-timeの設定を行います。
これにより指定時間以上のSQL文を出力してくれます。

[mysqld]
(略)
log-slow-queries = /var/log/mysqld-slow.log
long-query-time  = 2 

次にquery_cache_sizeの設定を行います。query_cache_sizeを設定すると同じSQL文が呼び出された場合はcacheから応答することが可能です。

max_connections  = 450 
thread_cache     = 450 
table_cache      = 450 
query_cache_size = 16M 

mysql.sockファイルが無い

mysqlはクライアントとmysqlサーバ間はsocket通信にてデータのやり取りを行なっています。
PHPなどのクライアントプログラムからmysql.sockのファイルパスを正確に指定しないとエラーが発生するので、
その回避方法をメモしておきます。
mysql.sockの設定はデフォルトだとおそらく/tmp/mysql.sockに設定されていると思いますが、
/etc/my.cnf内部の記述で変更されることがあります。(例) socket = /var/mysql/mysql.sock
デフォルトのmy.cnfは次のような感じだと思います。

[client]
port            = 3306
socket          = /tmp/mysql.sock
default-character-set = utf8

[mysqld]
port            = 3306
socket          = /tmp/mysql.sock
(略)

指定されたsocketのパスにmysql.sockファイルがない場合はmysqlが起動していない可能性があります。
プロセスの確認をしてみてmysqldが生きていることを確認します。

ps auxww | grep mysqld

プロセスが生きていなければ以下のコマンドで再起動させます。

sudo mysqld_safe

起動後にsocketのパスを確認してみます。

file /tmp/mysql.sock

ファイルが存在すればmysqlの設定は完了です。

phpからのconnectに失敗する

下のプログラムでmysqlとの接続に成功すれば問題ないのですが、失敗する可能性があります。

<?php
$con = @mysql_connect( 'localhost', 'root', '' );
if( !$con ) { 
    die( "disconnect " .  mysql_error() );
}

その場合はphp.ini側の設定が誤っている可能性があるので設定ファイルを変更するか、mysql_connect側の読み取り方法を変更します。
以下は1つ目の手段の/etc/php.iniの以下の設定を書き換えてしまいます。

; http://php.net/pdo_mysql.default-socket
;pdo_mysql.default_socket=/var/mysql/mysql.sock
pdo_mysql.default_socket=/tmp/mysql.sock

; http://php.net/mysql.default-socket
;mysql.default_socket = /var/mysql/mysql.sock
mysql.default_socket = /tmp/mysql.sock

; http://php.net/mysqli.default-socket
;mysqli.default_socket = /var/mysql/mysql.sock
mysqli.default_socket = /tmp/mysql.sock

以下は2つ目の手段でmysql_connect関数の第一引数で接続先のサーバ名とmysql.sockのファイルパスを指定します。

<?php
$con = @mysql_connect( 'localhost:3306:/tmp/mysql.sock', 'root', '' );
if( !$con ) {
    die( "disconnect " .  mysql_error() );
}

このように変更すれば/etc/my.cnfの記述を変更する必要はありません。

Master/Salveの設定

DBを一台構成にするのではなくWebサービスの場合は更新DB(master)1台、バックアップDB(slave)3台などのような構成になっているのが通常です。
masterDBサーバで実行されたQueryをトランザクションとしてslave側に流し、slave側でそのQueryを実行して差分を更新します。このような技術をDB
レプリケーションという呼び方をしたりします。設定は簡単で、my.cnfとレプリケーションユーザの設定ぐらいで出来ます。

Masterのmy.cnf
[mysqld]
server-id = 1
log-bin    =  mysql-bin
log-bin-index = mysql-bin
relay-log  = relay-bin
relay-log-index = relay-bin
replアカウントの追加

レピリケーションユーザとしてのアカウントをMaster側に追加します。レピリケーションを許すIPアドレスをrepl@(slave ip)というように記述し、
GRANT文にて権限を付与します。

GRANT REPLICATION SLAVE ON *.* TO repl@(slave ip) IDENTIFIED BY 'password';
MasterのデータをSlave側にコピー

Slaveサーバのデータは何も無い状態だと思うので、最初にデータのコピーを行います。
まずはMasterサーバのMysqlにロックをかけます。

mysql> FLUSH TABLES WITH READ LOCK;

次にデータディレクトリの内容を圧縮して、スレーブサーバに転送し、解凍します。

(master側で)
sudo tar -cf ~/data.tar /usr/local/mysql/data
scp ~/data.tar slaveserver:
(slave側で)
sudo tar -xzf ~/data.tar -C /usr/local/mysql/data

Master側のロックを解除します。

mysql> UNLOCK TABLES;
Master側のlogfileとpositionを確認

Master側で以下のコマンドでログファイルとPositionを確認します。

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 19500106 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

※ここから後はSlave側の設定になります。

Slaveのmy.cnfの設定

Master側のserver-idとは別の番号にする必要があります。

[mysqld]
server-id = 2
Masterへの接続設定

Master側で確認したlogfile,positionを設定します。
MASTER_LOG_FILE='mysql-bin.000005'
MASTER_LOG_POS=19500106

CHANGE MASTER TO
MASTER_HOST='Master IP',  MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=19500106; 
レプリケーションを開始します。

Slave側で以下のコマンドを実行します。

mysql> START SLAVE;