GA

2015/10/15

日本MySQLユーザ会の15周年パーティーのおさそい

来る2015/10/30(金)、日本MySQLユーザ会(MyNA)の15周年パーティーがあります。

日本MySQLユーザ会会15周年記念パーティー - connpass


15年に至るまでの流れとかは とみたさん

OSS貢献者賞を頂いたので昔話をします - @tmtms のメモ

とか




が詳しいです。俺も自分が参加するまで(4年くらい前?)の歴史はこれらで知る限りです。

というわけで、今回の幹事の 坂井さん に、「折角節目の年なので、おじさんたちを並べて思い出話(あの頃はあーだったこーだった)を聞きたいです!」という話をしていたら、 俺はおじさんの方にカウントされていた という衝撃的なことになりました。

イベントページ には当日どんなセッションがあるのかイマイチ書いてないのですが、わたしが把握している範囲ではこんなイベントになりそうです。

* 飲食出るよ
* セッションを聞くためのエリア(前の方に椅子)と歓談エリア(後ろ側で立食?)があるよ
* スピーカーは「思い出話」っぽいものをするよ(邪魔さえしなければ後ろの方で他の人と話しててもいいよ)
* 時間に余裕があればLTとかもやれるといいなーって話はしてるよ(できるかわからんですが)

なんか自分で書いててもどんなのになるんだかちょっとよくわかりません。
スピーカーの持ち時間は20分だと聞いていたので、後半時間空くのかなーと思ってたら「全然そんなことはない。時間配分超がんばってる。持ち時間15分になるかも」との返答。
どんな風に進行するのか、他人事のように楽しみにしておこうと思います。

取り敢えず、技術寄りよりは人に会う会になるのかなぁ。。という雰囲気を感じるので、わたしは技術的な話は封印して、「MySQLユーザ会のこれまでとこれから 2015」っぽいものとかやろうかなと思っています。が、順番最後だからカブったら悲惨だな。。

みなさまのご来場をお待ちしております :)


【2015/10/15 13:06】
おっと…肝心なことを。

MySQLのおじさんたちと何らかのつながりを持ちたい人の参加を募集しています :)
MySQLおじさんズと知り合いになると

* イベントのCfP紹介してくれたりする(かもしれない)
* MySQL関連イベントでぼっち回避率が上がる(といいな)
* Twitterでの個人的なつぶやきに マサカリが㌧でくるようになる 間違いがあれば訂正のツッコミを入れてくれる(ような世界線もある)
* 飲み会は割り勘

などなど、いいことがあるかも知れないしないかも知れないです。
興味がある人は、Twitterのアイコンを名札にしようかと思っているので 「ピンク色の ウーパールーパー とうふ」 っぽい奴を探していただければ幸いです :)

2015/10/08

Amazon RDS for MariaDBでできそうなこと、できなさそうなこと

TL;DR

Amazon RDS の MariaDB - Amazon Relational Database Service の方が詳しいですたぶん。
* InnoDBじゃなくてXtraDBが使いたい場合はアリです。
* スレッドプールが使いたい場合もアリです。
* サードパーティーなプラグインは使えなくなっています。残念。
* 単にユーザーとして観測できる範囲で調べて推測しているだけなので、違ったらごめんなさい。


MariaDB 10.0で使えるプラグインの一覧はinformation_schema.all_pluginsで参照できる。

