MySQLの様々な拡張方法を知る

この記事は、2015年「MySQLマニュアルを読む」アドベントカレンダーの17日目です.

 先日開催された MySQL User Conference Tokyo 2015 で、とみたまさひろさんが「MySQLを拡張する」というお話をされました。

 MySQLリファレンスマニュアルでは、24章が「MySQLの拡張」の話題となっています。


http://dev.mysql.com/doc/refman/5.7/en/extending-mysql.html

Chapter 24 Extending MySQL

24.1 MySQL Internals
24.2 The MySQL Plugin API
24.3 MySQL Services for Plugins
24.4 Adding New Functions to MySQL
24.5 Debugging and Porting MySQL


 見た感じはシンプルな短い章にも見えますが、実は奥が深い。
各節を開いた24章のもくじは、以下のとおりとなります。

24.1 MySQL Internals
    24.1.1 MySQL Threads
    24.1.2 The MySQL Test Suite

24.2 The MySQL Plugin API
    24.2.1 Plugin API Characteristics
    24.2.2 Plugin API Components
    24.2.3 Types of Plugins
    24.2.3.1 Storage Engine Plugins
        24.2.3.2 Full-Text Parser Plugins
        24.2.3.3 Daemon Plugins
        24.2.3.4 INFORMATION_SCHEMA Plugins
        24.2.3.5 Semisynchronous Replication Plugins
        24.2.3.6 Audit Plugins
        24.2.3.7 Authentication Plugins
        24.2.3.8 Password-Validation Plugins
        24.2.3.9 Protocol Trace Plugins
        24.2.3.10 Query Rewrite Plugins
    24.2.4 Writing Plugins
        24.2.4.1 Overview of Plugin Writing
        24.2.4.2 Plugin Data Structures
        24.2.4.3 Compiling and Installing Plugin Libraries
        24.2.4.4 Writing Full-Text Parser Plugins
        24.2.4.5 Writing Daemon Plugins
        24.2.4.6 Writing INFORMATION_SCHEMA Plugins
        24.2.4.7 Writing Semisynchronous Replication Plugins
        24.2.4.8 Writing Audit Plugins
        24.2.4.9 Writing Authentication Plugins
        24.2.4.10 Writing Password-Validation Plugins
        24.2.4.11 Writing Protocol Trace Plugins

24.3 MySQL Services for Plugins
    24.3.1 The Locking Service

24.4 Adding New Functions to MySQL
    24.4.1 Features of the User-Defined Function Interface
    24.4.2 Adding a New User-Defined Function
        24.4.2.1 UDF Calling Sequences for Simple Functions
        24.4.2.2 UDF Calling Sequences for Aggregate Functions
        24.4.2.3 UDF Argument Processing
        24.4.2.4 UDF Return Values and Error Handling
        24.4.2.5 UDF Compiling and Installing
        24.4.2.6 UDF Security Precautions 
    24.4.3 Adding a New Native Function

24.5 Debugging and Porting MySQL
    24.5.1 Debugging a MySQL Server
        24.5.1.1 Compiling MySQL for Debugging
        24.5.1.2 Creating Trace Files
        24.5.1.3 Using WER with PDB to create a Windows crashdump
        24.5.1.4 Debugging mysqld under gdb
        24.5.1.5 Using a Stack Trace
        24.5.1.6 Using Server Logs to Find Causes of Errors in mysqld
        24.5.1.7 Making a Test Case If You Experience Table Corruption
    24.5.2 Debugging a MySQL Client
    24.5.3 The DBUG Package

 とみたさんの紹介した UDF(24.4.1と24.4.2)、プラグイン(24.2と24.3)なども、ここで説明されています。
私自身も大昔に、興味本位でUDFにチャレンジしてみようと思ったことがあるのですが、何が悪かったのかうまく動作せずに失意の中で断念した事がありました。これだけドキュメントが揃っているとまた何か、本番稼働するものでなくても、アソビゴコロで作ってみたくなりますね。
 ご興味のあるかたは、ぜひチャレンジを!

MySQL User Conference 2015 に行ってきた

 オラクル社主催の MySQL User Conference Tokyo 2015 に参加してきました。

