173
MySQL 5.7にやられないためにおぼ えておいてほしいこと 安⼼してください。履いてますよ。 2015/10/03 yoku0825 phpcon 2015

MySQL 5.7にやられないためにおぼえておいてほしいこと

  • Upload
    yoku0825

  • View
    60.543

  • Download
    10

Embed Size (px)

Citation preview

Page 1: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQL 5.7にやられないためにおぼえておいてほしいこと安⼼してください。履いてますよ。

2015/10/03

yoku0825phpcon 2015

Page 2: MySQL 5.7にやられないためにおぼえておいてほしいこと

免責事項

MySQLの話をしますPHPの話は⼀切出てきません個⼈の⾒解であり、所属する組織または所属しない組織の意⾒を代表するわけがありませんアップデートはありますが、過去のスライドと内容カブってます。今から備えるMySQL最新バージョン5.7-MySQL 5.7の罠があなたを狙っている-光のMySQL 5.7-資料は公開しますので、 となりのセッションに移動するなら今です

-

1/172

Page 3: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQL 5.7にどんなイメージを持っていますか︖

光︖闇︖まっさら︖

2/172

Page 4: MySQL 5.7にやられないためにおぼえておいてほしいこと

なお、MySQL 5.7の闇の正体はこんな感じです

https://twitter.com/tmtms/status/636104524164296708

3/172

Page 5: MySQL 5.7にやられないためにおぼえておいてほしいこと

なお、MySQL 5.7の闇の正体はこんな感じです

MySQL を好きな⼈が、MySQLのちょっと変なところ

を、少しばかり強調しておもしろおかしく伝えている⾯

はあるので、その変な部分だけが⼀⼈歩きして多くの⼈

に理解されてしまうことを危惧はしていますが

http://sakaik.hateblo.jp/entry/20150823/yapc2015

4/172

Page 6: MySQL 5.7にやられないためにおぼえておいてほしいこと

お世辞抜きでMySQL 5.7楽しいですよ :)

お世辞抜きで地雷も多いけど

5/172

Page 7: MySQL 5.7にやられないためにおぼえておいてほしいこと

ところで皆様お気付きでしょうか

6/172

Page 8: MySQL 5.7にやられないためにおぼえておいてほしいこと

このスライドなんと表紙を抜いて171枚あります

7/172

Page 9: MySQL 5.7にやられないためにおぼえておいてほしいこと

1枚10秒です

8/172

Page 10: MySQL 5.7にやられないためにおぼえておいてほしいこと

資料はslideshareで公開します

ってか既にしてます http://www.slideshare.net/yoku0825/

mysql-57-53449734 9/172

Page 11: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQL 5.7とは

2年半ぶりの メジャーバージョンアップPHPさんは5.6の次を7にしましたが、MySQLは5.6 => 5.7 => 次は5.8っぽいです

-

新しい機能を使わないぶんには 、 “まあまあ良いMySQL”バギーってほどバギーではない( バグの流量を⾒る限り、 今のところは )

-

罠オプションがいっぱい5.5やそれ以前の情報をアテにして本番に突っ込むと痛い目を⾒る

-

それでもなお、アップグレードしたいバージョン新しい機能がてんこもり-

10/172

Page 12: MySQL 5.7にやられないためにおぼえておいてほしいこと

\こんにちは/

yoku0825@とある企業のDBAオラクれない-ポスグれない-マイエスキューエる-

家に帰ると妻の夫-せがれの⽗-ムスメの⽗-

Twitter: @yoku0825Blog: ⽇々の覚書MyNA ML: ⽇本MySQLユーザ会

11/172

Page 13: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQLの系譜

2008/11 MySQL 5.12010/12 MySQL 5.52013/02 MySQL 5.62015/xx MySQL 5.7

2015年8⽉に5.7.8-rc2(Realease Candidate, リリース候補版)

-

5.6のGA時点で「Oracleとしては18〜24か⽉で次のメジャーバージョンをリリースする予定」と⾔っていたので、ズレこんでいるのは確か

-

12/172

Page 14: MySQL 5.7にやられないためにおぼえておいてほしいこと

本編に⼊る前に、過去のスライドを⾒てくれた⽅へのお知らせです

show_compatibility_56= OFF問題performance_schema.{session|global}_{status|

variables}はSEELCT権限なくてもSELECTできるようになりました。

-

performance_schema= OFFの時にはshow_compatibility_56= OFFでもinformation̲schemaを⾒に⾏くようになりました。

-

13/172

Page 15: MySQL 5.7にやられないためにおぼえておいてほしいこと

updated at 2016/01/13

MySQL 5.7.11でdefault̲password̲lifetimeの暗黙のデフォルトは0になりました。それ以降のバージョンであれば360⽇におびえる必要はありません。⽇々の覚書: MySQL 5.7.11でdefault̲password̲lifetimeのデフォルトが0になるらしい︕

-

14/172

Page 16: MySQL 5.7にやられないためにおぼえておいてほしいこと

最低限これだけは知ってほしい5.7

16桁ハッシュのパスワードの廃⽌default̲password̲lifetimesql̲modeのデフォルト値変更log̲error̲verbosity vs. log̲warningsテンポラリーテーブルがInnoDBに

15/172

Page 17: MySQL 5.7にやられないためにおぼえておいてほしいこと

⼀応知っておいてほしい5.7

mysql.user.passwordカラムの廃⽌認証周りの構⽂の変更secure̲file̲privlog̲timestampsmysql̲install̲dbmysqld –initializeInnoDBバッファプールの暖気がデフォルトでONにbinlog̲formatのデフォルト変更rpmパッケージではvalidate̲passwordプラグインがデフォルトで有効innodb̲default̲row̲formatの注意

16/172

Page 18: MySQL 5.7にやられないためにおぼえておいてほしいこと

これを知っているとちょっと得する5.7

sysスキーマGTIDのオンライン有効化がサポートMySQLネイティブの全⽂検索が⽇本語対応InnoDB UNDO logのシュリンクサーバーサイドステートメントタイムアウトgenerated columnで関数インデックスSSL関連いろいろJSONデータ型マルチスレッドスレーブの機能向上

17/172

Page 19: MySQL 5.7にやられないためにおぼえておいてほしいこと

知っておいても損はない5.7

innodb̲buffer̲pool̲sizeのオンライン変更がサポートsync̲binlogのデフォルト変更マルチソースレプリケーションダイナミックレプリケーションフィルターInnoDBの新しい圧縮1テーブルに複数トリガー設定可能mysql p umplog-syslogオフラインモードGET̲LOCK関数で複数のロックを取れるQuery Rewrite Plugin

18/172

Page 20: MySQL 5.7にやられないためにおぼえておいてほしいこと

参考URL

MySQL :: MySQL 5.7 Reference Manual :: 1.4 What Is New in MySQL 5.7MySQL :: MySQL 5.7 Release NotesComplete list of new features in MySQL 5.7中の⼈が作った「新機能完全リスト」-

MySQL 5.7の新機能完全リスト | Yakst↑をがんばって⽇本語に訳したヤーツ-昨⽇アップデートした-

⽇々の覚書: 5.7

19/172

Page 21: MySQL 5.7にやられないためにおぼえておいてほしいこと

最低限これだけは知ってほしい5.7⼀応知っておいてほしい5.7これを知っているとちょっと得する5.7知っておいても損はない5.7

20/172

Page 22: MySQL 5.7にやられないためにおぼえておいてほしいこと

16桁ハッシュのパスワードの廃⽌

old̲passwords, skip̲secure̲authというオプションに⼼当たりはありませんか︖

16桁ハッシュのパスワードでもログインできるようにするオプション

-

MySQL 4.1(10年前)に非推奨MySQL 5.6でもデフォルトではログインできないなど風当たりが強くなり(16桁ハッシュのユーザーが存在する状態でアップグレードした場合のみ16桁ハッシュのユーザーが存在)MySQL 5.7からは全く使えなくなります

21/172

Page 23: MySQL 5.7にやられないためにおぼえておいてほしいこと

16桁ハッシュのパスワード #とは

対義語は41桁ハッシュ

mysql55> SELECT user, host, password FROM user WHERE user <> 'root';+--------------+------+-------------------------------------------+| user | host | password |+--------------+------+-------------------------------------------+| new_password | % | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 || old_password | % | 378b243e220ca493 |+--------------+------+-------------------------------------------+2 rows in set (0.00 sec)

22/172

Page 24: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQL 5.6へのアップグレード

ワーニングは出たけど、アップグレードはできた。ユーザー情報としては残ってるけど、実際にログインするにはskip̲secure̲authを駆使しないといけない。

$ /usr/mysql/5.6.23/bin/mysql_upgrade..Warning 1642 Pre-4.1 password hash found. It is deprecated and will be removed in a future release. Please upgrade it to a new format...

mysql56> SELECT user, host, password FROM user WHERE user <> 'root';+--------------+------+-------------------------------------------+| user | host | password |+--------------+------+-------------------------------------------+| new_password | % | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 || old_password | % | 378b243e220ca493 |+--------------+------+-------------------------------------------+2 rows in set (0.00 sec)

23/172

Page 25: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQL 5.7へのアップグレード

ワーニングなのは相変わらずだけど、ちゃんと移⾏されてない。

$ /usr/mysql/5.7.7/bin/mysql_upgrade -S /usr/mysql/5.7.7/data/mysql.sock -uroot..mysql_upgrade: [Warning] 1642: Pre-4.1 password hash found. It is deprecated and will be removed in a future release. Please upgrade it to a new format...

mysql57> SELECT user, host, authentication_string FROM user WHERE user <> 'root';+--------------+------+-------------------------------------------+| user | host | authentication_string |+--------------+------+-------------------------------------------+| new_password | % | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 || old_password | % | NULL |+--------------+------+-------------------------------------------+2 rows in set (0.00 sec)

$ mysql57 -uold_password -ptestERROR 1524 (HY000): Plugin 'mysql_old_password' is not loaded

24/172

Page 26: MySQL 5.7にやられないためにおぼえておいてほしいこと

default̲password̲lifetime

暗黙のデフォルトで360に設定されており、password̲last̲changedから360⽇以上経過するとそのアカウントでログインできなくなる。吊るしのまま使うとMySQL 5.7へのバージョンアップから360⽇後に突然アプリケーションからつなげなくなるよ。MySQL 5.7.11から先はデフォルトが0になっているのでこの罠はない 、 それ以前の場合は注意。

25/172

Page 27: MySQL 5.7にやられないためにおぼえておいてほしいこと

default̲password̲lifetime

mysql57> SELECT user, host, password_expired, password_last_changed, password_lifetime, account_locked FROM mysql.user WHERE user= 'yoku0825'\G*************************** 1. row *************************** user: yoku0825 host: % password_expired: Npassword_last_changed: 1999-07-31 00:00:00 password_lifetime: NULL account_locked: N1 row in set (0.00 sec)

