untitled .engineer

技術系のブログ(仮)

MySQL5.5からMySQL8.0にマイグレーションしたゆるい話


目次


本エントリの概要

この記事は MySQL Advent Calendar 2019 - Qiita の15日目です。
タイトルの通り、職場のMySQL5.5を8.0にマイグレーションした話を書きます。

前提と環境条件

  • 登場するサーバーはすべてWindows
    • ほぼ政治的な理由(主題ではないので具体的な理由は割愛)
  • システムは小規模でゆるいサービスレベル
    • スキーマ数約60/テーブル数約600/データ量約35GB
    • 利用者は社内関係者のみ、同時利用者数は日中最大でも数百人程度
    • 24H365D稼働ではあるが、夜間はアクセス極少
    • ホットスタンバイなサーバーがあり、 通常時はread_onlyではあるが、メインサーバー停止時に利用する
    • 参照先切り替えは運用で行う(自動的なHA構成なし)
    • サービスレベルは取り決めがいない
      • サーバー管理者が1人なので決めようがない(個人的に努力目標があるだけ)
      • 情シス部門には人がたくさんいるけど、対象のシステム群を管轄しているのが私だけ
    • 簡単に言うと「主要業務の営業時間外なら「ごめんなさい」しておけば「読み取り専用」でもよいことになっている」
  • マイグレーションの過程で非サポートな操作をしている
    • たまたま私の環境ではうまくいっただけ
    • 決して推奨するものではない

背景

  • MySQL5.5からバージョンアップするする詐欺を続けていた(個人的に)
    • 4.1→5.0→5.1→5.5まではちゃんと?アップグレードしていた
    • 管理者が3人→1人になり、工数確保できず止まってしまっていた
  • メインサーバーのOS WindowsServer2008のサポート切れが迫る
    • 2020年1月
    • 社内ルールでサポート切れのWindowsはN/W接続禁止
  • 設置先データセンターが202N年に閉鎖
    • 親会社の方針によりクラウドへの移行が決定

要件

せっかくやるなら一点切り替えで以下の5要件をこなしてしまおうと考えた

  • MySQL5.5 → MySQL8.0へバージョンアップする
    • サポート切れ対応/パフォーマンス改善
  • ポジションベースレプリケーション → GTIDベースレプリケーションへ移行
    • HA構成構築の容易さ、リカバリ工数改善(ただし壊れたことはない)
  • CLONE機能を使いたい使う
  • utf8mb3 → utf8mb4 に変換したいする
    • 直近で絵文字等の業務要件はないが、MySQLの標準に合わせる
    • やっておかないと「やろう」と思ってすぐにできることではない
  • できる限り停止時間を短く切り替え作業を行う
    • 数分で切り替える=平日営業時間外に作業可=深夜土日出勤なし←ひとり働き方改革

移行手順詳細

ここから具体的な手順を図を交えて紹介しますが、主に5要件に対する対応がわかっていただければよいと考え、かなり雑に書いています。
実際にはリハーサルで発生するエラーをつぶしながら手順を構築しており、my.cnfに本来記載しなければならない設定項目や文字コード/参照順序の違いによる対応などもかなり省略しています。
ポート番号やサーバーIDなども重複しないよう工夫しています。

f:id:dupont_kedama:20191125232211p:plain

既存の構成

f:id:dupont_kedama:20191125232320p:plain

  • 「メイン」サーバーから「バックアップ」サーバーと「スタンバイ」サーバーにレプリケーションしている(すべて5.5)
  • 「スタンバイ」は障害発生時の参照切替先
  • 「バックアップ」は夜間にサービス停止させてのコールドバックアップ用
  • この構成は移行後も維持する

1. スキーマ定義の取得

f:id:dupont_kedama:20191125232431p:plain

  • 「バックアップ」5.5からmysqldumpでスキーマ定義(データ以外)を取得
  • この後6までの間はDDLを禁止する(運用)
    • 開発もサーバー管理も私なので特に権限変えず

2. 5.6のインストール

f:id:dupont_kedama:20191125232449p:plain

  • 「バックアップ」に5.6をインストール
  • ダンプしたスキーマ定義をインポートする

