はじめに
Zabbix のデータベースを MariaDB で運用していたところ、history syncer internal processes 等の値が定期的に高騰するようになったため、時系列データベースである TimescaleDB に移行することにしました。本記事は、検証環境での検証結果のまとめです。
環境
1年ほど前に構築した検証環境があったので、Zabbixのバージョンを最新化(5.0.15)した上で検証しました。
PostgreSQL, TimescaleDB はコミュニティ版のものを使用しました。
項目 | 移行前 | 移行後 |
---|---|---|
OS | CentOS 8.2 | 同左 |
PHP | php-7.2.24-1 | 同左 |
Web | httpd-2.4.37-21 | 同左 |
DB | mariadb-10.3.17-1 | postgresql12-12.8-1PGDG + timescaledb_12-2.4.2-1 |
Zabbix Server | zabbix-server-mysql-5.0.15-1 | zabbix-server-pgsql-5.0.15-1 |
移行の流れ
以下のような流れで移行します。
- Zabbix Server の停止
- Zabbix 関連パッケージのアンインストール・インストール
- PostgreSQL のインストールと設定
- pgloader によるマイグレーション
- TimescaleDB のインストールと適用
- MariaDB の停止
- Zabbix Server の設定と起動
- SELinux モジュールの生成とインストール
1. Zabbix Server の停止
データベースに値が更新されないように、Zabbix Server を停止します。
sudo systemctl stop zabbix-server
2. Zabbix 関連パッケージのアンインストール・インストール
MySQL 接続用の Zabbix 関連パッケージをアンインストールし、 PostgreSQL 接続用の Zabbix 関連パッケージをインストールします。
sudo dnf remove -y zabbix-server-mysql
sudo dnf install -y zabbix-server-pgsql
sudo dnf remove -y zabbix-web-mysql
sudo dnf install -y zabbix-web-pgsql zabbix-apache-conf
3. PostgreSQL のインストールと設定
PostgreSQL公式サイトのマニュアル を参考に、PostgreSQL のインストールを設定をします。
リポジトリをインストールします。
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
OS同梱の PostgreSQL モジュールを無効化します。
sudo dnf -qy module disable postgresql
コミュニティ版 PostgreSQL をインストールします。
sudo dnf install -y postgresql12-server
データベースを初期化します。
sudo /usr/pgsql-12/bin/postgresql-12-setup initdb
接続設定を変更します。
sudo cp -p /var/lib/pgsql/12/data/pg_hba.conf{,.default}
sudo vi /var/lib/pgsql/12/data/pg_hba.conf
sudo diff -u /var/lib/pgsql/12/data/pg_hba.conf{.default,}
--- /var/lib/pgsql/12/data/pg_hba.conf.default 2021-09-26 16:42:06.589004356 +0900
+++ /var/lib/pgsql/12/data/pg_hba.conf 2021-09-26 16:46:38.837010714 +0900
@@ -83,9 +83,9 @@
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
-host all all 127.0.0.1/32 ident
+host all all 127.0.0.1/32 md5
# IPv6 local connections:
-host all all ::1/128 ident
+host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
PostgreSQL の起動と自動起動設定をします。
sudo systemctl start postgresql-12
sudo systemctl status postgresql-12
sudo systemctl enable postgresql-12
ユーザーとデータベースを作成します。
cd /var/tmp
sudo -u postgres createuser --pwprompt zabbix
sudo -u postgres createdb -O zabbix zabbix
4. pgloader によるマイグレーション
pgloader をインストールし、MariaDB から PostgreSQL にマイグレーションします。
なお、pgloader は epel や PostgreSQL のリポジトリにはパッケージがありませんでした。検証用途かつ単発実行のため、サードパーティーのパッケージをインストールしましたが、 pgloaderのソース を make してもよいでしよう。
インストールします。
sudo dnf install -y https://pkgs.dyn.su/el8/base/x86_64/pgloader-3.6.2-1.el8.x86_64.rpm
スキーマ登録用SQLと pgloader に流し込むコマンドを用意します。
mkdir /var/tmp/pgzabbix
cd /var/tmp/pgzabbix
gzip -d -c /usr/share/doc/zabbix-server-pgsql/create.sql.gz > schema.sql
sed '/INSERT.*/,$d' schema.sql > create.sql
grep ^ALTER schema.sql > alter.sql
vi commands.load
LOAD DATABASE FROM mysql://zabbix:PASSWORD@localhost/zabbix INTO postgresql://zabbix:PASSWORD@localhost/zabbix
WITH include no drop, truncate, create no tables, create no indexes, no foreign keys, reset sequences,
data only SET maintenance_work_mem TO '1024MB', work_mem to '256MB'
ALTER SCHEMA 'zabbix' RENAME TO 'public'
BEFORE LOAD EXECUTE create.sql
AFTER LOAD EXECUTE alter.sql;
マイグレーションします。
pgloader mysql://zabbix:PASSWORD@localhost/zabbix postgresql://zabbix:PASSWORD@localhost/zabbix
pgloader commands.load
動作確認として、まずログを確認します。
less /tmp/pgloader/pgloader.log
Encoding が UTF-8 であることを確認します。
mysql -u zabbix -p -e "SHOW CREATE DATABASE zabbix;"
sudo -u postgres psql -U postgres -l
テーブルを確認します。
mysql -u zabbix -p -e "SHOW TABLES FROM zabbix;"
psql -U zabbix -d zabbix -c "\dt" -h localhost
PostgreSQL のスキーマは public であることを想定していましたが、zabbix となっていました。
public というスキーマは既に存在するため、名前変更できなかったのかもしれません。
変更できなくても参照設定で対処できるので、このまま進めることにします。
5. TimescaleDB のインストールと適用
TimescaleDB をインストールします。
sudo dnf -y install timescaledb_12
TimescaleDB 用の設定(postgresql.conf の編集)は、 timescaledb-tune というツールが提供されているので、これを利用します。
sudo cp -p /var/lib/pgsql/12/data/postgresql.conf{,.default}
sudo dnf install -y https://packagecloud.io/timescale/timescaledb/el/8/x86_64/timescaledb-tools-0.11.0-0.el8.x86_64.rpm
sudo timescaledb-tune -pg-config /usr/pgsql-12/bin/pg_config
sudo diff -u /var/lib/pgsql/12/data/postgresql.conf{.default,}
最低限、以下の行が追加されていることを確認します。
+shared_preload_libraries = 'timescaledb' # (change requires restart)
PostgreSQL を再起動します。
sudo systemctl restart postgresql-12
Zabbix データベースに TimescaleDB を適用します。
echo "CREATE EXTENSION IF NOT EXISTS timescaledb SCHEMA zabbix CASCADE;" | sudo -u postgres psql -U postgres zabbix
gzip -d -c /usr/share/doc/zabbix-server-pgsql/timescaledb.sql.gz > timescaledb.sql
cat timescaledb.sql | psql -U zabbix zabbix -h localhost
動作確認として、 history テーブルの状態を確認します。
psql -U zabbix -d zabbix -c "\d+ history;" -h localhost
テーブル"zabbix.history"
列 | 型 | 照合順序 | Null 値を許容 | デフォルト | ストレージ | 統計目標 | 説明
--------+------------------+----------+---------------+-----------------------+------------+----------+------
itemid | numeric | | not null | | main | |
clock | bigint | | not null | '0'::bigint | plain | |
value | double precision | | not null | '0'::double precision | plain | |
ns | bigint | | not null | '0'::bigint | plain | |
インデックス:
"history_clock_idx" btree (clock DESC)
"idx_16883_history_1" btree (itemid, clock)
トリガー:
ts_insert_blocker BEFORE INSERT ON history FOR EACH ROW EXECUTE FUNCTION _timescaledb_internal.insert_blocker()
子テーブル: _timescaledb_internal._hyper_1_1_chunk,
_timescaledb_internal._hyper_1_2_chunk
アクセスメソッド: heap
パーティション用の BEFORE INSERT トリガが作成され、子テーブルが存在することが確認できます。
6. MariaDB の停止
MariaDB は不要になったので、停止します。
sudo systemctl stop mariadb
sudo systemctl disable mariadb
7. Zabbix Server の設定と起動
PostgreSQL 接続用の設定をします。
cd /etc/zabbix
sudo cp -p zabbix_server.conf{,.default}
sudo vi zabbix_server.conf
sudo diff -u zabbix_server.conf{.default,}
--- zabbix_server.conf.default 2021-08-30 18:32:00.000000000 +0900
+++ zabbix_server.conf 2021-09-26 17:50:32.458100230 +0900
@@ -105,6 +105,7 @@
# Mandatory: no
# Default:
# DBSchema=
+DBSchema=zabbix
### Option: DBUser
# Database user.
@@ -122,6 +123,7 @@
# Mandatory: no
# Default:
# DBPassword=
+DBPassword=PASSWORD
### Option: DBSocket
# Path to MySQL socket.
いよいよ Zabbix Server を起動しますが、その前に、SELinux が有効になっている場合はいったん停止します。
sudo setenforce 0
sudo systemctl restart zabbix-server
管理画面からアクセスする場合の PostgreSQL 接続用の設定をします。
cd /etc/zabbix/web
sudo cp -p zabbix.conf.php{,.default}
sudo vi zabbix.conf.php
diff -u zabbix.conf.php{.default,}
--- zabbix.conf.php.default 2020-10-27 17:03:50.308617898 +0900
+++ zabbix.conf.php 2021-09-26 17:55:05.496106605 +0900
@@ -1,7 +1,7 @@
<?php
// Zabbix GUI configuration file.
-$DB['TYPE'] = 'MYSQL';
+$DB['TYPE'] = 'POSTGRESQL';
$DB['SERVER'] = 'localhost';
$DB['PORT'] = '0';
$DB['DATABASE'] = 'zabbix';
@@ -9,7 +9,7 @@
$DB['PASSWORD'] = 'PASSWORD';
// Schema name. Used for PostgreSQL.
-$DB['SCHEMA'] = '';
+$DB['SCHEMA'] = 'zabbix';
// Used for TLS connection.
$DB['ENCRYPTION'] = false;
zabbix-web-deps が再インストールされたので、PHP のタイムゾーンを設定し直します。
cd /etc/php-fpm.d
sudo vi zabbix.conf
php_value[date.timezone] = Asia/Tokyo
変更を適用します。
sudo systemctl restart httpd
8. SELinux モジュールの生成とインストール
audit.log に denied ログが出力されていますので、audit.log からモジュールを生成し、インストールします。
ここでは大雑把にすべてのログから zabbix-server というモジュールを生成しています。
cd /var/tmp
sudo ausearch -m AVC | audit2allow -M zabbix-server
sudo semodule -i zabbix-server.pp
インストールできたので、 SELinux を有効に戻し、 Zabbix Server を再起動し、正常に起動できることを確認します。
sudo setenforce 1
sudo systemctl restart zabbix-server
sudo systemctl status zabbix-server
以上で作業は終了です。
トラブルシューティング
検証中に遭遇したトラブルについて触れます。
could not access file "$libdir/timescaledb-1.4.0": No such file or directory
TimescaleDB を入れなおしたら直りました。
sudo -u postgres psql -U postgres zabbix
DROP EXTENSION timescaledb CASCADE;
CREATE EXTENSION IF NOT EXISTS timescaledb SCHEMA zabbix CASCADE;
HINT: Upgrade your license to 'timescale' to use this free community feature.
/var/log/zabbix/zabbix_server.log に出力されました。
zabbix ユーザーに superuser 権限を付与しても解消されませんでした。
TimescaleDB を入れ直したら、直りました。