mysql57> FLUSH PRIVILEGES;Query OK, 0 rows affected (0.04 sec)

$ mysql57 -uyoku0825 -p -e "SELECT current_user()"Enter password:ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.

26/172

Page 28: MySQL 5.7にやられないためにおぼえておいてほしいこと

回避⽅法

my.cnfの[mysqld]セクションにdefault_password_lifetime= 0

SET GLOBALでオンライン変更も可能。-0を指定することで、default̲password̲lifetimeを利⽤しなくなる。全くEXPIREされなくなるのが嫌なら、⼤きな値にしても良い。

-

0より⼤きな値を指定する場合、単位は”⽇”-

27/172

Page 29: MySQL 5.7にやられないためにおぼえておいてほしいこと

回避⽅法

mysql57> SET GLOBAL default_password_lifetime= 0;Query OK, 0 rows affected (0.00 sec)

$ vim /etc/my.cnf[mysqld]default_password_lifetime= 0

28/172

Page 30: MySQL 5.7にやられないためにおぼえておいてほしいこと

sql̲modeのデフォルト値変更

5.5まで ““(指定なし)5.6 “NO̲ENGINE̲SUBSTITUTION”(存在しないストレージエンジンを指定してCREATE TABLEするとエラーになる)場合によっては/usr/my.cnfの罠で”STRICT̲TRANS̲TABLES,NO̲ENGINE̲SUBSTITUTION”

-

29/172

Page 31: MySQL 5.7にやられないためにおぼえておいてほしいこと

5.7のデフォルトのsql̲mode

ONLY̲FULL̲GROUP̲BYSTRICT̲TRANS̲TABLESNO̲ZERO̲IN̲DATENO̲ZERO̲DATEERROR̲FOR̲DIVISION̲BY̲ZERONO̲AUTO̲CREATE̲USERNO̲ENGINE̲SUBSTITUTIONsql̲modeの変更は5.6でもエミュレートできるので、デフォルトのまま⾏くなら5.6でも確認しておける

30/172

Page 32: MySQL 5.7にやられないためにおぼえておいてほしいこと

圧倒的ではないか

31/172

Page 33: MySQL 5.7にやられないためにおぼえておいてほしいこと

ONLY̲FULL̲GROUP̲BY

何故MySQLは今までこんなクエリーを許していたのかよくわからない感じのものが(valとnumが⼀意に紐づくかどうかがDBMSには判断できないはず)

mysql56> SELECT val, num, COUNT(*) AS c FROM t1 GROUP BY val ORDER BY c DESC LIMIT 5;+--------------------------------------+-----+---+| val | num | c |+--------------------------------------+-----+---+| 人類はストラトス | 16 | 8 || 僕は友達が巨人 | 333 | 7 || アウトブレイクストラトス | 46 | 7 || さんをつけろよマスター | 39 | 7 || 電波女と衰退しました | 140 | 7 |+--------------------------------------+-----+---+5 rows in set (0.04 sec)

32/172

Page 34: MySQL 5.7にやられないためにおぼえておいてほしいこと

ONLY̲FULL̲GROUP̲BY

ちゃんとエラーになる。

mysql56> SET sql_mode= CONCAT_WS(',', @@sql_mode, 'ONLY_FULL_GROUP_BY');Query OK, 0 rows affected (0.00 sec)

mysql56> SELECT val, num, COUNT(*) AS c FROM t1 GROUP BY val ORDER BY c DESC LIMIT 5;ERROR 1055 (42000): 'd1.t1.num' isn't in GROUP BY

33/172

Page 35: MySQL 5.7にやられないためにおぼえておいてほしいこと

ONLY̲FULL̲GROUP̲BY

今までと同じ、「何が返ってくるかわからなくてもいいよ」を表現するためのANY̲VALUE関数が追加された。

mysql57> SELECT val, ANY_VALUE(num), COUNT(*) AS c FROM t1 GROUP BY val ORDER BY c DESC LIMIT 5;+--------------------------------------+----------------+---+| val | ANY_VALUE(num) | c |+--------------------------------------+----------------+---+| 人類はストラトス | 16 | 8 || 僕は友達が巨人 | 333 | 7 || アウトブレイクストラトス | 46 | 7 || さんをつけろよマスター | 39 | 7 || 電波女と衰退しました | 140 | 7 |+--------------------------------------+----------------+---+5 rows in set (0.01 sec)

34/172

Page 36: MySQL 5.7にやられないためにおぼえておいてほしいこと

STRICT̲TRANS̲TABLES

⼀部のワーニングをワーニング(警告だけど成功)ではなくエラーにする。⼀般的には「勝⼿に桁を切り詰める」「勝⼿に⽂字列型を整数型にキャストする」がエラーになるやつ。

35/172

Page 37: MySQL 5.7にやられないためにおぼえておいてほしいこと

STRICT̲TRANS̲TABLES

mysql56> INSERT INTO t1 VALUES (1, REPEAT('a', 33));Query OK, 1 row affected, 1 warning (0.01 sec)

mysql56> SHOW WARNINGS;+---------+------+------------------------------------------+| Level | Code | Message |+---------+------+------------------------------------------+| Warning | 1265 | Data truncated for column 'val' at row 1 |+---------+------+------------------------------------------+1 row in set (0.00 sec)