mysql> SELECT plugin_name FROM ALL_PLUGINS order by 1;
+-----------------------------+
| plugin_name                 |
+-----------------------------+
| ARCHIVE                     |
| Aria                        |
| AUDIT_NULL                  |
| auth_0x0100                 |
| binlog                      |
| BLACKHOLE                   |
| cleartext_plugin_server     |
| CSV                         |
| daemon_example              |
| FEDERATED                   |
| FEEDBACK                    |
| InnoDB                      |
| InnoDB                      |
| INNODB_BUFFER_PAGE          |
| INNODB_BUFFER_PAGE          |
| INNODB_BUFFER_PAGE_LRU      |
| INNODB_BUFFER_PAGE_LRU      |
| INNODB_BUFFER_POOL_STATS    |
| INNODB_BUFFER_POOL_STATS    |
| INNODB_CHANGED_PAGES        |
| INNODB_CMP                  |
| INNODB_CMP                  |
| INNODB_CMPMEM               |
| INNODB_CMPMEM               |
| INNODB_CMPMEM_RESET         |
| INNODB_CMPMEM_RESET         |
| INNODB_CMP_PER_INDEX        |
| INNODB_CMP_PER_INDEX        |
| INNODB_CMP_PER_INDEX_RESET  |
| INNODB_CMP_PER_INDEX_RESET  |
| INNODB_CMP_RESET            |
| INNODB_CMP_RESET            |
| INNODB_FT_BEING_DELETED     |
| INNODB_FT_BEING_DELETED     |
| INNODB_FT_CONFIG            |
| INNODB_FT_CONFIG            |
| INNODB_FT_DEFAULT_STOPWORD  |
| INNODB_FT_DEFAULT_STOPWORD  |
| INNODB_FT_DELETED           |
| INNODB_FT_DELETED           |
| INNODB_FT_INDEX_CACHE       |
| INNODB_FT_INDEX_CACHE       |
| INNODB_FT_INDEX_TABLE       |
| INNODB_FT_INDEX_TABLE       |
| INNODB_LOCKS                |
| INNODB_LOCKS                |
| INNODB_LOCK_WAITS           |
| INNODB_LOCK_WAITS           |
| INNODB_METRICS              |
| INNODB_METRICS              |
| INNODB_SYS_COLUMNS          |
| INNODB_SYS_COLUMNS          |
| INNODB_SYS_DATAFILES        |
| INNODB_SYS_DATAFILES        |
| INNODB_SYS_FIELDS           |
| INNODB_SYS_FIELDS           |
| INNODB_SYS_FOREIGN          |
| INNODB_SYS_FOREIGN          |
| INNODB_SYS_FOREIGN_COLS     |
| INNODB_SYS_FOREIGN_COLS     |
| INNODB_SYS_INDEXES          |
| INNODB_SYS_INDEXES          |
| INNODB_SYS_TABLES           |
| INNODB_SYS_TABLES           |
| INNODB_SYS_TABLESPACES      |
| INNODB_SYS_TABLESPACES      |
| INNODB_SYS_TABLESTATS       |
| INNODB_SYS_TABLESTATS       |
| INNODB_TRX                  |
| INNODB_TRX                  |
| MEMORY                      |
| MRG_MyISAM                  |
| MyISAM                      |
| mysql_native_password       |
| mysql_old_password          |
| partition                   |
| PERFORMANCE_SCHEMA          |
| qa_auth_interface           |
| qa_auth_server              |
| simple_parser               |
| test_plugin_server          |
| unix_socket                 |
| XTRADB_INTERNAL_HASH_TABLES |
| XTRADB_READ_VIEW            |
| XTRADB_RSEG                 |
+-----------------------------+
85 rows in set (13.21 sec)

InnoDB関連が2つずつあるのは、片方がInnoDB(ただしNot Installed)でもう片方がXtraDB(Active)だから。
Mroonga, TokuDB, Sphinx, handlersocketなどのサードパーティープラグインは *この一覧にそもそも出ていない* ので利用できないようになっているっぽい。残念。

吊るしのMariaDBをインストールしてある(と思われる)ConoHaのMariaDBを試した時のall_pluginsの中身は 日々の覚書: 新ConoHaのMariaDBを試してみた にあるので割愛。結構減ってるのがわかる。

userstat は使えない。performance_schema有効にしろってことかしらん。

とはいえMariaDBは スレッドプール が組み込まれているので、パラメーターグループいじるだけで使えるのは素敵。thread_handling= pool-of-threads だけで有効にできるはず(試してはいない)

あとはInnoDBではなくXtraDBなので、XtraDB由来の機能は結構使えるはず。



って言ってる最中にここの存在を知る。
Amazon RDS の MariaDB - Amazon Relational Database Service

Progress Reportってクライアント側の実装も必要だから、踏み台になるEC2にはMariaDBのクライアントを用意しておいた方が良さげ。
MySQL 5.7のgenerated columnに相当する virtual column も使えるらしい。というかこれ5.2から使えたの…知らなかった…。Dynamic Column の方はよく紹介されるけど、これは知らなかった。Dynamic Columnはもちろん使える。

普通に使うなら使えそうですねー(普通に使うならMySQLでもいいという感じはするけど)

2015/10/07

CentOS 6.6ベースでMySQL 5.6 + Mroongaを簡単に試すDockerfile

書きました。--no-cacheでビルドすれば、ビルドした時点の最新のMySQL 5.6と最新のMroongaでビルドされるはず。


FROM yoku0825/cent66:init