MySQL User Conference Tokyo 2015

f:id:sakaik:20151215093025j:plain

 日本でのMySQLのカンファレンス。MySQL社の時代、サンマイクロシステムズの時代にそれぞれ何度か開催されたことがありましたが、オラクルに買収されてからは初めての開催です。米国での動きを見ていると、オラクル製品のイベントの一部としてMySQLのコーナー(ブロック)があるといった印象が強いので、ここで日本国内で、オラクルデータベースとはまったく別個にMySQLの名を冠した単独イベントが開催されたことを、たいへん嬉しく思っています。
 今回は、1日開催、セミナー1トラックのみ、企業等のブースもとくになし、というコンパクトな開催となりました。寂しくないのか?と言われれば、声を大きくして「寂しい!」と答えるでしょうけど、MySQLを取り巻く企業の体制が買収により大きく変わり、いったん「ゼロ」となった開催の流れを、5年以上の歳月をかけて*1単独イベントとしての開催にこぎ着けるまでには、並ならぬ障壁もあったことと推察します。今回の開催にあたって努力をされた主催者の皆様には、深く深く頭を下げて御礼申し上げます。楽しかった!

 来年は、「複数トラック」「ブースあり」「海外スピーカーあり(同通も)」「懇親会あり」の、より本格的なカンファレンスへの復活を期待しています(そのためにも「日本でこんなに盛り上がったぞ-」と紹介できるものが必要となるそうですので、参加されたみなさまは、何か、ご自分なりの思いをブログ等に綴られると良いかと思います)。


 さて、前置きはそれくらいにして、内容についてですが、とにかく「MySQL 5.7 はすごいぞ!」ということが印象づけられた一日でした。色々な箇所での工夫により速くなり、機能はいっぱい増えて。追いつくのに当分かかりそうです。それから、とみたまさひろさんの講演では「ただ使うだけでなく、自分で拡張(開発)できるんだよ!」ということを改めて紹介され、すっかり忘れていた「MySQLを良くする/便利にするためにわいわい言っていた10年程前」の空気を思い出しました。一時期、UDFとか盛り上がったんだけどなぁ(当社比)。


 内容については id:garage-kid さんが詳しく書いてくれているので、参加した人は当日の空気を思い出しながら、参加しなかった人は当日の空気を想像しながら、読まれると良いでしょう。
garagekidztweetz.hatenablog.com



おくのさん:
漢(オトコ)のコンピュータ道: MySQL User Conference Tokyo 2015で発表しました:MySQL 5.7におけるオプティマイザの改良点

www.slideshare.net


とみたさん:

www.slideshare.net

せじまさん:

www.slideshare.net


HPのJR東日本の事例・・・の元ネタ:
community.hpe.com


MySQLのデフォルトキャラセットを UTF-8 にしよう運動(「Affects Meを押そう!」):
MySQL Bugs: #71659: Make UTF8 Default Character Set

Sushi-beer issue(寿司ビール問題、またの名をハハババ問題):
MySQL Bugs: #76553: Sushi-Beer issue of MySQL with utf8mb4



各種アドベントカレンダー
MySQLマニュアルを読む Advent Calendar 2015 - Qiita
MySQL 5.7の「罠」に狙われてもやられないための Advent Calendar 2015 - Qiita
MySQL Fabric&Routerつらくない Advent Calendar 2015 - Qiita
MySQL Casual Advent Calendar 2015 - Qiita
Ruby脳にはCrystalつらい Advent Calendar 2015 - Qiita




 カンファレンス終了後は、夜に開催される別の会社の勉強会に参加しない人たちで、ひっそりと濃い話に明け暮れましたとさ。JSON型すごいよ!JSON!!全然触っていないけど、もう、惚れた!
f:id:sakaik:20151215191705j:plain

*1:開催することを私が知ったのは今年の10月末でしたが(笑)

MySQLマニュアルはダウンロードして手元にも!

この記事は、2015年「MySQLマニュアルを読む」アドベントカレンダーの16日目です.


 MySQLのマニュアルを、http://dev.mysql.com/doc/refman/5.7/en/ のページで(つまりオンラインで)読むことが多いと思いますが、実は MySQLマニュアルは全体をダウンロードすることもできます。


