20210125のMySQLに関する記事は4件です。

Docker開発環境

はじめに

現在開発中のアプリにDockerを導入したのでアウトプットします。

環境

Ruby on Rails '6.0.0'
Ruby '2.6.5'
MySQL '5.6.47'

Dockerfile

開発中アプリのルートディレクトリにDockerfileを作成します。

Dockerfile
FROM ruby:2.6.5

RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       libpq-dev \
                       nodejs

RUN mkdir /アプリ名
WORKDIR /アプリ名

ADD ./Gemfile /アプリ名/Gemfile
ADD ./Gemfile.lock /live_search/Gemfile.lock

RUN gem install bundler
RUN bundle install
ADD . /アプリ名

docker-compose.yml

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.6.47
    environment:
      MYSQL_ROOT_PASSWORD: 'password'
    ports:
      - "4306:3306"
    volumes:
      - ./db/mysql-data:/var/lib/mysql

  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/アプリ名
    ports:
      - "3000:3000"
    depends_on:
      - db

entrypoint.sh

entrypoint.sh
set -e

rm -f /myapp/tmp/pids/server.pid

exec "$@"

database.yml

database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db
  socket: /tmp/mysql.sock

password: password
host: db
を追加

コンテナを作成

ターミナル
% docker-compose build

DB作成、migrationの実行

ターミナル
% docker-compose run web bundle exec rake db:create
% docker-compose run web bundle exec rake db:migrate

コンテナを起動

ターミナル
% docker-compose up 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

BIツールでMySQLのデータを可視化した話

とある案件で、MySQLのデータを手っ取り早く可視化して関係者にお披露目する機会があった。
Google Data Studio ではそれが簡単にできるので、手順を紹介する。

Google Data Studio について

BIツール(Business Intelligence ツール)のひとつ。
BIツールといえば、Tableau(タブローと読む。Salesforceアナリティクス製品との統合を加速中)が老舗で、名前だけは良く聞くがライセンス費用は高め。
マイクロソフトの PowerBI はある程度まで無料で試すことができ、それなりに情報量も豊富だが、今回は Google Analytics で使用実績があった Google Data Studio を採用した。無料で使える。

接続できるデータソースは、

  • Googleが展開するサービス(Google Analytics、スプレッドシート、Cloud Storage、Search Console等)
  • BigQuery
  • MySQL
  • PostgreSQL
  • その他アップロードファイル

など。

新型コロナウイルス感染症の陽性者数などをAIで予測し、リアルタイムで表示するサイト COVID-19 感染予測 も Data Studio のダッシュボードを利用している。

手順

MySQL

まず、MySQLのconfファイルの場所をmysql --helpなどで確認し、MySQL側で外部からの接続を許可しておこう。

/etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 127.0.0.1

上記の行をコメントアウトし、MySQLを再起動する。

ちなみに、このbind-addressの誤った解説がネットで散見されるため、念の為に補足しておく。
これはリモートホストのIPアドレスを制限するものではなく、どのローカルアドレスでMySQLがlistenするかの指定である。
コメントアウトするとデフォルトの0.0.0.0になり、すべてのインターフェースで待ち受けることになる。
127.0.0.1が指定されていると自分自身しか接続できない。

続いて、mysql -u rootでMySQLに管理者ログインし、すべてのリモートホストから接続できるユーザを作成する。

grant all privileges on DB.* to ユーザ名@'%';

もし、Can't find any matching row in the user tableのエラーになったら、select user,host from mysql.user でユーザテーブルの内容を確認し、CREATE USERしてからGRANT ALLする。

create user DB@'%' identified by 'パスワード';

最終的に許可するリモートIPアドレスのリストは https://support.google.com/datastudio/answer/7088031?hl=ja に記載されているので、ポート番号3306とともにファイアウォールに追加する。

Data Studio

https://datastudio.google.com にGoogleアカウントでログインし、[作成] から [データソース] をクリックする。
image.png

MySQLを選択する。
image.png

接続情報を入力し、[認証] をクリックする。ポート番号はデフォルト通りなら入れなくて良い。
image.png

テーブルを選択するか、カスタムクエリにSQLを記述し、[接続] をクリックする。
image.png

テーブルまたはSQLの出力項目が展開されるので、必要に応じて修正し、[レポートを作成] をクリックする。
image.png

