Quantcast
Channel: 日々の覚書
Viewing all 581 articles
Browse latest View live

舞奈たんとは何なのか

$
0
0
4/1ですが大真面目なはなし(?)


俺が最初に言い出したのは多分この時。



日本MySQLユーザ会  略称MyNA(まいな)と日本MySQLユーザ会MariaDB分科会 略称MariNA(まりな)、擬人化されてないのおかしくね? みたいなネタでした(誰だったか忘れたけれど誰かが言ってたのをネタにしたと記憶している)


それ以降は割としょっちゅう言ってた気がします。




あれから2年が経ち…カッとしてクラウドワークスで発注しました。
今でもなんであんなにムキになって舞奈たんを擬人化したかったのか良くわかりません。
なお、舞奈たんは「マイナくん(仮)」の擬人化であってMySQLの擬人化ではないので、緑色です。

最初は 第2回 MySQL・PostgreSQLユーザーグループ(MyNA・JPUG)合同DB勉強会に間に合うようなスケジュールを考えていたんですが(「MySQLといかMyNAのPostgreSQLというかJPUGに対する優位点? 萌えキャラがいることですよ!」って言いたかった)、依頼してたデザイナーさんと連絡が取れなくなるなどクラウドソーシングの闇をいくつか見たあとで、最終的に キヨイチさんに受注していただきました(*-人-)