mysql56> SET sql_mode= CONCAT_WS(',', @@sql_mode, 'STRICT_TRANS_TABLES'Query OK, 0 rows affected (0.02 sec)

mysql56> INSERT INTO t1 VALUES (1, REPEAT('a', 33));ERROR 1406 (22001): Data too long for column 'val' at row 1

36/172

Page 38: MySQL 5.7にやられないためにおぼえておいてほしいこと

NO̲ZERO̲IN̲DATE

sql_mode= NO_ZERO_DATEとは別物。DATE, DATETIME型の「⽉」「⽇」に0を⼊れようとすると、ワーニングを発して ʻ0000-00-00 00:00:00ʼに切り詰める 。

37/172

Page 39: MySQL 5.7にやられないためにおぼえておいてほしいこと

NO̲ZERO̲IN̲DATE

mysql56> SET sql_mode= CONCAT_WS(',', @@sql_mode, 'NO_ZERO_IN_DATE');Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql56> INSERT INTO t1 VALUES ('2015-00-31');Query OK, 1 row affected, 1 warning (0.01 sec)

mysql56> SHOW WARNINGS;+---------+------+---------------------------------------------+| Level | Code | Message |+---------+------+---------------------------------------------+| Warning | 1264 | Out of range value for column 'dt' at row 1 |+---------+------+---------------------------------------------+1 row in set (0.00 sec)

mysql56> SELECT * FROM t1;+---------------------+| dt |+---------------------+| 0000-00-00 00:00:00 |+---------------------+1 row in set (0.00 sec)

38/172

Page 40: MySQL 5.7にやられないためにおぼえておいてほしいこと

NO̲ZERO̲IN̲DATE + strict̲mode

STRICT̲TRANS̲TABLESまたはSTRICT̲ALL̲TABLESと⼀緒に使うためのもの。

mysql56> SET sql_mode= CONCAT_WS(',', @@sql_mode, 'STRICT_TRANS_TABLES');Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql56> INSERT INTO t1 VALUES ('2015-00-31');ERROR 1292 (22007): Incorrect datetime value: '2015-00-31' for column 'dt' at row 1

39/172

Page 41: MySQL 5.7にやられないためにおぼえておいてほしいこと

NO̲ZERO̲DATE

DATE, DATETIME型にʼ0000-00-00ʼを⼊れようとするとワーニングにしてくれるもの。NO̲ZERO̲IN̲DATEと⼀緒で直接エラーではなくワーニングなので、strict̲modeと⼀緒に使う。

40/172

Page 42: MySQL 5.7にやられないためにおぼえておいてほしいこと

ERROR̲FOR̲DIVISION̲BY̲ZERO

未指定時は0で除算するとNULLになる

mysql56> INSERT INTO t2 VALUES (2/0);Query OK, 1 row affected (0.00 sec)

mysql56> SELECT * FROM t2;+------+| num |+------+| NULL |+------+1 row in set (0.00 sec)

41/172

Page 43: MySQL 5.7にやられないためにおぼえておいてほしいこと

ERROR̲FOR̲DIVISION̲BY̲ZERO

指定時は ワーニング になってNULLが⼊る。mysql56> SET sql_mode= CONCAT_WS(',', @@sql_mode, 'ERROR_FOR_DIVISION_BY_ZERO');Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql56> INSERT INTO t2 VALUES (2/0);Query OK, 1 row affected, 1 warning (0.01 sec)

mysql56> SHOW WARNINGS;+---------+------+---------------+| Level | Code | Message |+---------+------+---------------+| Warning | 1365 | Division by 0 |+---------+------+---------------+1 row in set (0.00 sec)

mysql56> SELECT * FROM t2;+------+| num |+------+| NULL || NULL |+------+2 rows in set (0.00 sec)

42/172

Page 44: MySQL 5.7にやられないためにおぼえておいてほしいこと

ERROR̲FOR̲DIVISION̲BY̲ZERO + strict̲mode

strict̲modeと合わせて初めてエラーになる。

mysql56> SELECT @@sql_mode;+------------------------------------------------+| @@sql_mode |+------------------------------------------------+| STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO |+------------------------------------------------+1 row in set (0.00 sec)

mysql56> INSERT INTO t2 VALUES (2/0);ERROR 1365 (22012): Division by 0

43/172

Page 45: MySQL 5.7にやられないためにおぼえておいてほしいこと

NO̲AUTO̲CREATE̲USER

パスワードなしのユーザーをCREATE USERせずに直接GRANTがワーニングになるのはコイツのせい。

mysql56> GRANT replication slave ON *.* TO u1;Query OK, 0 rows affected (0.00 sec)

mysql56> SET sql_mode= CONCAT_WS(',', @@sql_mode, 'NO_AUTO_CREATE_USER');Query OK, 0 rows affected (0.00 sec)

mysql56> GRANT replication slave ON *.* TO u2;ERROR 1133 (42000): Can't find any matching row in the user table

mysql56> CREATE USER u2;Query OK, 0 rows affected (0.00 sec)

mysql56> GRANT replication slave ON *.* TO u2;Query OK, 0 rows affected (0.00 sec)

44/172

Page 46: MySQL 5.7にやられないためにおぼえておいてほしいこと

sql̲modeが空でも多少の違いがあるっぽい

mysql56> CREATE TABLE t1 (num int default null, PRIMARY KEY(num));Query OK, 0 rows affected (0.16 sec)

mysql57> CREATE TABLE t1 (num int default null, PRIMARY KEY(num));ERROR 1171 (42000): All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead

MySQL 5.7.3 m13 does not allow DEFAULT NULL for primary key ・ Issue #13203 ・ rails/rails

45/172

Page 47: MySQL 5.7にやられないためにおぼえておいてほしいこと

log̲error̲verbosity vs. log̲warnings

今までのlog̲warningsはワーニング も 出⼒するイメージ5.6までの動作はこんな

sql̲print̲warning()の外側で判定されてるんだぜコイツ。。

-

value notes some warnings other warnings errors

log-warnings = 0

YES No Yes Yes

log-warnings >= 1

YES Yes Yes Yes

46/172

Page 48: MySQL 5.7にやられないためにおぼえておいてほしいこと

log̲error̲verbosity vs. log̲warnings

5.7のlog̲error̲verbosityはいわゆる普通のログレベルの制御。下⼿にlog̲warningsと⼲渉するため、意図しない値が設定されることがある。

log_warnings + 1の値が勝⼿にlog_error_verbosityにセットされる。log_warnings= 1が記述してあると、log_error_verbosity= 2(Noteを出⼒しない)になってしまうlog_warningsとlog_error_verbosityが混在していた場合、通常のオプションと同じく 後勝ち で設定される。

-

47/172

Page 49: MySQL 5.7にやられないためにおぼえておいてほしいこと

log̲error̲verbosity vs. log̲warnings

value notes warnings errors

log-warnings = 0log-error-verbosity = 1

No No Yes

log-warnings = 1log-error-verbosity = 2

No Yes Yes

log-warnings >= 2log-error-verbosity >= 3

Yes Yes Yes

MySQL Bugs: #74963: changes in 5.7.5 logging verbosity seem surprising and unexpected

48/172

Page 50: MySQL 5.7にやられないためにおぼえておいてほしいこと

テンポラリーテーブルがInnoDBに

CREATE TEMPORARY TABLE時のデフォルトはdefault̲tmp̲storage̲engine変数で制御(MySQL 5.6〜)暗黙のテンポラリーテーブル(Using temporary)はinternal̲tmp̲disk̲storage̲engine 変数の新設, 暗黙のデフォルトはInnoDBテンポラリーテーブルとして利⽤する場合、REDOログや排他ロックは必要ない(他のスレッドからそのテーブルは⾒えない, クラッシュ時にはクリアされる)その辺の処理をかっ⾶ばす 専⽤のibtmp1ファイル を作成する暗黙のデフォルトは innodb_temp_data_file_path= ibtmp1:12M:autoextend

-

49/172

Page 51: MySQL 5.7にやられないためにおぼえておいてほしいこと

テンポラリーテーブルがInnoDBに

ibdata1と同じく、データとインデックス, UNDOログが書き込まれるmysqldの再起動時に毎回再作成される, mysqldが再起動されるまでは再作成されない⼀度容量を確保してしまうと、mysqldを再起動するまでibtmp1は⼤きくなったまま

MyISAMなテンポラリーテーブルはDiskがあふれた場合にクエリーがエラーになってテンポラリーテーブル領域がクリアされた

-

50/172

Page 52: MySQL 5.7にやられないためにおぼえておいてほしいこと

テンポラリーテーブルがInnoDBに

MyISAMを使⽤した暗黙のテンポラリーテーブルがあふれた場合

mysql57> SELECT * FROM (SELECT * FROM t1 WHERE val LIKE 'abc%') AS t1, (SELECT * FROM t1 WHERE val LIKE 'def%') AS t2 ORDER BY t1.num;ERROR 126 (HY000): Incorrect key file for table '/tmp/#sql_2974_0.MYI'; try to repair it

$ tail error.log..2015-04-30T14:59:45.558360+09:00 87 [ERROR] /usr/mysql/5.7.7/bin/mysqld: Incorrect key file for table '/tmp/#sql_2974_0.MYI'; try to repair it2015-04-30T14:59:45.573411+09:00 87 [ERROR] Got an error from unknown thread, /home/yoku0825/mysql-5.7.7-rc/storage/myisam/mi_write.c:223

51/172

Page 53: MySQL 5.7にやられないためにおぼえておいてほしいこと

テンポラリーテーブルがInnoDBに

InnoDBを使⽤した暗黙のテンポラリーテーブルがあふれた場合

mysql57> SELECT * FROM (SELECT * FROM t1 WHERE val LIKE 'abc%') AS t1, (SELECT * FROM t1 WHERE val LIKE 'def%') AS t2 ORDER BY t1.num;ERROR 1114 (HY000): The table '/tmp/#sql_2974_0' is full

$ tail error.log..2015-04-30T15:04:22.549484+09:00 87 [ERROR] InnoDB: posix_fallocate(): Failed to preallocate data for file ./ibtmp1, desired size 67108864 bytes. Operating system error number 28. Check that the disk is not full or a disk quota exceeded. Make sure the file system supports this function. Some operating system error numbers are described at http://dev.mysql.com/doc/refman/5.7/en/operating-system-error-codes.html2015-04-30T15:04:22.590070+09:00 87 [Warning] InnoDB: 1048576 bytes should have been written. Only 794624 bytes written. Retrying again to write the rem

52/172

Page 54: MySQL 5.7にやられないためにおぼえておいてほしいこと

テンポラリーテーブルがInnoDBに

⼀度利⽤したibtmp1上の領域は再起動するまで解放されない。

$ ll /usr/mysql/5.7.7/data/ibtmp1-rw-r----- 1 yoku0825 yoku0825 485236736 4月 30 15:04 2015 /usr/mysql/5.7.7/data/ibtmp1

$ df -hFilesystem Size Used Avail Use% Mounted on/dev/mapper/vg_00-lv_root 42G 40G 17M 100% /

53/172

Page 55: MySQL 5.7にやられないためにおぼえておいてほしいこと

Disk Fullは簡単にデータがぶっ壊

れます(特にbinlog)

54/172

Page 56: MySQL 5.7にやられないためにおぼえておいてほしいこと

対策

internal_tmp_disk_storage_engineはオンラインでSET

GLOBALでも変更できる

$ vim my.cnf[mysqld]innodb_temp_data_file_path= ibtmp1:256M ## autoextendしなければ、このサイズで打ちどまる## orinternal_tmp_disk_storage_engine= MyISAM ## 今までどおりMyISAMを使わせる

mysql57> SET GLOBAL internal_tmp_disk_storage_engine= MyISAM;

55/172

Page 57: MySQL 5.7にやられないためにおぼえておいてほしいこと

最低限これだけは知ってほしい5.7

16桁ハッシュのパスワードの廃⽌default̲password̲lifetimesql̲modeのデフォルト値変更log̲error̲verbosity vs. log̲warningsテンポラリーテーブルがInnoDBに

56/172

Page 58: MySQL 5.7にやられないためにおぼえておいてほしいこと

最低限これだけは知ってほしい5.7⼀応知っておいてほしい5.7これを知っているとちょっと得する5.7知っておいても損はない5.7

57/172

Page 59: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysql.user.passwordカラムの廃⽌

MySQL 5.6とそれ以前は、パスワードハッシュはmysql.user.passwordに格納されていた。今まで存在はしたものの何もデータが⼊らなかったmysql.user.authentication̲stringというカラムに⼊っている。

58/172

Page 60: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQL 5.6ではこうだったのが

mysql56> SELECT user, host, password, authentication_string FROM user WHERE user <> 'root';+--------------+------+-------------------------------------------+-----------------------+| user | host | password | authentication_string |+--------------+------+-------------------------------------------+-----------------------+| new_password | % | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 | NULL || old_password | % | 378b243e220ca493 | NULL |+--------------+------+-------------------------------------------+-----------------------+2 rows in set (0.00 sec)

59/172

Page 61: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQL 5.7では、こう

mysql57> SELECT user, host, password, authentication_string FROM user WHERE user <> 'root';ERROR 1054 (42S22): Unknown column 'password' in 'field list'

mysql57> SELECT user, host, authentication_string FROM user WHERE user <> 'root';+--------------+------+-------------------------------------------+| user | host | authentication_string |+--------------+------+-------------------------------------------+| new_password | % | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 || old_password | % | NULL |+--------------+------+-------------------------------------------+2 rows in set (0.03 sec)

60/172

Page 62: MySQL 5.7にやられないためにおぼえておいてほしいこと

認証周りの構⽂の変更

SET PASSWORD= PASSWORD('..')が非推奨、SET PASSWORD=

'..'の構⽂に変更この構⽂は5.6までは逆にエラー”ERROR 1372 (HY000): Password hash should be a 41-digit hexadecimal number”になる。

-

61/172

Page 63: MySQL 5.7にやられないためにおぼえておいてほしいこと

SET PASSWORD= PASSWORD('..')が非推奨

mysql57> SET PASSWORD = PASSWORD('test');Query OK, 0 rows affected, 1 warning (0.04 sec)

*************************** 1. row *************************** Level: Warning Code: 1287Message: 'SET PASSWORD = PASSWORD('<plaintext_password>')' is deprecated and will be removed in a future release. Please use SET PASSWORD = '<plaintext_password>' instead1 row in set (0.00 sec)

mysql57> SET PASSWORD = 'root';Query OK, 0 rows affected (0.00 sec)

62/172

Page 64: MySQL 5.7にやられないためにおぼえておいてほしいこと

認証周りの構⽂の変更

SHOW GRANTSの出⼒結果からパスワードハッシュが取り除かれた。最近の5.5でもSUPERでないユーザーだとʼ<secret>ʻにマスクされるようになった。

-

63/172

Page 65: MySQL 5.7にやられないためにおぼえておいてほしいこと

SHOW GRANTSの出⼒結果からパスワードハッシュが取り除かれた

mysql56> SHOW GRANTS FOR yoku0825\G*************************** 1. row ***************************Grants for yoku0825@%: GRANT USAGE ON *.* TO 'yoku0825'@'%' IDENTIFIED BY PASSWORD '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29'1 row in set (0.00 sec)

mysql57> SHOW GRANTS FOR yoku0825\G*************************** 1. row ***************************Grants for yoku0825@%: GRANT USAGE ON *.* TO 'yoku0825'@'%'1 row in set (0.00 sec)

64/172

Page 66: MySQL 5.7にやられないためにおぼえておいてほしいこと

認証周りの構⽂の変更

CREATE USERせずにいきなりGRANTを叩くとワーニングまたはエラー。パスワードなしでいきなりGRANTはエラー。-sql_mode= NO_AUTO_CREATE_USERがデフォルトに設定されている。

-

65/172

Page 67: MySQL 5.7にやられないためにおぼえておいてほしいこと

CREATE USERせずにいきなりGRANTを叩くとワーニングまたはエラー

mysql57> GRANT USAGE ON *.* TO new_user;ERROR 1133 (42000): Can't find any matching row in the user table

mysql57> GRANT USAGE ON *.* TO new_user IDENTIFIED BY 'test';Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql57> SHOW WARNINGS\G*************************** 1. row *************************** Level: Warning Code: 1287Message: Using GRANT statement to modify existing user's properties other than privileges is deprecated and will be removed in future release. Use ALTER USER statement for this operation.1 row in set (0.00 sec)

66/172

Page 68: MySQL 5.7にやられないためにおぼえておいてほしいこと

認証周りの構⽂の変更

IDENTIFIED BY PASSWORD '..'構⽂の非推奨IDENTIFIED WITH mysql_native_password AS '..'が代替構⽂

-

67/172

Page 69: MySQL 5.7にやられないためにおぼえておいてほしいこと

IDENTIFIED BY PASSWORD '..'構⽂の非推奨

mysql57> CREATE USER new_user IDENTIFIED BY PASSWORD '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29';Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql57> SHOW WARNINGS\G*************************** 1. row *************************** Level: Warning Code: 1287Message: 'IDENTIFIED BY PASSWORD' is deprecated and will be removed in a future release. Please use IDENTIFIED WITH <plugin> AS <hash> instead1 row in set (0.00 sec)

mysql57> CREATE USER new_user IDENTIFIED WITH mysql_native_password AS '*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29';Query OK, 0 rows affected (0.00 sec)

68/172

Page 70: MySQL 5.7にやられないためにおぼえておいてほしいこと

認証周りの構⽂の変更

ALTER USERステートメント今まではGRANTステートメントで上書きしていたアカウントに紐付く属性の上書き

PASSWORD, REQUIRE SSL, MAX̲QUERIES̲PER̲HOUR, ..

-

5.6ではEXPIRE PASSWORDしかできなかった⼦が今後の標準になるっぽい

-

69/172

Page 71: MySQL 5.7にやられないためにおぼえておいてほしいこと

ALTER USERステートメント

mysql57> GRANT USAGE ON *.* TO yoku0826 WITH MAX_USER_CONNECTIONS 10;Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql57> SHOW WARNINGS\G*************************** 1. row *************************** Level: Warning Code: 1287Message: Using GRANT statement to modify existing user's properties other than privileges is deprecated and will be removed in future release. Use ALTER USER statement for this operation.1 row in set (0.00 sec)

mysql57> ALTER USER yoku0827 WITH MAX_USER_CONNECTIONS 10;Query OK, 0 rows affected (0.00 sec)

70/172

Page 72: MySQL 5.7にやられないためにおぼえておいてほしいこと

secure̲file̲priv

File̲priv持ちのユーザーのSELECT .. INTO OUTFILE ..ステートメントやLOAD DATA INFILE ..ステートメント、 LOAD_FILE関数の動作を制限。指定されていない場合、mysqldの実効ユーザー権限で全てのファイルにアクセス可能

-

相変わらずオンラインで変更は できない

71/172

Page 73: MySQL 5.7にやられないためにおぼえておいてほしいこと

secure̲file̲privの動作⾃体は変わっていない

mysql56> SELECT @@global.secure_file_priv;+--------------------+| @@secure_file_priv |+--------------------+| /tmp/ |+--------------------+1 row in set (0.00 sec)

mysql56> SELECT 1 INTO OUTFILE '/home/mysql/test.txt';ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

mysql56> SELECT LOAD_FILE('/etc/hosts');+-------------------------+| LOAD_FILE('/etc/hosts') |+-------------------------+| NULL |+-------------------------+1 row in set (0.02 sec)

72/172

Page 74: MySQL 5.7にやられないためにおぼえておいてほしいこと

secure̲file̲priv変更点

rpm, debなどのパッケージものの場合、5.7から暗黙のデフォルトが /var/lib/mysql-files に設定されるsecure_file_priv= NULLが指定されている場合、FILE権限を利⽤する操作は全て不可能。secure̲file̲privが設定されていない場合はワーニングを出⼒するようになった。

73/172

Page 75: MySQL 5.7にやられないためにおぼえておいてほしいこと

secure̲file̲priv未設定のワーニング

2015-02-17T07:09:49.446585Z 0 [Warning] Insecure configuration for --secure-file-priv: Current value does not restrict location of generated files. Consider setting it to a valid, non-empty path.

MySQL :: MySQL 5.7 Reference Manual :: 5.1.3 Server Command Options

74/172

Page 76: MySQL 5.7にやられないためにおぼえておいてほしいこと

log̲timestamps

デフォルトではスローログ, エラーログ, ジェネラルログの タイムスタンプがUTC になってしまう。暗黙のデフォルトはUTC。”UTC”または”SYSTEM”のどちらかしか取れない。

SET GLOBAL log_timestamps= SYSTEM; でオンライン変更も可能。

-

my.cnfの[mysqld]セクションにlog_timestamps= SYSTEM

推奨。-

バイナリーログは影響を受けない。MySQL :: MySQL 5.7 Reference Manual :: 5.1.4 Server System Variables

75/172

Page 77: MySQL 5.7にやられないためにおぼえておいてほしいこと

log̲timestamps

たとえばスローログ

$ tail data/slow.log..# Time: 2015-03-09T05:01:02.714121Z# User@Host: root[root] @ localhost [] Id: 14# Query_time: 0.000633 Lock_time: 0.000215 Rows_sent: 0 Rows_examined: 0SET timestamp=1425877262;INSERT INTO t1 SELECT * FROM t1 ORDER BY RAND() LIMIT 1;

76/172

Page 78: MySQL 5.7にやられないためにおぼえておいてほしいこと

log̲timestamps

log_timestamps= SYSTEMすると+09:00がオフセットとして追加される。

$ tail data/slow.log..# Time: 2015-03-09T14:03:16.607072+09:00# User@Host: root[root] @ localhost [] Id: 14# Query_time: 0.000671 Lock_time: 0.000226 Rows_sent: 0 Rows_examined: 0SET timestamp=1425877396;INSERT INTO t1 SELECT * FROM t1 ORDER BY RAND() LIMIT 1;

77/172

Page 79: MySQL 5.7にやられないためにおぼえておいてほしいこと

fluent-plugin-mysqlslowqueryさんは⼤丈夫だろ

うか78/172

Page 80: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysql̲install̲db

パスがscripts/mysql̲install̲dbからbin/mysql̲install̲dbに変わっているバイナリー.tar.gz, ソースビルド派のみ

scriptsからbinに移動されている5.5までshell script5.6ではPerl script5.7でCになってscriptじゃなくなったからだろうか。

-

rpmは相変わらず/usr/bin/mysql_install_dbにあるのでパスの変更は気にしなくていい。

-

/usr/my.cnf作らなくなりました :)