レポート編集画面になる。
image.png
ディメンションとは分析軸のことで、指標とは集計項目(合計値、平均値、中央値、最大値など)のこと。
例えば、時間帯ごとの消費エネルギーを見たければ、ディメンションに時間、指標にエネルギーを指定するといった具合。

実データをそのままここに載せる訳にはいかないので、ここではデータソースに「Google Analytics」を設定して説明する。データソースが違くても使い方は変わらないので。

Qiitaで埋め込んだトラッキングコードを持つ Google Analytics と接続し、

  • グラフに「棒付きデータ表」
  • ディメンションに「ページタイトル」
  • 指標に「ページビュー数」

を指定すると、人気投稿ランキングが簡単に作れた。
image.png

レポートが完成したら、共有ボタンから他のユーザと共有する。
image.png
Googleアカウント名やメールアドレス、Googleグループで共有できる他、[共有可能なリンクを取得] すれば不特定多数とレポートを共有できる。

無料版の Data Studio では1レポート1データソースに制限されるが、ダッシュボード・可視化ツールとして使うなら十分活用できると思う。
API と Google Apps Script を使えばコネクタも自作できそうだ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLでログインができない

結論

ユーザー名のホストの記載方法が間違っていた
全ホストからのアクセスを許可する記載方法は「%」

【誤用】
test@*
【正解】
test@%

修正

もとのログイン名を確認

>SELECT user, host FROM mysql.user;
+---------------+-----------+ 
| user          | host      | 
+---------------+-----------+ 
| test          | *         |
>drop user 'test'@'*';
>create user 'test'@'%' identified by 'password';
>grant all privileges on *.* to test@'%' identified by 'password';

確認

ユーザーが追加されているか確認

>SELECT user, host FROM mysql.user;
+---------------+-----------+ 
| user          | host      | 
+---------------+-----------+ 
| test          | %         |

ログインを確認

>mysql -u test -ppassword -h 192.168.1.xxx
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OpenShift4+MySQL8.0のActive-Standby構成

昨日構成したCentOS 8上でのMySQL 8.0 Active-Standby構成をOpenShift 4の上でやってみる。
まあ、昨日の記事の焼き直しだが新規性はこちらの方があるだろう。

改めて、今回説明する構成の良いところは使用しているサーバー側コンポーネントがすべてOpenShift 4がサポートするカバー範囲内となる点にある。
→ OpenShiftのサポート範囲に「RHEL Software Collections and RHT SSO Common Service」が含まれている。
https://docs.openshift.com/container-platform/4.6/welcome/oke_about.html
→ RHEL Software CollectionsにMySQL 8.0が含まれている。
https://developers.redhat.com/products/softwarecollections/overview

なお、今回使用するMySQLの細かいバージョンは、昨日の記事と同じ8.0.21である。

また、前回記事と同じくフェールオーバーの切り替えの自動化には触れていない。それでも手順は十分機械的なので、少し頑張るくらいでフェールオーバー自動化は可能だろう(「フェールオーバーしてみる」の手順2~5が自動化できれば良いのだ)。

構成

OpenShiftクラスターの作成については以下の記事を参照。最近Master3台構成に作り替えたのだが、まあ似たようなものだ。
https://qiita.com/rk05231977/items/ec1626c1223dddffc98a

今回の構成ではMySQLサーバーの開閉塞はNodePortで行うのだが、bastionサーバー経由でないとクラスターにアクセスできないため、やはりHAProxyは使用する。

ストレージは、簡単だったのでbastionサーバー上のNFSストレージを使用している。使えるならmysql1、2のPodが稼働するノードのローカルストレージか、iSCSI等のブロックストレージを使った方が良いだろう。

シェアードナッシングなのでmysql1とmysql2が実行される物理ノードは遠隔に配置できる。マルチAZ単一クラスター構成なら本記事に書いてあるままで、DRでもちょっと頑張れば動作するだろう。

image.png

nfsストレージとインターナルレジストリを準備する

1.以下の記事のうち、「NFSサーバーを作る」、「Image Registryを設定する」を参照し、それらを構成する。
https://qiita.com/rk05231977/items/59027862b59207a5e61f

2.mysql用のnfsストレージを作る。

# mkdir -p /export/mysql1 /export/mysql2
# chmod 777 /export/mysql1 /export/mysql2
# echo "/export 192.168.1.0/24(rw,no_root_squash)" >> /etc/exports
# exportfs -r

