研究活動：プリザンター（Ver1.4.9.1）はMariaDBで動作できるか？

# 1. はじめに
## 💭この記事について
こんにちは。インプリムのhmineです。

OSSのノーコード・ローコード開発ツール「プリザンター」は、さまざまなOSとDBの構成で実行環境を構築することができます。

開発元である弊社・株式会社インプリムで正式に検証した環境は以下FAQの通りです。

- **公式マニュアル：『FAQ：プリザンターの動作環境や推奨スペックが知りたい』**
  - https://pleasanter.org/ja/manual/faq-recommended-specifications

ただし、互換性があるOSやDBの使用により、上記以外にも「理論上は構築可能」というシステム構成が存在する可能性はあります。

## 🐬プリザンターのMySQL対応に関連して…
プリザンターはVer1.4.9.0以降、[MySQLに対応しました！](https://pleasanter.org/blogs/ver1490release)　🎊🎊🎊🎊🎊🎊

そこで寄せられるようになったのが「MySQLに対応したということは、MariaDBでも動きますか？」というご質問です。「理論上は動くはず」とお答えしていましたが、実際のところはどうなのか、気になったので試してみました。

**※本記事は筆者個人による研究活動のレポートです。組織の公式見解ではございません。**

# 目次
1. はじめに
2. 結論に代えて　MariaDB使用可否のフローチャート
3. プリザンターをMariaDBの環境で構築したレポート
   - AlmaLinux 9.4 × MariaDB 11.6
   - 使用したプリザンターはVer.1.4.9.1
4. プリザンター×MariaDBの課題1　検索機能の制限
   - テーブルの検索（フィルタ機能）の「フルテキスト」も制限
5. プリザンター×MariaDBの課題2　バージョンアップの不具合
6. 今後MariaDBの使用について検証するテーマ
7. 結び

# 2. 結論に代えて　MariaDB使用可否のフローチャート
はじめに今回の検証結果の範囲で考えた結論を元に、フローチャートを提示します。

※2024/10/15　プリザンターVer1.4.9.1で検証した結果です。  

- **質問1. プリザンターは、最新版を逐次バージョンアップして運用するか？**
  - **Yes**（逐次バージョンアップする）  
    →　🚫MariaDBは使用できない
  - **No**（導入してから当面は同じバージョンを使い続けて構わない）  
    →　**質問2. プリザンターで、横断検索orフルテキスト検索を使用するか？**
    - **Yes**（横断検索orフルテキスト検索を使用する）  
      →　💡MariaDBを使用する場合、Mroongaの導入が併せて必要
    - **No**（横断検索orフルテキスト検索を使用しない）
      →　💡MariaDBを使用する場合、所定の設定・運用ルールが必要

このように、現時点のプリザンターでMariaDBを使用する場合は、制約がいろいろとあることがわかりましたので、ひとつずつ本記事で説明します。

# 3. プリザンターをMariaDBの環境で構築したレポート

## 3-1. MariaDBについて
MariaDBはMySQLを元に作られたDBMSです。したがってMySQLと高い互換性があります。

インターネット上の日本語ドキュメントの量で比較すると、MySQLのドキュメントの方が多いです。ただしMySQLが元になっていることから、MriaDBもシステム構成の選択肢として十分に有力といえます。

- **参考記事：『Knowledge Base » MariaDB – 日本語 » MariaDB について』**
  - https://mariadb.com/kb/ja/mariadb-japanese-mariadb/

## 3-2. 準備
1. 以下のものを用意します。
   - VirtualBox
   - AlmaLinux 9.4 インストーラのisoファイル
     - 今回（2024/10/15時点）の最新版であるAlmaLinux 9.4 を使用しました。
     - AlmaLinux-9.4-x86_64-dvd.iso　…　約10GB。[公式HP](https://almalinux.org/ja/get-almalinux/)からダウンロード。
2. 上記1.で準備したものを使用し、仮想のAlmaLinuxを1台構築します。
3. AlmaLinux内部のソフトウェア等を最新化します。

## 3-3. 構築
全体的な構築手順は、プリザンターの以下のマニュアルの通りです。

- **公式マニュアル：『プリザンターを AlmaLinux にインストールする』**
  - https://pleasanter.org/ja/manual/getting-started-pleasanter-almalinux

📝**補記1. AlmaLinuxのバージョンに関して**  
上記マニュアルで前提条件としているAlmaLinuxのバージョンは9.2です。本記事のMariaDB検証ではバージョン9.4のAlmaLinuxを使用しましたが、マニュアルに記載されている基本的な操作の流れに違いはありませんでした。

📝**補記2. MariaDBのセットアップ手順** 
上記マニュアルの「手順2. データベースのセットアップ」については、MariaDBのセットアップ手順に置き換える必要があります。

今回は以下手順を使用してMariaDBをセットアップしました。

**1. 以下コマンドを実行し、MariaDBのリポジトリを設定する。**

```bash
$ sudo vi /etc/yum.repos.d/MariaDB.repo
```

以下の通り編集して保存。

```/etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = https://rpm.mariadb.org/11.6/almalinux9-amd64/
module_hotfixes = 1
gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck = 1
```

※上記`baseurl`に記載のURLは2024/10/15現在は有効だが、時間の経過とともに削除される可能性がある。URLが使用できない場合やMariaDB 11.6以外を使用する場合は、作業時点において有効なURLを指定すること。  

**2. 以下コマンドを実行し、MariaDBのサーバをインストールする。**

```bash
$ sudo dnf install -y MariaDB-server
```

**3. 以下コマンドを実行し、mariadbサービスの自動起動を有効化する。**

※確認のため、事後にサービスのステータスも確認する。

```bash
$ sudo systemctl enable mariadb
$ sudo systemctl start mariadb
$ systemctl status mariadb.service
```

**4. MariaDBのrootアカウントの初期設定を行う。**

以下、MariaDBにセーフモードでログインするためのコマンドを実行する。この設定により、最後の`mysql -u root mysql`コマンドにおいて、パスワードを入力せずMariaDBにログイン可能となる。

```bash
$ sudo systemctl stop mariadb
$ sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"
$ sudo systemctl start mariadb
$ mysql -u root mysql
```

以下SQLを実行し、MariaDBのrootアカウントの新しいパスワードを設定する。

```sql
> flush privileges;
> alter user 'root'@'localhost' identified by '<MariaDBのrootアカウントの新しいパスワード>';
> quit;
```

MariaDBのセーフモードを解除し、新しいパスワードでログインできることを確認する。

```bash
$ sudo systemctl stop mariadb
$ sudo systemctl unset-environment MYSQLD_OPTS
$ sudo systemctl start mariadb
$ mysql -u root -p<MariaDBのrootアカウントのパスワードを-pとの間に空白を入れずに記述> mysql
```

ログインができたら、MariaDBからログアウトする。

```sql
> quit;
```

**5. ここまででMariaDBはセットアップが完了。**

以降、プリザンターの公式マニュアルの最後までセットアップを続ける。Rds.jsonについてはMySQLの場合と同様に記述する。

**💡備考**

上記手順は、AlmaLinux Wiki内のLAMP環境を構築する手順を参考にしました。  
https://wiki.almalinux.org/series/LAMP-server.html#second-step-install-mariadb

## 3-4. CodeDefinerを初回実行し、エラーを検知

さて。

この実験において、CodeDefinerの実行結果は以下の通りでした。

以下ログに2箇所`<ERROR>`が表示されていますので、注目してください。末尾がCodeDefiner全体の結果としてエラーがあったという通知のログ、下から5行目が実際のエラー箇所で出力されたログです。

※Linuxのユーザ名は「hayato2024」としました。HAYATOくんは、プリザンターのイメージキャラクターです。

```
[hayato2024@localhost Implem.CodeDefiner]$ sudo -u hayato2024 /usr/local/bin/dotnet Implem.CodeDefiner.dll _rds /l "ja" /z "Asia/Tokyo"
<INFO> Starter.Main: Implem.CodeDefiner 1.4.9.1
<INFO> RdsConfigurator.CreateDatabase: Implem.Pleasanter
<INFO> UsersConfigurator.Execute: Implem.Pleasanter_Owner
<INFO> UsersConfigurator.Execute: Implem.Pleasanter_User
<INFO> SchemaConfigurator.Configure:
<INFO> Configurator.OutputLicenseInfo:
ServerName: localhost
Database: mysql
Deadline: 0001/01/01
Licensee:
Users: 0
<INFO> Configurator.OutputLicenseInfo: This edition is "Community Edition".
Type "y" (yes) if the license is correct, otherwise type "n" (no).

# キーボードでyを入力する。
y

<INFO> TablesConfigurator.ConfigureTableSet: AutoNumberings
<INFO> Tables.CreateTable: AutoNumberings
<INFO> Tables.CreateTable: AutoNumberings_deleted
<INFO> Tables.CreateTable: AutoNumberings_history
<INFO> TablesConfigurator.ConfigureTableSet: Binaries
<INFO> Tables.CreateTable: Binaries
<INFO> Tables.CreateTable: Binaries_deleted
<INFO> Tables.CreateTable: Binaries_history

～～　中略　～～

<INFO> Tables.CreateTable: Wikis
<INFO> Tables.CreateTable: Wikis_deleted
<INFO> Tables.CreateTable: Wikis_history
<ERROR> TablesConfigurator.Configure: Function 'ngram' is not defined
<INFO> PrivilegeConfigurator.Execute: Implem.Pleasanter_Owner
<INFO> PrivilegeConfigurator.Execute: Implem.Pleasanter_User
<SUCCESS> Starter.ConfigureDatabase: Database configuration has been completed.
<ERROR> Starter.Main: There were 1 errors. Please check the log file (/web/pleasanter/Implem.CodeDefiner/logs/Implem.CodeDefiner_20241015_143115.log).
```

**結果：**  
以下SQLコマンドについて「Function 'ngram' is not defined」のエラーメッセージで、エラー終了してしまいました。

```sql
create fulltext index `ftx` on `Items`(`FullText`) with parser `ngram`;
```

## 3-5. プリザンターの起動確認

CodeDefinerにエラーが生じたことは残念ですが、 **今回は飽くまで実験であるため、** マニュアルの手順を最後まで実施し、プリザンターを起動できるか確認を続行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/e219fe30-8c49-c7f5-b430-3fa3786e2c8d.png)

フルテキストインデックスの生成以外ではDB生成に成功したため、プリザンターを起動することができました。

　＊

以上よりわかることは、**MySQLとMariaDBの完全互換ではない要素をCodeDefinerやプリザンターが使用している場合がある**、ということです。

そして、セットアップ作業の時点ですぐに顕在化した要素が「フルテキストインデックス生成時に使用する日本語パーサーの指定」でした。

# 4. プリザンター×MariaDBの課題1　検索機能の制限

## 4-1. 横断検索機能とテーブル検索の「フルテキスト」の制限

📢**以下、制限事項には解消手順が存在します。**
📢**解消手順の説明は4. の後半部で説明します。**

ここからは、上記「3. プリザンターをMariaDBの環境で構築したレポート」までの操作で構築したプリザンターを起動した際、正常に使用できなかった機能について説明します。

フルテキストインデックスが作成できなかったために、DBの全文検索機能に依存するプリザンターの検索機能が制限されています。

具体的には、プリザンターの2つの機能の使用時にアプリケーションエラーが発生します。

1. 横断検索機能
2. テーブルの検索機能（フィルタ機能）における「フルテキスト」を指定した検索

[画面イメージ]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/0eb389dd-20b1-deaa-cdde-ad656af7964b.png)

