#author("2019-11-30T22:14:32+09:00","default:nowsky","nowsky")
*MySQL [#d6256ed2]
-[[MySQL:+http://dev.mysql.com/]]
-[[mariaDB:+https://mariadb.org/]]

MySQL vs mariaDBが続いているけれど、ぶっちゃけ中身はほぼ同じなのでどっちでも良い。
一応、mariaDBの方が高機能らしいが殆ど変わらないと思う。
MySQL5.5から&font(b){./configureではなく、cmakeを使う};ようになった。
~
*インストール [#u7d6d771]
&size(16){&font(b){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のオフィシャル>+http://dev.mysql.com/doc/mysql-sourcebuild-excerpt/5.7/en/source-configuration-options.html]]に書いてある
~
&size(16){&font(b){2. MySQLの設定・起動準備};};
&font(b){&color(#ff0000){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
 # ln -s /var/run/mysql/mysql.sock /tmp/mysql.sock
 # /usr/local/mysql/bin/mysql_secure_installation
 ---
 Enter current password for root (enter for none): "Enter"
 
 Set root password? [Y/n] "Enter"
   New password: "Password"
   Re-enter new password: "Password"
 
 Remove anonymous users? [Y/n] "Enter"
 
 Disallow root login remotely? [Y/n] "Enter"
 
 Remove test database and access to it? [Y/n] "Enter"
 
 Reload privilege tables now? [Y/n] "Enter"
 

MySQLのアップグレード時はインデックス修正も行う
 # /usr/local/mysql/bin/mysql_upgrade -u root -p
~
&size(16){&font(b){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
 

MariaDB v10.4以降でLinux上のrootユーザを使って "mysql -u root" を行うと、
ログインパスワードを聞かれずにログイン出来てしまう。
コレはMariaDBのrootアカウント思想に基づく物でどうしようも無いので許容する。
それも考慮した上で、ローカルアカウントのrootからのパスワードを強制する場合、
UnixSocketを使わないでMariaDBを起動させれば良い

- 参考:[[MariaDB 10.4.1〜のユーザー認証がカオスな話>+https://gizmeler.com/?p=466]]

~
&size(16){&font(b){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
~
&size(16){&font(b){5. 注意事項};};
-&font(b){&color(#ff0000){MySQL5.7.4以上を使う時のパスワードリミット};};
MySQL5.7.4で導入されたユーザパスワードの更新リミッタが、デフォルト状態だと360日に設定されている。
その為、"/etc/my.cnf"の[mysqld]項目に下記のコンフィグを入れないで稼働させ、
パスワードを変更しないまま利用すると、360日経過した時にユーザがロックされてしまう。
 default_password_lifetime=0
~
ロックされたユーザではMySQLにログインは出来るが、
&font(b){ユーザパスワード変更以外の操作が出来ない状態};(=通常のDB操作が不可能)になる。
この状態を解除するには、次のどちらかを実行する。
--mysql.usrテーブルのpassword_last_changedを書き換える
--"default_password_lifetime=0"を書いた後に、MySQLをリスタート
~
*ログローテート [#o75f06b6]
-[[MySQLログのローテーション設定:+https://blog.inouetakuya.info/entry/20130320/1363776504]]

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
 }
~
*レプリケーション [#ga2ab02e]
-[[nullpopopo:+https://nullpopopo.blogcube.info/2012/08/%E3%81%9F%E3%81%A3%E3%81%9F30%E5%88%86%E3%81%A7wordpress%E3%82%92%E5%86%97%E9%95%B7%E5%8C%96%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95.html]]
-[[MySQL レプリケーションの設定:+http://www.casleyconsulting.co.jp/blog-engineer/mysql/%E3%80%90dba%E5%88%9D%E7%B4%9A%E8%80%85%E5%90%91%E3%81%91%E3%80%91mysql-%E3%83%AC%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%A8%AD%E5%AE%9A/]]

MySQLではMaster/Slaveのレプリケーション構成を取る事が出来る。
DB冗長化を目的にしている場合、クラスタリングよりもレプリケーションの方が適している場合もある。
~
&size(16){&font(b){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
~
&size(16){&font(b){2. [Master] レプリケーションアカウント作成};};
Slaveサーバからレプリケーション接続を行う為に、MasterのMySQLにユーザを作成する
レプリケーションユーザには、replication権限を付与する。
 master> grant replication slave on *.* to 'ReplicaUser'@'SlaveServerIP' identified by 'ReplicaPassword';
~
&size(16){&font(b){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:
~
&size(16){&font(b){4. [Master/Slave] DBの初期同期};};
MasterのデータをSlaveにコピーしておき、Slaveの初回起動時のデータ同期時間を短縮する。
データの同期方法は、dumpでもディレクトリコピーでも良いので、
MasterのMySQLを起動したままデータコピーをする。
 # cd /var
 # tar Jcvf mysql.tar.xz mysql
 # scp mysql.tar.xz ${SlaveSSH}@${SlaveIP}:
~
&size(16){&font(b){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;
~
&size(16){&font(b){6. [Master] DBの書き込み開始};};
書き込み禁止していたMasterのMySQLで書き込みを再開する。
 master> unlock tables;
~
&size(16){&font(b){7. [Slave] 同期状況の確認};};
下記コマンドを実行して、Slaveのレプリケーション状況を確認する。
&font(b){[Master_Log_File]};/&font(b){[Read_Master_Log_Pos]};の二つがMasterと同じ値になっている事と、
&font(b){[Slave_IO_Running]};/&font(b){[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
~
&size(16){&font(b){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;