RUN echo "NETWORKING=yes" > /etc/sysconfig/network
RUN yum install -y which
RUN rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-1.noarch.rpm
RUN rpm -ivh http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
RUN yum install -y mysql-community-mroonga groonga-tokenizer-mecab
RUN service mysqld start && mysql -e "GRANT ALL ON *.* TO root@'%' WITH GRANT OPTION"

EXPOSE 3306
ENTRYPOINT /usr/sbin/mysqld --user=mysql

https://gist.github.com/yoku0825/9f76b7f112bc89903999


yoku0825/cent66:init は my_script/make_centos_baseimage_for_docker.sh at master · yoku0825/my_script を使って作った必要最小限(のように見える)CentOS 6.6のイメージで、whichとか入ってないのでこのDockerfileの中で入れてる。

CentOS 6.xならFROMの部分を変えればそのまま動くので、好きなベースイメージにしてあげればいい。
CentOS 7.xの場合、mysql-community-releaseのrpmファイルが変わるのでここ からRHEL 7用のやつに書き換えないといけないのと、serviceコマンドが動かない(CentOS 6.5の上のカーネルで動かしているので、systemctlも動かせなかった)ので、なんかもうちょっと書き換える必要がある。


しかし、Dockerfile作ったって言うこともなさそうなほどお手軽にインストールできるようになったなぁ。。MroongaがMySQLの公式yumリポジトリーに対応してくれたのが大きい。


Docker Hubにpushしてみたので、


$ sudo docker run -d yoku0825/cent66:mroonga508

とやるとおもむろにMroongaを試せるようになっております。

2015/10/02

MySQL 4.0からあるMAX_QUERIES_PER_HOURという機能について

MySQL CasualのSlack でふと まえあつさん が発した一言から、気になったので調べてみました。意外と知られてないんですね。

MAX_QUERIES_PER_HOUR count、MAX_UPDATES_PER_HOUR count、および MAX_CONNECTIONS_PER_HOUR count 制限は、いずれかの特定の 1 時間の間にこのアカウントに対して許可されるサーバーへのクエリー、更新、および接続の数を制限します。(結果がクエリーキャッシュから得られたクエリーは、MAX_QUERIES_PER_HOUR 制限に対してカウントされません。) count が 0 (デフォルト) である場合、これは、このアカウントに対する制限が存在しないことを示します。

MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.7.1.4 GRANT 構文


5.6まではGRANTステートメントで指定する。ユーザー固有の属性(mysql.userにカラムがある)なので、グローバル権限(GRANT .. ON *.*)でしかつけられない。

mysql56> SHOW GRANTS;
+-------------------------------------------------------------------+
| Grants for yoku0825@%                                             |
+-------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'yoku0825'@'%' WITH MAX_QUERIES_PER_HOUR 10 |
| GRANT ALL PRIVILEGES ON `d1`.* TO 'yoku0825'@'%'                  |
+-------------------------------------------------------------------+
2 rows in set (0.00 sec)


で、こうなる。mysqlコマンドラインクライアントは接続する時に内部的に`SELECT @@version;`を投げているので、1コネクションに対して2クエリー、5回接続してクエリーを投げたら終了(てことは、O/Rマッパー使ってる環境でこれやるともっと少なくなるだろうなあ。。)

$ while true ; do mysql56 -uyoku0825 -e "SELECT 1" d1 || break; done
+---+
| 1 |
+---+
| 1 |
+---+
+---+
| 1 |
+---+
| 1 |
+---+
+---+
| 1 |
+---+
| 1 |
+---+
+---+
| 1 |
+---+
| 1 |
+---+
+---+
| 1 |
+---+
| 1 |
+---+
ERROR 1226 (42000) at line 1: User 'yoku0825' has exceeded the 'max_questions' resource (current value: 10)

いくつかメモ。

* この制約はアカウント単位(user@host)でかかるので、yoku0825@%とyoku0825@localhostは別人でカウントされるのにエラーメッセージには`User 'yoku0825'`としか出てくれない。
* `FLUSH PRIVILEGES`ステートメントでクリアできる。
* GRANTステートメント上はMAX_QUERIES_PER_HOURなににエラーメッセージには'max_questions'ってかかれてて、GRANTにmax_quiestions_per_hourって書いてアレーってなった。
* ↑に書いた通り、接続時に内部的に暗黙のクエリーを投げてることが多い(接続元の実装依存)ので、綺麗に計れないかも知れない