http://dev.mysql.com/doc/refman/5.7/en/
f:id:sakaik:20151217142012j:plain


 マニュアルを表示したページの左ペインを下のほうにスクロールして行くと、「Download this Manual」というブロックがあります。最初は閉じているかもしれませんが、クリックすればその下にダウンロードできるファイルが出てきます。以下がそのリスト。

PDF (US Ltr)
PDF (A4)
PDF (RPM)
EPUB
HTML Download (TGZ)
HTML Download (Zip)
HTML Download (RPM)
Eclipse Doc Plugin (TGZ)
Eclipse Doc Plugin (Zip)
Man Pages (TGZ)
Man Pages (Zip)
Info (Gzip)
Info (Zip)

 試しに、MySQL 5.7 の英語マニュアルを PDF でダウンロードしてみると、、3870ページもあります! これは読み切れない!
なので、興味があるところから少しずつ読んでいきましょう。

たとえば MySQL 5.6 の日本語マニュアルをhtml形式で取得し、全体を MySQL データベースに登録して、日本語全文検索の実験をするなどの使い方もできるかもしれませんね。

 手元にも置いておくことで、オフラインでも見ることができるとか、PDFの検索機能を使えるとか、それぞれメリットがあることと思います。ぜひお試しください。



 それから、知っている人がいたら教えて欲しいのですが、以前はMySQLのマニュアルの subversion リポジトリが公開されていて、マニュアルのソース(PDFやhtmlなどに変換する前の状態)をチェックアウトできたと思うのですが、今、どこにいっちゃったんですかね。htmlとかになっちゃう前の状態で検索したりするのに重宝していたのですが。。。

マニュアル以外にもあるMySQLの最新情報源

この記事は、2015年「MySQLマニュアルを読む」アドベントカレンダーの15日目です.


 本日は、「MySQL User Conference 2015」に来ています。サンマイクロシステムス時代以来、8年ぶりの開催となり、1トラックのセッションながらも熱気に包まれています。うれしい。
MySQL User Conference Tokyo 2015


 ここで紹介されていた資料の在りかが非常に良いものだと思い、また、意外と知られていないのではないかという気がするので、今日は、マニュアルではありませんが、それらの資料について紹介したいと思います。



 MySQLを開発しているオラクル社では、初心者向けから、ピンポイントでの技術要素の紹介、最新情報の紹介まで様々なセミナーを開催しています。独自開催のセミナーもあり、他のイベントに参加して1セッション持つものもあり。
 それらのセミナーで使用された資料が公開されている場所があります。

MySQL:資料ダウンロード
https://www-jp.mysql.com/news-and-events/seminar/downloads.html


今だと、2015年10月から11月に開催された「MySQL 最新情報セミナー2015秋」の資料が一番上にあります。

The State of the Dolphin
MySQL 5.7 全文検索デモ
MySQL Enterprise Edition新機能
MySQL 5.7 レプリケーション最新機能とロードマップ
MySQL 5.7 JSONサポート
MySQL 5.7 新旧パラメタ比較

すごいですね。本日記のシリーズでも、マニュアルの What's New ページを紹介する予定でしたが、上記資料では、これらの情報を日本語で読むことができます。これらの資料を使って、自分たちで勉強会開催してもいいんじゃないかと思えるくらいです(特に詳しい講演者を呼べない地方で、資料を囲んでワイワイとやるのも面白いのではないでしょうか)。あ、権利関係よくわからないですが、これを使って講演するとか客寄せするとかでなければ問題ない気がします(要確認)。

 そのほか、

MySQL入門(インストール、アーキテクチャ基礎編)
MySQL入門(レプリケーション編)
MySQL入門(セキュリティ基礎編)
MySQL入門(チューニング基礎編)
MySQL入門(バックアップ編)

こんな資料も公開されており、それぞれがオラクルMySQLチーム渾身の内容。
おすすめです!


