MariaDB 10.3 で Spider Storage Engine を試す

2018年5月にGAになった MariaDB Server 10.3.7 以降 Spider ストレージエンジンが GA になりました。

https://mariadb.com/kb/en/library/mariadb-1037-release-notes/
https://mariadb.com/kb/en/library/spider-storage-engine-overview/
https://mariadb.com/kb/en/library/spider-installation/

# Spider の概要

Spider では非常にデータ数の多いテーブルなどをパーティション分割し、複数のノード(Data Node)にシャーディングすることにより、書き込み(write)でもスケールアウトすることができます。Tencent Games などで大規模に利用されているらしいです。

# テスト環境

- OS: CentOS 7.5.1804
- MariaDB 10.3.9 GA
- Spider Node x 1 (ホスト名: spider)
- Data Node x 2 (ホスト名: data1/data2)

# Data Node の設定

データノードは、Spiderでないストレージエンジンと同様にテーブルを作成し、Spider nodeからアクセスさせるためのユーザを作成します。

## InnoDBテーブル作成(対象ホスト: data1/data2)

明示的に InnoDB テーブルを作成します。

```sql
CREATE TABLE test.spider (
   id INT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(50)
) ENGINE=InnoDB;
```

## spider ユーザ作成

Spider node からパーティショニングしてさきほど作成した InnoDB テーブルにデータを格納したり、参照するためのユーザを各データノードで作成します。

```sql
GRANT ALL on *.* to spider@'%' identified by 'password';
FLUSH PRIVILEGES;
```

# Spider Node の設定(対象ホスト: spider)

Spider ストレージエンジンを用いるのは、data node に対する proxy のように動作する Spider node のみです。

## Spider Engineのインストール

インストール用のSQLがありますので、MariaDB monitor(mysql)でSOURCEします。

```
SOURCE /usr/share/mysql/install_spider.sql
```

## CREATE SERVER 

各 data node のIPアドレスが以下のように割り当てられているとします。

data1: 192.168.2.11
data2: 192.168.2.12

CREATE SERVER 文で Spider から data1, data2 という名前で参照可能とします。

```sql
CREATE SERVER data1 FOREIGN DATA WRAPPER mysql
 OPTIONS (
  HOST '192.168.2.11',
  DATABASE 'test',
  USER 'spider', 
  PASSWORD 'password',
  PORT 3306);

CREATE SERVER data2 FOREIGN DATA WRAPPER mysql
 OPTIONS (
  HOST '192.168.2.12',
  DATABASE 'test',
  USER 'spider', PASSWORD 'password',
  PORT 3306);

FLUSH TABLES;
```

## Spider table作成

Spide node上で Spider tableを作成し、data node上のInnoDBテーブルにパーティショニングするように設定します。

```sql
CREATE TABLE test.spider (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50)
) ENGINE=Spider COMMENT='wrapper "mysql", table "spider"'
 PARTITION BY HASH (id)
(
  PARTITION p1 COMMENT = 'srv "data1"',
  PARTITION p2 COMMENT = 'srv "data2"'
);
```

この例では id カラムの値に応じて各 data node に割り振っています。

確認は

```sql
SELECT * FROM information_schema.partitions WHERE table_name ='spider' \G
```

でできます。


# テストデータのINSERT

Spider node の spider table に対して、以下のSQLを1秒間に2回以上実行しないよう、適度に間隔をおいて数回実行します。

```sql
insert into spider (name) values (now());
```

# テストデータ確認

期待通りに data1/data2 にパーティショニングされ、Spider nodeでクエリをかけると全データを参照することができました。

## data1

```sql
MariaDB [test]> select * from spider;
+----+---------------------+
| id | name                |
+----+---------------------+
|  2 | 2018-09-10 11:54:16 |
|  4 | 2018-09-10 11:54:18 |
|  6 | 2018-09-10 11:54:20 |
+----+---------------------+
```

## data2

```sql
MariaDB [test]> select * from spider;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | 2018-09-10 11:54:14 |
|  3 | 2018-09-10 11:54:17 |
|  5 | 2018-09-10 11:54:19 |
+----+---------------------+
```

## Spider node

```sql
MariaDB [test]> select * from spider order by id;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | 2018-09-10 11:54:14 |
|  2 | 2018-09-10 11:54:16 |
|  3 | 2018-09-10 11:54:17 |
|  4 | 2018-09-10 11:54:18 |
|  5 | 2018-09-10 11:54:19 |
|  6 | 2018-09-10 11:54:20 |
+----+---------------------+
```