79/172

Page 81: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysql̲install̲db

せっかくバイナリーになったのに、あっという間に deprecated になった

5.7.6以降ではmysqld --initializeを使う。-まだしばらくはmysql_install_dbも使えそうだけど、いずれ置き換えられる。

-

80/172

Page 82: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysql̲install̲db

$ mysql_install_db --datadir=./2015-09-29 20:10:13 [WARNING] mysql_install_db is deprecated. Please consider switching to mysqld --initialize2015-09-29 20:10:17 [WARNING] The bootstrap log isn't empty:2015-09-29 20:10:17 [WARNING] mysqld: [Warning] --bootstrap is deprecated. Please consider using --initialize instead

OpenSSL 1.0.1e-fips 11 Feb 2013server-cert.pem: OKclient-cert.pem: OK

81/172

Page 83: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysql̲install̲dbの作成するユーザー

5.6までは root@localhost, [email protected], root@::1, root@hostnameが黙って作成された。5.7では(デフォルトは) root@localhostのみ 。

--skip-name-resolveな状態では”root@localhost”と”[email protected]”は別⼈なので、 Windows環境では注意

MySQL Bugs: #75656: 5.7.5 skip̲name̲resolve stops all connection attempts

-

mysql.sock.lockの登場によりソケットの上書きリスクは減ったものの、[email protected]は⼿で作っておいてもいいかも。

-

82/172

Page 84: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysqld –initialize

mysql̲install̲dbを置き換えるものとして–datadirは必ず指定してやらないといけない(mysql̲install̲dbには暗黙のデフォルトがあった)

-

初期パスワードは 標準エラー出⼒ に吐く--log-errorが設定されてるなら標準エラー出⼒がそっちに向くrpmで突っ込んだ場合は/var/log/mysqld.logからgrepして取り出すことになるかと。~/.mysql̲secretは作らない

-

83/172

Page 85: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysqld –initialize

$ bin/mysqld --initialize..2015-02-17T02:07:18.782831Z 1 [Note] Creating the system database2015-02-17T02:07:18.782984Z 1 [Warning] A temporary password is generated for root@localhost: wokeG8n=Joia2015-02-17T02:07:18.783207Z 1 [Note] Creating the system tables..

84/172

Page 86: MySQL 5.7にやられないためにおぼえておいてほしいこと

InnoDBバッファプールの暖気がデフォルトでONに

mysqld再起動直後にI/O読み込みがガリガリ発⽣するけどあわてないで。この処理が終わるまでの間にトラフィックが突っ込んでくるとかなり悲惨。

-

暗黙のデフォルトでは正常終了時にバッファプール全体の25%のページ番号をテキストファイルに書き出し、起動時にそのページ番号をバッファプールに読み込む。パーセンテージはinnodb̲buffer̲pool̲dump̲pct変数で指定可能、5.6では100%固定だったものが5.7ではデフォルト25%に。

-

個⼈的にはinnodb_buffer_pool_dump_at_shutdown= ON, innodb_buffer_pool_load_at_startup= OFFがいい。 85/172

Page 87: MySQL 5.7にやられないためにおぼえておいてほしいこと

binlog̲formatのデフォルト変更

今までのSTATEMENT(5.1の⼀時期だけMIXED)からROWにバイナリーログ容量の増加ここに1クエリーで100万⾏更新しているバッチがあるじゃろ︖ (AA略)

-

スレーブ側ではTRIGGERが実⾏されない(マスターとスレーブで違うトリガーを設定している場合に問題化)mysqlbinlog -vv はちょっと読みにくいなぁ。。

86/172

Page 88: MySQL 5.7にやられないためにおぼえておいてほしいこと

binlog̲format= STATEMENT

$ mysqlbinlog bin.000002# at 294#150929 20:12:51 server id 1 end_log_pos 396 CRC32 0x3fcab02a Query thread_id=4 exec_time=0 error_code=0SET TIMESTAMP=1443525171/*!*/;INSERT INTO t1 VALUES (1, 'one')/*!*/;..# at 567#150929 20:12:56 server id 1 end_log_pos 665 CRC32 0x5d3a9895 Query thread_id=4 exec_time=0 error_code=0SET TIMESTAMP=1443525176/*!*/;DELETE FROM t1 WHERE num = 1/*!*/;

