稼働中の MySQLサーバ から slaveサーバ を構築する備忘録

こんにちは。
MySQLサーバ の slaveサーバを構築する機会があったので備忘録を残しておきます。

確認事項

バイナリログが出力されていて、尚且つ server-id が設定されている必要があります。

vi /etc/my.cnf
=======================================
server-id=1001
log-bin = /var/lib/mysql/mysql-bin
=======================================

systemctl restart mysqld

レプリケーション用ユーザの作成

レプリケーション用のユーザを事前に作成しておきます。

create user 'repl'@'%' identified by 'xxxxxxxxxx';
grant replication slave on *.* to 'repl'@'%';

dumpファイルの取得

mysqldump で dumpデータを取得します。
ストレージエンジンが innodb であれば、–single-transaction オプションで DBをロックせずに取得が可能です。
また、–master-data=2 オプションでバイナリログの読み出し開始位置を出力しておきます。

mysqldump -u root -p --skip-lock-tables --quote-names --single-transaction --master-data=2 -A > /var/tmp/mysqldump.sql

dumpファイルのインポート

slaveサーバ に dumpファイルを転送して流し込みます。
単純に mysql コマンドとリダイレクトを組み合わせるだけで大丈夫です。

scp user@xxx.xxx.xxx.xxx:/var/tmp/mysqldump.sql /var/tmp/.
mysql -u root -p < /var/tmp/mysqldump.sql

テーブルチェック

mysql_upgrade コマンドを使ってテーブルのチェックを行います。

mysql_upgrade -u root -p
systemctl restart mysqld

バイナリログの開始位置を確認

–master-data=2 オプションでバイナリログの読み出し開始位置が出力されているので確認します。

grep "CHANGE MASTER" /var/tmp/mysqldump.sql

レプリケーション設定

mysql> change master to
    -> master_host='xxx.xxx.xxx.xxx',
    -> master_user='repl',
    -> master_password='xxxxxxxxxx',
    -> master_log_file='[バイナリログ]',
    -> master_log_pos=[ポジション];

mysql> start slave;
mysql> show slave status\G

【Ansible】Ansible と expect で MySQL 導入を自動化する【IaC】

こんにちは。
MySQL の導入が面倒だったので Ansible と expect で自動化にチャレンジします。

mysql_secure_installation の自動化

expect と awk でシェルスクリプトを作成します。

#!/bin/bash


# 初期パスワードを取得
IntPasswd=$(grep "A temporary password is generated for root@localhost:" /var/log/mysqld.log | awk '{ print $13}')

# パスワード指定
MysqlRootPasswd="{{ db_passwd }}"

expect -c '
    set timeout 10;
    spawn mysql_secure_installation;
    expect "Enter password for user root:";
    send -- "'"${IntPasswd}"'\n";
    expect "New password:";
    send -- "'"${MysqlRootPasswd}"'\n";
    expect "Re-enter new password:";
    send -- "'"${MysqlRootPasswd}"'\n";
    expect "Change the password for root ?";
    send "n\n";
    expect "Remove anonymous users?";
    send "y\n";
    expect "Disallow root login remotely?";
    send "y\n";
    expect "Remove test database and access to it?";
    send "y\n";
    expect "Reload privilege tables now?";
    send "y\n";
    interact;'

awk で初期パスワードを取得し、対話処理は expect で処理します。

Playbook

Ansible の playbook で処理します。

---
# tasks file for mysql-server80
- name: install mysql80 repository
  yum:
    name: https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
    state: present

- name: install mysql
  yum:
    name:
      - mysql-server
      - expect
    state: present

- name: put my.cnf
  template:
    src: ../templates/my.cnf.j2
    dest: /etc/my.cnf
    owner: root
    group: root
    mode: 0644
    backup: yes

- name: mkdir /var/log/mysql/
  file:
    path: /var/log/mysql
    state: directory
    owner: mysql
    group: mysql
    mode: 0755

- name: start mysql
  systemd:
    name: mysqld
    state: started
    enabled: yes

- name: confirm check_file
  stat: path=/usr/local/etc/mysql_stat.txt
  register: result_mysql_exit

- name: put mysql_secure_installation_script
  template:
    src: ../templates/mysql_secure_installation_script
    dest: /tmp/mysql_secure_installation_script
    owner: root
    group: root
    mode: 0755

- name: exec mysql_secure_installation_script
  shell: "/tmp/mysql_secure_installation_script"
  when: not result_mysql_exit.stat.exists

- name: create check_file
  file:
    path: /usr/local/etc/mysql_stat.txt
    state: touch
    mode: "u=rw,g=r,o=r"

- name: change error-log location
  lineinfile:
    dest: /etc/my.cnf
    state: present
    backrefs: yes
    regexp: '^log-error = /var/log/mysqld.log'
    line: 'log-error = /var/log/mysql/mysqld.log'
  notify: mysqld_restart

おまけ

こちらに CentOS7用の playbook を纏めていますので宜しければ。
https://github.com/keisukesanuki/default-CentOS7

古い MySQL インストール方法

こんにちは。
古いバージョンの MySQL をインストールする際に少し躓いたので備忘録を残しておきます。

手順

wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
tar -xvf mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar

yum localinstall mysql-community-server-5.7.24-1.el7.x86_64.rpm \
mysql-community-client-5.7.24-1.el7.x86_64.rpm \
mysql-community-common-5.7.24-1.el7.x86_64.rpm \
mysql-community-devel-5.7.24-1.el7.x86_64.rpm \
mysql-community-libs-5.7.24-1.el7.x86_64.rpm \
mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm

MySQL が停止して困った話

こんにちは。
メモリが枯渇して MySQL が起動しなくなったので、SWAP を追加したお話です。

背景

最近、メモリ不足で MySQL が勝手に停止する事象が発生してました。
取り急ぎ、下記のようなスクリプトを cron に登録してたのですが、さらに SWAP 領域を作成しておきます。

#!/bin/bash
ProcessName=mysqld
count=`ps aux | grep $ProcessName | grep -v grep | wc -l`
if [ $count = 0 ]; then
sudo systemctl restart $ProcessName
echo "$(date)_$ProcessName is dead" >> /var/log/mysqld/statu_log.txt
else
echo "$(date)_$ProcessName is alive" >> /var/log/mysqld/statu_log.txt
fi

dd if=/dev/zero of=/swap.img bs=1M count=500
chmod 600 /swap.img
mkswap /swap.img
swapon /swap.img
cp -p /etc/fstab /etc/fstab_20181118
vim /etc/fstab
================================
/swap.img swap swap defaults 0 0
================================
systemctl status mysqld