MysqlのActive-Standbyクラスターを作る

1.bastionサーバーにログインし、mysqlクラスターのyamlファイルを作る。
Infrastructure as Codeの世界へようこそ。

mysql.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-mysql
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Delete
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql1
  labels:
    instance-for: mysql1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Delete
  storageClassName: nfs-mysql
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /export/mysql1
    server: 192.168.1.1
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql2
  labels:
    instance-for: mysql2
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Delete
  storageClassName: nfs-mysql
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /export/mysql2
    server: 192.168.1.1
---
apiVersion: v1
kind: Namespace
metadata:
  name: mysql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql1
  namespace: mysql
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 5Gi
  storageClassName: nfs-mysql
  selector:
    matchLabels:
      instance-for: mysql1
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql2
  namespace: mysql
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 5Gi
  storageClassName: nfs-mysql
  selector:
    matchLabels:
      instance-for: mysql2
---
apiVersion: v1
kind: Service
metadata:
  name: mysql1
  namespace: mysql
  labels:
    app: mysql1
spec:
  ports:
  - port: 3306
    name: mysql
  clusterIP: None
  selector:
    app: mysql1
---
apiVersion: v1
kind: Service
metadata:
  name: mysql2
  namespace: mysql
  labels:
    app: mysql2
spec:
  ports:
  - port: 3306
    name: mysql
  clusterIP: None
  selector:
    app: mysql2
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql1
  namespace: mysql
spec:
  selector:
    matchLabels:
      app: mysql1
  serviceName: mysql1
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql1
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mysql1
        image: image-registry.openshift-image-registry.svc:5000/mysql/mysql-80
        imagePullPolicy: Always
        ports:
        - containerPort: 3306
          name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql/data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: mysql1
      nodeSelector:
        kubernetes.io/hostname: node1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql2
  namespace: mysql
spec:
  selector:
    matchLabels:
      app: mysql2
  serviceName: mysql2
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql2
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mysql2
        image: image-registry.openshift-image-registry.svc:5000/mysql/mysql-80
        imagePullPolicy: Always
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql/data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: mysql2
      nodeSelector:
        kubernetes.io/hostname: node2

2.yamlファイルをOpenShiftクラスターにデプロイする。

# oc create -f mysql.yaml

とりあえず、mysqlネームスペースにmysql1とmysql2という2つのStatefulSetが出来上がる。

インターナルレジストリにmysql-80のイメージをpushしていないので、上記をデプロイした直後にPodは起動しない。この後すぐの手順でイメージは配置する。

外部からのアクセスにNodePortが必要だが、それはまだ作っていない。

3.mysql-80のコンテナイメージをインターナルレジストリに配置する。
以下、説明は雑だが、registry.redhat.ioからイメージをpullしてインターナルレジストリに配置する。
https://catalog.redhat.com/software/containers/rhel8/mysql-80/5ba0ad4cdd19c70b45cbf48c

# podman login registry.redhat.io
# podman pull registry.redhat.io/rhel8/mysql-80

# oc login -u admin -p admin --server=https://api.ocp.example.com:6443
# oc port-forward svc/image-registry -n openshift-image-registry 5000 &

# podman login -u admin -p $(oc whoami -t) localhost:5000 --tls-verify=false
# podman tag registry.redhat.io/rhel8/mysql-80 localhost:5000/mysql/mysql-80
# podman push localhost:5000/mysql/mysql-80 --tls-verify=false

4.mysqlのPodを削除し、作り直す。

# oc delete pod -n mysql mysql1-0 mysql2-0

5.mysqlが起動したのを確認する。
Podのログの最後に「ready for connections. Version: '8.0.21'」と表示されることを確認する。

# oc logs -f -n mysql mysql1-0
# oc logs -f -n mysql mysql2-0

(実行結果)
[root@bastion mysql]# oc logs -f -n mysql mysql1-0
...
2021-01-24T12:01:42.398021Z 0 [System] [MY-010931] [Server] /usr/libexec/mysqld: ready for connections. Version: '8.0.21'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  Source distribution.

mysql1を構成する

1.何もデータが無いのもつまらないので、国データベースを初期データとしてロードしようか。