▲フルテキストインデックスが生成されていないDB環境下で、横断検索を実行した結果。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/e1e617b4-a81c-0f9d-b790-0ab06765eb21.png)

▲フルテキストインデックスが生成されていないDB環境下で、「フルテキスト」を指定しテーブル検索機能を使用した結果。

MySQLで全文検索を行うMatch構文については以下の公式サイトをご覧ください。

- **MySQL公式リファレンス：『12.10.1 自然言語全文検索』**
  - https://dev.mysql.com/doc/refman/8.0/ja/fulltext-natural-language.html

Match構文をフルテキストインデックスの対象列を指定せずに実行すると、SQLエラーになります。上記アプリケーションエラーは、それが原因で発生したものです。

## 4-2. DBの全文検索機能を使わない設定

上記のアプリケーションエラーは、どちらもプリザンターの設定で該当機能が使われないように設定することにより、回避することができます。

1. 横断検索機能  
   →プリザンターの運用管理者による設定作業で、アプリケーションエラーを回避可
2. テーブルの検索機能（フィルタ機能）における「フルテキスト」を指定した検索  
   →テーブルの管理者がルールを守ることで、アプリケーションエラーを回避可

### 🚫横断検索を無効化する

以下マニュアルに、横断検索機能を無効にできるパラメータの説明が記載されています。