判定のロジックはcheck_mqhにあって、
mysql-server/sql_connect.cc at 253084f78a60816ce19430cff00f861c520830c5 · mysql/mysql-server

check_mqhを呼んでいるのはmysql_parse(MySQLコマンドパケットのパース)
mysql-server/sql_parse.cc at 253084f78a60816ce19430cff00f861c520830c5 · mysql/mysql-server

check_mqhの中でtime_out_user_resource_limitsを呼んでいて、コイツはreset_utimeと現在時刻を比較して、3600秒経っていたら、カウンターをクリアして、reset_utimeに新しく現在時刻を指定する。
mysql-server/sql_class.cc at 253084f78a60816ce19430cff00f861c520830c5 · mysql/mysql-servertime_out_user_resource_limits

という訳で、一律00分にクリアーみたいなものではない。あんまり使い方思いつかないけど、調べてるのは楽しかった。ごちそうさまでした。

2015/09/15

MySQL Fabricつらい(リモートのmysqlfabricサーバーにmysqlfabricコマンドで接続するのにやっと成功)

MySQL Fabric、そのまま全てを(Fabric対応コネクターに全てを任せて)使うのはつらすぎるとして、せめてお手軽にMySQLを監視したりSwitchoverさせたりする器として使えないかな、というのを前からずっと考えていて(mysqlrpladmin 使えって? 知らない子ですね。。)

MySQL Fabricつらい Advent Calendar 2014 - Qiita


去年の12月に、「mysqlfabricをそのままクライアントとして使おうとするとlocalhostのmysqlfabricサーバーに接続しようとして転ける、リモートアドレス向けに接続しようとするとfabric.cfgの書き換えが必要でつらい」とか思ってばぐれぽしたのがこちら。
MySQL Bugs: #75308: mysqlfabric's --param option's syntax is not documented

実は4月くらいに返事が返ってきていたので、書いておこうかなと思います。

気が付いたらドキュメントにも上がってた。
MySQL :: MySQL Utilities :: 8.2.3.4 The Configuration Parameter (--param)



想定しているのは↓のような状態。
* 172.17.0.45なサーバーでバッキングストアのmysqldとmysqlfabricが起動している
* 172.17.0.46, 172.17.0.47なサーバーではmysqlfabricに管理されているmysqldが動いている。mysqlfabricコマンド(MySQL Utilities)はインストールされている。
* 172.17.0.47から172.17.0.45のmysqlfabricサーバーを叩いて情報を見たい

172.17.0.45$ mysqlfabric group lookup_servers myfabric1
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid          address    status      mode weight
------------------------------------ ---------------- --------- --------- ------
03a5981a-5ac9-11e5-9d85-0242ac11002f 172.17.0.47:3306 SECONDARY READ_ONLY    1.0
740fd00e-5ac8-11e5-9d81-0242ac11002e 172.17.0.46:3306 SECONDARY READ_ONLY    1.0

172.17.0.45からフツーに`mysqlfabric`をクライアントとして実行すると、この通り結果が返ってくる。


172.17.0.47$ mysqlfabric group lookup_servers myfabric1
Password for admin:
<urlopen error [Errno 111] Connection refused>