# curl -k -O -L https://downloads.mysql.com/docs/world.sql.gz
# gunzip world.sql.gz
# oc exec -i -n mysql mysql1-0 -- mysql -u root < world.sql

2.以降、oc exec経由でmysql1のインスタンスを構成するが、長たらしいコマンドを避けるため短縮コマンドを定義する。

# mysql1="oc exec -n mysql mysql1-0 -- mysql -u root"

3.MySQL Workbenchから繋ぐ用のadminユーザーを作る。

# $mysql1 -e "CREATE USER 'admin'@'%' IDENTIFIED BY 'password';"
# $mysql1 -e "GRANT ALL ON *.* TO 'admin'@'%';"

4.ここからがレプリケーション用の構成。
https://dev.mysql.com/doc/refman/8.0/en/binlog-replication-configuration-overview.html

MySQLにserver-idを設定し、レプリケーション用のユーザーを作る。
server_idは、前回記事を引き継いで201を設定しようか。
レプリケーション元のIPアドレスを特定することが難しいので、replのホスト名は%である。
あと、仮想マシンで試したときは要らなかったと思うがコンテナだと「WITH mysql_native_password」が無いとレプリケーションがエラーを吐く。何でだ。

# $mysql1 -e "SET PERSIST server_id = 201;"

# $mysql1 -e "CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'password';"
# $mysql1 -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';"

5.レプリケーション用の初期データを用意し、レプリケーションの開始点を確認する。

# $mysql1 -e "FLUSH TABLES WITH READ LOCK;"
# $mysql1 -e "SHOW MASTER STATUS\G;" > master-status.txt
# oc exec -n mysql mysql1-0 -- mysqldump -u root --all-databases --master-data > dbdump.db
# $mysql1 -e "UNLOCK TABLES;"
# cat master-status.txt

(実行結果 - SHOW MASTER STATUS)
[root@bastion mysql]# cat master-status.txt
*************************** 1. row ***************************
             File: binlog.000002
         Position: 736399
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:

「binlog.~」と「Position」の値がStandby側でレプリケーションを開始するのに必要となる。

mysql2サーバー構成する

1.mysql2を構成するための短縮コマンドを定義する。

# mysql2="oc exec -n mysql mysql2-0 -- mysql -u root"

2.MySQL Workbenchから繋ぐ用のadminユーザーを作る。

# $mysql2 -e "CREATE USER 'admin'@'%' IDENTIFIED BY 'password';"
# $mysql2 -e "GRANT ALL ON *.* TO 'admin'@'%';"

3.mysql2にレプリケーション用の設定を行う。
server_idを202に設定する。
レプリケーション用のユーザーを作成する。

# $mysql2 -e "SET PERSIST server_id = 202;"

# $mysql2 -e "CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'password';"
# $mysql2 -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';"

3.初期データとして、mysql1のバックアップをロードする。

# oc exec -i -n mysql mysql2-0 -- mysql -u root < dbdump.db

4.レプリケーションを開始する。

# MASTER_LOG_FILE=$(grep -oP '(?<=File: ).*' master-status.txt)
# MASTER_LOG_POS=$(grep -oP '(?<=Position: ).*' master-status.txt)

# $mysql2 -e "CHANGE MASTER TO MASTER_HOST='mysql1', \
MASTER_USER='repl', MASTER_PASSWORD='password', \
MASTER_LOG_FILE='${MASTER_LOG_FILE}', MASTER_LOG_POS=${MASTER_LOG_POS};"
# $mysql2 -e "START SLAVE;"
# $mysql2 -e "SHOW SLAVE STATUS\G;"

「Slave_IO_State: Waiting for master to send event」、「Last_IO_Error:」、「Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates」となっていることを確認する。

HAproxyを設定し、NodePortを作る

1.OpenShiftクラスター作成時に、bastionサーバー上にHAproxyを導入したと思うので、それを流用する。
haproxy.cfgのファイル末尾に以下を追加する。
node1、node2、node3は、OpenShiftクラスターを構成するノードと、そのIPアドレスである。

/etc/haproxy/haproxy.cfg
frontend mysql
    bind *:3306
    mode tcp
    default_backend mysql
backend mysql
    balance source
    mode tcp
    server node1 192.168.1.3:30306 check
    server node2 192.168.1.4:30306 check
    server node3 192.168.1.5:30306 check