私も全然見てこなかったので、ちゃんと読みたいな、と思いました。
(この資料を使って、しれっと、あたかも自分の資料であるかのように講演できるようになれば、内容を理解したと考えてよいのでしょう。目指してみませんか。大変そうですが)

MySQLメジャーバージョンアップ後に必要なスクリプト

この記事は、2015年「MySQLマニュアルを読む」アドベントカレンダーの14日目です.



 13日目の日記では、とりあえず MySQL 5.6 から 5.7 にバージョンを上げたところで終了した。
よくよく考えてみれば、システム系のテーブルの変更が含まれているのだから、そのまま動かして良いわけがない。
ということで、日記が2日に分断してしまったが、今日は、アップグレード後のスクリプトについて書いてみる。

MySQL :: MySQL 5.7 Reference Manual :: 4.4.7 mysql_upgrade — Check and Upgrade MySQL Tables

マニュアル 4.4.7 に紹介されている mysql_upgrade を実行する必要があるようだ。
なお、マニュアルには mysql_upgrade の色々なオプションについて説明があるので、必要に応じてよく読んで使うと良いだろう。
今回は、オプションなしの素のままで実行してみる。

# mysql_upgrade 
Checking if update is needed.
Checking server version.
Running queries to upgrade MySQL server.
Checking system database.
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.engine_cost                                  OK
:(略)
Upgrade process completed successfully.

 アソビゴコロを出して、試しにもう一回実行してみると、

# mysql_upgrade 
Checking if update is needed.
This installation of MySQL is already upgraded to 5.7.10, use --force if you still need to run mysql_upgrade

 もういいらしい(笑)。

# /etc/init.d/mysqld restart
Stopping mysqld:                                           [  OK  ]
Starting mysqld:                                           [  OK  ]

この mysql_upgrade スクリプトの実行により、分かりやすいところでは mysql.user テーブルの定義に変化が見られる。


スクリプト実行前:

mysql> DESC USER;
+------------------------+-----------------------------------+------+-----+---------+-------+
| Field                  | Type                              | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+---------+-------+
| Host                   | char(60)                          | NO   | PRI |         |       |
| User                   | char(16)                          | NO   | PRI |         |       |
| Password               | char(41)                          | NO   |     |         |       |
| Select_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv            | enum('N','Y')                     | NO   |     | N       |       |
:(略)


スクリプト実行後:

mysql> DESC USER;    
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Field                  | Type                              | Null | Key | Default               | Extra |
+------------------------+-----------------------------------+------+-----+-----------------------+-------+
| Host                   | char(60)                          | NO   | PRI |                       |       |
| User                   | char(32)                          | NO   | PRI |                       |       |
| Select_priv            | enum('N','Y')                     | NO   |     | N                     |       |
| Insert_priv            | enum('N','Y')                     | NO   |     | N                     |       |
| Update_priv            | enum('N','Y')                     | NO   |     | N                     |       |
:(略)

 Password カラムがなくなったのが、わかる。
User名のカラムも、これまでの16文字から32文字へと拡大されていることにも気づくだろう。
Passwordカラム廃止については、Yoku0825さんが、今年(2015年)の3月の私の誕生日に書いてくれた日記にて紹介されている。
日々の覚書: MySQL 5.7.6でmysql.userテーブルのパスワードのカラム名がなんか変わった
ただし、Yoku0825さんが書かれた MySQL 5.7.6 の時点では Userカラムはまだ16文字のままだった模様。変化の足跡が見られて、面白い。



これで安心して 5.7を使える環境になった・・・・かな。

MySQLの公式yumリポジトリでのメジャーバージョン更新方法

この記事は、2015年「MySQLマニュアルを読む」アドベントカレンダーの13日目です.


 毎日この「MySQLマニュアルを読む」の日記を書きながらも、そういえば手元にMySQL5.7環境がほとんどない*1ことに気づいたので、色々な所からアクセスできるLinux上(レンサバ上)にも入れておきたいな、と思いました。
 実験用に用意してあるCentOS上に、MySQL の公式リポジトリから入れたMySQL 5.6 が入っているものがあったので、それを 5.7 にアップグレードすることにしました。


 まず、MySQLの公式yumリポジトリについて知らない人は、ここを見ると良いです。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 2.5.1 MySQL Yum リポジトリを使用して MySQL を Linux にインストールする