87/172

Page 89: MySQL 5.7にやられないためにおぼえておいてほしいこと

binlog̲format= ROW

$ mysqlbinlog -vv bin.000003# at 289#150929 20:13:06 server id 1 end_log_pos 335 CRC32 0x86f3973c Table_ma# at 335#150929 20:13:06 server id 1 end_log_pos 383 CRC32 0x5074896b Write_ro

BINLOG 'QnIKVhMBAAAALgAAAE8BAAAAAGwAAAAAAAEAAmQxAAJ0MQACCA8CIAACPJfzhg==QnIKVh4BAAAAMAAAAH8BAAAAAGwAAAAAAAEAAgAC//wBAAAAAAAAAANvbmVriXRQ'/*!*/;### INSERT INTO `d1`.`t1`### SET### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */### @2='one' /* VARSTRING(32) meta=32 nullable=1 is_null=0 */# at 549#150929 20:13:08 server id 1 end_log_pos 595 CRC32 0x8b20ac8b Table_ma# at 595#150929 20:13:08 server id 1 end_log_pos 643 CRC32 0xb50de268 Delete_r

BINLOG 'RHIKVhMBAAAALgAAAFMCAAAAAGwAAAAAAAEAAmQxAAJ0MQACCA8CIAACi6wgiw==RHIKViABAAAAMAAAAIMCAAAAAGwAAAAAAAEAAgAC//wBAAAAAAAAAANvbmVo4g21'/*!*/;### DELETE FROM `d1`.`t1`### WHERE### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */### @2='one' /* VARSTRING(32) meta=32 nullable=1 is_null=0 */

88/172

Page 90: MySQL 5.7にやられないためにおぼえておいてほしいこと

rpmパッケージではvalidate̲passwordプラグインがデフォルトで有効

デフォルトでは8⽂字以上、英⼤⽂字⼩⽂字数字記号の4種類これを満たしていないとSET PASSWORDが転けるしSHOW

VARIABLESさえ⾒られない。Do̲you̲love̲MySQL57? でこれを満たせるのでどうぞご活⽤ください( Do̲you̲love̲PHP7? でもいいですよ :-P

89/172

Page 91: MySQL 5.7にやられないためにおぼえておいてほしいこと

validate̲passwordプラグイン

mysql> SHOW VARIABLES LIKE 'validate%';ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

mysql> SET PASSWORD= 'unsafe_password';ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

mysql> SET PASSWORD= 'Do_you_love_MySQL57?';Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'validate%';+--------------------------------------+--------+| Variable_name | Value |+--------------------------------------+--------+| validate_password_dictionary_file | || validate_password_length | 8 || validate_password_mixed_case_count | 1 || validate_password_number_count | 1 || validate_password_policy | MEDIUM || validate_password_special_char_count | 1 |+--------------------------------------+--------+6 rows in set, 1 warning (0.00 sec)

90/172

Page 92: MySQL 5.7にやられないためにおぼえておいてほしいこと

innodb̲default̲row̲formatの注意

innodb_file_format= Barracuda, innodb_large_prefix= ONと合わせて、innodb_default_row_format= Dynamicがデフォルトに。InnoDBのセカンダリーキー767bytes制限、1⾏のデータ8000bytes制限を⾶び越えるための設定(5.5から使えた)がデフォルト化。

91/172

Page 93: MySQL 5.7にやられないためにおぼえておいてほしいこと

innodb̲default̲row̲formatの注意

ただし、オンラインALTER TABLEにちょっとだけ影響を及ぼす。

ADD INDEXには影響ないです。-ADD COLUMNの場合、オンラインはオンラインなんだけど同時にROW̲FORMATの暗黙の変換が(場合によって)⾏われるので、テーブルを再構築し始める(オンラインはオンラインでできる)

-

既にROW̲FORMATが明⽰されている場合は暗黙の変換は起こらない。

92/172

Page 94: MySQL 5.7にやられないためにおぼえておいてほしいこと

⼀応知っておいてほしい5.7

mysql.user.passwordカラムの廃⽌認証周りの構⽂の変更secure̲file̲privlog̲timestampsmysql̲install̲dbmysqld –initializeInnoDBバッファプールの暖気がデフォルトでONにbinlog̲formatのデフォルト変更rpmパッケージではvalidate̲passwordプラグインがデフォルトで有効innodb̲default̲row̲formatの注意

93/172

Page 95: MySQL 5.7にやられないためにおぼえておいてほしいこと

最低限これだけは知ってほしい5.7⼀応知っておいてほしい5.7これを知っているとちょっと得する5.7知っておいても損はない5.7

94/172

Page 96: MySQL 5.7にやられないためにおぼえておいてほしいこと

sysスキーマ

performance̲schemaの情報を⾒やすくするためのビュー, ストアドプロシージャの集合ストアドプロシージャの⽅はあまり本家で語られることがないけれど、ps̲setup̲saveとか便利。

-

SHOW DATABASESするとsysがいますが、気にしないでください。

95/172

Page 97: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.metrics

監視に良さそうな項目の詰め合わせ。Type= InnoDB Metricsも詰め合わせてある。SHOW ENGINE

INNODB STATUSをパースしなくてもそのままfluentdに⾷わせてKibanaに送ったらいいんじゃないか疑惑 in 俺の中。

96/172

Page 98: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.metrics

mysql> SELECT * FROM metrics LIMIT 10;+----------------------------+----------------+---------------+---------+| Variable_name | Variable_value | Type | Enabled |+----------------------------+----------------+---------------+---------+| aborted_clients | 4963 | Global Status | YES || aborted_connects | 1 | Global Status | YES || binlog_cache_disk_use | 0 | Global Status | YES || binlog_cache_use | 14779017 | Global Status | YES || binlog_stmt_cache_disk_use | 0 | Global Status | YES || binlog_stmt_cache_use | 502 | Global Status | YES || bytes_received | 21737114595 | Global Status | YES || bytes_sent | 33296720984 | Global Status | YES || compression | OFF | Global Status | YES || com_admin_commands | 5827 | Global Status | YES |+----------------------------+----------------+---------------+---------+10 rows in set (0.02 sec)

97/172

Page 99: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.schema̲index̲statistics

どのインデックスを使ってどれだけハンドラーが呼ばれたか、そのレイテンシーの合計は…というのが⾒られる。あんまり使われてないインデックスをあぶりだすのは後述のsys.schema_unused_indexesビューでもいける。

98/172

Page 100: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.schema̲index̲statistics

mysql> SELECT * FROM schema_index_statistics LIMIT 1\G*************************** 1. row *************************** table_schema: xxxxxxxx table_name: table_1 index_name: PRIMARY rows_selected: 14113184select_latency: 5.21 m rows_inserted: 0insert_latency: 0 ps rows_updated: 13327613update_latency: 39.57 m rows_deleted: 0delete_latency: 0 ps1 row in set (0.01 sec)

99/172

Page 101: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.schema̲unused̲indexes

名前そのものズバリ、使われてない(統計開始から⼀度も使われていない)インデックスを⼀覧してくれる。ただし、performance_schema.setup_actors, performance_schema.setup_objects, performance_schema.setup_instruments= 'wait/io/table/

sql/handler'あたりの設定に依存する。吊るしで使ってるならフツーのテーブルではmysqldの起動時から全部統計が有効になっている。

100/172

Page 102: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.schema̲unused̲indexes

mysql> SELECT * FROM sys.schema_unused_indexes LIMIT 3\G*************************** 1. row ***************************object_schema: xxxxxxx object_name: table_1 index_name: idx_number_1*************************** 2. row ***************************object_schema: xxxxxxx object_name: table_1 index_name: idx_number_2*************************** 3. row ***************************object_schema: xxxxxxx object_name: table_1 index_name: idx_number_33 rows in set (0.01 sec)

101/172

Page 103: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.statement̲analysis

sys.format_statementというストアドファンクションを噛んでいるせいで、queryカラムが切り詰められる。performance_schema.events_statements_summary_by_diges

t.digest_textに切り詰められていないステートメントがあるので、USING (digest)でJOINしてやるとpt-query-

digestっぽい出⼒が得られる。

102/172

Page 104: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.statement̲analysis

mysql> SELECT * FROM sys.statement_analysis LIMIT 1\G*************************** 1. row *************************** query: UPDATE `table_21` SET `bo ... RE `table_21` . `column_1` = ? db: xxxxxxx full_scan: exec_count: 13263309 err_count: 0 warn_count: 0 total_latency: 1.40 h max_latency: 18.38 ms avg_latency: 378.83 us lock_latency: 20.10 m rows_sent: 0 rows_sent_avg: 0 rows_examined: 13263309rows_examined_avg: 1 rows_affected: 13263227rows_affected_avg: 1 tmp_tables: 0 tmp_disk_tables: 0 rows_sorted: 0sort_merge_passes: 0 digest: a73db02641a1215f4e54093763bde706 first_seen: 2015-06-24 17:46:51 last_seen: 2015-09-28 11:10:24

103/172

Page 105: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.statements̲with̲errors̲or̲warnings

カジュアルに桁切り詰めワーニングを無視してるステートメントとか⼀網打尽にできる。--gtid-enforce-consistency= WARNと組み合わせて使うと夢が広がる。DBAからの攻めの⼀⼿にどうぞ。

104/172

Page 106: MySQL 5.7にやられないためにおぼえておいてほしいこと

sys.statements̲with̲errors̲or̲warnings

mysql> SELECT * FROM sys.statements_with_errors_or_warnings LIMIT 1\G*************************** 1. row *************************** query: SELECT IF ( ( `locate` ( ? , ` ... . `COMPRESSED_SIZE` ) ) DESC db: sys exec_count: 1 errors: 1 error_pct: 100.0000 warnings: 0warning_pct: 0.0000 first_seen: 2015-09-28 10:36:27 last_seen: 2015-09-28 10:36:27 digest: 97b93c349004ed5d8774479aecc83eda1 row in set (0.02 sec)

105/172

Page 107: MySQL 5.7にやられないためにおぼえておいてほしいこと

危険なヤツら

sys.innodb̲buffer̲stats̲by̲schemasys.innodb̲buffer̲stats̲by̲tablesys.schema̲table̲statistics̲with̲bufferこれ注意。 迂闊に触ると死ぬ ことがある。内部的にinformaition̲schema.innodb̲buffer̲pageを⾒ているので、でかいバッファプール(経験則だと20GB超)でやるとたまに突き刺さる。特にCtrl + Cでクエリーを殺すと突き刺さる率が俺の中では⾼い

