仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

社内のZabbixを4.0系から6.0系にアップグレードした

CentOS 7上で動かしていたZabbix 4.0を、Ubuntu 22.04に移行しつつZabbix 6.0系にアップグレードしました。Zabbixのインストール自体はなんてことはないのですが、データベースのアップグレードですこし難儀したため、その記録です。

移行元のLAMP環境

  • OS: CentOS 7.9.2009
  • Webサーバー: 2.4.6
  • DB: MariaDB 5.5.68
  • PHP: 5.4.16
  • Zabbix: 4.0.42

CentOS 7自体はまだサポート中ですが、新しいZabbixでは新しめのPHPを要求されるため、Ubuntu 22.04で再構築してDBを移行することとしました。

DBは、文字コードがlatin1で作られていたため、今回を期にUTF-8に移行します。これが今回の罠ポイントです。

移行先のLAMP環境

  • OS: Ubuntu 22.04
  • Webサーバー: Apache 2.4.52
  • DB: MariaDB 10.6.7
  • PHP: 8.1.2
  • Zabbix: 6.0.6

Webサーバー・DB・PHPはaptで入る標準のもの、Zabbixは後述のZabbix公式のものを使用しました。コンテナ版に移行することも一瞬考えましたが、Zabbix AgentのIPアドレス変更のことを考えるのが面倒だったため、移行前と同じくVMで構築してIPアドレスを継承することとしました。

旧サーバーの停止とダンプ作成

サーバーのサービスを停止してダンプを取得します。取得したダンプは、新しいサーバーに転送しておきます。

# systemctl stop zabbix-server
# mysqldump --opt --flush-logs --single-transaction --databases zabbix | gzip -9 > /root/zabbix.sql.gz

Zabbixのインストール

まずはDBのインストールです。Zabbixインストールガイドの通りすすめるとMySQL 8.0が入るため、先にMariaDBをインストールします。

$ sudo apt update
$ sudo apt install mariadb-server

以下のZabbixインストールガイドに従って、手順2のbまで進めます。

Download and install Zabbix

latin1→utf8mb4ではデータベースがマイグレーションできない?

6.0導入の手順に従えば、データベースはutf8mb4で作成して、インポートしたテーブルもutf8mb4に変換すれば良いようでしたが、実際に試してみたところ、Zabbixサーバー起動時に実行されるデータベースのマイグレーションに失敗してしまいました。

[Z3005] query failed: [1071] Specified key was too long; max key length is 3072 bytes [create index items_1 on items (hostid,key_(1021))]

インポートしたデータベースのバージョンが04000000/04000006で、上記のエラーが出るようになった時点では04050003/04050003まで上がっていたので、おそらくこのあたりのマイグレーション処理が今回の環境に対応できていなさそうです。1文字3バイトと1文字4バイトの違いでなにかが起きていそうにも見えますが……これを深追いするのは大変そうです。

あれこれ試してみた結果、一度utf8mb3に変換した状態でデータベースのマイグレーションをすれば成功することがわかったので、データベースは2段階で変換をすることにしました。

データベースをインポートしてutf8mb3化する

MariaDBに入ってデータベースを作成します。この時点で文字コードにutf8mb3を指定します。

$ sudo mysql

> create database zabbix default charset=utf8mb3 collate=utf8mb3_bin;
> grant all on zabbix.* to zabbix@localhost identified by "<password>";

旧サーバーのダンプをリストアします。

$ zcat zabbix.sql.gz | mysql -u zabbix -p

途中でエラーが出て止まってしまいました。データがでかすぎるやつみたいです。

ERROR 1118 (42000) at line 2071: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

innodb_strict_modeを0に変更することで回避できるようなので、設定を投入します。

$ sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf

[mysqld]
innodb_strict_mode=0

mariadbサービスを再起動してインポートを再実行します。

$ sudo systemctl restart mariadb
$ zcat zabbix.sql.gz | mysql -u zabbix -p

Zabbix 5.0の以下の手順にしたがって、データベースのテーブルの文字コードをutf8mb3、参照順序をutf8mb3_binに変更します。データベースは作成時に文字コードを指定したため、手順1〜4はスキップして、5から実行します。

2 Repairing Zabbix database character set and collation

スクリプトをダウンロードして、zabbixデータベースに流し込み、それを実行します。

$ sudo mysql zabbix < utf8_convert.sql
$ sudo mysql zabbix

> SET @ZABBIX_DATABASE = 'zabbix';
> CALL zbx_convert_utf8();
> drop procedure zbx_convert_utf8;

この時点で一度Zabbixサーバーを起動します。ログを確認して、データベースのマイグレーションが完了することを確認します。

$ sudo systemctl start zabbix-server
$ sudo tail -f /var/log/zabbix/zabbix_server.log

確認ができたらZabbixサーバーを一旦止めます。

$ sudo systemctl stop zabbix-server

データベースとテーブルのutf8mb4化

続けてutf8mb4化を進めていきます。Zabbix 6.0の以下の手順にしたがって、データベースとテーブルの文字コードをutf8mb4、参照順序をutf8mb4_binに変更します。今度はすべての手順を実行します。

2 Repairing Zabbix database character set and collation

$ sudo mysql zabbix
> SELECT @@character_set_database, @@collation_database;
+--------------------------+----------------------+
| @@character_set_database | @@collation_database |
+--------------------------+----------------------+
| utf8mb3                  | utf8mb3_bin          |
+--------------------------+----------------------+

> alter database zabbix character set utf8mb4 collate utf8mb4_bin;

> SELECT @@character_set_database, @@collation_database;
+--------------------------+----------------------+
| @@character_set_database | @@collation_database |
+--------------------------+----------------------+
| utf8mb4                  | utf8mb4_bin          |
+--------------------------+----------------------+

スクリプトをダウンロードして、テーブル側を修正します。

$ sudo mysql zabbix < utf8mb4_convert.sql
$ sudo mysql zabbix

> SET @ZABBIX_DATABASE = 'zabbix';
> CALL zbx_convert_utf8();
> drop procedure zbx_convert_utf8;

Zabbixサーバーを起動して、正常に起動することを確認します。

$ sudo systemctl start zabbix-server
$ sudo tail -f /var/log/zabbix/zabbix_server.log

まとめ

Zabbix 4.0からZabbix 6.0への移行は、MySQLでかつlatin1を使用していた場合は、文字コードをutf8mb3、utf8mb4の2段階で変更する必要があるという話でした。latin1はなんとなく罠が多い印象でしたが、抜け出すにも罠があったとは……という感じでした。

Zabbixのアップグレードが終わって満足しかけて思い出しましたが、そもそも私はメール通知用の送信サーバーを変更したあと、テストメール送信がZabbix 4.0ではできなくて、アップグレードをしようと思い立ったのでした。ううう、そっちのテストに戻らねば……。