3. 5.7のインストール

f:id:dupont_kedama:20191125232505p:plain

4. 8.0のインストール

f:id:dupont_kedama:20191125232520p:plain

5. 中間インスタンスへのデータ投入

f:id:dupont_kedama:20191125232537p:plain

  • 「メイン」5.5→「バックアップ」5.5のレプリケーションを停止する
  • 「バックアップ」5.5からmysqldumpでデータのみを取得する
  • 5.6にダンプしたデータを流し込む
  • 5.6→5.7→8.0に伝播して追いつくのを待つ

6. 中間インスタンスのデータ同期

f:id:dupont_kedama:20191125232603p:plain

7. 本番およびスタンバイに8.0をインストール

f:id:dupont_kedama:20191125232636p:plain

  • 「新メイン」サーバーと「スタンバイ」に8.0をインストール
    • gtid_mode=ON_PERMISSIVE

8. 本番およびスタンバイにデータ複製

f:id:dupont_kedama:20191125232651p:plain

  • 「バックアップ」5.7→8.0のレプリケーションを停止する
  • 「バックアップ」8.0からCLONE機能で「新メイン」8.0に複製する
  • 「バックアップ」8.0からCLONE機能で「スタンバイ」8.0に複製する

9. 本番およびスタンバイの準備完了

f:id:dupont_kedama:20191125232708p:plain

10. 切替作業

f:id:dupont_kedama:20191125232736p:plain

  • すべてのレプリケーションおよび5.5~5.7のサービスを停止
  • すべての8.0で gtid_mode=ON に変更
  • すべての8.0のポートを既存の役割のポートに戻す
  • 「新メイン」8.0→「バックアップ」8.0でレプリケーションの設定
  • 「新メイン」8.0→「スタンバイ」8.0でレプリケーションの設定
    • ここから MASTER_AUTO_POSITION = 1
  • アプリケーションからの接続先を「メイン移行先」に変更

11. 後始末

f:id:dupont_kedama:20191125232751p:plain

感想

  • 予想より容易だった
    • GTID_MODE=ONへの移行やutf8mb4への変換などでいくつか壁(エラーが出るなど)にぶつかったが、いずれも思っていた以上に低い壁だった
    • 中には「その対処で正解なのかわからないけど解消したからヨシ」としているものも
      f:id:dupont_kedama:20191125235724j:plain
  • MySQLは最新版でも日本語情報量が多くて本当に助かる
    • 「日々の覚書」様、「MySQL道普請便り」様等々(省略すみません)
    • それらがなければ高い壁だったかもしれない
  • 苦労したのはどちらかというとアプリケーション側の対応
    • 古いTalendがMySQL8.0に接続できないとか(情報量極少)
  • CLONE機能本気便利
    • 対象を8.0.17にして大正解だったと思う
    • 開発環境とステージングを合わせるときとかにも使ってる
  • 正直やっぱりよくわかってない
    • かなり回りくどいことをしているような気がしている
    • 怖い人たちにソースコード読めって言われそう

参考) 非サポートな操作(のひとつ)

MySQL5.5から8.0のチェーンレプリケーションを構成しているが、これは公式にはサポートされない構成

出典

https://dev.mysql.com/doc/refman/8.0/en/replication-compatibility.html

抜粋

The use of more than two MySQL Server versions is not supported in replication setups involving multiple masters, regardless of the number of master or slave MySQL servers. For example, if you are using a chained or circular replication setup, you cannot use MySQL 8.0.1, MySQL 8.0.2, and MySQL 8.0.4 concurrently, although you could use any two of these releases together.

翻訳

マスターまたはスレーブMySQLサーバーの数に関係なく、複数のマスターを含むレプリケーションセットアップでは、3つ以上のMySQLサーバーバージョンの使用はサポートされていません。 たとえば、連鎖または循環レプリケーションセットアップを使用している場合、MySQL 8.0.1、MySQL 8.0.2、およびMySQL 8.0.4を同時に使用することはできませんが、これらのリリースの2つを一緒に使用することはできます。