-

106/172

Page 108: MySQL 5.7にやられないためにおぼえておいてほしいこと

名前で判りそうなやつら

sys.statements̲with̲temp̲tablessys.statements̲with̲full̲table̲scanssys.statements̲with̲runtimes̲in̲95th̲percentilesys.statements̲with̲sortingsys.statements̲with̲temp̲tables

107/172

Page 109: MySQL 5.7にやられないためにおぼえておいてほしいこと

sysスキーマのストアドプロシージャ/ファンクション

mysql> SELECT routine_name, routine_type FROM information_schema.routines WHERE routine_schema= 'sys';+-------------------------------------+--------------+| routine_name | routine_type |+-------------------------------------+--------------+..| ps_setup_disable_background_threads | PROCEDURE || ps_setup_disable_consumer | PROCEDURE || ps_setup_disable_instrument | PROCEDURE || ps_setup_disable_thread | PROCEDURE || ps_setup_enable_background_threads | PROCEDURE || ps_setup_enable_consumer | PROCEDURE || ps_setup_enable_instrument | PROCEDURE || ps_setup_enable_thread | PROCEDURE || ps_setup_reload_saved | PROCEDURE || ps_setup_reset_to_default | PROCEDURE || ps_setup_save | PROCEDURE |..+-------------------------------------+--------------+36 rows in set (0.01 sec)

108/172

Page 110: MySQL 5.7にやられないためにおぼえておいてほしいこと

GTIDのオンライン有効化がサポート

5.6ではマスターとスレーブで同じgtid-modeを持たなければならず、gtid̲modeはオンライン変更不可能だった。

masterslave gtid-mode= OFF gtid-mode= ON

gtid-mode= OFF ○ ×

gtid-mode= ON × ○

109/172

Page 111: MySQL 5.7にやられないためにおぼえておいてほしいこと

GTIDのオンライン有効化がサポート

5.7ではOFF̲PERMISSIVEとON̲PERMISSIVEが追加され、かつ、オンラインでgtid̲modeを変更できるようになった。

masterslave OFF OFF̲PERMISSIVE ON̲PERMISSIVE ON

OFF ○ ○ ○ ×

OFF̲PERMISSIVE

○ ○ ○ ×

ON̲PERMISSIVE

× ○ ○ ○

ON × ○ ○ ○

110/172

Page 112: MySQL 5.7にやられないためにおぼえておいてほしいこと

GTIDのオンライン有効化

slave> SET GLOBAL gtid_mode= OFF_PERMISSIVE;master> SET GLOBAL gtid_mode= OFF_PERMISSIVE;

slave> SET GLOBAL gtid_mode= ON_PERMISSIVE;master> SET GLOBAL gtid_mode= ON_PERMISSIVE;

slave> SET GLOBAL enforce_gtid_consistency= ON;master> SET GLOBAL enforce_gtid_consistency= ON;

slave> SET GLOBAL gtid_mode= ON;master> SET GLOBAL gtid_mode= ON;

111/172

Page 113: MySQL 5.7にやられないためにおぼえておいてほしいこと

GTIDのオンライン有効化がサポート

enforce_gtid_consistencyの取りうる値がON, OFF, WARNの3種類に。enforce_gtid_consistency= WARNだと、ON̲PERMISSIVE以上のgtid̲modeではエラーになるステートメントがワーニングで出⼒される。

sys.statements_with_errors_or_warningsで拾っていくスタイル。

-

112/172

Page 114: MySQL 5.7にやられないためにおぼえておいてほしいこと

enforce̲gtid̲consistency= WARN

mysql57> SELECT @@enforce_gtid_consistency;+----------------------------+| @@enforce_gtid_consistency |+----------------------------+| WARN |+----------------------------+1 row in set (0.00 sec)

mysql57> CREATE TABLE t2 AS SELECT * FROM t1;Query OK, 1 row affected, 1 warning (0.04 sec)Records: 1 Duplicates: 0 Warnings: 1

mysql57> SHOW WARNINGS;+---------+------+---------------------------------------------------------------+| Level | Code | Message |+---------+------+---------------------------------------------------------------+| Warning | 1786 | Statement violates GTID consistency: CREATE TABLE ... SELECT. |+---------+------+---------------------------------------------------------------+1 row in set (0.00 sec)

113/172

Page 115: MySQL 5.7にやられないためにおぼえておいてほしいこと

GTIDのオンライン有効化がサポート

今まではレプリケーションの系全体を⼀度シャットダウンしないといけなかった。mysqlfailoverやmysqlfabricはGTIDの有効化が条件になっている。

MHA for MySQLがrelay_log_info_repository= TABLE

(クラッシュセーフスレーブの条件)で上⼿く動かなかったので、どうにかしたかった。。

-

これから流⾏る…といいな。

114/172

Page 116: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQLネイティブの全⽂検索が⽇本語対応

Not Only InnoDB.WITH PARSER句で利⽤するフルテキストパーサーを指定できる(指定⾃体は5.5からできる)Ngram(デフォルトで有効)とMeCab(バンドルされているが、⾃分でmecabrcを編集してINSTALL PLUGIN)ざっとベンチした感じ、「MeCab」かつ「ファイルソートが気にならないレベルの⾏数」なら使えるかと。

115/172

Page 117: MySQL 5.7にやられないためにおぼえておいてほしいこと

MeCab FTパーサーの有効化

$ vim /etc/my.cnf[mysqld]loose-mecab-rc-file= /usr/lib64/mysql/mecab/etc/mecabrc

mysql57> INSTALL PLUGIN mecab SONAME 'libpluginmecab.so';Query OK, 0 rows affected (0.02 sec)

116/172

Page 118: MySQL 5.7にやられないためにおぼえておいてほしいこと

MySQLの全⽂検索で検索

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

mysql57> SELECT * FROM t1 WHERE match(val) against ('がんばらない' IN BOOLEAN MODE);+-----+--------------------------------------+| num | val |+-----+--------------------------------------+| 4 | 魔法少女@がんばらない || 25 | ささみさん@がんばらない || 85 | テラ@がんばらない |+-----+--------------------------------------+3 rows in set (0.00 sec)

117/172

Page 119: MySQL 5.7にやられないためにおぼえておいてほしいこと

InnoDB UNDO logのシュリンク

前提としてinnodb-undo-tablespaces >= 2が必要(UNDOログがibdata1ではなくてundo001とかに書かれている必要がある)

ibdata1が作成される時点で指定されていなければならないので、mysql_install_db(or mysqld --initialize)の時点でmy.cnfに書き込んでおかないといけない。

-

SET GLOBAL innodb_undo_log_truncation= 1で有効化。innodb_max_undo_log_sizeを超えているundoログがある場合、デフォルトではパージ処理が128回(これが最⼤値)呼ばれるたびにundo001とかのシュリンクが⾛ってしまうので、⼩さくなったのが確認できたら無効に戻しておく⽅が良い。

118/172

Page 120: MySQL 5.7にやられないためにおぼえておいてほしいこと

サーバーサイドステートメントタイムアウト

5.7.7までの書き⽅と変わっているセッション変数(と暗黙のデフォルトとしてのグローバル変数)でも指定可能。単位はミリ秒。SELECTステートメントでだけ有効。安⼼してください。

119/172

Page 121: MySQL 5.7にやられないためにおぼえておいてほしいこと

サーバーサイドステートメントタイムアウト

mysql57> SELECT /*+ MAX_EXECUTION_TIME(1000) */ * FROM t1;ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded

mysql57> SET SESSION max_execution_time= 1000;Query OK, 0 rows affected (0.00 sec)

mysql57> SELECT * FROM t1;ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded

120/172

Page 122: MySQL 5.7にやられないためにおぼえておいてほしいこと

generated columnで関数インデックス

「実カラムの値を計算した結果」を格納する専⽤のカラムを作成できる

STOREDタイプはALTER TABLE時に値が計算されてDiskに固定化

-

VIRTUALタイプはSELECT時に都度計算-どちらのタイプもセカンダリーインデックスを作成できる(セカンダリーインデックスはどちらのタイプでもDiskに固定化される)

-

121/172

Page 123: MySQL 5.7にやられないためにおぼえておいてほしいこと

generated column

mysql> SELECT * FROM t1;+------+------------+| num | val |+------+------------+| 1 | one || 99 | ninty-nine |+------+------------+2 rows in set (0.00 sec)

mysql> ALTER TABLE t1 ADD is_over_20 TINYINT AS (num > 20) NOT NULL;Query OK, 0 rows affected (0.02 sec)Records: 0 Duplicates: 0 Warnings: 0

122/172

Page 124: MySQL 5.7にやられないためにおぼえておいてほしいこと

generated column

mysql> SELECT * FROM t1;+------+------------+------------+| num | val | is_over_20 |+------+------------+------------+| 1 | one | 0 || 99 | ninty-nine | 1 |+------+------------+------------+2 rows in set (0.00 sec)

mysql> ALTER TABLE t1 ADD KEY (is_over_20);Query OK, 0 rows affected (0.03 sec)Records: 0 Duplicates: 0 Warnings: 0

123/172

Page 125: MySQL 5.7にやられないためにおぼえておいてほしいこと

generated columnで関数インデックス

⽣成された列にNOT NULL制約、UNIQUE制約もかけられる(疑似チェック制約が作れる)直接値を投⼊することはできないが、「カラム」としては定義されるのでSELECT *とかINSERT INTO .. VALUESに注意。

124/172

Page 126: MySQL 5.7にやられないためにおぼえておいてほしいこと

SSL関連いろいろ

オレオレ証明書を⼀発で作ってくれるmysql_ssl_rsa_setup

コマンドどこで実⾏してもdatadirに出⼒されるので、出⼒先を変える時は--datadirオプションを渡す

-

$ mysql_ssl_rsa_setup..writing RSA key

$ ll *.pem-rw------- 1 mysql mysql 1675 Sep 29 20:22 ca-key.pem-rw-r--r-- 1 mysql mysql 1078 Sep 29 20:22 ca.pem-rw-r--r-- 1 mysql mysql 1086 Sep 29 20:22 client-cert.pem-rw------- 1 mysql mysql 1679 Sep 29 20:22 client-key.pem-rw------- 1 mysql mysql 1679 Sep 29 20:22 private_key.pem-rw-r--r-- 1 mysql mysql 451 Sep 29 20:22 public_key.pem-rw-r--r-- 1 mysql mysql 1086 Sep 29 20:22 server-cert.pem-rw------- 1 mysql mysql 1679 Sep 29 20:22 server-key.pem

125/172

Page 127: MySQL 5.7にやられないためにおぼえておいてほしいこと

SSL関連いろいろ

クライアントにSSL接続を強要するrequire_secure_transportオプション

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