2.haproxyをreloadし、firewalldを設定する。

# systemctl reload haproxy
# firewall-cmd --add-service=mysql --zone=external --permanent
# firewall-cmd --reload

3.mysql1に接続するNodePortを作る。

nodeport-mysql1.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: mysql
spec:
  type: NodePort
  ports:
    - name: mysql
      protocol: TCP
      port: 3306
      targetPort: 3306
      nodePort: 30306
  selector:
    app: mysql1
# oc create -f nodeport-mysql1.yaml

MySQL WorkbenchからMySQLに繋ぐ

1.手元のPCにMySQL Workbenchをダウンロードしてインストールする。
https://www.mysql.com/jp/products/workbench/

2.HAproxyのIPアドレスに向けたConnectionを作って繋ぐ。
image.png

3.レコードを追加してみよう。
Schemas > world > Tables > countryのテーブルを開き、以下のSQL文を実行(⚡)する。

INSERT INTO `world`.`country` (`Code`, `Name`, `Continent`, `Region`, `SurfaceArea`, `Population`, `LocalName`, `GovernmentForm`, `Code2`) VALUES ('ASR', 'Asura Kingdom', 'Europe', 'Central Region', '100000.00', '1000000', 'Asura Kingdom', 'Monarchy', 'AA');

image.png

レコードが追加されただろうか。
image.png

フェールオーバーしてみる

1.mysql1が稼働しているnode1を電源オフしてもいいのだが、さすがに何なのでStatefulSetのレプリカ数を0にする。

# oc scale sts -n mysql mysql1 --replicas=0

2.MySQL Workbenchで表がロードできなくなった事を確認する。
image.png
image.png

3.念のため、mysqlへのアクセスを閉塞する。
NodePortを消せばいい。

# oc delete svc -n mysql mysql

4.mysql2でレプリケーションを停止し、Activeサーバーになっても良い様に準備する。

# $mysql2 -e "SHOW SLAVE STATUS\G;"
 → 「Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates」となっているのを確認する。
# $mysql2 -e "STOP SLAVE;"
# $mysql2 -e "RESET SLAVE ALL;"

# $mysql2 -e "FLUSH TABLES WITH READ LOCK;"
# $mysql2 -e "SHOW MASTER STATUS\G;" > master-status.txt
# $mysql2 -e "UNLOCK TABLES;"
# cat master-status.txt

この時点でmysql2は新しいActiveサーバーとして機能しているので、HAproxyの振り分けをmaster2に変更する。

5.mysql2に向けたNodePortを作成する。

nodeport-mysql2.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: mysql
spec:
  type: NodePort
  ports:
    - name: mysql
      protocol: TCP
      port: 3306
      targetPort: 3306
      nodePort: 30306
  selector:
    app: mysql2
# oc create -f nodeport-mysql2.yaml

6.MySQL Workbenchで再度、表をロードする。
繋がるようになっているはずである。ついでに、先にmysql1で追加したレコードがmysql2にもデータ反映されている事を確認しよう。
image.png

7.mysql2がActiveサーバーになっている段階で、もう一つレコードを追加してみる。
MySQL Workbenchで以下の文を実行(⚡)する。

INSERT INTO `world`.`country` (`Code`, `Name`, `Continent`, `Region`, `SurfaceArea`, `Population`, `LocalName`, `GovernmentForm`, `Code2`) VALUES ('MLS', 'Holy Country of Millis', 'South America', 'Southern Millis', '100000', '1000000', 'Millis', 'Church State', 'MI');

image.png
image.png

元のActiveサーバーに切り戻す

mysql1サーバーに切り戻すところもやってみよう。

1.mysql1のレプリカ数を1に戻す。

# oc scale sts -n mysql mysql1 --replicas=1
# oc logs -f -n mysql mysql1-0
 → 「ready for connections.~」が表示されるのを待つ。

2.まずはmysql1を、mysql2のレプリカ(Standby)として構成する。シャットダウン中のデータ更新に追いつかせるためである。

# MASTER_LOG_FILE=$(grep -oP '(?<=File: ).*' master-status.txt)
# MASTER_LOG_POS=$(grep -oP '(?<=Position: ).*' master-status.txt)

