bitA Tech Blog
🕷

MariaDBのSpiderストレージエンジンをDockerで試してみた

に公開

✨ 本記事はbitA Tech Blog Advent Calendar 2日目の記事です。

MariaDBではSpiderストレージエンジンを使用することでデータベースの分散化を実現できます。
本記事ではDockerを用いてSpiderストレージエンジンがどのように動作するのか確認してみました。

Spiderストレージエンジンとは

シャーディング機能を備えたストレージエンジンで、異なるインスタンス上のテーブルを同一インスタンス上にあるかのように扱うことを可能にするものです。

spiderストレージエンジンイメージ

事前準備

Spiderストレージエンジンを試すにあたりの事前に準備するものを解説します。

利用コンテナ

Container Version
mariadb 11.8

Docker イメージの作成

公開されているmariadbのコンテナイメージのままではSpiderストレージエンジンは利用できません。
事前準備としてmariadbのコンテナイメージをベースに mariadb-plugin-spider をインストールしたコンテナイメージを作成します。

FROM mariadb:11.8

RUN apt-get update && \
    apt-get install -y mariadb-plugin-spider && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

各ノードのテーブル作成

各ノードとなるデータベースのテーブルを定義します。
各ノードは通常のMariaDBのインスタンスを作成し、同一の構成の node_test01_table 、 node_test02_table テーブルを作成します。
こちらのテーブルは通常のテーブルと同じようにエンジンに InnoDB を指定します。