$ mysql57 --protocol=tcp --skip-sslERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.

126/172

Page 128: MySQL 5.7にやられないためにおぼえておいてほしいこと

JSONデータ型

データ型としてのJSONであり、基本的にはデータのバリデーションのみ⾏ってくれる(バイナリーパックとかしているらしいけど、クライアントから⾒るとバリデーションの有無だけがTEXT/BLOBに突っ込む時との違い)JSONの検索はgenerated columnによる関数インデックスで多少何とかできる。基本的に、今まで(トランザクションの保護が欲しいとかの理由で)TEXT/BLOBにJSONを突っ込んでいた⼈たちがちょっと幸せになるための機能。

127/172

Page 129: MySQL 5.7にやられないためにおぼえておいてほしいこと

JSONデータ型

バリデーションに失敗した時のエラーが3000番台なのが新しい。

mysql57> CREATE TABLE t2 (num serial, j json);Query OK, 0 rows affected (0.02 sec)

mysql57> INSERT INTO t2 VALUES (1, 'aaa');ERROR 3140 (22032): Invalid JSON text: "Invalid value." at position 0 in value (or column) 'aaa'.

128/172

Page 130: MySQL 5.7にやられないためにおぼえておいてほしいこと

JSON型のための関数

mysql> SELECT val FROM t1 LIMIT 1\G*************************** 1. row ***************************val: {"dt": 1443603809, "id": 1850147, "cod": 200, "sys": {"id": 7619, "type": 1, "sunset": 1443601626, "country": "JP", "message": 0.0181, "sunrise": 1443558902}, "base": "stations", "main": {"temp": 294.52, "humidity": 49, "pressure": 1020, "temp_max": 295.37, "temp_min": 292.04}, "name": "Tokyo", "wind": {"deg": 200, "speed": 6.7}, "coord": {"lat": 35.69, "lon": 139.69}, "clouds": {"all": 75}, "weather": [{"id": 803, "icon": "04n", "main": "Clouds", "description": "broken clouds"}], "visibility": 10000}1 row in set (0.00 sec)

mysql> SELECT json_extract(val, '$.dt') AS dt, json_extract(val, '$.sys.country') AS country FROM t1 LIMIT 1;+------------+---------+| dt | country |+------------+---------+| 1443603809 | "JP" |+------------+---------+1 row in set (0.00 sec)

129/172

Page 131: MySQL 5.7にやられないためにおぼえておいてほしいこと

マルチスレッドスレーブの機能向上

5.6まではスキーマが分かれていないとパラレルに動けなかった5.7ではslave_parallel_type= {DATABASE|LOGICAL_CLOCK}でスキーマ単位のMTSと、 マスターで記録されたロジカルタイムスタンプ を利⽤したMTSが選べる。マスターはどのトランザクションとどのトランザクションが 競合せずにCOMMITできたか を知っている

-

競合せずにCOMMITできたトランザクション同⼠は、スレーブでパラレルに実⾏されても競合することはない

-

gitでファイルAを更新したコミットとファイルBを更新したコミットはコンフリクトしないから、どっちを先にマージしても構わない…というのと⼀緒(かな︖)

-

130/172

Page 132: MySQL 5.7にやられないためにおぼえておいてほしいこと

これを知っているとちょっと得する5.7

sysスキーマGTIDのオンライン有効化がサポートMySQLネイティブの全⽂検索が⽇本語対応InnoDB UNDO logのシュリンクサーバーサイドステートメントタイムアウトgenerated columnで関数インデックスSSL関連いろいろJSONデータ型マルチスレッドスレーブの機能向上

131/172

Page 133: MySQL 5.7にやられないためにおぼえておいてほしいこと

最低限これだけは知ってほしい5.7⼀応知っておいてほしい5.7これを知っているとちょっと得する5.7知っておいても損はない5.7

132/172

Page 134: MySQL 5.7にやられないためにおぼえておいてほしいこと

innodb̲buffer̲pool̲sizeのオンライン変更がサポート

バッファプールを⼤きくするときinnodb̲buffer̲pool̲chunk̲size ごとに新しいページを確保しながらゴニョゴニョやる

-

この処理中は バッファプールへの全てのアクセスがブロックされる

-

133/172

Page 135: MySQL 5.7にやられないためにおぼえておいてほしいこと

innodb̲buffer̲pool̲sizeのオンライン変更がサポート

バッファプールを⼩さくするときinnodb̲buffer̲pool̲chunk̲size ごとにページを追い出しながらゴニョゴニョやる

-

常にバッファプールミスヒットが起こり続けるイメージでだいたい合ってる。

-

⽌めてバッファプールの暖気をしなおすよりは速くて便利だけど、本当にオンラインでやるべきではない。

134/172

Page 136: MySQL 5.7にやられないためにおぼえておいてほしいこと

innodb̲buffer̲pool̲sizeのオンライン変更

非同期で裏でやるのでSET GLOBALはすぐ戻ってくる

mysql57> SET GLOBAL innodb_buffer_pool_size= 2 * 1024 * 1024 * 1024;Query OK, 0 rows affected (0.00 sec)

$ less error.log2015-09-29T11:24:49.099855Z 0 [Note] InnoDB: Resizing buffer pool from 134217728 to 2147483648. (unit=134217728)2015-09-29T11:24:49.100508Z 0 [Note] InnoDB: disabled adaptive hash index.2015-09-29T11:24:49.274486Z 0 [Note] InnoDB: buffer pool 0 : 15 chunks (122880 blocks) were added.2015-09-29T11:24:49.277227Z 0 [Note] InnoDB: buffer pool 0 : hash tables were resized.2015-09-29T11:24:49.330346Z 0 [Note] InnoDB: Resized hash tables at lock_sys, adaptive hash index, dictionary.2015-09-29T11:24:49.330397Z 0 [Note] InnoDB: Completed to resize buffer pool from 134217728 to 2147483648.2015-09-29T11:24:49.333206Z 0 [Note] InnoDB: Re-enabled adaptive hash index.

135/172

Page 137: MySQL 5.7にやられないためにおぼえておいてほしいこと

sync̲binlogのデフォルト変更

InnoDBのクラッシュリカバリーの中でバイナリーログを使う箇所があるより安全なsync_binlog= 1に変更…というか-sync_binlog= 0は 危険な設定 (クラッシュリカバリーが失敗することがある)

-

binlogへの書き出しが失敗した際に、⼀貫性を保つためmysqldをダウンさせるオプションが有効になっている

MySQL :: MySQL 5.7 Reference Manual :: 17.1.6.4 Binary Logging Options and Variables

-

実は5.6から既にsync̲binlog= 0は危険 なんだけど。-

136/172

Page 138: MySQL 5.7にやられないためにおぼえておいてほしいこと

マルチソースレプリケーション

マルチスレッドスレーブ(MTS)とは別物。1つのI/Oスレッドは相変わらず1つのマスターにしか接続しない。今のところMTSと併⽤できない。複数のMySQLから集約スレーブを作ってJOINJOIN。⽔平シャーディングしたサーバーの集約。

137/172

Page 139: MySQL 5.7にやられないためにおぼえておいてほしいこと

シングルソース、シングルスレッドレプリケーション

138/172

Page 140: MySQL 5.7にやられないためにおぼえておいてほしいこと

シングルソース、マルチスレッドレプリケーション

139/172

Page 141: MySQL 5.7にやられないためにおぼえておいてほしいこと

マルチソース、シングルスレッドレプリケーション

140/172

Page 142: MySQL 5.7にやられないためにおぼえておいてほしいこと

マルチソースレプリケーション

今までのレプリケーション関連コマンドの末尾にFOR

CHANNEL 'channel_name'をつけるだけでOK

mysql57> STOP SLAVE FOR CHANNEL 'node2';

mysql57> SHOW SLAVE STATUS FOR CHANNEL 'node2'\G

mysql57> START SLAVE FOR CHANNEL 'node2';

141/172

Page 143: MySQL 5.7にやられないためにおぼえておいてほしいこと

ダイナミックレプリケーションフィルター

--replicate-ignore-*オプションとか--replicate-do-*オプション相当の操作がSQLインターフェースで可能になったただしSQLスレッドは停⽌する必要がある

142/172

Page 144: MySQL 5.7にやられないためにおぼえておいてほしいこと

ダイナミックレプリケーションフィルター

mysql57> CHANGE REPLICATION FILTER replicate_ignore_db= (mysql, performance_schema);ERROR 3017 (HY000): This operation cannot be performed with a running slave sql thread; run STOP SLAVE SQL_THREAD first

mysql57> STOP SLAVE sql_thread;

mysql57> CHANGE REPLICATION FILTER replicate_ignore_db= (mysql, performance_schema);Query OK, 0 rows affected (0.00 sec)

mysql57> START SLAVE sql_thread;

143/172

Page 145: MySQL 5.7にやられないためにおぼえておいてほしいこと

InnoDBの新しい圧縮

Transparent Page Compression今までの圧縮はソフトウェア(InnoDB内)でページまるごとzlib圧縮Transparent Page Compressionはページの中のデータ部分だけ圧縮し、ページ内の空き領域の圧縮はファイルシステムとデバイスに任せるzlibとlz4が選べる

144/172

Page 146: MySQL 5.7にやられないためにおぼえておいてほしいこと

InnoDBの新しい圧縮

対応ディストリビューションが限定されている、Intel SSDでxfsだとデバイスに任せた⽅がむしろ遅かった、とか、⾃分でベンチした⽅が良さげFusion-ioとなら相性良いはず(今までとほぼ同じ圧縮率、今までの無圧縮に数%のオーバーヘッドだけで済むとか⾔ってる)Third day with InnoDB transparent page compressionInnoDB Transparent Page Compression | MySQL Server Blog

145/172

Page 147: MySQL 5.7にやられないためにおぼえておいてほしいこと

1テーブルに複数トリガー設定可能

{BEFORE|AFTER} {INSERT|UPDATE|DELETE}トリガーがあったが、同じアクションに対するトリガーは1つしか定義できなかった。MySQL 5.7からはBEFORE INSERTトリガーを3つとか作れる。複数設定できるということは順番の概念が発⽣するので気を付けて。

146/172

Page 148: MySQL 5.7にやられないためにおぼえておいてほしいこと

1テーブルに複数トリガー設定可能

mysql57> CREATE TRIGGER before_insert_1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 SET num = NEW.num, val = NEW.val;Query OK, 0 rows affected (0.01 sec)

mysql57> CREATE TRIGGER before_insert_2 BEFORE INSERT ON t1 FOR EACH ROW UPDATE t2 SET val = '残念だったな' WHERE num = NEW.num;Query OK, 0 rows affected (0.00 sec)

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