- **公式マニュアル：『パラメータ設定：Search.json』　＞　DisableCrossSearch**
  - https://pleasanter.org/ja/manual/search-json

「DisableCrossSearch」を「true」に書き換えて反映（プリザンターを再起動）すれば、アプリケーションエラーは発生しません。

### 🚫テーブル検索機能（フィルタ機能）で「フルテキスト」を選ばない

以下マニュアルに、テーブルを検索する方式の設定箇所について記載されています。

- **公式マニュアル：『テーブルの管理：検索：検索の設定：検索の種類』**
  - https://pleasanter.org/ja/manual/table-management-search-type

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/c4e34cfc-0f4f-e393-2158-1721c345437a.png)

上図のドロップダウンリストから「フルテキスト」を選ばないように運用回避すれば、アプリケーションエラーは発生しません。

## 4-3. 否！それでも全文検索を使いたい！

ここからは、上記のような機能制限をしたくない場合の代替案について記載します。

以下、公式マニュアル記載外の操作ですが、全文検索システムMroongaを導入することで、4-2.で使用を禁止した機能を復活させることができました。

### 4-3-1. エラーの原因：ngram全文パーサーとは

遠回りになりますが、Mroongaに何をしてもらいたいかを説明するため、先ほどCodeDefiner実行時エラーの原因になったSQL文の確認に戻ります。

