MariaDBのその後の動きをまとめてみる - 2024年4月版
日本でも数少ないMariaDB社の株価ウォッチャーとして以前の記事の続きを書いておく。
2023年5月には本当のPenny StockになったMariaDB社。ちなみにPenny StocksとはSEC(米国証券取引委員会)の定義では1株あたり$5未満で取引されるものを指すらしいが、MariaDB社ことMariaDB PLCの株価は長らく$1未満のままとなっている。NYSEの上場廃止基準にあたりそうだけどそれでも上場し続けていられるのは不思議だけどそういうものなのでしょう。
Penny stock - Wikipedia
記事執筆時点での最新の動きは3月26日に、様々な製品を買収して拡大してきたプログレス・ソフトウェア社がMariaDB社の買収の計画を発表。1株あたり$0.60で総額約$40.6Mとのこと。現時点では買収は完了していない。
時系列を少し遡ると↓ざっくりこんな感じ。
- 2023年10月 資金調達(ローン)の発表と同時に社員84名、約28%の削減とSkySQLやXpandといった製品の切り離しを発表
MariaDB plc Enters Into $26.5 Million Financing Agreement - 2023年12月 SkySQLをスピンアウトしサービス名と同じ名前の会社へ移管
MariaDB Finalizes Spinoff of SkySQL
さらなるドタバタの動きがあったのが2024年2月。
2月7日、1月は$0.20前後で取引されていたものが2倍以上の$0.47に急騰、取引量もそれまで10万にも満たなかった件数がこの日だけ3,700万件。IRの情報などは一切発表がないにもかかわらず株価としては不自然な動きに見えた。単なるマネーゲームなのか、なにかあったんでしょうかね。次に動きが出たのは約10日後。
2月16日、プライベートエクイティのK1 Investment Managementが$37.7Mのオファーを提案し非上場化の方向であることを発表。1株あたりは$0.55で2月5日の終値から189%のプレミアム。3月末までの完了を目指すとされていた。一瞬$0.40超の値を付けるも$0.30台に落ち着く。
2月23日、それまで出資していた北欧の投資会社RP Ventures社がこのK1社の発表に激おこ。K1社の発表により$0.55ドルが実質的に天井となってしまうことが不服だった模様。債務不履行通知を送付してMariaDB社の口座から現金を引き上げて貸し手としてのRP社の返済に充てるという"Sweep"と呼ばれる動きを起こすと警告される事態に。
この状況を静観していられなかったようで、元MySQL社でコミュニティチームを率い、MariaDB社の立ち上げにも参画していたMariaDB FoundationのCEOのKaj Arnöが声明を発表しダメージコントロールを図っていた。
3月26日、しばらくニュースも関連するIRの発表も音沙汰が無いままK1社の買収判断の期限となる3月29日が迫っていたところに、プログレス・ソフトウェア社が決算発表のタイミングでMariaDB社の買収の意向を発表。いつの間にか$0.20台に戻っていたMariaDB社の株価はニュースを受けて再び急騰して$0.50弱に到達しているところ。
MariaDBの顛末を書き留めておく
MariaDBの開発コミュニティMariaDB Foundationではなく、サポートや有償ツールを販売しているMariaDB Corporationが12ヶ月の間に一気にグダグダすぎることになっていたのでまとめておく。
MariaDB Foundationは複数の企業がスポンサーをしているものの、もちろんMariaDB Corporationが筆頭のスポンサーであり、コアメンバーにMariaDB Corporationの社員もいる。
一連の事案がニュースとしてのバリューがないのかMariaDB自体を追ってる人がいないのか、上場するとの発表以外は日本のIT系メディアではほとんどスルーされている状態である。
顛末
- 2022年2月1日 NYSE上場のSPAC(特別買収目的会社)と合併する形でNYSEに上場すると発表
※SPAC: https://smbiz.asahi.com/article/14622436 - 2022年5月-6月 JPモルガンとゴールドマンがこの案件の事務幹事会社を降りる (この時点でいろいろヤバい)
※ https://www.thedeal.com/spacs/jpm-goldman-cut-ties-with-angel-pond-mariadb-deal/ - 2022年12月19日 SPACとの統合で看板を掛け替えMariaDBが上場していることに
初値は$11.55だが同日終値は$6.75 その後数日で初値の1/3以下に下落 - 2023年1月18日 出資者の99%が資金撤退の方向済み 6月までに資金ショートのリスクが出る
※ https://twitter.com/ElinaLappalaine/status/1615655206460481537 - 2023年2月1日 従業員の8%をリストラすると発表
※ https://www.marketscreener.com/quote/stock/MARIADB-PLC124600271/news/MARIADB-PLC-Regulation-FD-Disclosure-form-8-K-42872884/
これが12ヶ月足らずの出来事である。この後で元々の投資家の一角だった中国のアリババが7%弱の株を取得していたり別の投資家グループによる動きも多少はあるが株価は$3台の最安値を付けていたりする。
なおSPACを使った上場は、ベンチャー企業の資金調達を支援して成長を加速させる可能性を秘めているものの、本来の上場の基準にはるかに満たないような企業まで上場させることになってしまうこともあるため裏口上場と呼ばれたりしているケースも。上記と同じような事案がすでに多発していて2022年3月末にSPAC案件を担当する証券会社や投資銀行への規制の強化がされ、2社のアドバイザー引き受けからの撤退につながっている。
2023年2月15日追記
2月13日付で12月31日締めの第一四半期決算が公開されたが売り上げの1.5倍ぐらい販管費にかかる状態は変わらず。決算書の読み方を間違えてると思いたいが債務超過状態に見える。現預金や売掛金がそれなりにあるものの、この状態の後で出資者が撤退となると資金ショートのリスクも現実味を帯びてくる。
2023年4月9日追記
上記の1月18日部分を修正。元記事を翻訳しつつ読んでたけど誤りがあった模様。出資者の資金引き上げはまさかの上場的なものの前日。。。
2023年5月30日追記
4月上旬にしばらく空席だったCFOが採用され、いくつかプレスリリースを打って挽回を試みたものの、5月の中旬にはついに株価が1ドルを切ってしまった。
2023年5月31日追記
今度はCEO, CRO, CTO交代の記事。CRO (chief revenue officer)がもともといて交代なのかは知らんけど。
finance.yahoo.com
ちなみに6月5日付けで就任するCTOはPostgreSQLのコントリビューターだったりOracle DBの記事書いていたりでMySQLやMariaDB色が見られないのが興味深いところ。
Jupyter NotebookとMySQL X DevAPI
Pythonのコードを試すのに便利なJupyter Notebookを使って、Connector/PythonからMySQL X DevAPIを試す環境を作ってみました。Jupyter Notebookの利用には Anaconda に含まれるPythonとJupyter を使うことが強く推奨(strongly recommend)されています。
https://jupyter.org/install.html
ちなみにAnacondaは「データサイエンス向けに作成された Pythonパッケージ」と Python.jp で紹介されています。WindowsでもmacOSでもGUIのインストーラでさくさくインストールできます。
AnacondaへのConnector/Pythonのインストール
Anaconda.orgにパッケージをインストールする場合は conda install コマンドを使うとされています。
https://conda.io/docs/user-guide/tasks/manage-pkgs.html#installing-packages-from-anaconda-org
ところがAnaconda.orgには、標準のanacondaチャンネルではConnector/Python 2.0.4が、その他のチャンネルでも8.0系にバージョン番号ポリシーが変更される前の2.2.3が最新という状態で、Connector/Python 8.0をインストールすることができません。
https://anaconda.org/anaconda/mysql-connector-python
そこでnon-condaパッケージのインストールという手順を使います。
https://conda.io/docs/user-guide/tasks/manage-pkgs.html#installing-non-conda-packages
pipパッケージ管理ツールでmysql-connector-pythonパッケージをバージョン番号を指定して、Connector/Python 8.0.6をインストールします。
https://pypi.python.org/pypi/mysql-connector-python
# Anacondaの仮想環境の確認 sakila:~ sakila$ conda info --envs # conda environments: # root * /Users/sakila/anaconda3 # 仮想環境rootをアクティベート # Windowsではこのコマンドでエラーなくアクティベートできた # macOSではエラーになるのでエラーメッセージのsource付きコマンドを実行 sakila:~ sakila$ activate root Error: activate must be sourced. Run 'source activate envname' instead of 'activate envname'. sakila:~ sakila$ source activate envname CondaEnvironmentNotFoundError: Could not find environment: envname . You can list all discoverable environments with `conda info --envs`. sakila:~ sakila$ source activate root # pipコマンドでConnector/Python 8.0.6をインストール (root) sakila:~ sakila$ pip install mysql-connector-python==8.0.6 Collecting mysql-connector-python==8.0.6 Downloading mysql_connector_python-8.0.6-cp36-cp36m-macosx_10_12_x86_64.whl (3.2MB) 100% |======================================| 3.2MB 413kB/s Installing collected packages: mysql-connector-python Successfully installed mysql-connector-python-8.0.6
これでJupyter NotebookからConnector/Python 8.0.6を利用できるようになりました。
MySQL 8.0.4のインストールとX Pluginの登録
MySQL 8.0.4に関してはWindowsはZIP, LinuxやmacOSはTARを展開するのが手っ取り早いです。ちなみにWindows用のMySQL Installerは8.0.4が用意されていませんでした。--initializeまたは--initialize-insecureなどで初期化し、起動しておきます。
X DevAPIをサポートするためにX Pluginを登録します。
https://dev.mysql.com/doc/refman/8.0/en/document-store-setting-up.html
MySQL Shellがインストールしてあれば下記のコマンドでX Pluginが登録できます。
mysqlsh -u user -h localhost --classic --dba enableXProtocol
MySQL Shellがなければmysqlクライアントからサーバーに接続し、下記のコマンドを実行します。
mysql> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so';
なおWindows上ではmysqlx.soだとファイルが見つからないためエラーとなるので、mysqlx.dllに変更します。
X DevAPIの動作確認のためJSONデータを含んだサンプルデータベースworld_xデータベースを下記からダウンロードし、展開してロードしておきます。
https://dev.mysql.com/doc/index-other.html
mysql -uroot < /foo/bar/world_x-db/world_x.sql
Jupyter Notebookからの動作確認
Anaconda Navigatorを起動しJupyter Notebookを選択します。起動直後のJupyter NotebookはWebブラウザ上にフォルダの一覧が表示される状態となっています。必要に応じてノート作成のフォルダを作成するか選択し、その後、画面右上のNewのプルダウンからPython 3を選択し、Notebookを新規作成します。
NotebookではIn [1]:の横のテキストボックスにPythonのコードを記載し、Shift + Enterで実行することができます。