CREATE TABLE IF NOT EXISTS `node_test01_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `node_id` int(11) NOT NULL DEFAULT 0,
  `created_at` datetime(3) NOT NULL DEFAULT current_timestamp(3),
  `created_user` varchar(255) NOT NULL,
  `updated_at` datetime(3) NOT NULL DEFAULT current_timestamp(3) ON UPDATE current_timestamp(3),
  `updated_user` varchar(255) NOT NULL,
  `index01` int(11) NOT NULL DEFAULT 0,
  `value01` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`,`node_id`,`created_at`),
  KEY `idx01` (`index01`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE COLUMNS(`created_at`)
(
    PARTITION `p20251201` VALUES LESS THAN ('2025-12-01'),
    PARTITION `p20251208` VALUES LESS THAN ('2025-12-08'),
    PARTITION `p20251215` VALUES LESS THAN ('2025-12-15'),
    PARTITION `pmax` VALUES LESS THAN (MAXVALUE) ENGINE=InnoDB
);

CREATE TABLE IF NOT EXISTS `node_test02_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `node_id` int(11) NOT NULL DEFAULT 0,
  `created_at` datetime(3) NOT NULL DEFAULT current_timestamp(3),
  `created_user` varchar(255) NOT NULL,
  `updated_at` datetime(3) NOT NULL DEFAULT current_timestamp(3) ON UPDATE current_timestamp(3),
  `updated_user` varchar(255) NOT NULL,
  `index01` int(11) NOT NULL DEFAULT 0,
  `value01` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`,`node_id`,`created_at`),
  KEY `idx01` (`index01`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE COLUMNS(`created_at`)
(
    PARTITION `p20251201` VALUES LESS THAN ('2025-12-01'),
    PARTITION `p20251208` VALUES LESS THAN ('2025-12-08'),
    PARTITION `p20251215` VALUES LESS THAN ('2025-12-15'),
    PARTITION `pmax` VALUES LESS THAN (MAXVALUE) ENGINE=InnoDB
);

Spider テーブルの作成

MariaDBインスタンスの1つにSpiderストレージエンジンを指定したテーブルを作成します(ここではSpiderテーブルと呼ぶことにします)

Spiderテーブルを作成するには INSTALL SONAME 'ha_spider'; を実行し、Spiderストレージエンジンをインストールします。
エンジンのインストール後、 CREATE SERVER 文によってノードとなるインスタンスを指定します。

Spiderテーブルの作成は各ノードの設定後に実施する必要もあるためご注意ください。

テーブル作成時はエンジンに Spider を指定し、パーティションの設定によって各ノードに振り分けるデータを指定します。

今回の検証では node_id の値によって下記のようにデータが振り分けられるようテーブルを定義しました。

node_id インスタンス テーブル
1, 4, 7 のいずれか node-db-1 node_test01_table
2, 5, 8 のいずれか node-db-2 node_test01_table
3, 6, 9 のいずれか node-db-3 node_test01_table
上記以外の値 node-db-1 node_test02_table
-- Spider ストレージエンジンのインストール
INSTALL SONAME 'ha_spider';

-- ノードインスタンスを設定
-- 例として node-db-1 インスタンスを node1 として設定する場合
CREATE SERVER node1 FOREIGN DATA WRAPPER mysql
  OPTIONS (
    HOST 'node-db-01',
    DATABASE 'node_database',
    USER 'node-db-01-user',
    PASSWORD 'node-db-01-user-pw',
    PORT 3306
  );

-- Spider テーブルを定義
CREATE TABLE IF NOT EXISTS `test01_table` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `node_id` int(11) NOT NULL DEFAULT 0,
    `created_at` datetime(3) NOT NULL DEFAULT current_timestamp(3),
    `created_user` varchar(255) NOT NULL,
    `updated_at` datetime(3) NOT NULL DEFAULT current_timestamp(3) ON UPDATE current_timestamp(3),
    `updated_user` varchar(255) NOT NULL,
    `index01` int(11) NOT NULL DEFAULT 0,
    `value01` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`,`node_id`,`created_at`),
    KEY `idx01` (`index01`) USING BTREE
) ENGINE = Spider DEFAULT CHARSET=utf8mb4
PARTITION BY LIST (`node_id`) (
    PARTITION p_node01 VALUES IN (1,4,7) COMMENT 'server "node1", table "node_test01_table"',
    PARTITION p_node02 VALUES IN (2,5,8) COMMENT 'server "node2 node3", table "node_test01_table"',
    PARTITION p_node03 VALUES IN (3,6,9) COMMENT 'server "node2 node3", table "node_test02_table"',
    PARTITION p_other DEFAULT COMMENT 'server "node1", table "node_test02_table"'
);

実際にやってみた

ここまでの事前準備をもとにDocker ComposeでMariaDBのインスタンスを作成し動作を確認します。
mariadb のコンテナイメージではコンテナの初回起動時にスクリプトを実行する機能があるため、こちらを活用し各テーブルの作成も同時に実施します。

確認に使用したスクリプトを下記にまとめましたので適宜ご利用ください。

https://github.com/komeloper/mariadb-spider

MariaDB インスタンスの作成 & 起動

プロジェクトルートで下記を実行し、 MariaDBのインスタンスを立ち上げます。

# mariadbインスタンスを起動
$ docker compose up -d

Spider テーブルの確認

Spiderテーブルを作成した primary コンテナに接続し、テーブルが作成されているか確認します。

# Spider テーブルを作成したコンテナに接続
$ docker compose exec -it primary bash

# コンテナ内からmariadb client を利用しデータベースへ接続
> mariadb -u root -p spider_database

# Spider テーブルの確認
MariaDB [spider_database]> show tables;
+---------------------------+
| Tables_in_spider_database |
+---------------------------+
| test01_table              |
+---------------------------+

ノードインスタンスのテーブルを確認

primary コンテナと同様に node-db-1, node-db-2, node-db-3 コンテナでも動作を確認します。
この時点ではデータは挿入されていないため、テーブルが存在するのみです。

# ノードとなる MariaDB コンテナのデータベースへ接続
$ docker compose exec -it node-db-1 bash

> mariadb -u root -p node_database

# テーブルの確認
MariaDB [node_database]> show tables;
+-------------------------+
| Tables_in_node_database |
+-------------------------+
| node_test01_table       |
| node_test02_table       |
+-------------------------+

データを挿入する

primary コンテナのMariaDBインスタンスの test01_table にデータを挿入します。
今回は node_id の値が1 ~ 10となる値を挿入しました。

# Spider テーブルにデータを挿入
MariaDB [spider_database]> insert into test01_table (
-> node_id,
-> created_user,
-> updated_user,
-> index01,
-> value01 ) values
-> (1, 'user_name', 'user_name', 1, 'data 01'),
-> (2, 'user_name', 'user_name', 1, 'data 02'),
-> (3, 'user_name', 'user_name', 1, 'data 03'),
-> (4, 'user_name', 'user_name', 1, 'data 04'),
-> (5, 'user_name', 'user_name', 1, 'data 05'),
-> (6, 'user_name', 'user_name', 1, 'data 06'),
-> (7, 'user_name', 'user_name', 1, 'data 07'),
-> (8, 'user_name', 'user_name', 1, 'data 08'),
-> (9, 'user_name', 'user_name', 1, 'data 09'),
-> (10, 'user_name', 'user_name', 1, 'data 10');

Query OK, 10 rows affected (0.075 sec)

データを確認する

各テーブルにどのようにデータが挿入されたか確認します。

Spiderテーブルでは挿入した全てデータが表示され、1つのテーブルのようにみえますが、実態はありません。

# Spider テーブルのデータを確認
MariaDB [spider_database]> select * from test01_table;
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+
| id | node_id | created_at              | created_user | updated_at              | updated_user | index01 | value01 |
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+
| 12 |       1 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 01 |
| 15 |       4 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 04 |
| 18 |       7 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 07 |
| 13 |       2 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 02 |
| 16 |       5 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 05 |
| 19 |       8 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 08 |
| 14 |       3 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 03 |
| 17 |       6 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 06 |
| 20 |       9 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 09 |
| 21 |      10 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 10 |
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+

続いてノード側のテーブルを確認します。
Spiderテーブルを定義した通りにデータが振り分けられていることが確認できます。

# node-db-1 コンテナの node_test01_table のデータを確認
MariaDB [node_database]> select * from node_test01_table;
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+
| id | node_id | created_at              | created_user | updated_at              | updated_user | index01 | value01 |
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+
| 12 |       1 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 01 |
| 15 |       4 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 04 |
| 18 |       7 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 07 |
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+

# node-db-1 コンテナの node_test02_table のデータを確認
MariaDB [node_database]> select * from node_test02_table;
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+
| id | node_id | created_at              | created_user | updated_at              | updated_user | index01 | value01 |
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+
| 21 |      10 | 2025-11-26 14:29:01.776 | user_name    | 2025-11-26 14:29:01.776 | user_name    |       1 | data 10 |
+----+---------+-------------------------+--------------+-------------------------+--------------+---------+---------+

おわりに

Dockerを用いてMariaDBのSpiderストレージエンジンを試してみました。

昨今では様々なDBaaSなど便利なサービスが増えているため、実際に使用する機会は少なそうですが、どのようにサービスが動いているか知るきっかけになりました。

今回は簡単なデータ挿入の検証のみでしたが、今後も勉強を兼ねてこちらの機能の深掘りもしたいと考えています。

参考情報

bitA Tech Blog
bitA Tech Blog

Discussion