```sql
create fulltext index `ftx` on `Items`(`FullText`) with parser `ngram`;
```

MariaDBにおいて上記SQL実行でエラーになった箇所は、`with parser ngram`です。

試しに以下SQLを実行すれば、MariaDBにフルテキストインデックスを生成することはできます。（なお、詳細はこの後すぐに述べますが、これはエラーの解決策**ではない**SQLです。）

```sql
create fulltext index `ftx` on `Items`(`FullText`);
```

フルテキストインデックスが作られ、アプリケーションエラーは発生しなくなります。

ただし、アプリケーションエラーを防くだけでは不完全です。`with parser ngram`を除いてしまうと、全文検索の日本語パーサーが設定されず、先ほど実験したプリザンターの検索機能が正常に動作しません。たとえば、単純な「テスト」という単語を含むデータの検索であっても、対象のデータを抽出できない状態になります。

[画面イメージ]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/7cebebd9-7a4c-7c62-954d-e93559fe6021.png)

▲「検索」に「テスト」と入力してフィルタを設定すると…（下の画像に続く）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/19eb6142-8253-19e9-71b5-8c824deebef7.png)

▲データが何も抽出されない。

この事象は、いま作成したフルテキストインデックスに日本語パーサーの指定がないために起きています。日本語パーサーとは、DBの全文検索で使われる日本語の解析機能のことです。すなわち、日本語パーサーが正しく働くことで、日本語の長文から単語を抽出することが可能となります。今の状態では、「検索エラーテスト」の中に「テスト」という日本語の単語が存在すると認識されていません。