mysql57> SELECT * FROM t2;+-----+--------------------+| num | val |+-----+--------------------+| 1 | 残念だったな |+-----+--------------------+1 row in set (0.00 sec)

147/172

Page 149: MySQL 5.7にやられないためにおぼえておいてほしいこと

mysql p ump

mysql d umpの後継を狙っているらしい。論理バックアップのパラレル版。mysqlpumpの中だけで圧縮(zlib, lz4)--userオプションでGRANTステートメントを出⼒してくれたり--watch-progressオプションがデフォルト有効インデックスの遅延ロード(--defer-table-indexes)がデフォルトで有効まだ発展途上。これからに期待

148/172

Page 150: MySQL 5.7にやられないためにおぼえておいてほしいこと

log-syslog

エラーログをloggerで出⼒する今までもmysqld_safeには--syslogオプションがあったけど、アレはmysqld_safeのログだけlog_syslog_facility, log_syslog_tagオプションで読みやすくできるちなみにこっちはlog_timestampsの影響を受けないので、エラーログは今後こっちが⾒やすいかも

149/172

Page 151: MySQL 5.7にやられないためにおぼえておいてほしいこと

log-syslog

$ less /var/log/messages..Sep 29 20:27:54 e23cb0f9dde9 mysqld[1683]: /usr/sbin/mysqld (mysqld 5.7.8-rc-log) starting as process 1683 .....Sep 29 20:27:54 e23cb0f9dde9 mysqld[1683]: Event Scheduler: Loaded 0 eventsSep 29 20:27:54 e23cb0f9dde9 mysqld[1683]: /usr/sbin/mysqld: ready for connections.#012Version: '5.7.8-rc-log' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server (GPL)

150/172

Page 152: MySQL 5.7にやられないためにおぼえておいてほしいこと

オフラインモード

クエリーが終わったものから順番に切断(server has gone awayが返る)SUPER権限以外はそれ以降接続できなくなるエラーコードが3032でそれ⽤のものになっているので、このあたり上⼿くハンドルすればgraceful shutdownの夢を⾒るか

151/172

Page 153: MySQL 5.7にやられないためにおぼえておいてほしいこと

オフラインモード

mysql57-root> SET GLOBAL offline_mode= 1;Query OK, 0 rows affected (0.00 sec)

mysql57-yoku0825> show databases;ERROR 2006 (HY000): MySQL server has gone away

$ mysql57 -uyoku0825ERROR 3032 (HY000): The server is currently in offline mode

152/172

Page 154: MySQL 5.7にやられないためにおぼえておいてほしいこと

GET̲LOCK関数で複数のロックを取れる

複数取れるってことは、デッドロックの可能性があるってことだデッドロックしてもInnoDBのように他のロックをリリースはしてくれないから、コネクションを切断するか⾃分でrelease̲lockかrelease̲all̲locksしてやらないとダメ

153/172

Page 155: MySQL 5.7にやられないためにおぼえておいてほしいこと

GET̲LOCK関数でデッドロックさせてみる

mysql57> SELECT GET_LOCK('yoku0825', 1);+-------------------------+| GET_LOCK('yoku0825', 1) |+-------------------------+| 1 |+-------------------------+1 row in set (0.00 sec)

mysql57> SELECT GET_LOCK('yoku0826', 1);ERROR 3058 (HY000): Deadlock found when trying to get user-level lock; try rolling back transaction/releasing locks and restarting lock acquisition.

mysql57> SELECT RELEASE_ALL_LOCKS();+---------------------+| RELEASE_ALL_LOCKS() |+---------------------+| 1 |+---------------------+1 row in set (0.00 sec)

154/172

Page 156: MySQL 5.7にやられないためにおぼえておいてほしいこと

Query Rewrite Plugin

SQLをパースする前とパースした後にプラグインAPIの⼝が⽤意されているMySQL Proxyがmysqldの中に⼊っちゃってる感じパース前ならクエリー書き換え放題パース後のAPIに上⼿く差し込むようにすれば監査ログを吐き出せるようにできるかな

155/172

Page 157: MySQL 5.7にやられないためにおぼえておいてほしいこと

Query Rewrite Plugin

156/172

Page 158: MySQL 5.7にやられないためにおぼえておいてほしいこと

知っておいても損はない5.7

innodb̲buffer̲pool̲sizeのオンライン変更がサポートsync̲binlogのデフォルト変更マルチソースレプリケーションダイナミックレプリケーションフィルターInnoDBの新しい圧縮1テーブルに複数トリガー設定可能mysql p umplog-syslogオフラインモードGET̲LOCK関数で複数のロックを取れるQuery Rewrite Plugin

157/172

Page 159: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

5.6 defaultに合わせるようなmy.cnfを書くと、5.6コンパチに近付けられる。my.cnfだけじゃどうしようもないものもある(mysql.user.passwordカラムがなくなったやつとか)

158/172

Page 160: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

binlog̲error̲action IGNORE̲ERROR ABORT̲SERVER

binlog̲format STATEMENT ROW

binlog̲group̲commit̲sync̲delay

N/A 0

binlog̲group̲commit̲sync̲no̲delay̲count

N/A 0

binlog̲gtid̲simple̲recovery

OFF ON

check̲proxy̲users N/A OFF

default̲authentication̲plugin

N/A(mysql̲native̲password)

mysql̲native̲password

default̲password̲lifetime

N/A(0) (<= 5.7.10は360) 0

159/172

Page 161: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

disabled̲storage̲engines

N/A ”“(empty)

eq̲range̲index̲dive̲limit

10 200

gtid̲executed̲compression̲period

N/A 1000

have̲statement̲timeout N/A YES

innodb̲adaptive̲hash̲index̲parts

N/A(1) 8

innodb̲additional̲mem̲pool̲size

8M N/A

innodb̲buffer̲pool̲chunk̲size

N/A 128M

160/172

Page 162: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

innodb̲buffer̲pool̲dump̲at̲shutdown

OFF ON

innodb̲buffer̲pool̲dump̲pct

N/A(100) 25

innodb̲buffer̲pool̲instances

8 1

innodb̲buffer̲pool̲load̲at̲startup

OFF ON

innodb̲checksum̲algorithm

innodb CRC32

innodb̲default̲row̲format

N/A(compact) dynamic

innodb̲file̲format Antelope Barracuda

innodb̲file̲format̲max Antelope Barracuda

161/172

Page 163: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

innodb̲fill̲factor N/A(100) 100

innodb̲flush̲sync N/A ON

innodb̲large̲prefix OFF ON

innodb̲log̲buffer̲size 8M 16M

innodb̲log̲checksum̲algorithm

N/A(none) CRC32

innodb̲log̲checksums N/A(OFF) ON

innodb̲log̲write̲ahead̲size

N/A(0) 8k

innodb̲mirrored̲log̲groups

1(N/A) N/A

innodb̲max̲undo̲log̲size

N/A 1G

162/172

Page 164: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

innodb̲numa̲interleave N/A(OFF) OFF

innodb̲page̲cleaners N/A(1) 1

innodb̲purge̲rseg̲truncate̲frequency

N/A 128

innodb̲purge̲threads 1 4

innodb̲strict̲mode OFF ON

innodb̲temp̲data̲file̲path

N/A ibtmp1:12M:autoextend

innodb̲undo̲log̲truncate

N/A OFF

innodb̲use̲sys̲malloc ON N/A(ON)

internal̲tmp̲disk̲storage̲engine

N/A(MyISAM) InnoDB

163/172

Page 165: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

log̲backward̲compatible̲user̲definitions

N/A OFF

log̲builtin̲as̲identified̲by̲password

N/A OFF

log̲error̲verbosity N/A 3

log̲syslog N/A OFF

log̲syslog̲facility N/A daemon

log̲syslog̲include̲pid N/A ON

log̲syslog̲tag N/A ”“(empty)

log̲timestamps N/A(SYSTEM) UTC

log̲warnings 1 2

max̲execution̲time N/A 0

max̲points̲in̲geometry N/A 65536

164/172

Page 166: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

mysql̲native̲password̲proxy̲users

N/A OFF

ngram̲token̲size N/A 2

offline̲mode N/A OFF

optimizer̲switch snip snip

performance̲schema̲* snip snip

require̲secure̲transport N/A OFF

secure̲file̲priv ”“(empty) /var/lib/mysql-files(rpm, dpkg only)

show̲compatibility̲56 N/A OFF

slave̲net̲timeout 3600 60

slave̲parallel̲type N/A DATABASE

sql̲mode snip snip

165/172

Page 167: MySQL 5.7にやられないためにおぼえておいてほしいこと

変更された暗黙のデフォルト

variable̲name 5.6 default 5.7 default

super̲read̲only N/A OFF

sync̲binlog 0 1

table̲open̲cache̲instances

1 16

thread̲concurrency 10 N/A

timed̲mutexes OFF N/A

transaction̲write̲set̲extraction

N/A OFF

166/172

Page 168: MySQL 5.7にやられないためにおぼえておいてほしいこと

⼼得

向こう1年くらいは新機能には⼿を出さない新しいパラメーター、変更になったパラメーターは調べておいた⽅がいい

5.5 => 5.6は⼀部を除いてそんなに影響はなかった(し、オンラインで変更できるものが多かった)

-

5.6の時と同じペースなら、GAから1年後くらいにアーリーマジョリティーが出てくるかなってところ。既存のものを置き換えるよりは、まっさらなサービスを作るタイミングで積極的に 地雷を踏み抜く 運⽤上の問題を洗い出していく踏み抜いた 罠 運⽤上の問題を共有してもらえれば、次の⼈はうまくいく

-167/172

Page 169: MySQL 5.7にやられないためにおぼえておいてほしいこと

罠 #とは

知らないところに置かれているといきなり⾷らって致命傷になることがある置いてある場所がわかって、どんな罠だかがわかって、解除の⽅法を知っていれば致命傷にはならないみんなで知れば怖くない<censored>

168/172

Page 170: MySQL 5.7にやられないためにおぼえておいてほしいこと

発⾒報告はたとえばこんなところに

⽇本MySQLユーザ会メーリングリストメーリングリストに登録するだけで⽇本MySQLユーザ会員なんですよ知ってました︖

-

中の⼈も⾒てたり、真⾯目成分多め-MySQL Casual Slackユーザー成分多め-

Qiita、ブログその他⾃⾝の情報発信場所

169/172

Page 171: MySQL 5.7にやられないためにおぼえておいてほしいこと

よろしくお願いします

170/172

Page 172: MySQL 5.7にやられないためにおぼえておいてほしいこと

それでは、楽しいPHP 7 + MySQL

5.7ライフを :)171/172

Page 173: MySQL 5.7にやられないためにおぼえておいてほしいこと

Questions and/or

Suggestions?172/172