# $mysql1 -e "CHANGE MASTER TO MASTER_HOST='mysql2', \
MASTER_USER='repl', MASTER_PASSWORD='password', \
MASTER_LOG_FILE='${MASTER_LOG_FILE}', MASTER_LOG_POS=${MASTER_LOG_POS};"
# $mysql1 -e "START SLAVE;"

3.mysql1サーバーで以下のコマンドを実行し、レプリケーションが追いつくのを待つ。

# $mysql1 -e "SHOW SLAVE STATUS\G;"

「Slave_IO_State: Waiting for master to send event」、「Last_IO_Error:」、「Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates」となっていることを確認する。

レプリケーションが追いついたらmysql1をActiveサーバーとして復帰するための準備完了である。

4.mysql2へのアクセスを閉塞する。

# oc delete svc -n mysql mysql

5.mysql1サーバーのレプリケーションを止め、Activeに復帰させる準備をする。

# $mysql1 -e "SHOW SLAVE STATUS\G;"
 → 「Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates」となっているのを確認する。
# $mysql1 -e "STOP SLAVE;"
# $mysql1 -e "RESET SLAVE ALL;"

# $mysql1 -e "FLUSH TABLES WITH READ LOCK;"
# $mysql1 -e "SHOW MASTER STATUS\G;" > master-status.txt
# $mysql1 -e "UNLOCK TABLES;"

6.master1に振るNodePortを作成し、MySQLへのアクセスを再開する。

# oc create -f nodeport-mysql1.yaml

7.MySQL Workbenchで再度、表をリロードする。表がリロードされ、master2側に追加したレコードがmaster1にも反映されていることを確認する。
image.png

8.最後に、mysql2サーバーが改めてStandbyとなるように再構成する。

# MASTER_LOG_FILE=$(grep -oP '(?<=File: ).*' master-status.txt)
# MASTER_LOG_POS=$(grep -oP '(?<=Position: ).*' master-status.txt)

# $mysql2 -e "CHANGE MASTER TO MASTER_HOST='mysql1', \
MASTER_USER='repl', MASTER_PASSWORD='password', \
MASTER_LOG_FILE='${MASTER_LOG_FILE}', MASTER_LOG_POS=${MASTER_LOG_POS};"
# $mysql2 -e "START SLAVE;"
# $mysql2 -e "SHOW SLAVE STATUS\G;"

「Slave_IO_State: Waiting for master to send event」、「Last_IO_Error:」、「Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates」となっていることを確認する。

(おまけ1)何回か往復したい時の追加データ

INSERT INTO `world`.`country` (`Code`, `Name`, `Continent`, `Region`, `SurfaceArea`, `Population`, `LocalName`, `GovernmentForm`, `Code2`) VALUES ('RAN', 'Ranoa Kingdom', 'Europe', 'Northern Central', '10000', '100000', 'Ranoa', 'Monarchy', 'RA');
INSERT INTO `world`.`country` (`Code`, `Name`, `Continent`, `Region`, `SurfaceArea`, `Population`, `LocalName`, `GovernmentForm`, `Code2`) VALUES ('KDK', 'King Dragon Kingdom', 'Europe', 'Southern Central', '50000', '500000', 'King Dragon Kingdom', 'Monarchy', 'KD');

(おまけ2)今回構成の消費メモリ

2回往復後の消費メモリ。
mysql1、mysql2の2台合わせて、大体1GBといったところか。
image.png

(おまけ3)きれいさっぱり消し去る

1.mysqlネームスペースを消す。

# oc delete namespace mysql

2.PV、StorageClassを消す。

# oc delete pv mysql1 mysql2
# oc delete sc nfs-mysql

3.イメージプルーニングを行い、使われなくなったmysql-80イメージを消す。

# oc adm prune images

4.nfsのストレージも消す。

# sed -i '/\/export.*/d' /etc/exports
# exportfs -r
# rm -rf /export

5.何なら、HAproxyの定義も消す。

/etc/haproxy/haproxy.cfg
(ファイル最後の以下を削除)

frontend mysql
    bind *:3306
    mode tcp
    default_backend mysql
backend mysql
    balance source
    mode tcp
    server node1 192.168.1.3:30306 check
    server node2 192.168.1.4:30306 check
    server node3 192.168.1.5:30306 check
# systemctl reload haproxy
# firewall-cmd --remove-service=mysql --zone=external --permanent
# firewall-cmd --reload

これで本記事の手順を1からやり直すことが出来る。
やってみよう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む