MySQL

MySQL vs mariaDBが続いているけれど、ぶっちゃけ中身はほぼ同じなのでどっちでも良い。
一応、mariaDBの方が高機能らしいが殆ど変わらないと思う。
MySQL5.5から./configureではなく、cmakeを使うようになった。

インストール

1. ビルド

//MySQL 5.1系統
# tar zxvf mysql-5.1.73.tar.gz
# cd mysql-5.1.73
# ./configure --prefix=/usr/local/mysql --without-readline
# make
# make install

//MySQL 5.5系統
# tar zxvf mysql-5.6.15.tar.gz
# cd mysql-5.6.15
# cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
# make
# make install

cmakeのオプションはMySQLのオフィシャルに書いてある


2. MySQLの設定・起動準備
x86_64のOSを使っているのなら、下を必ず行う事!!
PHPとかのconfigure時に"--with-libdir=lib64"を指定すると、lib64を見に行ってしまって転ける

# ln -s /usr/local/mysql/lib /usr/local/mysql/lib64



MySQL用のユーザを作成する。

# groupadd mysql
# useradd -g mysql -d /var/mysql -s /sbin/nologin mysql
# rm -rf /var/mysql/*
# rm -rf /var/mysql/*.*



起動スクリプトの設置を行う。コピーしたスクリプトの中身も書き換える。

# {MySQLのソースコード}/support-files/mysql.server /etc/init.d/mysqld
# chmod 755 /etc/init.d/mysqld
# chkconfig --add mysqld
# chkconfig mysqld on



MySQLのデータベースを初期化する。

# /usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql --user=mysql --ldata=/var/mysql



3. MySQLの起動後設定
起動した後に、データベース内のゴミを削除する。

# /etc/init.d/mysqld start
# mysqladmin -u root password {MySQLのrootユーザパスワード}

# mysql -u root -p
Enter password: {MySQLのrootユーザパスワード}
> use mysql;
> delete from user where user='';
> delete from user where password='';
> drop database test;
> flush privileges;
> exit



4. MySQLのユーザ・パスワード・データベース登録
(例) ユーザ:hoge , パスワード:pass , データベース名:bar

# mysql -u root -p
Enter password: {MySQLのrootユーザパスワード}
> create database bar;
> grant all on bar.* to hoge identified by 'pass';
> flush privileges;
> exit



5. 注意事項

ログローテート

MySQLでログローテートを行うには、logrotateからmysqladminコマンドを実行して、
flush-logsでローテートとログ再読込を行う必要がある。
mysqladminはDB内のroot権限でコマンドを実行する必要があるが、logrotateにパスワードを直書きするとエラーになる為、
ユーザ・パスワードを外部ファイル化して呼び出す事により認証処理とローテートを行う

# chown root.root /etc/.my.cnf.pass
# chmod 400 /etc/.my.cnf.pass
# vi /etc/.my.cnf.pass
---
[client]
user     = root
password = {MySQLのrootユーザパスワード}
# vi /etc/logrotate.d/mysql
---
/var/log/mysql/*.log {
   daily
   dateext
   ifempty
   compress
   rotate 7
   missingok
   postrotate
       if test -x /usr/local/mysql/bin/mysqladmin && \
           /usr/local/mysql/bin/mysqladmin --defaults-extra-file=/etc/.my.cnf.pass ping &>/dev/null
       then
           /usr/local/mysql/bin/mysqladmin --defaults-extra-file=/etc/.my.cnf.pass flush-logs
       fi
   endscript
}


レプリケーション

MySQLではMaster/Slaveのレプリケーション構成を取る事が出来る。
DB冗長化を目的にしている場合、クラスタリングよりもレプリケーションの方が適している場合もある。


1. [Master/Slave] バイナリログ取得
Master/Slaveのレプリケーション構成を取る際は、バイナリログを取得する必要がある。
バイナリログのローテート間隔・容量指定はディスク容量を考慮しつつ調整する。
MySQLサーバを識別する為に任意のサーバIDも設定する。

[Master]
# vi /etc/my.cnf
---
log-bin          = mysql-bin
expire_logs_days = 30
max_binlog_size  = 10485760
binlog_format    = mixed
server-id        = 1

[Slave]
# vi /etc/my.cnf
---
log-bin          = mysql-bin
expire_logs_days = 30
max_binlog_size  = 10485760
binlog_format    = mixed
server-id        = 2



2. [Master] レプリケーションアカウント作成
Slaveサーバからレプリケーション接続を行う為に、MasterのMySQLにユーザを作成する
レプリケーションユーザには、replication権限を付与する。

master> grant replication slave on *.* to 'ReplicaUser'@'SlaveServerIP' by 'ReplicaPassword';



3. [Master] DBの書き込み禁止
レプリケーション前のデータ同期を行う為に、DB書き込みを禁止した後、バイナリログ同期ポイントをメモする。
なお、作業途中でMySQLコンソールからログアウトすると、DBロックも解除されてしまう為、
ここからの作業は複数のターミナルを起動しつつ作業を行う。

master> flush tables with read lock;
master> show master status\G;
*************************** 1. row ***************************
            File: mysql-bin.000001
        Position: 100100
    Binlog_Do_DB:
Binlog_Ignore_DB:



4. [Master/Slave] DBの初期同期
MasterのデータをSlaveにコピーしておき、Slaveの初回起動時のデータ同期時間を短縮する。
データの同期方法は、dumpでもディレクトリコピーでも良いので、
MasterのMySQLを起動したままデータコピーをする。

# cd /var
# tar Jcvf mysql.tar.xz mysql
# scp mysql.tar.xz ${SlaveSSH}@${SlaveIP}:



5. [Slave] データ同期
MasterからコピーしてきたデータをSlaveのMySQLに適用し、SlaveのMySQLを再起動する。
その後、SlaveからMasterに対してレプリケーションクエリを発行する。

slave> change master to
       master_host='SlaveServerIP'
       master_user='ReplicaUser'
       master_password='ReplicaPassword'
       master_log_file='mysqld-bin.000001'
       master_log_pos=100100;
slave> start slave;



6. [Master] DBの書き込み開始
書き込み禁止していたMasterのMySQLで書き込みを再開する。

master> unlock tables;



7. [Slave] 同期状況の確認
下記コマンドを実行して、Slaveのレプリケーション状況を確認する。
[Master_Log_File]/[Read_Master_Log_Pos]の二つがMasterと同じ値になっている事と、
[Slave_IO_Running]/[Slave_SQL_Running]の二つがYESになっていれば、同期は完了している。

slave> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 'MasterServerIP'
                  Master_User: 'ReplicaUser'
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 100100
               Relay_Log_File: mysql-relay-bin.0000001
                Relay_Log_Pos: 100100
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes



8. [Master/Slave] 再レプリケーション
何かしらの理由でレプリケーションが外れてしまい、同期不完全になってしまった場合、
MasterのDBを一時的に書き込み禁止にした後、Slaveでバイナリログを再指定すれば同期が再開される。

[Master]
master> flush tables with read lock;
master> show master status\G;
*************************** 1. row ***************************
            File: mysql-bin.000022
        Position: 200200
    Binlog_Do_DB:
Binlog_Ignore_DB:

[Slave]
slave> change master to master_log_file='mysql-bin.000022', master_log_pos=200200;

[Master]
master> unlock tables;