まずは動作確認を兼ねて、Connector/Pythonのリファレンスマニュアルのサンプルコードを組み合わせて、稼働中のMySQLサーバーのバージョンをVERSION()関数で確認してみます。

from mysql.connector import (connection) cnx = connection.MySQLConnection(user='root', host='127.0.0.1') cur = cnx.cursor(buffered=True) cur.execute("SELECT VERSION()") print(cur.fetchone()) cur.close() cnx.close()
続いてSQLを変更して実際のデータとして先ほどインポートしたworld_xスキーマのcountryinfoテーブルのデータを取得してみます。このテーブルはCollectionとなるテーブル構造(JSON型の列とJSONドキュメント内の_id要素を抽出したGenerated Columnの_id列のみ、_id列は主キー)となっています。
mysql> desc world_x.countryinfo; +-------+-------------+------+-----+---------+------------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+------------------+ | doc | json | YES | | NULL | | | _id | varchar(32) | NO | PRI | NULL | STORED GENERATED | +-------+-------------+------+-----+---------+------------------+ 2 rows in set (0.02 sec)
from mysql.connector import (connection) cnx = connection.MySQLConnection(user='root', host='127.0.0.1') cur = cnx.cursor(buffered=True) cur.execute("SELECT * FROM world_x.countryinfo") print(cur.fetchone()) cur.close() cnx.close()
Jupyter NotebookからのX Dev APIでのアクセス
先ほどと同様に、リファレンスマニュアルのサンプルコードを少し変更して、SQL文でもアクセスしたCollectionであるcountryinfoテーブルにX Dev APIでアクセスしてみます。ここでは10ドキュメント(=10行)取得して配列docに格納、その先頭レコードのうちName要素を取得して表示しています。インポート対象パッケージはmysqlxになっています。