- **参考：MySQL公式ドキュメント：『ngram 全文パーサー』**
  - https://dev.mysql.com/doc/refman/8.0/ja/fulltext-search-ngram.html

**CodeDefinerの想定外だったこと：**  
MariaDBではMySQLと異なり、ngram全文パーサーを指定できないことが想定外でした。

### 4-3-2. Mroonga導入で全文検索を復活させよう！

実際に手を動かして、Mroongaの検証を続けます。

今回は、最適の方式であるかどうかは度外視して、とりあえず機能制限の解除ができるかという観点で実験をしてみました

### 4-3-3. 検証：Mroonga導入手順

**1. プリザンターのサービス停止**

以下コマンドを実行する。

```bash
$ sudo systemctl stop pleasanter
```

**2. Mroongaのインストール前確認**

以下コマンドを実行し、MariaDBにログインする。

```bash
$ mysql -u root -p<MariaDBのrootアカウントのパスワードを-pとの間に空白を入れずに記述> Implem.Pleasanter
```

※CodeDefinerの実行後の環境で手順を実施する想定であるため、データベース名は「Implem.Pleasanter」を指定。

以下SQLを実行し、Mroongaが「Engine」に存在しないことを確認する。

```sql
> show engines;
```

**3. Mroongaのインストールとインストール後確認**

以下SQLを実行。MariaDBのプラグイン機能を使用してMroongaをインストールする。

```sql
> INSTALL PLUGIN Mroonga SONAME 'ha_mroonga.so';
```

再度`show engines;`を実行し、Mroongaが「Engine」に存在することを確認する。

```sql
> show engines;

+--------------------+---------+-------------------------------------------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                                                         | Transactions | XA   | Savepoints |
+--------------------+---------+-------------------------------------------------------------------------------------------------+--------------+------+------------+
| CSV                | YES     | Stores tables as CSV files                                                                      | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables                                       | NO           | NO   | NO         |
| Aria               | YES     | Crash-safe tables with MyISAM heritage. Used for internal temporary tables and privilege tables | NO           | NO   | NO         |
| MyISAM             | YES     | Non-transactional engine with good performance and small data footprint                         | NO           | NO   | NO         |
| MRG_MyISAM         | YES     | Collection of identical MyISAM tables                                                           | NO           | NO   | NO         |
| Mroonga            | YES     | CJK-ready fulltext search, column store                                                         | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, foreign keys and encryption for tables                | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                                                              | NO           | NO   | NO         |
| SEQUENCE           | YES     | Generated tables filled with sequential values                                                  | YES          | NO   | YES        |
+--------------------+---------+-------------------------------------------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.001 sec)
```

