プロジェクト

全般

プロフィール

MySQL5.x→8.xへのアップグレード

前提条件

MySQL 5.xのサポート落ちに伴うMySQL8.xへのアップグレードを行う。

RPM版でremi版などPHPに伴ってオフィシャルリポジトリを使っていない環境を想定する。

事前準備

  • データベースのバックアップを作成する
    # mysqldump -u root -p -x --all-databases > mysql.sql
    
  • サービスの停止
    # systemctl stop mysqld
    
  • データディレクトリを退避し、空のディレクトリを作成
    # cd /var/lib
    # mv mysql mysql_old
    # mkdir mysql
    # chown mysql.mysql mysql
    
  • リポジトリを登録する
    RPMはOSに合わせて適宜選択すること
    # rpm -ivh https://dev.mysql.com/get/mysql57-community-release-el6-9.noarch.rpm
    

依存ライブラリ「compat-mysql51」を解消しつつ更新する

「compat-mysql51」の依存性でバージョンアップが出来ない(cronやpostfixが依存しているので消せない)
ため、このRPMを依存性の影響の無いパッケージに入れ替えながらアップデートする。

方法としてはyumを対話モードで実行し、「compat-mysql51」削除と代替の「mysql-community-libs-compat」
インストールを同時に行う。その過程でMySQL8.xも同時に導入される。

  • yumの対話モードを実行
    # yum shell
    読み込んだプラグイン:fastestmirror
    Yum シェルの設定をしています
    > install mysql-community-libs-compat
    インストール処理の設定をしています
    Loading mirror speeds from cached hostfile
     * remi-safe: ftp.riken.jp
    > erase compat-mysql51
    削除処理の設定をしています
    > transaction
    「compat-mysql51」削除と代替の「mysql-community-libs-compat」およびMySQL8.xのインストールがそれぞれ実行されます。
    > exit
    

初期設定

  • 初期化を行います(たぶんエラーになります
    # mysqld --initialize-insecure
    
  • エラーとなった原因となる非互換の設定をコメントアウトします
    # vi /etc/my.cnf
    --------------------
    innodbやtimezoneなどをコメントアウトします
    timezoneは初回起動が成功してDB復元を行った後にしか有効に出来ません
    <pre>
    </pre>
    
  • 初期DBを削除し、再度初期化を行います
    rm -rf /var/lib/mysql/*
    # mysqld --initialize-insecure
    
  • 成功するまでこれを繰り返します

DBのリストア

MySQLが起動するようになったので、SQLでDBをリストアします。

  • rootユーザのパスワードなどがないとリストア出来ないので初期設定を行います。
    # mysql_secure_installation 
    --------------------
    パスワードのみ設定し、後はデフォルト
    
  • DBのリストアを実効
    # mysql -h localhost -u root -p < mysql.sql 
    

この時点でmysqlコマンドでログインは可能ですが、テーブル参照などは
権限の問題で参照が出来ない状態です。(rootユーザでも

旧形式のテーブルでリストアされてしまったため、システムテーブルに互換性が
なくユーザ情報などが利用できないため、リストア後にアップグレードする必要
があります。

DBのアップグレード

従来は「mysql_upgrade」コマンドを実行していたのですが、8.xからは起動時に
mysqldコマンドのオプションでアップグレードチェックをするようになったため
起動スクリプトに追加を行います。

  • 起動スクリプトの修正
    下記のように「--upgrade=FORCE」を追加する。
    systemctlの場合は/usr/lib/systemd/system/mysqld.serviceと思われる
    # vi /etc/init.d/mysqld
    --------------------
            $exec $MYSQLD_OPTS --datadir="$datadir" --socket="$socketfile" \
                    --pid-file="$mypidfile" --upgrade=FORCE \
                    --basedir=/usr --user=mysql $extra_opts >/dev/null &
            safe_pid=$!
    
  • 上記編集後にサービスを再起動する。
    # systemctl restart mysqld
    
  • ログを参照し、DBアップグレード処理が入ったことを確認する
    # less /var/log/mysqld.log
    --------------------
    2021-02-09T07:36:04.606136Z 4 [System] [MY-013381] [Server] Server upgrade from '80023' to '80023' started.
    2021-02-09T07:36:08.415146Z 4 [System] [MY-013381] [Server] Server upgrade from '80023' to '80023' completed.
    

設定の復元

  • timezoneなど、システムテーブル参照の必要があった互換性のある設定を元に戻します
    utf-8はUTF8MB3または後継のUTF8MB4が推奨されています
    # vi /etc/my.cnf
    --------------------
    character-set-server=UTF8MB4
    default-time-zone = 'Asia/Tokyo'
    など
    
  • 正常に起動することを確認します(互換性が無い設定を復活させていないか
    # systemctl restart mysqld
    
  • 正常に利用できることを確認します
    # mysql -u root -p
    mysql> show databases;
    mysql> quit;
    

    *アプリケーションから参照できることが確認出来れば完了です

片付け

完全に必要が無いと見なしたら、バックアップしたmysql.sqlと/var/lib/mysql_oldを削除できます。