172.17.0.47$ strace -e connect mysqlfabric group lookup_servers myfabric1
--- SIGCHLD (Child exited) @ 0 (0) ---
--- SIGCHLD (Child exited) @ 0 (0) ---
Password for admin:
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(32274), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
connect(3, {sa_family=AF_INET6, sin6_port=htons(32274), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
connect(3, {sa_family=AF_INET6, sin6_port=htons(32274), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 ECONNREFUSED (Connection refused)
connect(3, {sa_family=AF_INET, sin_port=htons(32274), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)
<urlopen error [Errno 111] Connection refused>

172.17.0.47で同じことをやろうとすると、当然ながらlocalhost向けに接続しに行こうとして転ける。
ここまではいい。ここまではいいんだけど、

(少なくとも当時)どうやってリモートのmysqlfabricに接続するのかが全くドキュメントに書いてない。。:(;゙゚'ω゚'):


取り敢えず正解は、[protocol.xmlrpc]セクションのaddressを書き換えること。ただしこのパラメーターはmysqlfabricをサーバーとして起動した時はbind-address的な意味を持つので、サーバーとしても動かしてるホストでこれをホイホイ書き換えるのは結構危険。
日々の覚書: MySQL Fabricつらい(クライアントとしてのmysqlfabricとサーバーとしてのmysqlfabricのオプションの扱いが一緒)

で、mysqlfabricには--paramがあるからそれでfabric.cfgいじらなくてもパラメーター上書きできるんじゃね? => --paramの説明が全くドキュメントになくて記法が全然わからない

までが前回のあらすじ。


で、--paramの書き方は"--param=セクション.パラメータ=値"だそうだ。fabric.cfgに手を入れてない172.17.0.46からやってみる。

172.17.0.46$ mysqlfabric --param=protocol.xmlrpc.address=172.17.0.45:32274 group lookup_servers myfabric1
Password for admin:
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid          address    status      mode weight
------------------------------------ ---------------- --------- --------- ------
03a5981a-5ac9-11e5-9d85-0242ac11002f 172.17.0.47:3306 SECONDARY READ_ONLY    1.0
740fd00e-5ac8-11e5-9d81-0242ac11002e 172.17.0.46:3306 SECONDARY READ_ONLY    1.0

( ゚д゚) ポカーン。。
今までの苦労が何だったんだくらいの勢いで簡単。


172.17.0.46$ mysqlfabric --param=protocol.xmlrpc.address=172.17.0.45:32274 --param=protocol.xmlrpc.password=xxxx group lookup_servers myfabric1
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid          address    status      mode weight
------------------------------------ ---------------- --------- --------- ------
03a5981a-5ac9-11e5-9d85-0242ac11002f 172.17.0.47:3306 SECONDARY READ_ONLY    1.0
740fd00e-5ac8-11e5-9d81-0242ac11002e 172.17.0.46:3306 SECONDARY READ_ONLY    1.0

passwordを渡してやるとプロンプトも出なくなる。


172.17.0.46$ mysqlfabric --param=protocol.xmlrpc.address=172.17.0.45:32274 --param=protocol.xmlrpc.password=xxxx group promote myfabric1
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                                uuid finished success result
------------------------------------ -------- ------- ------
1d048c45-bd68-4e79-b77d-0c9bb22a7431        1       1      1

state success          when                                                   description
----- ------- ------------- -------------------------------------------------------------
    3       2   1.44228e+09 Triggered by .
    4       2   1.44228e+09                      Executing action (_define_ha_operation).
    5       2   1.44228e+09                       Executed action (_define_ha_operation).
    3       2   1.44228e+09 Triggered by .
    4       2   1.44228e+09                      Executing action (_find_candidate_fail).
    5       2   1.44228e+09                       Executed action (_find_candidate_fail).
    3       2   1.44228e+09 Triggered by .
    4       2   1.44228e+09                     Executing action (_check_candidate_fail).
    5       2   1.44228e+09                      Executed action (_check_candidate_fail).
    3       2   1.44228e+09 Triggered by .
    4       2   1.44228e+09                          Executing action (_wait_slave_fail).
    5       2   1.44228e+09                           Executed action (_wait_slave_fail).
    3       2   1.44228e+09 Triggered by .
    4       2   1.44228e+09                      Executing action (_change_to_candidate).
    5       2   1.44228e+09                       Executed action (_change_to_candidate).


172.17.0.46$ mysqlfabric --param=protocol.xmlrpc.address=172.17.0.45:32274 --param=protocol.xmlrpc.password=xxxx group lookup_servers myfabric1
Fabric UUID:  5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

                         server_uuid          address    status       mode weight
------------------------------------ ---------------- --------- ---------- ------
03a5981a-5ac9-11e5-9d85-0242ac11002f 172.17.0.47:3306   PRIMARY READ_WRITE    1.0
740fd00e-5ac8-11e5-9d81-0242ac11002e 172.17.0.46:3306 SECONDARY  READ_ONLY    1.0

この通り、promoteもできる。
XML-RPCでつつけばいいんだけど、それだと何故か認証を無効にしないと通せなかったので、これを食ってシェル芸でiptablesで向き先変えるのとかやってみるかな。。

日々の覚書: MySQL Fabricつらい(XML-RPCでつついてみる編)

2015/09/08

MySQL 5.7.9のinnodb_default_row_formatがまた何か企んでいるようです

MySQL 5.7.9では innodb_default_row_format というサーバー変数が追加される(らしい。5.7.9はリリース前なので試せない)
オンライン変更可能なグローバル変数なので、`SET GLOBAL innodb_default_row_format= ..'で変更も可能。暗黙のデフォルトは"Dynamic"。

名前と値から察せられる通り、kamipoさん の悲願をかなえる類のもの…なんだけれども、

MySQL(InnoDB) で "Index column size too large. The maximum column size is 767 bytes." いわれるときの対策 - かみぽわーる


これ、


The innodb_file_format configuration option is ignored if a table is created or altered to use ROW_FORMAT=DYNAMIC. For example, innodb_file_format=Antelope is ignored if you create a table with a DYNAMIC row format. The Barracuda file format is used instead.

http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_default_row_format



CREATE TABLEの時は良い。kamipo時代の到来という感じで、基本的にはメリットになる(や、ページが強制的に分割されるから、innodb_fill_factor とかいじってる人にはそうじゃないだろうけど)

ただしALTER TABLE、テメーはダメだ。勝手にROW_FORMAT= Dynamicとか押し込むな。頼む。

Change ROW_FORMAT property
Although ALGORITHM=INPLACE is allowed, the data is reorganized substantially, so it is still an expensive operation.
MySQL :: MySQL 5.7 Reference Manual :: 14.10.1 Overview of Online DDL

オンラインでALTER TABLEできるけど、テーブルの再構築が走るので重くなる。
ROW_FORMAT= Compactなテーブルは、ALTER TABLEする時にROW_FORMAT= Compactを明示的に指定しないといけない。

何故ALTER TABLEにも適用するようにしたんだこのオプション。。



ばぐれぽ読む限りは、割と希望が見える。

I have analyzed your bug and the reasoning for the deprecation of the variable and I do agree with your findings.

I am now handing over your request to developers for the decision-making.

Hopefully, we shall hear from them soon.

MySQL Bugs: #78347: innodb_default_row_format: Undesireable new behaviour

さあみんなであふぇくつみー。


【2015/09/08 13:53】





2015/09/01

論理削除Casual Talks #ronsakucasual でMySQLで論理削除する話をしてきた

論理削除 Casual Talks #1 : ATND に行ってきました。

アプリケーション方面では色々あるし、DBAから見ても良いことはないはず…と思ってましたが、 *ちゃんとMySQLの都合に沿ってやれば* 意外と忌避する理由もないことにふと気付きました。途中で3回くらいテーマ変更して最終的にこの形に落ち着いたカタチです。はふん。


ごめんなさい、当日流していたスライドに致命的な誤り(5.5以降ではなく、5.5以降 *ではない*)がありました。。まとめてくれた方ごめんなさい…><






DBAっぽく、という背景があったので、「論理削除? それUPDATEじゃん」というのが割と前提にあります。「DELETEじゃなくてUPDATEなんだから、削除とか言わずにスーパー非表示フラグでいいじゃん、システム的に *ちゃんとMySQLの都合に沿ってやれば* はそこまで変わらないし」というのが個人の見解です。

しゃらっと *ちゃんとMySQLの都合に沿ってやれば* という感じで流してますが、要はつまり









こういう話で、bool(MySQLだとboolがないのでENUMかTINYINTかな)だと必ず"="演算子の等価比較に持ち込める(そして持ち込めないクエリーはユーザートラフィックが吐いてはいけない)ので好きとか、カーディナリティーがどうこうというより必ず全てのセカンダリーインデックスの先頭につけろでないとインデックスだけで完結できないぞとかそんな話です。

( ´-`).oO(や、別に先頭じゃなくてもいいんですが、万人が正しいセカンダリーインデックスを考えてくれるかというとそうではないわけで、打ち漏らされるくらいなら全部先頭につけろって感じです。自信のある人は正しいところにつけてください。。

@t_wadaさん と色々お話できて、「こんなすごい人でも闇に対しては少しずつ立ち向かうしかないのだなぁ」とか「あー、SQLアンチパターンの本持ってくるの忘れた…(サインほしかった)」とか「エンタープライズ 闇 Casual」とか楽しかったです。

もし次があるなら、Oracle(DBの方)の重課金してる人たちがスーパー非表示についてどう思ってるのかとか聞きたいですね。「スーパー非表示? え、Flashbackじゃだめなの?」みたいな。

@kenchanくんさん お疲れ様でした!



ちなみにスライド冒頭のInnoDBさんの「よくやるよくやる」はチェンジバッファのことですのでご安心ください(?)
論理削除(ライフサイクルを終えるまでスーパー非表示)と非同期削除(一時的にスーパー非表示&非同期パージ)の間には少し溝があるような気がしました。