MySQL :: MySQL 5.7 Reference Manual :: 2.5.1 Installing MySQL on Linux Using the MySQL Yum Repository

 私も1年半ほど前に日記にかきました。
MySQLをCentOSにyumリポジトリからインストールする - sakaikの日々雑感~(T)編


 この方法で入れたMySQL 5.6 は、yum update では 5.6内のマイナーバージョンしか上げてくれません。勝手に 5.7にはならないのです。
(なられても困るけど)

メジャーバージョンを変更(5.6→5.7など)する方法については、上記マニュアルのページ内に説明があります。
http://dev.mysql.com/doc/refman/5.6/ja/linux-installation-yum-repo.html#yum-repo-select-series
http://dev.mysql.com/doc/refman/5.7/en/linux-installation-yum-repo.html#yum-repo-select-series
MySQL5.6日本語マニュアルより引用:

デフォルトでは、MySQL Yum リポジトリは、インストール中に選択したリリースシリーズ内の最新バージョンに MySQL を更新します (詳細はSelecting a Release Seriesを参照してください)。つまり、たとえば 5.6.x インストールは 5.7.x リリースに自動的には更新されません。別のリリースシリーズに更新するには、(デフォルトで、または自分で) 選択したシリーズのサブリポジトリを無効にし、ターゲットシリーズのサブリポジトリを有効にする必要があります。それをするには、 Selecting a Release Seriesで説明されている、/etc/yum.repos.d/mysql-community.repo ファイル内のサブリポジトリのエントリを編集するための手順に従います。

原則として、あるリリースシリーズから別のものにアップグレードするには、シリーズをスキップせずに次のシリーズに移動します。たとえば、現在 MySQL 5.5 を稼働していて、5.7 にアップグレードする場合は、MySQL 5.7 にアップグレードする前にまず 5.6 にアップグレードします。

 今日の日記は、ここからはマニュアルの話題ではなく、実際に私が試した内容について書きたいと思います。


 まず、今のmysqlに関するリポジトリ設定を確認:

# yum repolist all | grep mysql
mysql-connectors-community        MySQL Connectors Community      enabled:    17
mysql-connectors-community-source MySQL Connectors Community - So disabled
mysql-tools-community             MySQL Tools Community           enabled:    31
mysql-tools-community-source      MySQL Tools Community - Source  disabled
mysql55-community                 MySQL 5.5 Community Server      disabled
mysql55-community-source          MySQL 5.5 Community Server - So disabled
mysql56-community                 MySQL 5.6 Community Server      enabled:   214
mysql56-community-source          MySQL 5.6 Community Server - So disabled
mysql57-community-dmr             MySQL 5.7 Community Server Deve disabled
mysql57-community-dmr-source      MySQL 5.7 Community Server Deve disabled

 5.6に関するものが enabledに、5.7に関するものが disabled になっていることがわかりました。
5.6のときに rpm を取ってきて設定したものなので、5.7のものには -dmr (Development Milestone Release) がついています。
新しいリポジトリ設定ファイルを取ってくるべきかどうか悩んだのですが、このまま進めることにしました。
結論から言うと、特に問題なかったように見えるので、 -dmr付きのものは -dmrなしの57と同じ所に向くようになっているのかもしれません(yum.repos.d下のファイルの記述方法をよく知らないので、単なるラベルだけの話なのかもしれませんが)。


 次に、56のリポジトリを無効にして、57のほうを有効にします:

# yum-config-manager  --disable mysql56-community
# yum-config-manager  --enable mysql57-community-dmr

 それぞれ、設定内容(変更後の内容)が画面に表示されます。
 念のため、変更結果を確認してみます。