📝なお、今回`INSTALL PLUGIN`の実行でインストールされたMroongaのバージョンは、[最新が14.08である](https://mroonga.org/ja/)のに対し、以下SQLの実行結果の通り「7.07」でかなり低くなっている。

```sql
> SHOW VARIABLES LIKE 'mroonga_version';

+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| mroonga_version | 7.07  |
+-----------------+-------+
```

📝したがって本記事の手順は最適解とはいえないが、今回深堀はしない。参考ドキュメントは以下Mroongaのリファレンスページの通り。

- **参考：Mroonga公式ドキュメント：『2. インストール　＞　2.5. AlmaLinux』**
  - https://mroonga.org/ja/docs/install/almalinux.html#almalinux-9-with-mariadb-10-11-package

📝MariaDBのバージョン再選定やインストール手順の見直しにより、Mroongaのバージョン引き上げは可能と思われる。

**4. 「Items」テーブルの定義変更**

以下SQLを実行し、「Items」テーブルの「FullText」カラムでMronngaを使用した全文検索が可能となるよう設定を変更する。

```sql
> create fulltext index `ftx` on `Items`(`FullText`);
> alter table `Items` ENGINE=Mroonga;
> alter table `Items` COMMENT='engine "InnoDB"';
```

📝プリザンターのテーブルのエンジンは基本的にInnoDBを想定しているため、再生成する「Items」テーブルもInnoDBのストレージエンジンのふるまいをさせた方が良いだろう、という考えから、今回はラッパーモードによるMroonga利用を試みた。

- **参考：Mroonga公式ドキュメント：『4. チュートリアル　＞　4.4. ラッパーモード』**
  - https://mroonga.org/ja/docs/tutorial/wrapper.html#how-to-specify-the-parser-for-full-text-search

**5. プリザンターのサービス再起動**

`quit;`でMariaDBからログアウトする。

```sql
> quit;
```

以下コマンドを実行する。

```bash
$ sudo systemctl start pleasanter
```

**6. プリザンター確認**

プリザンターにログインし、[本項の冒頭](#4-プリザンターmariadbの課題1検索機能の制限)で抽出できなかったデータが抽出できるようになったことを確認する。


# 5. プリザンター×MariaDBの課題2　バージョンアップの不具合

ここまでの検証で、MariaDBの全文検索に依存するプリザンターの機能（横断検索と、テーブルにおける「フルテキスト」指定のフィルタ機能）を使用できない、という問題は、上記「4. プリザンター×MariaDBの課題1　検索機能の制限」で提示した2種類どちらかの方法で解決できそうだとわかりました。

ところが、別の問題が判明しています。

## 5-1. プリザンターのバージョンアップ時、不必要なテーブルの作り替えが発生

プリザンターをバージョンアップする際のCodeDefiner実行時（詳細は以下マニュアルを参照）、機能追加を行う目的でテーブル定義の作り替えがときどき発生します。

- **マニュアル：『1.4.8.0以降のバージョンアップ手順(Linux)』**
  - https://pleasanter.org/ja/manual/version-up-linux-1.4.8.0

本来、このタイミングで、定義を変える必要のないテーブルを作り替えることはNGです。
しかし今回MariaDBの検証中、私が使用した環境では、毎回全テーブルについて新しく作り替えられてしまう事象が確認されました。

⚠️発生するタイミング：2回目以降のCodeDefiner実行時に発生する。
⚠️事象：必ず全テーブルがCreate Tableによって新規作成されてしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/a3269428-7669-3996-445f-026b53e10157.png)

　＊

ここでテーブルを作り替えるか否かはCodeDefinerが条件分岐処理で判断をしています。この判断は「DBの仕様」と「個別の環境設定」の両方に依存しており、そのいずれかまたは両方が、CodeDefinerが想定していなかった動作をしたとみられます。※詳細はまだ検証していません。

不要な負荷をかけていること、および、本来あるべき動作と一致していないことから、詳細がわかるまでは、バージョンアップはMariaDB環境でプリザンターを利用する際の禁止事項になるかと思います。

　＊

**結論：**  
プリザンターを運用する際、最新版を逐次バージョンアップして運用する体制では、MariaDBの使用は不可🚫

# 6. 今後MariaDBの使用について検証するテーマ

今回はここまでで筆を置きたいと思います。以下の課題が宿題として残っている状態です。

- 新しいバージョンのMroongaを利用可能とする
- Mroongaで使用するパーサーの選択肢を広げる（Mecab等）
- プリザンターのバージョンアップ時、不要なテーブルの作り替えを発生させない

# 7. 結び

さまざまな要素が絡む検証でした。

私なりにまとめた結論は[冒頭のフローチャート](#2-結論に代えてmariadb使用可否のフローチャート)に記載しましたので、記事の本編と併せてご覧いただければ幸いです。

**ミドルウェア間で互換性が謳われていたとしても、アプリ側の作りによっては互換性を活かせないケースがあること。** それ故に、 **きちんと人の手で検証をしたほうが良いということ** が教訓になりました。（そもそもMySQL対応の時点でMariaDBの考慮もしておくべきだった、というご意見もでてくるかと思います。）

　＊
 
 これからも時間があるときに、プリザンターがMariaDB上で動作できるよう、検証を続けたいと思います。