import mysqlx # Connect to server on localhost session = mysqlx.get_session({ 'host': 'localhost', 'port': 33060, 'user': 'root', 'password': '' }) schema = session.get_schema('world_x') # Use the collection 'my_collection' collection = schema.get_collection('countryinfo') # Specify which document to find with Collection.find() result = collection.find().limit(10).execute() # Print document docs = result.fetch_all() print('Name: {0}'.format(docs[0]['Name'])) session.close()
ちなみにMySQLサーバーのユーザーにパスワードがない場合、ポート3306を使用するMySQL標準プロトコルの例では接続情報にパスワードに関する表記はなくても問題ありませんが、X Dev APIの場合は空文字を指定しないと接続時にエラーとなります。
もしかして気づかれていないかも知れないMySQLのパスワード関連の機能
validate_passwordプラグイン
MySQL 5.6で登場し、MySQL 5.7.8からはYumまたはSLESレポジトリからのインストール、もしくはrpmパッケージでインストールした場合に有効になっているのがvalidate_passwordプラグインです。validate_passwordプラグインはパスワード強度の検証を行うプラグインです。「初心者殺しの罠」だの「クソ機能→速攻削除」だの言われちゃうかわいそうなかわいそうな機能だったりします。tarで入れればデフォルトでは無効なのでrpmじゃなくてtarで入れよう。
機能と設定の概要はMySQL 5.6の日本語リファレンスマニュアルを参考にしてみて下さい。
validate_passwordプラグインでは以下の項目を検証します。
https://dev.mysql.com/doc/refman/8.0/en/validate-password-options-variables.html
| validate_password_check_user_name | パスワードとユーザ名を比較 |
| validate_password_dictionary_file | 禁止されたパスワードのリストを格納した辞書ファイル名 |
| validate_password_length | 最低文字数 |
| validate_password_mixed_case_count | 大文字と小文字を含めることを強制 |
| validate_password_number_count | 数字の数 |
| validate_password_special_char_count | 特殊文字の数 |
| validate_password_policy | ポリシーの強度 |
validate_password_check_user_nameはMySQL 5.7.15 (= GA後) にて追加されたオプションです。このパラメタを ON に設定すると、パスワードの設定や変更の際にユーザー名、もしくは逆になっていないかの検証が行われます。ここでのユーザー名は USER()およびCURRENT_USER()のユーザー名部分です(ホスト名は検証に利用されない)。またバイト列でのユーザー名との比較となります。
パスワード再利用ポリシー
以前使ったパスワードを再利用させない面倒くさいポリシーを設定できる機能がMySQL 8.0.3 RCで追加されました。また「速攻削除」とか言われちゃうのかな。。。とりあえずデフォルトではオフになっているので安心して下さい。
https://dev.mysql.com/doc/refman/8.0/en/password-management.html#password-reuse-policy
設定項目は下記の2つです。
| password_history | 何世代のパスワードを利用不可とするか |
| password_reuse_interval | 同じパスワードはどれだけ経たないと再利用できないか |
このパラメータはサーバー全体の設定値となります。MySQL 8.0の新機能 SET PERSIST 文 でも設定できます。
CREATE USER文やALTER USER文でユーザーごとに設定することもできます。
mysql> CREATE USER 'yoku0825'@'localhost' PASSWORD HISTORY 825; mysql> ALTER USER 'soudai1025'@'localhost' PASSWORD REUSE INTERVAL 1025 DAY;
いい感じの設定ができますね。
変更したパスワードは新たに追加されたpassword_historyテーブルに格納されていきます。
mysql> DESC password_history; +--------------------+--------------+------+-----+----------------------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------------+--------------+------+-----+----------------------+-------+ | Host | char(60) | NO | PRI | | | | User | char(32) | NO | PRI | | | | Password_timestamp | timestamp(6) | NO | PRI | CURRENT_TIMESTAMP(6) | | | Password | text | YES | | NULL | | +--------------------+--------------+------+-----+----------------------+-------+ 4 rows in set (0.00 sec)
例えばパスワードを変更し、確認してみると下記のような状態となります。(パスワードの文字列はダミーです。たぶん)
mysql> ALTER USER 'yoku0825'@'localhost' IDENTIFIED BY 'ConoHa'; mysql> ALTER USER 'yoku0825'@'localhost' IDENTIFIED BY 'Anzu'; mysql> SELECT * FROM password_history; +-----------+----------+----------------------------+-------------------------------------------+ | Host | User | Password_timestamp | Password | +-----------+----------+----------------------------+-------------------------------------------+ | localhost | yoku0825 | 2017-12-06 00:02:22.120225 | *01234567890123456789A1FB252ADCCED23DHOGE | | localhost | yoku0825 | 2017-12-06 00:01:45.514278 | *9876543210987654321006CDBDBBE5538249FUGA | +-----------+----------+----------------------------+-------------------------------------------+
ちなみにMySQL 5.7.9 GAで話題となり、MySQL 5.7.11でデフォルト値が360日から0 (= 無制限) に変更された default_password_lifetime はMySQL 8.0.3 RCの時点でのデフォルト値は0となっています。
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_password_lifetime
GAでどうなるかは誰も知りません。
MySQL Fabric? 知らない子ですねぇ とりあえず可用性関連の製品が単一障害点を持ってたり、開発エンジニアが単一障害点とか悪い冗談ですよね。
MySQLの公式Dockerイメージを使おうとしたときのメモ
(追記) MySQL界が誇る優秀な外部APIによってご指摘いただけたのでパスワード周りを訂正
`-e MYSQL_ALLOW_EMPTY_PASSWORD=1` でrootのパスワード空っぽにできるますよ;) @RKajiyama
— yoku0825 (@yoku0825) August 21, 2017
MySQLの公式Dockerイメージを使おうとしたときのメモ - rkajiyamaの日記https://t.co/hqEWOTdxID
MySQLサーバーのコミュニティ版バイナリが含まれる公式Dockerイメージのマニュアルはこちら。
https://hub.docker.com/r/mysql/mysql-server/
マニュアルに書いてある基本の起動するコマンド
docker run --name my-container-name -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql/mysql-server:tag
| オプション | 設定項目 |
|---|---|
| --name | my-container-nameは任意の名称 |
| -d | 対象イメージ タグでMySQLのバージョン等を指定 |
| -e | 環境変数 マニュアル中段のEnvironment Variables |
| -p | ポートフォワーディング設定 ホスト側:コンテナ側 |
| -v | ディレクトリのマッピング ホスト側:コンテナ側 |
バージョン等を指定するためのタグの一覧
5.5から8.0のマイナーバージョンを指定可能(全てではない)
https://hub.docker.com/r/mysql/mysql-server/tags/
起動コマンド例
docker run --name my80 -d mysql/mysql-server:8.0 -e MYSQL_ROOT_PASSWORD=mysql -p 6603:3306 -v /Users/mysql/mysql-docker/data:/var/lib/mysql
ちょっとしたハマりどころ
MySQLサーバーのパスワード設定は必須必須ではない、けどオプション必須
初期化オプション --initialize-insecure に該当する設定はなさそうあるけどオプションの指定が必要。パスワード関連の環境変数が設定がされていないとコンテナが起動しない。MYSQL_RANDOM_ROOT_PASSWORDとMYSQL_ONETIME_PASSWORDを設定すると --initialize と同様の動きになる模様。MYSQL_ALLOW_EMPTY_PASSWORDを使うと --initialize-insecure と同様に。
| MYSQL_ROOT_PASSWORD | 明示的にパスワードを設定 |
| MYSQL_RANDOM_ROOT_PASSWORD | ランダムパスワードを設定 |
| MYSQL_ONETIME_PASSWORD | 初回ログイン時にパスワードの変更を強制 |
| MYSQL_ALLOW_EMPTY_PASSWORD | --initialize-insecureと同様にパスワード無しを許容 |
ランダムパスワードは下記コマンドで表示されるログにて確認可能
docker logs my-container-name
一瞬では起動しない(いつ起動が完了したか分からない)
コンテナの起動コマンドを打つと一瞬で応答が返ってきて出力もきわめてシンプル。MySQLサーバーがすでに起動しているのかと思ったらまだだったりする。
docker psのSTATUS表示がhealth: startingなら起動中、healthyなら起動済み。
(docker runコマンドのオプションでログをコンソールに出すようにすればよさげな話だけど)
MySQL 5.7.17で追加されたあのプラグインについて
この記事は MySQL Casual Advent Calendar 2016 の13日目の記事です!
MySQL 5.7.17がリリースされたわけですが、みなさん待望のあの機能がついに追加されました。なので早速試してみましょう。
プラグインとしての機能追加なので、まずはプラグインをインストールします。
http://dev.mysql.com/doc/refman/5.7/en/connection-control-plugin-installation.html
mysql> INSTALL PLUGIN connection_control SONAME 'connection_control.so'; Query OK, 0 rows affected (0.02 sec) mysql> INSTALL PLUGIN connection_control_failed_login_attempts SONAME 'connection_control.so'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS -> WHERE PLUGIN_NAME LIKE 'connection%'; +------------------------------------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +------------------------------------------+---------------+ | CONNECTION_CONTROL | ACTIVE | | CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | ACTIVE | +------------------------------------------+---------------+ 2 rows in set (0.00 sec)
プラグインのインストール時にシステム変数ならびにステータス変数が追加されます。
mysql> SHOW GLOBAL VARIABLES LIKE 'connection_control%'; +-------------------------------------------------+------------+ | Variable_name | Value | +-------------------------------------------------+------------+ | connection_control_failed_connections_threshold | 3 | | connection_control_max_connection_delay | 2147483647 | | connection_control_min_connection_delay | 1000 | +-------------------------------------------------+------------+ 3 rows in set (0.01 sec) mysql> SHOW GLOBAL STATUS LIKE 'connection_control%'; +------------------------------------+-------+ | Variable_name | Value | +------------------------------------+-------+ | Connection_control_delay_generated | 0 | +------------------------------------+-------+ 1 row in set (0.01 sec)
システム変数については以下の通りです。
| connection_control_failed_connections_threshold | 接続に失敗した場合に遅延を適用するまでの回数の閾値 |
| connection_control_min_connection_delay | 当初の遅延時間(ミリ秒) |
| connection_control_max_connection_delay | 最大の遅延時間(ミリ秒) |
閾値を超えて接続に失敗するたびにconnection_control_min_connection_delay分の遅延が追加されます。
ではデフォルト値のまま試してみましょう。
$ while true; do time ./mysql -uscott -ptiger; done mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'scott'@'localhost' (using password: YES) real 0m0.014s user 0m0.007s sys 0m0.004s mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'scott'@'localhost' (using password: YES) real 0m0.014s user 0m0.007s sys 0m0.003s mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'scott'@'localhost' (using password: YES) real 0m0.010s user 0m0.006s sys 0m0.003s mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'scott'@'localhost' (using password: YES) real 0m1.017s user 0m0.006s sys 0m0.003s mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'scott'@'localhost' (using password: YES) real 0m2.015s user 0m0.007s sys 0m0.004s mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'scott'@'localhost' (using password: YES) real 0m3.017s user 0m0.007s sys 0m0.004s mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'scott'@'localhost' (using password: YES) real 0m4.018s user 0m0.006s sys 0m0.005s mysql: [Warning] Using a password on the command line interface can be insecure.
4回目の失敗から遅延が1秒ずつ追加されているのが分かります。
このConnection-Controlプラグインによって総当たり攻撃(ブルートフォースアタック)などの対策とすることができそうです。
MySQL 5.7.17ではマルチマスター型レプリケーションのグループレプリケーション プラグインがGAになるという大きな機能追加がありました。グループレプリケーションと類似するGalera Clusterとの機能の比較や性能比較も公開されています。グループレプリケーションはきっと誰かが書いてくれると思うので、気づいていない人も多そうなConnection-Controlプラグインについて書いてみました。
MySQL 5.7のGeoHash
MySQL 5.7で追加された機能一つにBoost.Geometryとの統合によるGISの強化があります。さらにGeoHashという機能が追加されています。GeoHashは地点の情報をハッシュ値として格納する機能で、ハッシュ長によって精度を変えることができます。緯度経度の値から長さの異なるGeoHashを生成し、そこから再度緯度経度の値を算出してみます。今回の例では直線距離で約3km離れた2地点の緯度経度を利用しています。
なお緯度経度の情報および十進表記は下記のサイトの情報を使いました
http://user.numazu-ct.ac.jp/~tsato/webmap/sphere/coordinates/advanced.html
| 関数 | 内容 |
| ST_GeoHash() | 緯度経度の値またはPOINT型の値からGeoHash値を生成 |
| ST_LatFromGeoHash() | GeoHash値から緯度を算出 |
| ST_LongFromGeoHash() | GeoHash値から経度を算出 |
| ST_PointFromGeoHash() | GeoHash値から緯度経度を算出しPOINT型の値を返す |
# 横浜スタジアム ホームベース付近 北緯35°26′35″ 東経139°38′25″ # 十進表記 北緯35.442972 東経139.640223 mysql> SELECT -> ST_GeoHash(139.640223, 35.442972, 4) AS GeoHash4, -> ST_GeoHash(139.640223, 35.442972, 32) AS GeoHash32; +----------+------------------------+ | GeoHash4 | GeoHash32 | +----------+------------------------+ | xn73 | xn739s4ym0c53e0pys2c9g | +----------+------------------------+ 1 row in set (0.01 sec) mysql> SELECT -> ST_LatFromGeoHash(ST_GeoHash(139.640223, 35.442972, 4)) AS GeoHash4, -> ST_LatFromGeoHash(ST_GeoHash(139.640223, 35.442972, 32)) AS GeoHash32; +----------+-----------+ | GeoHash4 | GeoHash32 | +----------+-----------+ | 35.4 | 35.442972 | +----------+-----------+ 1 row in set (0.00 sec) mysql> SELECT -> ST_LongFromGeoHash(ST_GeoHash(139.640223, 35.442972, 4)) AS GeoHash4, -> ST_LongFromGeoHash(ST_GeoHash(139.640223, 35.442972, 32)) AS GeoHash32; +----------+------------+ | GeoHash4 | GeoHash32 | +----------+------------+ | 139.7 | 139.640223 | +----------+------------+ 1 row in set (0.01 sec)
# 横浜駅きた西口 北緯35°28′2″ 東経139°37′23″ # 十進表記 北緯35.467360 東経139.623148 mysql> SELECT -> ST_GeoHash(139.623148, 35.467360, 4) AS GeoHash4, -> ST_GeoHash(139.623148, 35.467360, 32) AS GeoHash32; +----------+----------------------------------+ | GeoHash4 | GeoHash32 | +----------+----------------------------------+ | xn73 | xn73c0wkr5j52nh2eub7y5bpbpbpbpbp | +----------+----------------------------------+ 1 row in set (0.00 sec) mysql> SELECT -> ST_LatFromGeoHash(ST_GeoHash(139.623148, 35.467360, 4)) AS GeoHash4, -> ST_LatFromGeoHash(ST_GeoHash(139.623148, 35.467360, 32)) AS GeoHash32; +----------+-------------------+ | GeoHash4 | GeoHash32 | +----------+-------------------+ | 35.4 | 35.46736000000001 | +----------+-------------------+ 1 row in set (0.01 sec) mysql> SELECT -> ST_LongFromGeoHash(ST_GeoHash(139.623148, 35.467360, 4)) AS GeoHash4, -> ST_LongFromGeoHash(ST_GeoHash(139.623148, 35.467360, 32)) AS GeoHash32; +----------+--------------------+ | GeoHash4 | GeoHash32 | +----------+--------------------+ | 139.7 | 139.62314800000001 | +----------+--------------------+ 1 row in set (0.00 sec)
ハッシュ長を4桁にした場合は情報が丸められ、同じ緯度経度の情報になっています。プライバシー保護などの観点から、正確な位置を利用するのではなく大まかな場所やエリアで表示させるなどに利用できそうです。