# yum repolist all | grep mysql
mysql-connectors-community        MySQL Connectors Community      enabled:    17
mysql-connectors-community-source MySQL Connectors Community - So disabled
mysql-tools-community             MySQL Tools Community           enabled:    31
mysql-tools-community-source      MySQL Tools Community - Source  disabled
mysql55-community                 MySQL 5.5 Community Server      disabled
mysql55-community-source          MySQL 5.5 Community Server - So disabled
mysql56-community                 MySQL 5.6 Community Server      disabled
mysql56-community-source          MySQL 5.6 Community Server - So disabled
mysql57-community-dmr             MySQL 5.7 Community Server Deve enabled:    34
mysql57-community-dmr-source      MySQL 5.7 Community Server Deve disabled

 5.7 が enable になりました。(sourceは、このマシンでは取得していないので、disabled のままにしています)


 あとは update するだけ:

# yum update
(略)

=============================================================================================================================================
 Package                                  Arch                    Version                       Repository                              Size
=============================================================================================================================================
Updating:
 mysql-community-client                   x86_64                  5.7.10-1.el6                  mysql57-community-dmr                   23 M
 mysql-community-common                   x86_64                  5.7.10-1.el6                  mysql57-community-dmr                  324 k
 mysql-community-libs                     x86_64                  5.7.10-1.el6                  mysql57-community-dmr                  2.1 M
 mysql-community-release                  noarch                  el6-7                         mysql57-community-dmr                  8.6 k
 mysql-community-server                   x86_64                  5.7.10-1.el6                  mysql57-community-dmr                  134 M

Transaction Summary
=============================================================================================================================================
Upgrade       5 Package(s)
(略)

 今回、事前に他のソフトを含めて全部 yum update 済だったので、ここでは yum update とだけ指定してアップデートしましたが、mysqlだけをアップデートしたいときには、パッケージ名を指定して実行する必要があります。


 起動してみる:

$ mysql -uroot -p
(略)
mysql> status
--------------
mysql  Ver 14.14 Distrib 5.7.10, for Linux (x86_64) using  EditLine wrapper

Connection id:          3
Current database:       
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.10 MySQL Community Server (GPL)
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    utf8
Db     characterset:    utf8
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 2 min 44 sec

Threads: 1  Questions: 7  Slow queries: 0  Opens: 67  Flush tables: 1  Open tables: 60  Queries per second avg: 0.042
--------------

mysql> 

 無事、5.7になりました。

このあと、システムテーブル更新のスクリプトを走らせなきゃいけないのかもしれない。(Passwordカラムが存在しているので)
とりあえず動いているので(実験サーバだし)、本気で使う方はちゃんとマニュアル読んで、調べて下さい。

mysql> desc user;
+------------------------+-----------------------------------+------+-----+---------+-------+
| Field                  | Type                              | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+---------+-------+
| Host                   | char(60)                          | NO   | PRI |         |       |
| User                   | char(16)                          | NO   | PRI |         |       |
| Password               | char(41)                          | NO   |     |         |       |
(略)

*1:仮想環境のWindows上にひとつあるだけ

MySQLマニュアルの「Topic」での一覧表示

この記事は、2015年「MySQLマニュアルを読む」アドベントカレンダーの12日目です.

 MySQLドキュメントページの、見落としていた機能を、梶山さんに教えていただきました。
 このアドヴェントカレンダー向けの一連の日記の初日で紹介した、ドキュメント一覧のページ。

f:id:sakaik:20151212173149j:plain


 ここには、各バージョンのMySQLマニュアルや各周辺ツールのドキュメント、りりーすノートへのリンクなどがあるのですが、ここにはもう一つの隠された機能がありました。右上の「Topic」というボタンが、それです。よく見たら、「Browse MySQL Documentation by:」と「by」があるので、選択できるのだなと気づけるのですが、私は完全に見落としていました。

f:id:sakaik:20151212173835j:plain

 「Topic」ボタンを押すと、こんな画面になり、マニュアルの目次構成とはまた異なった視点で、各トピックへと辿ることができます。
MySQLの最新バージョンのドキュメントへのリンクとなっているものも多いですが、

MySQL Yum Repository
A Quick Guide to Using the MySQL Yum Repository
MySQL Installer
など、バージョンドキュメントとは異なるドキュメントへ続くものもあるのが、ポイントです。



 ただし、リンク先から戻ってくると、「Topic」ではなく「Product」のほうのページになってしまうのが、ちょっぴりイケていない部分です。。