( ´-`).oO(現在もう候補画像は見られませんが、当時1案と呼ばれていたものが僅差で勝ちました。というわけでこれが舞奈たん。




この手のネタは人によって好き嫌い分かれそうですが、まあかつて↓こんなことやってた人たちなので大丈夫だろうとか思ってましたし思ってます。

萌え萌えなMySQL互換オープンソースデータベース「MoSQL」 - GIGAZINE


もともと、俺が会社目的でも個人目的でもスライドなりステッカーなりサイトなり好きなように使えるように発注したものなので、ライセンスはとてもゆるいです。
値段ぶんくらいは使い倒したいと思っているのでみなさんも協力してくだしあ。

ちなみに「どこからその予算出てるの?」と聞かれることが何度かありましたが、俺のお小遣いです


何が言いたいかと言うと今月のクレジットカードの引き落としがくぁwせdrftgyふじこlp

epelからyumでCactiをインストールするとcacti.sqlがない

$
0
0
久々にCactiをインストールしようとしたらハマった。
ハマったところは Cactiをインストール via yum - CentOS@さくらVPSで構築するサーバ管理・運用メモを見て解決したんだけれど(ビバインターネット)2016年にもなってまだcacti.sql入ってないの馬鹿なの? とか思ってたらなんか変な動作してる。


なんだこれ。

# cat /etc/centos-release
CentOS release 6.6 (Final)

# yum install -y epel-release

# yum install -y cacti
..

# rpm -ql cacti | grep cacti.sql
/usr/share/doc/cacti-0.8.8b/cacti.sql

# ll /usr/share/doc/cacti-0.8.8b/cacti.sql
ls: cannot access /usr/share/doc/cacti-0.8.8b/cacti.sql: No such file or directory

# rpm -Vv cacti | grep cacti.sql
......... d /usr/share/doc/cacti-0.8.8b/cacti.sql

epelからyumで突っ込むとcacti.sqlは無い。
でもrpm -Vでもmissingとも言われない。


# yum install -y epel-release yum-utils

# yumdownloader cacti

# yum install -y crontabs httpd mysql net-snmp net-snmp-utils php php-mysql php-snmp rrdtool perl
# rpm -i cacti-0.8.8b-7.el6.noarch.rpm

# rpm -ql cacti | grep cacti.sql
/usr/share/doc/cacti-0.8.8b/cacti.sql

# ll /usr/share/doc/cacti-0.8.8b/cacti.sql
-rw-r--r-- 1 root root 178349 Aug 7 2013 /usr/share/doc/cacti-0.8.8b/cacti.sql

# rpm -Vv cacti | grep cacti.sql
......... d /usr/share/doc/cacti-0.8.8b/cacti.sql

yumdownloaderからのrpmでインストールするとフツーにあった(コンテナーは新しく立ち上げ直した)
えー、なにこれ。


# yum install -y epel-release yum-utils

# yumdownloader cacti
# yum install -y ./cacti-0.8.8b-7.el6.noarch.rpm

# rpm -ql cacti | grep cacti.sql
/usr/share/doc/cacti-0.8.8b/cacti.sql

# ll /usr/share/doc/cacti-0.8.8b/cacti.sql
ls: cannot access /usr/share/doc/cacti-0.8.8b/cacti.sql: No such file or directory

# rpm -Vv cacti | grep cacti.sql
......... d /usr/share/doc/cacti-0.8.8b/cacti.sql

yumdownloaderからのyumコマンドだと消えるので、yumコマンドが悪さをしてるのはそうなんだろうけど。。
ナニコレ。

CentOS 6.6とCentOS 7.2(の吊るしのDockerイメージ)で確認。


【2016/04/26 13:42】

教えてもらいました! ビバインターネット!





# yum install -y epel-release

# diff -C1 /etc/yum.conf{.orig,}
*** /etc/yum.conf.orig 2016-04-26 04:44:45.807999999 +0000
--- /etc/yum.conf 2016-04-26 04:44:55.390999997 +0000
***************
*** 12,14 ****
distroverpkg=centos-release
! tsflags=nodocs

--- 12,14 ----
distroverpkg=centos-release
! #tsflags=nodocs

# yum install -y cacti

# rpm -ql cacti | grep cacti.sql
/usr/share/doc/cacti-0.8.8b/cacti.sql

# ll /usr/share/doc/cacti-0.8.8b/cacti.sql
-rw-r--r-- 1 root root 178349 Aug 7 2013 /usr/share/doc/cacti-0.8.8b/cacti.sql

やった!! ありがとうございます!!

はじめてのMySQLへのPull-Request体験談

$
0
0
の前に、いくつかMySQLへのContributeの前提を。

MySQLへのコードの寄贈は

1. Oracleプロファイルを持っていないといけない。ダウンロードする時に "No thanks"に気付かないと作らされるアレ。
2. Oracle Contributor Agreement にサインしないといけない(OCAにサインしたかどうかがOracleプロファイルに紐付けられる…ので、Oracleプロファイルが必要みたい)

が前提になる。


【2016/05/06 23:35】

ちなみにMariaDBの場合も似たようなもので

If you want the code to be part of the main MariaDB tree, you also have to give the MariaDB Foundation a shared copyright to your code. This is needed so that the foundation can offer the code to other projects (like MySQL).

You do this by either:

1. Signing the MariaDB Contributor Agreement (MCA) and then scanning and sending it to the foundation.
2. Sending an email to maria-developers where you say that your patch and all fixes to it are provided to the MariaDB Foundation under the MCA.
3. Licensing your code using the BSD license.
Contributing Code - MariaDB Knowledge Base

MCAにサインするか、パッチのライセンスを明示的にBSDにする必要がある。


これなしでいきなりPull-Requestしても多分蹴られる(ってか手違いで蹴られた)


前提について詳しくはこのへんの記事が読みやすくて良いと思う。




で、取り敢えず バグレポートを上げて、GitHubでも Pull-Requestを出してみた。

予想としては
Hi, thank you for your contribution. Please confirm this code is submitted under the terms of the OCA (Oracle's Contribution Agreement) you have previously signed by cutting and pasting the following text as a comment:
"I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it."
Thanks

bug 79747: crc32 optimizations by grooverdan · Pull Request #68 · mysql/mysql-server

こんな感じで、「これコピペしてね」って言われると思ってたんだけどさにあらず。



Hi, thank you for submitting this pull request. In order to consider your code we need you to sign the Oracle Contribution Agreement (OCA). Please review the details and follow the instructions at http://www.oracle.com/technetwork/community/oca-486395.html
Please make sure to include your MySQL bug system user (email) in the returned form.
Thanks

Fix Bug#80833 by yoku0825 · Pull Request #102 · mysql/mysql-sys


(;・3・) アルェー、コピペしようにもコピペするべき文章が見当たらないぞー。

mysql/mysql-server と mysql/mysql-sys でbotが違うのかなぁと思いつつ、かるーく 梅ッシュ 最近のVerifiedおじさんことUmeshに「GitHubでPull-Request出したけど大丈夫ですかね?」的なジャブをかましてみるも、「大丈夫じゃね?」的な返答。

そして待つことしばし。


Hi, there was no response to our request to sign an OCA or confirm the code is submitted under the terms of the OCA. As such this request will be closed.
Thanks

Fix Bug#80833 by yoku0825 · Pull Request #102 · mysql/mysql-sys


Σ(゚д゚lll) confirm用のメッセージが表示されないまま「お前がconfirmしないからcloseするわー」ってなった!!!1


困った時の Lenkaちゃん 。
bugs.mysql.comにパッチを送り付けると、Lenkaちゃんから「受け取ったよ!」ってメールが来る(Lenkaちゃん宛てにbugs.mysql.comからメールが飛んでるっぽく、それを転送してくれるんだけど、どうもその時間差から察するに、自動転送ってわけではなさそう)ので、きっと彼女なら詳しいはず。

待つことしばし。


it looks like that for some reason I have not added (or it was somehow removed…) your GitHub name.
As a result the script did not know that you signed OCA.

( д ) ゚ ゚ ホワッ!?

そしてmysql-oca-botと同じアイコンの mysql-admin というアカウントによってreopenされるPull-Request。
https://github.com/mysql/mysql-sys/pull/102#issuecomment-215091765


その後は無事にbotによってbugs.mysql.comがアップデートされました。

Lenkaちゃんありがとう。



…ところでついさっき気付いたんだけど、俺、今まで一度も○racleさんにGitHubアカウント提出したことなかったや。。(今はOCAの段階で聞かれるのかしらん? 体験談求む)

取り敢えず困った時はLenkaちゃん。ありがとうございました(*-人-)

innotopが最近息してないなーと思ったんだ

$
0
0
使っている人口がどれくらいいるかわからないですが、 innotop というtopライクにMySQLの状況を表示してくれる便利スクリプトが世の中には存在しています。

日々の覚書: innotopがすごく便利

もともとGoogle Codeにホスティングされてたんだけど、Google Codeはサービス終了しちゃったから(いつからか知らないけど)GitHubに移行してて、ひょっとしたらこのまま(移行だけしてメンテナンスされなくなって)息を引き取るんじゃないか疑惑が当時から俺の中にあったりなかったり。


原因がそれかどうかは全く知らないけれど、 innotopは5.6までは問題なく使える(5.6で使えなくなった時にちゃんと対応された)んだけど、5.7だと `SHOW ENGINE INNODB STATUS` をパースできなくなっていて(それ以外は何とか使える)、随分前からこれはIssueに上がってるんだけど、全然直される気配がない。

App crash on the "T" and "L" pages · Issue #109 · innotop/innotop


というか、 "Support MySQL 5.7"と銘打たれたコミットがひどすぎて、テストすら通らない(何故マージされたし)

Support MySQL 5.7 by potto007 · Pull Request #114 · innotop/innotop


ちまちま直してったら、こんな転け方もした。日付が違う? 馬鹿な。

$ perl t/InnoDBParser.t
1..5
ok 1 - /home/yoku0825/git/innotop/t/innodb-status-007
ok 2 - /home/yoku0825/git/innotop/t/innodb-status-001
ok 3 - /home/yoku0825/git/innotop/t/innodb-status-002
not ok 4 - /home/yoku0825/git/innotop/t/innodb-status-009
# Failed test '/home/yoku0825/git/innotop/t/innodb-status-009'
# at InnoDBParser.t line 2193.
# Structures begin differing at:
# $got->{IB_timestring} = '2015-06-09 13:52:05'
# $expected->{IB_timestring} = '2013-06-19 13:47:37'
ok 5 - /home/yoku0825/git/innotop/t/innodb-status-008
ok 6 - /home/yoku0825/git/innotop/t/innodb-status-006
# Looks like you planned 5 tests but ran 6.
# Looks like you failed 1 test of 6 run.


という訳でまずテストを直すPRした。これがマージされれば Issue #109のやつも頑張るかも知れない。これがマージされないようなら、 innotop は死んだんであろう(というか、死んだと思ってForkしてゴニョったやつをrpmbuildしたらテストが通らないのに気が付いた。。)

Fix broken test for 5.7 by yoku0825 · Pull Request #135 · innotop/innotop


出来れば死なずにメンテナンスされ続けて欲しいなーと思いつつ、今後どうなるかなぁ。。
(多少なら自分で使う分くらいは頑張れると思うんだけど、全面的にメンテナンスは無理だなきっと。。)


【2016/05/11 00:20】

MySQL Routerの接続でMySQL Fabricのlogテーブルがあふれた(event_schedulerをOFFにするとあぶない)

$
0
0
MySQL Fabricには /etc/mysql/fabric.cfg の [logging]セクションの他にもログを取る部分が仕込まれていて、


mysql> SELECT * FROM fabric.log;
+---------------------------+----------------------------+------------------------------+-----------------------------------------------------------------------+----------+------+
| subject | reported | reporter | message | category | type |
+---------------------------+----------------------------+------------------------------+-----------------------------------------------------------------------+----------+------+
| 0 | 2016-05-16 06:48:47.000000 | mysql.fabric.services.manage | Fabric node version (1.5.6) started. | 0 | 0 |
| manage.ping | 2016-05-16 06:48:52.000000 | mysql.fabric.command | Started command (manage, ping). | 1 | 0 |
| manage.ping | 2016-05-16 06:48:52.000000 | mysql.fabric.command | Finished command (manage, ping). | 1 | 1 |
..
| dump.servers | 2016-05-16 06:55:53.000000 | mysql.fabric.command | Finished command (dump, servers). | 1 | 1 |
| dump.sharding_information | 2016-05-16 06:55:53.000000 | mysql.fabric.command | Started command (dump, sharding_information). | 1 | 0 |
| dump.sharding_information | 2016-05-16 06:55:53.000000 | mysql.fabric.command | Finished command (dump, sharding_information). | 1 | 1 |
+---------------------------+----------------------------+------------------------------+-----------------------------------------------------------------------+----------+------+
1297 rows in set (0.02 sec)

なんというか、どぱーと吐いている。

( ´-`).oO(こんなトランザクションで保護される必要もなさそうな間っ平なログをMySQLに突っ込むとか、何考えてるのか小一時間問い詰めたい。


そしてなんか周辺の流れを見ても、何のフィルターもなく毎回INSERTされてるように見える。マジか(Python詳しい人誰か)

https://github.com/mysql/mysql-fabric/blob/release/1.5.5/lib/mysql/fabric/handler.py#L305-L307



$ mysqlbinlog -R -uroot -h 172.17.0.4 --stop-never -vv --start-position=182893 bin.000001 | grep "^#"
..

# at 285377
#160516 15:55:53 server id 1 end_log_pos 285408 CRC32 0x7f70413b Xid = 5500
# at 285408
#160516 15:55:53 server id 1 end_log_pos 285473 CRC32 0xb35843f4 Anonymous_GTID last_committed=772 sequence_number=773
# at 285473
#160516 15:55:53 server id 1 end_log_pos 285555 CRC32 0xd3de3d80 Query thread_id=4 exec_time=0 error_code=0
# at 285555
#160516 15:55:53 server id 1 end_log_pos 285614 CRC32 0x12ff61e4 Table_map: `fabric`.`log` mapped to number 110
# at 285614
#160516 15:55:53 server id 1 end_log_pos 285734 CRC32 0x3c061fb3 Write_rows: table id 110 flags: STMT_END_F
### INSERT INTO `fabric`.`log`
### SET
### @1='dump.servers' /* VARSTRING(120) meta=120 nullable=0 is_null=0 */
### @2=1463349353.000000 /* TIMESTAMP(6) meta=6 nullable=0 is_null=0 */
### @3='mysql.fabric.command' /* VARSTRING(192) meta=192 nullable=0 is_null=0 */
### @4='Finished command (dump, servers).' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
### @5=1 /* INT meta=0 nullable=0 is_null=0 */
### @6=1 /* INT meta=0 nullable=0 is_null=0 */
# at 285734
#160516 15:55:53 server id 1 end_log_pos 285765 CRC32 0x39af684e Xid = 5508
# at 285765
#160516 15:55:53 server id 1 end_log_pos 285830 CRC32 0xe449e1fe Anonymous_GTID last_committed=773 sequence_number=774
# at 285830
#160516 15:55:53 server id 1 end_log_pos 285912 CRC32 0x239e9184 Query thread_id=4 exec_time=0 error_code=0
# at 285912
#160516 15:55:53 server id 1 end_log_pos 285971 CRC32 0xe2235101 Table_map: `fabric`.`log` mapped to number 110
# at 285971
#160516 15:55:53 server id 1 end_log_pos 286116 CRC32 0xf5cc5f55 Write_rows: table id 110 flags: STMT_END_F
### INSERT INTO `fabric`.`log`
### SET
### @1='dump.sharding_information' /* VARSTRING(120) meta=120 nullable=0 is_null=0 */
### @2=1463349353.000000 /* TIMESTAMP(6) meta=6 nullable=0 is_null=0 */
### @3='mysql.fabric.command' /* VARSTRING(192) meta=192 nullable=0 is_null=0 */
### @4='Started command (dump, sharding_information).' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
### @5=1 /* INT meta=0 nullable=0 is_null=0 */
### @6=0 /* INT meta=0 nullable=0 is_null=0 */

MySQL Routerを起動している間中、ずっとこれが来る。
それぞれのmysqlrouterから1秒に3リクエストずつ来ているらしく、そんな感じで倍々ゲームになっている:(;゙゚'ω゚'):

さてどうしようか。


【2016/05/17 13:46】

event_schedulerをOFFにしてたのがいけなかったのか!!!!

mysql> SELECT * FROM events\G
*************************** 1. row ***************************
EVENT_CATALOG: def
EVENT_SCHEMA: fabric
EVENT_NAME: prune_log
DEFINER: mikasa_fabric@127.0.0.1
TIME_ZONE: SYSTEM
EVENT_BODY: SQL
EVENT_DEFINITION: DELETE FROM log WHERE TIMEDIFF(UTC_TIMESTAMP(), reported) > MAKETIME(3600,0,0)
EVENT_TYPE: RECURRING
EXECUTE_AT: NULL
INTERVAL_VALUE: 3600
INTERVAL_FIELD: SECOND
SQL_MODE: NO_ENGINE_SUBSTITUTION
STARTS: 2016-04-04 15:49:10
ENDS: NULL
STATUS: ENABLED
ON_COMPLETION: NOT PRESERVE
CREATED: 2016-04-04 15:49:10
LAST_ALTERED: 2016-04-04 15:49:10
LAST_EXECUTED: NULL
EVENT_COMMENT:
ORIGINATOR: 33893
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: utf8_general_ci
*************************** 2. row ***************************
EVENT_CATALOG: def
EVENT_SCHEMA: fabric
EVENT_NAME: prune_error_log
DEFINER: mikasa_fabric@127.0.0.1
TIME_ZONE: SYSTEM
EVENT_BODY: SQL
EVENT_DEFINITION: DELETE FROM error_log WHERE TIMEDIFF(UTC_TIMESTAMP(), reported) > MAKETIME(3600,0,0)
EVENT_TYPE: RECURRING
EXECUTE_AT: NULL
INTERVAL_VALUE: 3600
INTERVAL_FIELD: SECOND
SQL_MODE: NO_ENGINE_SUBSTITUTION
STARTS: 2016-04-04 15:49:11
ENDS: NULL
STATUS: ENABLED
ON_COMPLETION: NOT PRESERVE
CREATED: 2016-04-04 15:49:11
LAST_ALTERED: 2016-04-04 15:49:11
LAST_EXECUTED: NULL
EVENT_COMMENT:
ORIGINATOR: 33893
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: utf8_general_ci
2 rows in set (0.00 sec)

mysql> SELECT @@event_scheduler;
+-------------------+
| @@event_scheduler |
+-------------------+
| OFF |
+-------------------+
1 row in set (0.00 sec)


MySQL Bugs: #73206: MySQL Fabric should report a warning when MySQL Event Scheduler is disabled




1. logテーブルをBlackhole化する

mysql> use fabric
mysql> ALTER TABLE log Engine= Blackhole;

一番最初にこれが出てくるのもなんだかななんだけど、なんとこれ無事に動く。
mysqlfabricデーモンを再起動してもフツーに動いた。マジか。


2. ロギングをすっ飛ばすようにMySQL Fabric側をゴニョる

$ diff -C1 /usr/lib/python2.6/site-packages/mysql/fabric/handler.py handler.py
*** /usr/lib/python2.6/site-packages/mysql/fabric/handler.py 2015-09-11 14:31:50.000000000 +0900
--- handler.py 2016-05-16 16:51:12.000000000 +0900
***************
*** 209,214 ****
"""
- persister.exec_stmt(_INSERT_FABRIC_LOG,
- {"params": (subject, reported, reporter, info, info_category,
- info_type)}
- )

--- 209,210 ----

これでももちろんMySQL Routerはちゃんと動く。


3. 定期的にlogテーブルからレコードをパージする

至極当たり前すぎる。
何故かすごくごちゃごちゃとインデックスが張ってあるので、reportedで期間を切って定期的に消すのはそんなに難しくないはずだ。
(最近のMySQLはOPTIMIZE TABLEもオンラインでできるのでー。。)

mysql> SHOW CREATE TABLE log\G
*************************** 1. row ***************************
Table: log
Create Table: CREATE TABLE `log` (
`subject` varchar(40) NOT NULL,
`reported` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`reporter` varchar(64) NOT NULL,
`message` text,
`category` int(11) NOT NULL,
`type` int(11) NOT NULL,
KEY `key_subject_reported` (`subject`,`reported`),
KEY `key_reporter` (`reporter`),
KEY `key_reported` (`reported`),
KEY `key_category` (`category`),
KEY `key_type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


これ、実際に運用してる人はどうしてるんでしょうか。
お客様の中にMySQL Fabricを運用している方はいらっしゃいませんか?


…いらっしゃいませんね。

innotopのその後 2016年6月

$
0
0
日々の覚書: innotopが最近息してないなーと思ったんだ から 1か月。innotop v1.11がリリースされました。

v1.10からのアップデート内容はざっくりと

- MariaDB 10.1のサポート #124
- MySQL 5.7のマルチソースレプリケーションに対応 #129
- 壊れたテストの修正 #135
- perl 5.22でエラーになる問題の修正 #136
- MySQL 5.7で "L", "K"画面が表示できない不具合の修正 #137

あたりでしょうか。 @ryochinさん++。


MySQL 5.7に本格対応ということで晴れて v1.11 としてリリースされました(が、 コードの中のバージョンがv1.10のままというIssue が。。)

どうせならepelリポジトリーに入ってくれると楽でいいので、Red HatのBugzillaに上げてみました。
(本当にこれで良いのかどうかわからないけど、伝わるといいなあ…と思っていたらさっきの #139 が上がってきてアレなんですが)



innotopのリポジトリーで色々やってくれる lefredって先月Oracle(2016/06/14現在でMySQL Community Managerって書いてある)に入ったんですね。



入社後も バージョンageてよっていうIssueに反応してくれてるので、IssueやPRがあれば反応するっていうスタンスなんですかね(Percona時代からinnotop自体そんな感じだったけれど)

innotopの近況報告でした。

MySQL 5.7のmysql_upgradeがやたら重い件

$
0
0
日々の覚書: MySQL 5.7のmysql_upgradeは本当にDATETIME型を新しいフォーマットに直してくれるけれど でちょっと触れてるんだけど、DATETIME型(TIME型とTIMESTAMP型もあるけど)には現在2つのフォーマットが合って、

- 5.5とそれ以前のDATETIME型(秒部の小数点数非対応、8バイト、以下 旧DATETIME型)
- 5.6とそれ以降のDATETIME型(秒部の小数点数対応、小数部無しの場合は5バイト、以下DATETIME2型)

で、MySQL 5.7のmysql_upgradeは旧DATETIME型をDATETIME2型にアップグレードしてくれるよ、こいつらはレプリケーションで混ぜるとよろしくないから、これで安心だね、みたいなのが 前に書いた記事のあらすじ。


と、MySQL 5.6 => 5.7のmysql_upgradeが特に問題にはなっていなかったので気付かなかったんだけれど、ふと気付いたら我らが Chiba.pm@masasuzさんが













というわけで計ってみた。
d2.xlargeインスタンスをスポットで借りてゴニョゴニョ。

テストデータはこんな感じ。

$ perl -MDigest::MD5 -e 'for (my $n= 1; $n <= 100000000; $n++) {printf("%d\t%s\n", $n, Digest::MD5::md5_hex($n));}'> /data/md5
mysql> CREATE TABLE t1 (num serial, val varchar(32) not null, dt datetime not null);
mysql> LOAD DATA INFILE '/data/md5' INTO TABLE t1 (num, val) SET dt = NOW();
$ ll d1/t1.ibd -h
-rw-rw---- 1 mysql mysql 6.9G Jun 21 02:16 d1/t1.ibd


結果はこんな感じ。1回ずつしか計ってないから誤差はあると思う。

fromtotimeメモ
5.5(旧DATETIME)5.7(DATETIME2)31:165.5のmysqldで作ったデータをそのまま5.7のmysqldで起動してmysql_upgrade
5.5(旧DATETIME)5.6(旧DATETIME)00:065.5のmysqldで作ったデータをそのまま5.6のmysqldで起動してmysql_upgrade
5.6(旧DATETIME)5.7(旧DATETIME)00:16↑のデータを5.7のmysqld —avoid-temporal-upgradeで起動してmysql_upgrade
5.6(旧DATETIME)5.7(DATETIME2)36:53↑↑のデータを5.7のmysql_upgrade
5.6(旧DATETIME)5.6(DATETIME2)23:01↑↑↑のデータを5.6でALTER TABLE t1 FORCE
5.5(旧DATETIME)5.6(DATETIME2)22:375.5からmysqldumpして5.6にリストア(ダンプに別途1:31かかってる)
5.6(DATETIME2)5.7(DATETIME2)00:11↑のデータを5.7へmysql_upgrade



5.5のmysqldで作ったデータをそのまま5.7のmysqldで起動してmysql_upgradeした時のリソースの様子。

$ dstat -tamr 10
date/time |usr sys idl wai hiq siq| read writ| recv send| in out | int csw | used buff cach free| read writ
21-06 02:23:44| 5 0 64 30 0 0| 0 19M| 6B 4B| 0 0 |1288 1142 |4895M 109M 24.9G 155M| 0 518
21-06 02:23:54| 6 1 65 29 0 0| 0 21M| 0 0 | 0 0 |1385 1176 |4969M 109M 24.8G 152M| 0 563
21-06 02:25:54| 6 0 64 30 0 0| 0 22M| 0 0 | 0 0 |1402 1194 |5822M 115M 24.0G 157M| 0 580


単にdatadirをコピーしてるだけの間は↓これくらい出ていたので、MySQL側の限界ではある様子。

$ dstat -tamr 10
21-06 03:00:14| 0 0 48 52 0 0| 410B 143M| 81B 606B| 0 0 |3491 594 | 889M 75.6M 24.1G 4991M|0.10 3434
21-06 03:00:24| 0 0 50 49 0 0| 410B 137M| 60B 570B| 0 0 |3366 544 | 926M 75.7M 25.4G 3632M|0.10 3295
21-06 03:00:34| 0 0 52 47 0 0| 0 149M| 79B 607B| 0 0 |3616 579 | 964M 75.7M 26.7G 2239M| 0 3576


30秒だけ pt-ioprofile でI/O状況を見てみたらこんな感じ。

# pt-ioprofile --cell sizes
Tue Jun 21 02:22:59 UTC 2016
Tracing process ID 4076
total pwrite fsync lseek filename
48041558016 96468992 0 47945089024 /data/mysql/d1/#sql-fec_2.ibd
136257004 136252928 4076 0 /data/mysql/ib_logfile1
115982336 115982336 0 0 /data/mysql/ibdata1
0 0 0 0 /data/mysql/ib_logfile0

テンポラリーな.ibdファイルを作ってるので、テーブルコピーのALTER TABLEがまさに走っているはず。
pt-ioprofileを見るに、ibdファイルそのものよりもInnoDBログファイルに書き込んでいる(そう、テーブルコピーのALTER TABLEは1000行ずつコミットするらしい)ので、innodb_flush_log_at_trx_commit= 0とかすると速くなるかも。

そのALTER TABLEがオンラインALTER TABLEかどうかを確かめる方法

$
0
0
MySQL 5.6以降の InnoDB オンラインDDLについて、「これってオンラインでできたっけ?」とここ最近だけで何度か聞かれたので。
ちなみにここを見てもわかる。
何故か概要ページにできるかできないかの表があることと、 ALTER TABLEのページから概要ページに直接リンクがないので見つけにくいらしい。
で、このページを思い出せなくてもできるかどうか確認する方法。
  • 同じ構造を持った空のテーブルを作ります
mysql57> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`val` varchar(32) DEFAULT NULL,
UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)

mysql57> CREATE TEMPORARY TABLE tt1 LIKE t1;
Query OK, 0 rows affected (0.00 sec)

  • 試したいALTER TABLEに LOCK=NONEを明示して実行するます
mysql57> ALTER TABLE tt1 ADD KEY (val), LOCK=NONE; -- インデックスの追加はできる
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql57> ALTER TABLE tt1 ADD FULLTEXT KEY (val), LOCK=NONE; -- FTインデックスの追加はできない
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED.

mysql57> ALTER TABLE tt1 MODIFY val varchar(63), LOCK=NONE; -- 255バイトをまたがないvarcharのサイズ変更はできる
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql57> ALTER TABLE tt1 MODIFY val varchar(64), LOCK=NONE; -- 255バイトをまたぐやつはできない
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: Cannot change column type INPLACE. Try LOCK=SHARED.

mysql57> ALTER TABLE tt1 MODIFY val varchar(63) CHARACTER SET latin1, LOCK=NONE; -- 文字コードの変換もできない
ERROR 1846 (0A000): LOCK=NONE is not supported. Reason: Cannot change column type INPLACE. Try LOCK=SHARED.
ね、簡単でしょ?

MySQL Fabricの様子を監視するための何か

$
0
0
MySQL Fabricでぼっこぼこにされたはなし で考えていた、MySQL FabricのMySQLプロトコルの口でAPIを叩いて監視しようと思っているはなし。

MySQLプロトコルの口では "CALL"ステートメントをフックして(というか単にクエリーを正規表現でマッチさせて) MySQL Fabricの各種APIを呼べるようになっている。
  => 日々の覚書: MySQL Fabricつらい(Fabricサーバー上のMySQLプロトコルの口でFabricのAPIが呼べる編)

ので、これを使うことにする。叩くAPIはたぶんこの辺。


mysqlfabricmysql用途
mysqlfabric manage pingCALL manage.ping()mysqlfabricデーモンが生きてるかどうか
mysqlfabric statistics nodeCALL statistics.node()node_uptime, node_startupを見たいとき
mysqlfabric group lookup_groupsCALL group.lookup_groups()group_idをここで取る
mysqlfabric group health ‘group_id’CALL group.health(‘group_id’)is_alive, status, is_not_runningとか見どころがいっぱい
statisticsまでは拘らなくてもいいかなと思って、書いたのがこんな。


my $conn= DBI->connect("dbi:mysql:;host=fabric_ipaddr;port=32275", "fabric_usser", "fabric_password",
{RaiseError => 1, PrintError => 0,
mysql_connect_timeout => 1, mysql_read_timeout => 1, mysql_write_timeout => 1});

my $manage_ping= $conn->prepare("CALL manage.ping()");
$manage_ping->execute;

my $lookup_groups= $conn->prepare("CALL group.lookup_groups()");
$lookup_groups->execute;
$lookup_groups->fetchall_arrayref(); ### Skip because 1st Result set is fabric's uuid.
$lookup_groups->more_results; ### Go ahead to next Result set.
foreach my $group (@{$lookup_groups->fetchall_arrayref({})})
{
my $group_id= $group->{group_id};

my $group_health= $conn->prepare("CALL group.health(?)");
$group_health->execute($group_id);
$group_health->fetchall_arrayref(); ### Skip because 1st Result set is fabric's uuid.
$group_health->more_results; ### Go ahead to next Result set.

my $primary_server= "";
foreach my $server (@{$group_health->fetchall_arrayref({})})
{
if ($server->{io_not_running} || $server->{sql_not_running})
{
critf("group_health is something wrong: %s", $server);
}
else
{
$primary_server= $server->{uuid} if $server->{status} eq "PRIMARY";
}
}
critf("There's no PRIMARY state server in %s", $group_id) unless $primary_server;
}

CALL group.lookup_groups();(をはじめとする色々なストアドプロシージャもどきの)戻りが複数の結果セットをカジュアルに返すので、生まれて初めて more_results なんてメソッドを呼んだ。manage pingなんかは1つしか返さないので、本当はちゃんとループさせて "TTL"が入ってたら多分応答ヘッダーの方だとか判定した方がいいんだろう(たぶん、する)
1つ目の結果セットが "mysqlfabricのUUID"と "Time-To-Live"を返し、2つ目の結果セットにコマンドの結果が詰まっている。

$ mysqlfabric group lookup_groups
Fabric UUID: 5ca1ab1e-a007-feed-f00d-cab3fe13249e
Time-To-Live: 1

group_id description failure_detector master_uuid
------------ ----------- ---------------- ------------------------------------
fabric_A None 0 8658f0e6-fb9e-11e5-8c6f-001a4a571800
fabric_B None 1 a1ffe373-3e73-11e6-87b3-001a4a5718ee


MySQL [(none)]> CALL group.lookup_groups();
+--------------------------------------+-----+---------+
| fabric_uuid | ttl | message |
+--------------------------------------+-----+---------+
| 5ca1ab1e-a007-feed-f00d-cab3fe13249e | 1 | NULL |
+--------------------------------------+-----+---------+
1 row in set (0.01 sec)

+--------------+-------------+------------------+--------------------------------------+
| group_id | description | failure_detector | master_uuid |
+--------------+-------------+------------------+--------------------------------------+
| fabric_A | NULL | 0 | 8658f0e6-fb9e-11e5-8c6f-001a4a571800 |
| fabric_B | NULL | 1 | a1ffe373-3e73-11e6-87b3-001a4a5718ee |
+--------------+-------------+------------------+--------------------------------------+
2 rows in set (0.01 sec)

さて…切り替わりをフックするのはどうしようかな。。threat.report_failureあたりは何のマシな情報も吐いてくれなかった。。


mysql> CALL threat.report_failure('a1ffe373-3e73-11e6-87b3-001a4a5718ee');
+--------------------------------------+-----+---------+
| fabric_uuid | ttl | message |
+--------------------------------------+-----+---------+
| 5ca1ab1e-a007-feed-f00d-cab3fe13249e | 1 | NULL |
+--------------------------------------+-----+---------+
1 row in set (0.58 sec)

+--------------------------------------+----------+---------+--------+
| uuid | finished | success | result |
+--------------------------------------+----------+---------+--------+
| 90517342-6a1f-424f-bed3-7a65f6140167 | 1 | 1 | 1 |
+--------------------------------------+----------+---------+--------+
1 row in set (0.58 sec)

+-------+---------+---------------+---------------------------------------------------------------+
| state | success | when | description |
+-------+---------+---------------+---------------------------------------------------------------+
| 3 | 2 | 1467708190.44 | Triggered by <mysql.fabric.events.Event object at 0x239f350>. |
| 4 | 2 | 1467708190.47 | Executing action (_report_failure). |
| 5 | 2 | 1467708190.5 | Executed action (_report_failure). |
| 3 | 2 | 1467708190.48 | Triggered by <mysql.fabric.events.Event object at 0x22777d0>. |
| 4 | 2 | 1467708190.5 | Executing action (_find_candidate_fail). |
| 5 | 2 | 1467708190.59 | Executed action (_find_candidate_fail). |
| 3 | 2 | 1467708190.58 | Triggered by <mysql.fabric.events.Event object at 0x239f8d0>. |
| 4 | 2 | 1467708190.59 | Executing action (_check_candidate_fail). |
| 5 | 2 | 1467708190.65 | Executed action (_check_candidate_fail). |
| 3 | 2 | 1467708190.64 | Triggered by <mysql.fabric.events.Event object at 0x239f950>. |
| 4 | 2 | 1467708190.65 | Executing action (_wait_slave_fail). |
| 5 | 2 | 1467708190.87 | Executed action (_wait_slave_fail). |
| 3 | 2 | 1467708190.86 | Triggered by <mysql.fabric.events.Event object at 0x239fa90>. |
| 4 | 2 | 1467708190.87 | Executing action (_change_to_candidate). |
| 5 | 2 | 1467708191.02 | Executed action (_change_to_candidate). |
+-------+---------+---------------+---------------------------------------------------------------+
15 rows in set (0.58 sec)

MySQL 5.7のngramパーサーはアルファベットを含む文章を上手くトークナイズできない

$
0
0
MySQL Bugs: #82330: Don't recursively-evaluate stopword after tokenize

ngramパーサーを使ってアルファベット混じりの日本語全文検索をしようとすると悲劇が起こる。デフォルトのストップワード一覧は このへん


MySQL 5.7.13で全文検索INDEXを使ってるんですけど半角英字でヒットする奴とヒットしないやつが居るんですけどこれって何ででしょう… ちなみに NGRAMを2文字 です。 例えばbabyって単語が含まれてる文章でbabyって単語がヒットしません。 stop wordsには含まれてないんですがなんでだろうと…

http://mysql-casual.slackarchive.io/general/-/1466580139/1469433820/1469174336000008/


mysql57> CREATE TABLE t1 (num serial, val varchar(32), FULLTEXT KEY (val) WITH PARSER ngram);
Query OK, 0 rows affected (0.40 sec)

mysql57> INSERT INTO t1 VALUES (1, 'baby');
Query OK, 1 row affected (0.04 sec)

mysql57> SELECT * FROM t1;
+-----+------+
| num | val |
+-----+------+
| 1 | baby |
+-----+------+
1 row in set (0.01 sec)

mysql57> SELECT * FROM t1 WHERE MATCH(val) AGAINST ('baby' IN BOOLEAN MODE);
Empty set (0.02 sec)

mysql57> SET GLOBAL innodb_ft_aux_table = 'd1/t1';
Query OK, 0 rows affected (0.01 sec)

mysql57> SELECT * FROM i_s.INNODB_FT_INDEX_CACHE;
Empty set (0.05 sec)

確かに何も入らない。俺の知ってるBigramなら "ba", "ab", "by"の3つのトークンが入るはずなのに。


ソースコードをざっくり流してみたところ、

/*Ngram checks whether the token contains any words in stopwords.
We can't simply use CONTAIN to search in stopwords, because it's
built on COMPARE. So we need to tokenize the token into words
from unigram to f_n_char, and check them separately. */

https://github.com/mysql/mysql-server/blob/mysql-5.7.13/storage/innobase/fts/fts0fts.cc#L4790-L4845


( ゚д゚) ・・・

(つд⊂)ゴシゴシ

(;゚д゚) ・・・

(つд⊂)ゴシゴシゴシ
_, ._
(;゚ Д゚) …!?


トークナイズした後に、トークンにストップワードが含まれてないか、1gramからngramまで順番に評価する…だと…!?

よく見たらドキュメントにも書いてある。

ngram Parser Stopword Handling

The built-in MySQL full-text parser compares words to entries in the stopword list. If a word is equal to an entry in the stopword list, the word is excluded from the index. For the ngram parser, stopword handling is performed differently. Instead of excluding tokens that are equal to entries in the stopword list, the ngram parser excludes tokens that contain stopwords. For example, assuming ngram_token_size=2, a document that contains “a,b” is parsed to “a,” and “,b”. If a comma (“,”) is defined as a stopword, both “a,” and “,b” are excluded from the index because they contain a comma.

By default, the ngram parser uses the default stopword list, which contains a list of English stopwords. For a stopword list applicable to Chinese, Japanese, or Korean, you must create your own. For information about creating a stopword list, see Section 13.9.4, “Full-Text Stopwords”.

Stopwords greater in length than ngram_token_size are ignored.

http://dev.mysql.com/doc/refman/5.7/en/fulltext-search-ngram.html


というわけで、MySQL 5.7.13現在のngramパーサーは

1. "baby"を "ba", "ab", "by"にトークナイズする
2. "ba"を "b", "a"に再分割してストップワード評価。"a"がストップワードなのでこの "ba"のトークンは登録されない。
3. "ab"を "a", "b"に再分割してストップワード評価。"a"がストップワードなのでこの "ab"のトークンも登録されない
4. "by"は再分割する前からストップワードなので "by"のトークンも登録されない

たまたま、"baby"は完全にトークナイズされないワードだった…:(;゙゚'ω゚'):

他にデフォルトのストップワードである "to"を含む "TOKYO"なんかは、

mysql57> truncate t1;
Query OK, 0 rows affected (0.41 sec)

mysql57> INSERT INTO t1 VALUES (1, 'tokyo');
Query OK, 1 row affected (0.04 sec)

mysql57> SELECT * FROM t1;
+-----+-------+
| num | val |
+-----+-------+
| 1 | tokyo |
+-----+-------+
1 row in set (0.03 sec)

mysql57> SELECT * FROM t1 WHERE MATCH(val) AGAINST ('tokyo' IN BOOLEAN MODE);
+-----+-------+
| num | val |
+-----+-------+
| 1 | tokyo |
+-----+-------+
1 row in set (0.04 sec)

mysql57> SET GLOBAL innodb_ft_aux_table = 'd1/t1';
Query OK, 0 rows affected (0.00 sec)

mysql57> SELECT * FROM i_s.INNODB_FT_INDEX_CACHE ORDER BY position;
+------+--------------+-------------+-----------+--------+----------+
| WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------+--------------+-------------+-----------+--------+----------+
| ok | 2 | 2 | 1 | 2 | 1 |
| ky | 2 | 2 | 1 | 2 | 2 |
| yo | 2 | 2 | 1 | 2 | 3 |
+------+--------------+-------------+-----------+--------+----------+
3 rows in set (0.00 sec)

"to"の部分以外はトークナイズされるので、一見検索できてそうに見えるけど、やっぱり "to"のトークンが握りつぶされているので


mysql57> INSERT INTO t1 VALUES (2, 'okyo');
Query OK, 1 row affected (0.03 sec)

mysql57> SELECT * FROM t1;
+-----+-------+
| num | val |
+-----+-------+
| 1 | tokyo |
| 2 | okyo |
+-----+-------+
2 rows in set (0.01 sec)

mysql57> SELECT * FROM t1 WHERE MATCH(val) AGAINST ('tokyo' IN BOOLEAN MODE);
+-----+-------+
| num | val |
+-----+-------+
| 1 | tokyo |
| 2 | okyo |
+-----+-------+
2 rows in set (0.01 sec)

こうなる(´・ω・`)

取り敢えずの回避策は、 デフォルトのストップワードリストを使わせなければいいので、 innodb_ft_server_stopword_tableを指定してやればいいはず。


mysql57> CREATE TABLE stopwords (value varchar(255) NOT NULL PRIMARY KEY);
Query OK, 0 rows affected (0.16 sec)

mysql57> SET GLOBAL innodb_ft_server_stopword_table = 'd1/stopwords';
Query OK, 0 rows affected (0.02 sec)

mysql57> OPTIMIZE TABLE t1;
+-------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-------+----------+----------+-------------------------------------------------------------------+
| d1.t1 | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| d1.t1 | optimize | status | OK |
+-------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.68 sec)

mysql57> SELECT * FROM t1;
+-----+-------+
| num | val |
+-----+-------+
| 1 | tokyo |
| 2 | okyo |
+-----+-------+
2 rows in set (0.01 sec)

mysql57> SELECT * FROM t1 WHERE MATCH(val) AGAINST ('tokyo' IN BOOLEAN MODE);
+-----+-------+
| num | val |
+-----+-------+
| 1 | tokyo |
+-----+-------+
1 row in set (0.07 sec)

mysql57> SELECT * FROM i_s.INNODB_FT_INDEX_CACHE ORDER BY position;
+------+--------------+-------------+-----------+--------+----------+
| WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------+--------------+-------------+-----------+--------+----------+
| ok | 2 | 3 | 2 | 3 | 0 |
| to | 2 | 2 | 1 | 2 | 0 |
| ky | 2 | 3 | 2 | 3 | 1 |
| ok | 2 | 3 | 2 | 2 | 1 |
| ky | 2 | 3 | 2 | 2 | 2 |
| yo | 2 | 3 | 2 | 3 | 2 |
| yo | 2 | 3 | 2 | 2 | 3 |
+------+--------------+-------------+-----------+--------+----------+
7 rows in set (0.02 sec)

回避できた。
しかしこれ、どうしてこんな仕様にした。。

SHOWステートメントをSHWOとタイポしてしまう

$
0
0
SHOWってshwoってタイポしませんか? わたしはします。

mysqlコマンドラインクライアントでの改変は、やった。


クエリーリライトプラグインも、やった。

Handlerさんコンニチワ (lsステートメントとかcatステートメントとかやった)

次はパーサーいじって改変せねばなるまい。

ということで書いた。
https://gist.github.com/yoku0825/68369433679392b2284e4eaf258b00c6

このパッチを適用したmysqldを起動すれば、


mysql57> shwo databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)


_人人人人人人人人人_
> shwo databases <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄

もちろんGPLですので、typoが気になる方は導入してみると、仕事の効率が上がるかも知れません。


ところで、クエリーの強制書き換えを3つの場所でやってみた感想。

- 一番お手軽なのはなんと今回のSQLパーサー
  - 変なの書けばコンパイル時にエラーになるか、いじったところが動かないだけ
    - mysqlコマンドラインクライアントとクエリーリライトは容赦なくSEGV食らう
  - しかも全バージョン対応(だと思う)
  - やりたいことがエイリアス的な何か、って決まってるならアリだと思う(か?)
- なんか このときはクエリーリライト用っぽい構造体の名前だったりしたけど、 今見ると明らかにaudit_pluginを使うようになってる。。
  - pre-parseならなんとか似たように使えるけど、post-parseは全然書き方が変わってる。つらい。

というわけで、もしなんかやるとしたら、SQLパーサーがいいかなって思いました。

mikasafabric for MySQLのビルド

$
0
0
mikasafabric for MySQLが何なのかについては こちら

取り敢えずビルド方法のメモ。雑に。


#!/bin/bash

version="0.1.1"
dirname="mikasafabric-${version}"

rm -rf ~/rpmbuild
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

if [ -d ~/$dirname ] ; then
rm -rf ~/$dirname
fi
git clone https://github.com/gmo-media/mikasafabric.git ~/$dirname
cd ~/$dirname
git checkout ${version}
cd $OLDPWD

tar czf ~/rpmbuild/SOURCES/${dirname}.tar.gz $dirname
rpmbuild -bb ~/$dirname/mikasafabric.spec

ビルドにはpython-develとrpm-buildが必要。実際にmikasafabricを動かすにはmysql-connector-pythonが必要。CentOS 7.2とCentOS 6.7くらいでビルドして動作できる。実際に本番で動いているのはCentOS 7.2。

バージョンはセマンティックバージョニングじゃ ない。Groongaに似てるかも。
機能が1つ増える、バグが1つFIXされると末尾の数字が増える。 `yum install ~/rpmbuild/RPMS/noarch/mikasafabric-*.rpm` で上書きインストールできて便利だからというだけの理由。


GitHub Pagesでyumリポジトリー作りたい。

FLUSH PRIVILEGESやFLUSH TABLESはバイナリーログに書かれるのでgtid_executedに記録されるよ

$
0
0
や、まあ、バイナリーログに吐かれるのはマニュアルに書いてあってそうなんだけれども、GTID振られるのは失念してた。

一つだけマニュアルが誤解を招く表現。

デフォルトでは、サーバーは FLUSH ステートメントをバイナリログに書き込み、それらがレプリケーションスレーブにレプリケートされるようにします。ロギングを抑制するには、オプションの NO_WRITE_TO_BINLOG キーワード、またはそのエイリアス LOCAL を指定します。

注記
FLUSH LOGS、FLUSH TABLES WITH READ LOCK (テーブルリスト付き、またはなし)、および FLUSH TABLES tbl_name ... FOR EXPORT は、スレーブにレプリケートされると問題が発生するため、どのような場合でもバイナリログに書き込まれません。

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


FLUSH LOGSのうちロギングされないのは「バイナリーログをフラッシュする」時だけで、追加引数なしのFLUSH LOGSとFLUSH BINARY LOGSだけがバイナリーロギングされない。

https://github.com/mysql/mysql-server/blob/mysql-5.6.32/sql/sql_reload.cc#L156-L170

それ以外のFLUSH SLOW LOGSやFLUSH ENGINE LOGS, FLUSH PRIVILEGES, WITH READ LOCKなしのFLUSH TABLESはしっかりバイナリーロギングされてスレーブでも実行される。迂闊にFLUSH TABLESとかマスターでやると、スレーブでも実行されてクエリーキャッシュが吹っ飛ばされるとか、マスターとスレーブの mysql.user がズレてる状態でFLUSH PRIVILEGESがレプリカされると地獄が見えるなとか思いますたん。

FLUSH TABLES WITH READ LOCKFLUSH TABLES .. FOR EXPORT はそれぞれ違う関数を通り、それらの関数の後に write_bin_logは呼ばれない(ので、コイツらはロギングされることはない)


簡単なところなので、コードを読むにはなかなか面白かった。

MySQL 8.0.0でmysqlスキーマの中身がほぼ全部InnoDBになった

$
0
0
MySQL 8.0でmysqlスキーマの中身が全部InnoDBになった。


5.7だと↓だったのが、

mysql57> SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'mysql' ORDER BY table_name;
+---------------------------+--------+
| table_name | engine |
+---------------------------+--------+
| columns_priv | MyISAM |
| db | MyISAM |
| engine_cost | InnoDB |
| event | MyISAM |
| func | MyISAM |
| general_log | CSV |
| gtid_executed | InnoDB |
| help_category | InnoDB |
| help_keyword | InnoDB |
| help_relation | InnoDB |
| help_topic | InnoDB |
| innodb_index_stats | InnoDB |
| innodb_table_stats | InnoDB |
| ndb_binlog_index | MyISAM |
| plugin | InnoDB |
| proc | MyISAM |
| procs_priv | MyISAM |
| proxies_priv | MyISAM |
| servers | InnoDB |
| server_cost | InnoDB |
| slave_master_info | InnoDB |
| slave_relay_log_info | InnoDB |
| slave_worker_info | InnoDB |
| slow_log | CSV |
| tables_priv | MyISAM |
| time_zone | InnoDB |
| time_zone_leap_second | InnoDB |
| time_zone_name | InnoDB |
| time_zone_transition | InnoDB |
| time_zone_transition_type | InnoDB |
| user | MyISAM |
+---------------------------+--------+
31 rows in set (0.01 sec)


↓が8.0.0

mysql80> SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'mysql' ORDER BY table_name;
+---------------------------+--------+
| TABLE_NAME | ENGINE |
+---------------------------+--------+
| column_stats | InnoDB |
| columns_priv | InnoDB |
| component | InnoDB |
| db | InnoDB |
| default_roles | InnoDB |
| engine_cost | InnoDB |
| func | InnoDB |
| general_log | CSV |
| gtid_executed | InnoDB |
| help_category | InnoDB |
| help_keyword | InnoDB |
| help_relation | InnoDB |
| help_topic | InnoDB |
| innodb_index_stats | InnoDB |
| innodb_table_stats | InnoDB |
| plugin | InnoDB |
| procs_priv | InnoDB |
| proxies_priv | InnoDB |
| role_edges | InnoDB |
| server_cost | InnoDB |
| servers | InnoDB |
| slave_master_info | InnoDB |
| slave_relay_log_info | InnoDB |
| slave_worker_info | InnoDB |
| slow_log | CSV |
| tables_priv | InnoDB |
| time_zone | InnoDB |
| time_zone_leap_second | InnoDB |
| time_zone_name | InnoDB |
| time_zone_transition | InnoDB |
| time_zone_transition_type | InnoDB |
| user | InnoDB |
+---------------------------+--------+
32 rows in set (0.02 sec)

general_log, slow_logは相変わらずとして、それ以外はInnoDBになった。
column_stats, component, default_roles, role_edgesが新設テーブル、ndb_binlog_index, event, procがなくなってる。ndb_binlog_indexはコンパイル方法が違うのかとも思うけど取り敢えず置いておく。


あと、mysqld --initializeした中でも、 **InnoDB: Creating foreign key constraint system tables.** って書いてあるので、おおおって感じがした。

$ bin/mysqld --no-defaults --initialize-insecure --basedir=./ --datadir=./data
2016-09-05T01:17:12.549926Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000)
2016-09-05T01:17:12.550002Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000)
2016-09-05T01:17:12.550282Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2016-09-05T01:17:12.842536Z 1 [Warning] InnoDB: New log files created, LSN=49311
2016-09-05T01:17:12.890633Z 1 [Warning] InnoDB: Creating foreign key constraint system tables.
2016-09-05T01:17:14.176756Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 7a644122-7306-11e6-bba7-02018582356a.
2016-09-05T01:17:14.185156Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2016-09-05T01:17:14.185650Z 3 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.

MySQL 8.0.0からmysql_install_dbがなくなってる、ついでにbinディレクトリ探求

$
0
0
日々の覚書: MySQL 5.7.6でデータベースの初期化が変わる mysql_install_dbからmysqld --initialize

1年半の時を経て、ついに消えた様子。
(MySQL 5.7の時点で、mysql_install_dbはscriptディレクトリーからbinディレクトリーに移動になってた)


$ ll bin/mysql_install_db
ls: cannot access bin/mysql_install_db: No such file or directory

あと、SDIファイル関連ぽい ibd2sdi とかいうファイルがあるけど使い方はいまいち謎。


$ bin/ibd2sdi -d >(cat -) data/ibdata1
[INFO] ibd2sdi: SDI from both copies is empty.

それ以外は特になさげ


$ diff <(ls -1 /usr/mysql/5.7.14/bin) <(ls -1 /usr/mysql/8.0.0/bin)
1c1,2
< innochecksum
---
> ibd2sdi
> innochecksum
12c13
< mysql_client_test
---
> mysql_client_test_embedded
15a17
> mysqld-debug
19a22
> mysql_embedded
21,22d23
< mysql_install_db
< mysql_plugin
28c29
< mysqltest
---
> mysqltest_embedded


ついでにplugindirも漁ってみるけど、これはコンパイルオプションとかに依存してそうな気もするので何とも言えない。
component_example*が気になる。mysql.componentテーブルと関連があるのかな。

$ diff <(ls -1 /usr/mysql/5.7.14/lib/plugin) <(ls -1 /usr/mysql/8.0.0/lib/plugin)
2d1
< auth.so
4,5c3,5
< auth_test_plugin.so
< daemon_example.ini
---
> component_example_component1.so
> component_example_component2.so
> component_example_component3.so
11d10
< libdaemon_example.so
39,42d37
< qa_auth_client.so
< qa_auth_interface.so
< qa_auth_server.so
< replication_observers_example_plugin.so

MySQL 8.0.0時代のmy.cnfの探り方

$
0
0
以前、straceで開いてるmy.cnfを調べて…とかやってたけど、それももう過去の話。

日々の覚書: ラッパーも含めて mysqldが起動するときにどのmy.cnfを舐めてるのか知りたいとき


MySQL 8.0.0では performance_schema.variables_info という便利なテーブルができた。


mysql80> SELECT * FROM performance_schema.variables_info LIMIT 10;
+--------------------------+-----------------+---------------+-----------+----------------------+
| VARIABLE_NAME | VARIABLE_SOURCE | VARIABLE_PATH | MIN_VALUE | MAX_VALUE |
+--------------------------+-----------------+---------------+-----------+----------------------+
| auto_increment_increment | COMPILED | | 1 | 65535 |
| auto_increment_offset | COMPILED | | 1 | 65535 |
| autocommit | COMPILED | | 0 | 0 |
| automatic_sp_privileges | COMPILED | | 0 | 0 |
| avoid_temporal_upgrade | COMPILED | | 0 | 0 |
| back_log | COMPILED | | 0 | 65535 |
| basedir | COMMAND_LINE | | 0 | 0 |
| big_tables | COMPILED | | 0 | 0 |
| bind_address | COMPILED | | 0 | 0 |
| binlog_cache_size | COMPILED | | 4096 | 18446744073709551615 |
+--------------------------+-----------------+---------------+-----------+----------------------+
10 rows in set (0.00 sec)

パラメーターの名前と最小値、最大値を表示してくれるのはいいんだけど、それなら現在の値も一緒に出してほしいところ。
performance_schema.global_variablesあたりとJOINすればいいだけだから、sysに入ってくるかしら。

まあ、そんなことよりこれの凄そうなところは(取り敢えず、このクエリーはJOINしてある)


mysql> SELECT variable_name, variable_source, variable_path, variable_value FROM performance_schema.variables_info JOIN performance_schema.global_variables USING(variable_name) WHERE variable_path <> '';
+-------------------------+-----------------+---------------+----------------+
| variable_name | variable_source | variable_path | variable_value |
+-------------------------+-----------------+---------------+----------------+
| innodb_buffer_pool_size | GLOBAL | /etc/my.cnf | 1073741824 |
+-------------------------+-----------------+---------------+----------------+
1 row in set (0.01 sec)


variable_pathにどのmy.cnfから読んできたか書いてくれるところ…なんだけど、残念ながらこれ、 "!include"に対応していないぽい。


$ cat /etc/my.cnf
[mysqld]
innodb_buffer_pool_size= 1G

!include /usr/mysql/8.0.0/test.cnf


$ cat /usr/mysql/8.0.0/test.cnf
[mysqld]
innodb_buffer_pool_size= 256M

こう設定した場合、設定が後勝ちするため innodb_buffer_pool_sizeは256MBで起動してくる。( 日々の覚書: my.cnfのパラメータ優先順位 )
しかしこう、


mysql> SELECT variable_name, variable_source, variable_path, variable_value FROM performance_schema.variables_info JOIN performance_schema.global_variables USING(variable_name) WHERE variable_path <> '';
+-------------------------+-----------------+---------------+----------------+
| variable_name | variable_source | variable_path | variable_value |
+-------------------------+-----------------+---------------+----------------+
| innodb_buffer_pool_size | GLOBAL | /etc/my.cnf | 268435456 |
+-------------------------+-----------------+---------------+----------------+
1 row in set (0.01 sec)

/etc/my.cnfが見えちゃうという(´・ω・`)
(どうやら仕様らしい。 MySQL Bugs: #82861: performance_schema.variable_info.variable_path doesn't reflect config-including でFeature Requestとして出し直す、みたいな話になった)

variable_sourceの値はこのあたりをとることまでは確かめた。



パラメーターを設定した場所variable_source
/etc/my.cnfGLOBAL
$basedir/my.cnfSERVER
—defaults-file=/etc/my.cnfEXPLICIT
—defaults-extra-file=/etc/my.cnfEXTRA
—innodb-buffer-pool-size=256MCOMMAND_LINE
SET GLOBAL innodb_buffer_pool_size= 256MDYNAMIC


mysql> SHOW CREATE TABLE performance_schema.variables_info\G
*************************** 1. row ***************************
Table: variables_info
Create Table: CREATE TABLE `variables_info` (
`VARIABLE_NAME` varchar(64) NOT NULL,
`VARIABLE_SOURCE` enum('COMPILED','GLOBAL','SERVER','EXPLICIT','EXTRA','USER','LOGIN','COMMAND_LINE','PERSISTED','DYNAMIC') DEFAULT NULL,
`VARIABLE_PATH` varchar(1024) DEFAULT NULL,
`MIN_VALUE` varchar(64) DEFAULT NULL,
`MAX_VALUE` varchar(64) DEFAULT NULL
) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

ほとんどのパラメーターがCOMPILEDになってるから、COMPILEDはコンパイル時に設定したデフォルトで、あと謎いのは USER, LOGIN くらいですかね。PERSISTED はまたあとで。

MySQL 8.0.0でSET PERSIST構文が出来て、my.cnfへの反映忘れが防げそう

$
0
0
MySQL 8.0.0時代のmy.cnfの探り方 の続き。

ここに /etc/my.cnf から読み込まれた innodb_buffer_pool_size = 128MB があるじゃろ? (AA略)


mysql80> SELECT variable_name, variable_source, variable_path, variable_value FROM performance_schema.variables_info JOIN performance_schema.global_variables USING(variable_name) WHERE variable_name = 'innodb_buffer_pool_size';
+-------------------------+-----------------+---------------+----------------+
| variable_name | variable_source | variable_path | variable_value |
+-------------------------+-----------------+---------------+----------------+
| innodb_buffer_pool_size | GLOBAL | /etc/my.cnf | 134217728 |
+-------------------------+-----------------+---------------+----------------+
1 row in set (0.01 sec)

これを


mysql80> SET PERSIST innodb_buffer_pool_size = 256 * 1024 * 1024;
Query OK, 0 rows affected (0.00 sec)

mysql80> SELECT variable_name, variable_source, variable_path, variable_value FROM performance_schema.variables_info JOIN performance_schema.global_variables USING(variable_name) WHERE variable_name = 'innodb_buffer_pool_size';
+-------------------------+-----------------+---------------+----------------+
| variable_name | variable_source | variable_path | variable_value |
+-------------------------+-----------------+---------------+----------------+
| innodb_buffer_pool_size | DYNAMIC | | 268435456 |
+-------------------------+-----------------+---------------+----------------+
1 row in set (0.00 sec)

こうじゃ。

( ゚д゚) ・・・

(つд⊂)ゴシゴシ

(;゚д゚) ・・・

(つд⊂)ゴシゴシゴシ
_, ._
(;゚ Д゚) …!?


_人人人人人人人_
> SET PERSIST <
 ̄Y^Y^Y^Y^Y^Y^Y^ ̄


ではmysqldを再起動して、


mysql80> SELECT variable_name, variable_source, variable_path, variable_value FROM performance_schema.variables_info JOIN performance_schema.global_variables USING(variable_name) WHERE variable_name = 'innodb_buffer_pool_size';
+-------------------------+-----------------+---------------------------------------+----------------+
| variable_name | variable_source | variable_path | variable_value |
+-------------------------+-----------------+---------------------------------------+----------------+
| innodb_buffer_pool_size | PERSISTED | /usr/mysql/8.0.0/data/mysqld-auto.cnf | 134217728 |
+-------------------------+-----------------+---------------------------------------+----------------+
1 row in set (0.00 sec)

$ cat /usr/mysql/8.0.0/data/mysqld-auto.cnf
{ "mysql_server": {"innodb_buffer_pool_size": "134217728" } }

え…書き換わってないじゃんダメじゃん。。

バグ(だと思う)で、innodb_buffer_pool_sizeだけはSET PERSISTで指定した値じゃなくて、SET PERSISTで指定する **前の** 値が保存されちゃってるぽい。
他のサーバー変数はイケた。

MySQL Bugs: #82905: SET PERSIST stores previous value of innodb_buffer_pool_size to mysqld-auto.cnf


innodb_io_capacity_maxとかならこの通り。

mysql80> SET PERSIST innodb_io_capacity_max = 8000;
Query OK, 0 rows affected (0.00 sec)

$ cat /usr/mysql/8.0.0/data/mysqld-auto.cnf
{ "mysql_server": {"innodb_io_capacity_max": "8000" } }


なお、SET PERSISTできるのは当然ながら SET GLOBAL 可能なオプションだけ。

mysql80> SET PERSIST last_insert_id = 2;
ERROR 1228 (HY000): Variable 'last_insert_id' is a SESSION variable and can't be used with SET GLOBAL


ところで、セッションスコープしかない変数をを手でmysqld-auto.cnfに書いたら、mysqldが異常終了じゃなくてクラッシュなさるようになった。。
(存在しない変数ならワーニングで無視してくれるんだけど、存在してかつセッションスコープしかないやつだと落ちる。。)

MySQL 8.0.0で追加されたROLEの仕組み

$
0
0
正直なんの情報もなくてすごく困ったんだけど、何故か自分のブログ記事に助けられた。

日々の覚書: MariaDB 10.0.5で実装されたROLEを試す


ほぼこの時と同じ。MariaDB 10.0の時はロールを割り当てるユーザーが存在しなくても割り当てられたけど、MySQL 8.0は先にCREATE USERしておかないと割り当てられなかったことくらい。

mysql80> CREATE ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

mysql80> GRANT SELECT ON mysql.* TO sys_select;
Query OK, 0 rows affected (0.00 sec)

mysql80> SELECT * FROM mysql.user WHERE user = 'sys_select'\G
*************************** 1. row ***************************
Host: %
User: sys_select
Select_priv: N
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
Process_priv: N
File_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Show_db_priv: N
Super_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Execute_priv: N
Repl_slave_priv: N
Repl_client_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Create_user_priv: N
Event_priv: N
Trigger_priv: N
Create_tablespace_priv: N
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin: mysql_native_password
authentication_string:
password_expired: Y
password_last_changed: 2016-09-05 11:55:04
password_lifetime: NULL
account_locked: Y
Create_role_priv: N
Drop_role_priv: N
1 row in set (0.00 sec)

MariaDB 10.0では is_role なるカラムでロールかどうかを識別していたけど、MySQL 8.0にはそれっぽいカラムはなさげ。account_lockedで代用している気配。


mysql80> GRANT sys_select TO yoku0825;
Query OK, 0 rows affected (0.00 sec)

mysql80> SELECT * FROM default_roles;
Empty set (0.00 sec)

mysql80> SELECT * FROM role_edges;
+-----------+------------+---------+----------+-------------------+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+-----------+------------+---------+----------+-------------------+
| % | sys_select | % | yoku0825 | N |
+-----------+------------+---------+----------+-------------------+
1 row in set (0.00 sec)

ロールのマッピングはmysql.role_edgesテーブルに記録される。


$ mysql80 -uyoku0825

mysql80> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| yoku0825@% |
+----------------+
1 row in set (0.00 sec)

mysql80> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| NONE |
+----------------+
1 row in set (0.00 sec)

mysql80> SHOW GRANTS;
+------------------------------------------+
| Grants for yoku0825@% |
+------------------------------------------+
| GRANT USAGE ON *.* TO `yoku0825`@`%` |
| GRANT `sys_select`@`%` TO `yoku0825`@`%` |
+------------------------------------------+
2 rows in set (0.00 sec)

mysql80> SELECT user, host FROM mysql.user;
ERROR 1142 (42000): SELECT command denied to user 'yoku0825'@'localhost' for table 'user'

mysql80> SET ROLE sys_select;
Query OK, 0 rows affected (0.00 sec)

mysql80> SELECT current_role();
+------------------+
| current_role() |
+------------------+
| `sys_select`@`%` |
+------------------+
1 row in set (0.00 sec)

mysql80> SELECT user, host FROM mysql.user;
+------------+-----------+
| user | host |
+------------+-----------+
| sys_select | % |
| yoku0825 | % |
| mysql.sys | localhost |
| root | localhost |
+------------+-----------+
4 rows in set (0.00 sec)

まるっきり MariaDBのときと同じで助かるというか捗るというか。

MariaDBは10.1からとされていた(10.1使ってないから本当にされたのか知らない。。)デフォルトロールも実装されている。
勘に任せてALTER USERしてみた。


mysql80> ALTER USER yoku0825 DEFAULT ROLE sys_select;
Query OK, 0 rows affected (0.01 sec)

mysql80> SELECT * FROM default_roles;
+------+----------+-------------------+-------------------+
| HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+------+----------+-------------------+-------------------+
| % | yoku0825 | % | sys_select |
+------+----------+-------------------+-------------------+
1 row in set (0.00 sec)

$ mysql80 -uyoku0825
mysql80> SELECT current_role();
+------------------+
| current_role() |
+------------------+
| `sys_select`@`%` |
+------------------+
1 row in set (0.00 sec)

なるほど大正解。しかしこれ、ユーザーアカウントとROLEを区別してないってことは、もしかして逆もできるのかしら。


mysql80> GRANT yoku0825 TO sys_select;
Query OK, 0 rows affected (0.01 sec)

mysql80> SELECT * FROM role_edges;
+-----------+------------+---------+------------+-------------------+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+-----------+------------+---------+------------+-------------------+
| % | sys_select | % | yoku0825 | N |
| % | yoku0825 | % | sys_select | N |
+-----------+------------+---------+------------+-------------------+
2 rows in set (0.00 sec)

( д ) ゚ ゚ やっぱりできた
アカウント同士でも試してみたけど


mysql80> GRANT root@localhost TO yoku0825;
Query OK, 0 rows affected (0.00 sec)

$ mysql80 -uyoku0825
mysql80> SET ROLE root@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql80> SET GLOBAL innodb_buffer_pool_dump_now= 1;
Query OK, 0 rows affected (0.00 sec)

おおおおおお…ユーザーとロールは区別した方がいいと思うんだけど、設定次第でこうも出来ると…。
ロール機能自体はウェルカムですねべんり。

MySQL 8.0.0のmysqlコマンドラインクライアントでは `--ssl` オプションの名前が変わった

$
0
0
実は(?) GA後の MySQL 5.7.11でdeprecatedになっていたヤーツ。

The client-side --ssl option is deprecated as of MySQL 5.7.11 and is removed in MySQL 8.0. For client programs, it is preferable to use --ssl-mode instead:
Use --ssl-mode=REQUIRED instead of --ssl=1 or --enable-ssl.
Use --ssl-mode=DISABLED instead of --ssl=0, --skip-ssl, or --disable-ssl.
No explicit --ssl-mode option is equivalent to no explicit --ssl option.
The server-side --ssl option is not deprecated.

MySQL :: MySQL 5.7 Reference Manual :: 7.4.5 Command Options for Secure Connections

結構盛大に変わる。。


$ mysql80 --ssl
mysql: [ERROR] unknown option '--ssl'

$ mysql80 --help | grep ssl
--ssl-mode=name SSL connection mode.
--ssl-ca=name CA file in PEM format.
--ssl-capath=name CA directory.
--ssl-cert=name X509 cert in PEM format.
--ssl-cipher=name SSL cipher to use.
--ssl-key=name X509 key in PEM format.
--ssl-crl=name Certificate revocation list.
--ssl-crlpath=name Certificate revocation list path.
ssl-ca (No default value)
ssl-capath (No default value)
ssl-cert (No default value)
ssl-cipher (No default value)
ssl-key (No default value)
ssl-crl (No default value)
ssl-crlpath (No default value)

`--help` が不完全な気がする(デフォルトを出す方に載ってない)
あと、取り得る値とかも出してくれないのでちょっと不親切。。
引用の通り、今までの `--ssl` と同じように使うには `--ssl-mode=REQUIRED` で良いみたい。

ついでに気づいちゃったんだけど、


$ mysql80 -h127.0.0.1 -P64057 --ssl-mode=required -sse "SHOW SESSION STATUS LIKE 'Ssl_cipher'"
Ssl_cipher DHE-RSA-AES256-SHA

$ mysql80 -h127.0.0.1 -P64057 --ssl-mode=req -sse "SHOW SESSION STATUS LIKE 'Ssl_cipher'"
Ssl_cipher DHE-RSA-AES256-SHA

$ mysql80 -h127.0.0.1 -P64057 --ssl-mode=r -sse "SHOW SESSION STATUS LIKE 'Ssl_cipher'"
Ssl_cipher DHE-RSA-AES256-SHA

$ mysql80 -h127.0.0.1 -P64057 --ssl-mode=v -sse "SHOW SESSION STATUS LIKE 'Ssl_cipher'" ### vだけだとverify_caとverify_identityの両方があり得るのでエラー
Unknown option to ssl-mode: v
Alternatives are: 'DISABLED','PREFERRED','REQUIRED','VERIFY_CA','VERIFY_IDENTITY'

$ mysql80 -h127.0.0.1 -P64057 --ssl-mode=verify_i -sse "SHOW SESSION STATUS LIKE 'Ssl_cipher'" ### verify_iでverify_identity相当
ERROR 2026 (HY000): SSL connection error: SSL certificate validation failure

$ mysql80 -h127.0.0.1 -P64057 --ssl-mode=verify_c -sse "SHOW SESSION STATUS LIKE 'Ssl_cipher'" ### verify_cでverify_ca相当
Ssl_cipher DHE-RSA-AES256-SHA

あ、あー、これ前方一致で補完するやつだ!
5.7.14の時点でそうだった。

MySQL 8.0.0現在の文字コードについて

$
0
0
Planning the defaults for MySQL 5.8 | MySQL Server Blog の時点で

In addition to utf8mb4, we are also considering switching the default collation to be utf8mb4_unicode_520_ci.

と地雷宣言が為されていた文字コード問題。
(utf8mb4_unicode_520_ci は🍣と🍺を区別するけど、ハハとパパを区別してくれないヤーツ)

|                    | utf8mb4_bin | utf8mb4_general_ci | utf8mb4_unicode_ci | utf8mb4_unicode_520_ci|
|--------------------|-------------|--------------------|--------------------|-----------------------|
| Hiragana-Katakana | cs (unkind) | cs (unkind) | ci (good) | ci(good) |
| Youon | cs (good) | cs (good) | ci (critical) | ci(critical) |
| Dakuten-Handakuten | cs (good) | cs (good) | ci (critical) | ci(critical) |
| Wide-Narrow | cs (unkind) | cs (unkind) | ci (good) | ci(good) |
| Sushi-Beer | cs | ci | ci | cs |

MySQL Bugs: #79977: utf8mb4_unicode_520_ci don't make sense for Japanese FTS


かみぽさんが「せっかくActiveRecordで直したのに今度はMySQLでデフォルトになるん…」みたいなことを言っていたやつ。

取り敢えず手元の8.0.0現在では、

$ bin/mysqld --no-defaults --help --verbose | egrep '(character-set|collation)-server'
mysqld: Can't change dir to '/usr/local/mysql/data/' (Errcode: 2 - No such file or directory)
2016-09-05T04:05:23.602489Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000)
2016-09-05T04:05:23.602584Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000)
2016-09-05T04:05:23.602946Z 0 [ERROR] Can't find error-message file '/usr/local/mysql/share/errmsg.sys'. Check error-message file location and 'lc-messages-dir' configuration directive.
-C, --character-set-server=name
--collation-server=name
character-set-server latin1
collation-server latin1_swedish_ci

文字コード/照合順序は5.7と同じくlatin1/latin1_swedish_ci。
その一方で、


mysql80> SHOW COLLATION LIKE 'utf8mb4%';
+----------------------------+---------+-----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+----------------------------+---------+-----+---------+----------+---------+
| utf8mb4_0900_ai_ci | utf8mb4 | 255 | | Yes | 8 |
| utf8mb4_bin | utf8mb4 | 46 | | Yes | 1 |
| utf8mb4_croatian_ci | utf8mb4 | 245 | | Yes | 8 |
| utf8mb4_cs_0900_ai_ci | utf8mb4 | 266 | | Yes | 8 |
| utf8mb4_czech_ci | utf8mb4 | 234 | | Yes | 8 |
| utf8mb4_danish_ci | utf8mb4 | 235 | | Yes | 8 |
| utf8mb4_da_0900_ai_ci | utf8mb4 | 267 | | Yes | 8 |
| utf8mb4_de_pb_0900_ai_ci | utf8mb4 | 256 | | Yes | 8 |
| utf8mb4_eo_0900_ai_ci | utf8mb4 | 273 | | Yes | 8 |
| utf8mb4_esperanto_ci | utf8mb4 | 241 | | Yes | 8 |
| utf8mb4_estonian_ci | utf8mb4 | 230 | | Yes | 8 |
| utf8mb4_es_0900_ai_ci | utf8mb4 | 263 | | Yes | 8 |
| utf8mb4_es_trad_0900_ai_ci | utf8mb4 | 270 | | Yes | 8 |
| utf8mb4_et_0900_ai_ci | utf8mb4 | 262 | | Yes | 8 |
| utf8mb4_general_ci | utf8mb4 | 45 | Yes | Yes | 1 |
| utf8mb4_german2_ci | utf8mb4 | 244 | | Yes | 8 |
| utf8mb4_hr_0900_ai_ci | utf8mb4 | 275 | | Yes | 8 |
| utf8mb4_hungarian_ci | utf8mb4 | 242 | | Yes | 8 |
| utf8mb4_hu_0900_ai_ci | utf8mb4 | 274 | | Yes | 8 |
| utf8mb4_icelandic_ci | utf8mb4 | 225 | | Yes | 8 |
| utf8mb4_is_0900_ai_ci | utf8mb4 | 257 | | Yes | 8 |
| utf8mb4_latvian_ci | utf8mb4 | 226 | | Yes | 8 |
| utf8mb4_la_0900_ai_ci | utf8mb4 | 271 | | Yes | 8 |
| utf8mb4_lithuanian_ci | utf8mb4 | 236 | | Yes | 8 |
| utf8mb4_lt_0900_ai_ci | utf8mb4 | 268 | | Yes | 8 |
| utf8mb4_lv_0900_ai_ci | utf8mb4 | 258 | | Yes | 8 |
| utf8mb4_persian_ci | utf8mb4 | 240 | | Yes | 8 |
| utf8mb4_pl_0900_ai_ci | utf8mb4 | 261 | | Yes | 8 |
| utf8mb4_polish_ci | utf8mb4 | 229 | | Yes | 8 |
| utf8mb4_romanian_ci | utf8mb4 | 227 | | Yes | 8 |
| utf8mb4_roman_ci | utf8mb4 | 239 | | Yes | 8 |
| utf8mb4_ro_0900_ai_ci | utf8mb4 | 259 | | Yes | 8 |
| utf8mb4_sinhala_ci | utf8mb4 | 243 | | Yes | 8 |
| utf8mb4_sk_0900_ai_ci | utf8mb4 | 269 | | Yes | 8 |
| utf8mb4_slovak_ci | utf8mb4 | 237 | | Yes | 8 |
| utf8mb4_slovenian_ci | utf8mb4 | 228 | | Yes | 8 |
| utf8mb4_sl_0900_ai_ci | utf8mb4 | 260 | | Yes | 8 |
| utf8mb4_spanish2_ci | utf8mb4 | 238 | | Yes | 8 |
| utf8mb4_spanish_ci | utf8mb4 | 231 | | Yes | 8 |
| utf8mb4_sv_0900_ai_ci | utf8mb4 | 264 | | Yes | 8 |
| utf8mb4_swedish_ci | utf8mb4 | 232 | | Yes | 8 |
| utf8mb4_tr_0900_ai_ci | utf8mb4 | 265 | | Yes | 8 |
| utf8mb4_turkish_ci | utf8mb4 | 233 | | Yes | 8 |
| utf8mb4_unicode_520_ci | utf8mb4 | 246 | | Yes | 8 |
| utf8mb4_unicode_ci | utf8mb4 | 224 | | Yes | 8 |
| utf8mb4_vietnamese_ci | utf8mb4 | 247 | | Yes | 8 |
| utf8mb4_vi_0900_ai_ci | utf8mb4 | 277 | | Yes | 8 |
+----------------------------+---------+-----+---------+----------+---------+
47 rows in set (0.00 sec)

utf8mb4の照合順序は結構増えてる。0900_ai_ciはUnicode 9.0.0ベースのAccentInsensitiveだろうか。どうも各言語ごとに0900_ai_ciが生えるような形をしてる。

MySQL :: WL#9108: Add language specific case insensitive collations of utf8mb4


「ai_ciが追加されるからunicode_ciはAccentSensitiveでいいよね」って流れになってもらわないと、このままutf8mb4_unicode_ciがデフォルトになる ( Planning the defaults for MySQL 5.8 | MySQL Server Blog ) のはつらい。WL#9108見ても、japanese_ciを作る予定はなさそうだし(なさそうだしそもそも、罠いのが **暗黙のデフォルトになる** のが嫌なのだ俺は。。)

mysql80> SELECT 'ハハ' = 'パパ' COLLATE utf8mb4_unicode_ci;
+------------------------------------------------+
| 'ハハ' = 'パパ' COLLATE utf8mb4_unicode_ci |
+------------------------------------------------+
| 1 |
+------------------------------------------------+
1 row in set (0.00 sec)

mysql80> SELECT 'ハハ' = 'パパ' COLLATE utf8mb4_general_ci;
+------------------------------------------------+
| 'ハハ' = 'パパ' COLLATE utf8mb4_general_ci |
+------------------------------------------------+
| 0 |
+------------------------------------------------+
1 row in set (0.00 sec)

mysql80> SELECT 'ハハ' = 'パパ' COLLATE utf8mb4_unicode_520_ci;
+----------------------------------------------------+
| 'ハハ' = 'パパ' COLLATE utf8mb4_unicode_520_ci |
+----------------------------------------------------+
| 1 |
+----------------------------------------------------+
1 row in set (0.00 sec)



今後どうなるのか(特に 暗黙のデフォルトが 何になるのか)注目しておいた方がよさげ。
Viewing all 581 articles
Browse latest View live