Slide 1

Slide 1 text

ぼくらが8.0に至ったみちのり(踏 破) おらにえデータストアサミット 2019/05/23 yoku0825 Middlewares Deep Talks

Slide 2

Slide 2 text

MySQL 8.0 mysql80 160> SELECT CURDATE() /* JST */; +------------+ | CURDATE() | +------------+ | 2018-04-20 | +------------+ 1 row in set (0.00 sec) mysql80 160> SELECT @@version; +-----------+ | @@version | +-----------+ | 8.0.11 | +-----------+ 1 row in set (0.00 sec) 1/118

Slide 3

Slide 3 text

MySQL 8.0 mysql80 101493> SELECT CURDATE() /* JST */; +------------+ | CURDATE() | +------------+ | 2019-05-23 | +------------+ 1 row in set (0.00 sec) mysql80 101493> SELECT @@version; +-----------+ | @@version | +-----------+ | 8.0.16 | +-----------+ 1 row in set (0.00 sec) 2/118

Slide 4

Slide 4 text

MySQL 8.0 ナッツシェル( What is New in MySQL 8.0 の章)が何故か どんどん増える $ curl -L -s https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshe ll.html | perl -nlE 'if ($_ =~ /(8\.0\.\d+)/) { say $1 }' | sort -t "." -k 3 -n | uniq -c 1 8.0.0 3 8.0.2 3 8.0.3 2 8.0.4 2 8.0.12 6 8.0.13 6 8.0.14 8 8.0.16 8.0.15はガチで8.0.14のリグレッションを1件だけ直した「メンテナンスリリース」だった。よってWhat is Newの中にはない 3/118

Slide 5

Slide 5 text

すごい () 4/118

Slide 6

Slide 6 text

MySQL 8.0 「メンテナンスリリース」 だと言い張る The MySQL 8.0.12 Maintenance Release is Generally Available | MySQL Server Blog ‐ The MySQL 8.0.13 Maintenance Release is Generally Available | MySQL Server Blog ‐ The MySQL 8.0.14 Maintenance Release is Generally Available | MySQL Server Blog ‐ The MySQL 8.0.16 Maintenance Release is Generally Available | MySQL Server Blog ‐ 8.0.15はガチで8.0.14のリグレッションを1件だけ直した「メンテナンスリリース」だった。よって公式ブログに記事は無い() 5/118

Slide 7

Slide 7 text

すごい () 6/118

Slide 8

Slide 8 text

GA #と は 7/118

Slide 9

Slide 9 text

\こんばんは/ yoku0825@とある企業のDBA オラクれない ‐ ポスグれない ‐ マイエスキューエる ‐ 生息域 Twitter: @yoku0825 ‐ Blog: 日々の覚書 ‐ 日本MySQLユーザ会 ‐ MySQL Casual ‐ 8/118

Slide 10

Slide 10 text

ぼくらが8.0に 至ったみちの り(踏破) 9/118

Slide 11

Slide 11 text

前日譚 - ぼくらが 8.0にいたるまでの みちのり(未到) 10/118

Slide 12

Slide 12 text

前日譚か ら半年 11/118

Slide 13

Slide 13 text

MySQL 8.0.15、本番 導入しました! 12/118

Slide 14

Slide 14 text

ド新規でいきたかっ たんですがバージョ ンアップです 13/118

Slide 15

Slide 15 text

インスタンスの特徴 2011年にMySQL 5.5でサービス開始 文字コードは (3バイト) UTF-8 ‐ 接続元アプリケーションはJava ‐ テーブルは ほぼ InnoDBストレージエンジン ‐ 2016年、MySQL 5.6バージョンアップ 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ‐ 14/118

Slide 16

Slide 16 text

インスタンスの特徴 2011年にMySQL 5.5でサービス開始 文字コードは (3バイト) UTF-8 ‐ 接続元アプリケーションはJava ‐ テーブルは ほぼ InnoDBストレージエンジン ‐ 2016年、MySQL 5.6バージョンアップ 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ‐ 15/118

Slide 17

Slide 17 text

インスタンスの特徴 2011年にMySQL 5.5でサービス開始 文字コードは (3バイト) UTF-8 ←救いだった ‐ 接続元アプリケーションはJava ‐ テーブルは ほぼ InnoDBストレージエンジン ‐ 2016年、MySQL 5.6バージョンアップ 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ‐ 16/118

Slide 18

Slide 18 text

インスタンスの特徴 2011年にMySQL 5.5でサービス開始 文字コードは (3バイト) UTF-8 ←救いだった ‐ 接続元アプリケーションはJava ‐ テーブルは ほぼ InnoDBストレージエンジン ‐ 2016年、MySQL 5.6バージョンアップ 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ← 5.7どこ行っ た? ‐ 17/118

Slide 19

Slide 19 text

インスタンスの特徴 2011年にMySQL 5.5でサービス開始 文字コードは (3バイト) UTF-8 ←救いだった ‐ 接続元アプリケーションはJava ‐ テーブルは ほぼ InnoDBストレージエンジン ‐ 2016年、MySQL 5.6バージョンアップ 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ← 5.7どこ行っ た? データ作り直しだからいいんじゃね? ‐ 18/118

Slide 20

Slide 20 text

インスタンスの特徴 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ← 5.7どこ行っ た? データ作り直しだからいいんじゃね? ‐ 2018年秋、既存のデータもアプリも捨てられないことが確 定 19/118

Slide 21

Slide 21 text

インスタンスの特徴 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ← 5.7どこ行っ た? データ作り直しだからいいんじゃね? ‐ 2018年秋、既存のデータもアプリも捨てられないことが確 定 MySQL 5.6から8.0へのレプリケーションでのデータ移行 ‐ 20/118

Slide 22

Slide 22 text

インスタンスの特徴 2018年、アプリケーションのフルスクラッチリファクタリ ング(?)が決定 接続元アプリケーションはPHP(Laravel)に変更 ‐ MySQLも8.0にバージョンアップすることが決定 ← 5.7どこ行っ た? データ作り直しだからいいんじゃね? ‐ 2018年秋、既存のデータもアプリも捨てられないことが確 定 MySQL 5.6から8.0へのレプリケーションでのデータ移行 ‐ しかも2011年から継ぎ足され続けた秘伝のJavaがつなぎに来る ‐ 21/118

Slide 23

Slide 23 text

インスタンスの特徴 2018年秋、既存のデータもアプリも捨てられないことが確 定 MySQL 5.6から8.0へのレプリケーションでのデータ移行 ‐ しかも2011年から継ぎ足され続けた秘伝のJavaがつなぎに来る ‐ 2018年冬、気が付く 22/118

Slide 24

Slide 24 text

インスタンスの特徴 2018年秋、既存のデータもアプリも捨てられないことが確 定 MySQL 5.6から8.0へのレプリケーションでのデータ移行 ‐ しかも2011年から継ぎ足され続けた秘伝のJavaがつなぎに来る ‐ 2018年冬、気が付く 5.6から8.0へのレプリケーション、死ぬわ… ‐ 23/118

Slide 25

Slide 25 text

インスタンスの特徴 2018年秋、既存のデータもアプリも捨てられないことが確 定 MySQL 5.6から8.0へのレプリケーションでのデータ移行 ‐ しかも2011年から継ぎ足され続けた秘伝のJavaがつなぎに来る ‐ 2018年冬、気が付く 5.6から8.0へのレプリケーション、死ぬわ… 主にSQLスレッドと俺の心が ‐ 24/118

Slide 26

Slide 26 text

インスタンスの特徴 2018年秋、既存のデータもアプリも捨てられないことが確 定 MySQL 5.6から8.0へのレプリケーションでのデータ移行 ‐ しかも2011年から継ぎ足され続けた秘伝のJavaがつなぎに来る ‐ 2018年冬、気が付く 5.6から8.0へのレプリケーション、死ぬわ… 主にSQLスレッドと俺の心が サポートされない構成だしな ‐ 25/118

Slide 27

Slide 27 text

インスタンスの特徴 2018年冬、気が付く 5.6から8.0へのレプリケーション、死ぬわ… 主にSQLスレッドと俺の心が サポートされない構成だしな ‐ 「せめて今のマスターを5.7にバージョンアップせねば…」 ‐ 26/118

Slide 28

Slide 28 text

インスタンスの特徴 2018年冬、気が付く 5.6から8.0へのレプリケーション、死ぬわ… 主にSQLスレッドと俺の心が サポートされない構成だしな ‐ 「せめて今のマスターを5.7にバージョンアップせねば…」 ‐ 「調整の結果、新規の開発とは別件としてバージョンアップを進める ことになりました」 ‐ 27/118

Slide 29

Slide 29 text

インスタンスの特徴 2018年冬、気が付く 5.6から8.0へのレプリケーション、死ぬわ… 主にSQLスレッドと俺の心が サポートされない構成だしな ‐ 「せめて今のマスターを5.7にバージョンアップせねば…」 ‐ 「調整の結果、新規の開発とは別件としてバージョンアップを進める ことになりました」 ‐ 「メンテナンス日程は新規開発のリリースメンテと合わせてやること になりました」 ‐ 28/118

Slide 30

Slide 30 text

という訳 で 29/118

Slide 31

Slide 31 text

開発開始時 master(5.6) schema1 schema2 slave(5.6) schema1 schema2 slave(5.6) schema1 schema2 slave(5.6) schema1 schema2 slave(8.0) schema1 schema2 schema3 30/118

Slide 32

Slide 32 text

スレーブから先にバージョンを上げて master(5.6) schema1 schema2 slave(5.7) schema1 schema2 slave(5.6) schema1 schema2 slave(5.6) schema1 schema2 slave(8.0) schema1 schema2 schema3 31/118

Slide 33

Slide 33 text

上げて master(5.6) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.6) schema1 schema2 slave(8.0) schema1 schema2 schema3 32/118

Slide 34

Slide 34 text

上げて master(5.6) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 33/118

Slide 35

Slide 35 text

開発が終わり master(5.6) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 34/118

Slide 36

Slide 36 text

データコンバートのリハーサルがされ master(5.6) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 35/118

Slide 37

Slide 37 text

カットーバー当日 master(5.6) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 36/118

Slide 38

Slide 38 text

データのコンバートが終わってから master(5.6) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 37/118

Slide 39

Slide 39 text

ガシャッ master(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 38/118

Slide 40

Slide 40 text

やった5.7から8.0ならレプリケーションが上手く… master(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 39/118

Slide 41

Slide 41 text

:(;゙゚’ω゚’): な んか俺が考えて たのと違う 40/118

Slide 42

Slide 42 text

今もこのまま動いています master(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(5.7) schema1 schema2 slave(8.0) schema1 schema2 schema3 41/118

Slide 43

Slide 43 text

この過程で気が付い たMySQL 8.0の良 いところ/悪いとこ ろをそっと伝えます 42/118

Slide 44

Slide 44 text

Why MySQL 8.0? iPhoneと同じで、 深い意味はないけど最新が使いたい ‐ リグレッションはあるかも知れないけれどそれで8割方は良い体験が 得られる ‐ 一度最新を使うともう過去には戻れない ‐ 43/118

Slide 45

Slide 45 text

MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数 Window関数 CTE(WITH句) 式インデックス 44/118

Slide 46

Slide 46 text

MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 45/118

Slide 47

Slide 47 text

MySQL 8.0の予想外に良かったところ Instant ADD COLUMN ROLE 46/118

Slide 48

Slide 48 text

まだまだあるぞ試してない新機能 RESOURCE GROUP CHECK制約 partial_revoke パラレルIndex READ JSONのパーシャルアップデート in binlog 47/118

Slide 49

Slide 49 text

MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数 Window関数 CTE(WITH句) 式インデックス 48/118

Slide 50

Slide 50 text

SELECT .. FOR UPDATE SKIP LOCKED mysql80 28> SELECT * FROM t1 ORDER BY num LIMIT 1 FOR UPDATE; +-----+------+ | num | val | +-----+------+ | 1 | one | +-----+------+ 1 row in set (0.00 sec) mysql80 29> SELECT * FROM t1 ORDER BY num LIMIT 1 FOR UPDATE; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql80 29> SELECT * FROM t1 ORDER BY num LIMIT 1 FOR UPDATE SKIP LOCKED; +-----+------+ | num | val | +-----+------+ | 2 | two | +-----+------+ 1 row in set (0.00 sec) 49/118

Slide 51

Slide 51 text

SELECT .. FOR UPDATE SKIP LOCKED キュー的な処理向き Q4Mのようにwaitしてくれる訳ではなくて、自前でスピン する必要がある InnoDBの特性をそのまま使えるのはすごく良いんだけれど この令和の時代にMySQLでキューを新しく実装することが あるんだろうか…? 50/118

Slide 52

Slide 52 text

イマイチ 51/118

Slide 53

Slide 53 text

MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数 Window関数 CTE(WITH句) 式インデックス 52/118

Slide 54

Slide 54 text

JSON_TABLE関数 SELECT DISTINCT tweet_id, LEFT(REPLACE(text, '\n', '\\n'), 16) AS text FROM t2, JSON_TABLE(t2.j, '$.statuses[*]' COLUMNS ( tweet_id NUMERIC(32) PATH '$.id', text VARCHAR(300) PATH '$.text' ) ) AS json; +---------------------+----------------------+ | tweet_id | text | +---------------------+----------------------+ | 1131026738492739584 | @ikaneko MySQLメイ | | 1131025041070497792 | LAMP環境\n\nLinux, | | 1131024962121281536 | RT @OracleDev_JP | | 1131026921276317697 | RT @sirius_gener | +---------------------+----------------------+ 4 rows in set (0.00 sec) 53/118

Slide 55

Slide 55 text

JSON_TABLE関数 今までのJSON関数と違うのは、「JSONの配列型の部分を行 として扱ってFROM句サブクエリーにできること」 JSON型は使ってるけど、飽くまでアプリケーション側でシ リアライズするよなぁ… 固定の要素をカラムに切り出すだけならgenerated columnで十分だ し ‐ 54/118

Slide 56

Slide 56 text

イマイチ 55/118

Slide 57

Slide 57 text

MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数 Window関数 CTE(WITH句) 式インデックス 56/118

Slide 58

Slide 58 text

Window関数 たくさんあるたまごパックの在庫から、賞味期限が古い方か ら順番に100個使う mysql80 51> SELECT * FROM t1 LIMIT 3; +---------+------------+----------------+ | pack_id | egg_amount | expiration_day | +---------+------------+----------------+ | 1 | 4 | 2019-05-23 | | 2 | 1 | 2019-05-25 | | 3 | 4 | 2019-05-25 | +---------+------------+----------------+ 3 rows in set (0.00 sec) 57/118

Slide 59

Slide 59 text

Window関数 たくさんあるたまごパックの在庫から、賞味期限が古い方か ら順番に100個使う mysql80 51> SELECT pack_id, egg_amount, expiration_day, SUM(egg_a mount) OVER (ORDER BY expiration_day, pack_id) AS egg_total FROM t1 LIMIT 3; +---------+------------+----------------+-----------+ | pack_id | egg_amount | expiration_day | egg_total | +---------+------------+----------------+-----------+ | 1 | 4 | 2019-05-23 | 4 | | 27 | 2 | 2019-05-23 | 6 | | 33 | 4 | 2019-05-23 | 10 | +---------+------------+----------------+-----------+ 3 rows in set (0.01 sec) 58/118

Slide 60

Slide 60 text

Window関数 たくさんあるたまごパックの在庫から、賞味期限が古い方か ら順番に100個使う mysql80 51> WITH list AS (SELECT pack_id, egg_amount, expiration_day, SUM(egg_amoun t) OVER (ORDER BY expiration_day, pack_id) AS egg_total FROM t1), -> last_one AS (SELECT * FROM list WHERE egg_total >= 100 ORDER BY eg g_total LIMIT 1) -> SELECT * FROM list WHERE egg_total < 100 -> UNION ALL -> SELECT * FROM last_one; +---------+------------+----------------+-----------+ | pack_id | egg_amount | expiration_day | egg_total | +---------+------------+----------------+-----------+ | 1 | 4 | 2019-05-23 | 4 | | 27 | 2 | 2019-05-23 | 6 | | 33 | 4 | 2019-05-23 | 10 | .. | 489 | 3 | 2019-05-23 | 96 | | 491 | 5 | 2019-05-23 | 101 | +---------+------------+----------------+-----------+ 41 rows in set (0.04 sec) 59/118

Slide 61

Slide 61 text

Window関数 MySQLには、Window関数がなかったから、あんまり使い 方が思い浮かばないんじゃないか説 有効期限のあるものを古い方からn個…みたいなユースケー スがあって、それにベストマッチした あとはランキング(同着ありとかなしとか)で使えそう Window関数の結果カラムで絞り込みたい場合はCTEと併用 する 60/118

Slide 62

Slide 62 text

61/118

Slide 63

Slide 63 text

MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数 Window関数 CTE(WITH句) 式インデックス 62/118

Slide 64

Slide 64 text

CTE(WITH句) FROM句にいっぱい書き連ねるようなクエリーを WITH で先 頭にくくりだせる SELECT MAX(txt), MIN(txt) FROM ( SELECT concat(cte2.txt, cte3.txt) as txt FROM ( SELECT CONCAT(cte1.txt,'is a ') as txt FROM ( SELECT 'This ' as txt ) as cte1 ) as cte2, ( SELECT 'nice query' as txt UNION SELECT 'query that rocks' UNION SELECT 'query' ) as cte3 ) as cte4; 63/118

Slide 65

Slide 65 text

CTE(WITH句) FROM句にいっぱい書き連ねるようなクエリーを WITH で先 頭にくくりだせる WITH cte1(txt) AS (SELECT "This "), cte2(txt) AS (SELECT CONCAT(cte1.txt,"is a ") FROM cte1), cte3(txt) AS (SELECT "nice query" UNION SELECT "query that rocks" UNION SELECT "query"), cte4(txt) AS (SELECT concat(cte2.txt, cte3.txt) FROM cte2, cte3) SELECT MAX(txt), MIN(txt) FROM cte4; 64/118

Slide 66

Slide 66 text

CTE(WITH句) 管理画面とか分析的なクエリーは見通しが良くなった しかしまあそういう分析的なクエリーってMySQL遅いよ ね… 書けるようになったし速度も改善されているんだけど、やっぱりそこ まで劇的に速くなったわけではない ‐ もともと分析クエリーをMySQLでさばいていたので、見通 しが良くなっただけでも良かったとしよう 65/118

Slide 67

Slide 67 text

まあまあ 66/118

Slide 68

Slide 68 text

MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数 Window関数 CTE(WITH句) 式インデックス 67/118

Slide 69

Slide 69 text

式インデックス 事前に計算できる(= NOW() とかはダメ)値に対して式を通し た値をインデックスにできる 5.7ではgenerated columnを作ってそれにインデックスを足してい たが、カラムなしでインデックスだけドスンと作れる ‐ mysql> ALTER TABLE t1 ADD KEY idx_exp ((age > 20)); mysql> EXPLAIN SELECT .. FROM t1 WHERE age > 20; +----+-------------+-------+------------+------+---------------+------+---------+------+-------+---- ------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | fil tered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+-------+---- ------+-------------+ | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 10195 | 33.33 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+------+-------+---- ------+-------------+ 1 row in set, 1 warning (0.00 sec) 68/118

Slide 70

Slide 70 text

( ゚д゚) 69/118

Slide 71

Slide 71 text

式インデックス…? mysql> EXPLAIN SELECT .. FROM t1 WHERE age > 20; +----+-------------+-------+------------+------+---------------+- -----+---------+------+-------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+- -----+---------+------+-------+----------+-------------+ | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 10195 | 33.33 | Using where | +----+-------------+-------+------------+------+---------------+- -----+---------+------+-------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) 70/118

Slide 72

Slide 72 text

式インデックス オプティマイザーが選ばないインデックスは使われない 不等号とかIN演算子でもインデックス作れるのが良いところだと 思ったのに… ‐ ちょっとコスト計算キツすぎませんかね… ‐ 8.0.12では選ばれたのに… テスト環境では選ばれたのに… その他その他 71/118

Slide 73

Slide 73 text

イマイチ 72/118

Slide 74

Slide 74 text

MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数 Window関数 CTE(WITH句) 式インデックス 73/118

Slide 75

Slide 75 text

MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 74/118

Slide 76

Slide 76 text

新しいデータディクショナリー どのテーブルはどのファイルに格納されてて、カラムのデー タ型は何で…という情報を一元管理するサブシステム ここが平ファイルベースからInnoDBベース( mysql.ibd ファイルに格納される)にガラっと変わった アトミックDDL(DDLに失敗したら完全に元の状態に戻る) が実装されたのもこれのおかげ 75/118

Slide 77

Slide 77 text

新しいデータディクショナリー 全てのテーブルへのアクセスのベースになるので、 「新機 能 使わなければ 大丈夫」 といった五七五が効かない 何かあった時に回避が難しい ‐ ド新規で作ったテーブルはちゃんとテストされているだろう けど、特にMySQL 5.7未満からアップグレードを重ねてき たMySQLには㌧でもないテーブル定義が埋まっていたりす る 何故かテーブルコメントがSJISで書かれたテーブル ‐ lower_case_table_names= 1と相性が悪い… ‐ 76/118

Slide 78

Slide 78 text

予想通り 77/118

Slide 79

Slide 79 text

MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 78/118

Slide 80

Slide 80 text

SQLパーザーのリファクタリング 地味に(?)リファクタしたらしい MySQL 8.0: Refactoring and Improving the Parser | MySQL Server Blog ‐ それはそれで良いんだけど、これも全アクセスの礎になって 回避しようがない部分… Window関数やCTEの追加でごりっと手を入れるからついで に(?)リファクタなのかなあ 5.7の時もパーザーのリファクタはやりたいって言ってたしなあ ‐ 79/118

Slide 81

Slide 81 text

SQLパーザーのリファクタリング 拍子抜けするくらい何もなかった パーザーとは関係ないところで、今まで通ってた管理用のクエリーが 通らなくなった(廃止になった構文がある)とか予約語が増えたとか はある ‐ 偉いぞ 80/118

Slide 82

Slide 82 text

よかった 81/118

Slide 83

Slide 83 text

MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 82/118

Slide 84

Slide 84 text

SET PERSIST SET GLOBAL は現在の設定値を更新するだけで mysqld を再起 動すると揮発する 永続化させたければ自分で my.cnf を更新しないといけない ‐ SET PERSIST は現在の設定値を更新した上で $datadir/ mysqld-auto.cnf に変更内容を記録する SQLインターフェイスだけで設定の永続化までやってくれる ‐ 83/118

Slide 85

Slide 85 text

SET PERSIST /etc/my.cnf と $datadir/mysqld-auto.cnf に同じパラメー ターに対する設定があった場合、優先されるのはどっち? my.cnf 系が読み込まれた後に mysqld-auto.cnf が読まれる ‐ MySQLのパラメーター設定は 後勝ち ‐ つまり mysqld-auto.cnf の方が強い ‐ 「my.cnf編集して再起動したんですけど、 max_connections増えてない…」「それ、mysqld- auto.cnfから読んでるんじゃ?」みたいなことはありそう 84/118

Slide 86

Slide 86 text

SET PERSIST MySQL開発チームの中の人とかは、「my.cnfを編集できな い、SQLインターフェイスしかないマネージドなMySQLで も設定変更を可能に」的なことを言っていたけど そもそも SET GLOBAL や SET PERSIST に必要なSuper権限を認めてい ないマネージドMySQLとか ‐ 提供している側からすれば「どっちが優先されるの問題」でエンド ユーザーに混乱を招く原因になりかねないとか ‐ 稼働中にいきなり着火する系ではないのが救い 85/118

Slide 87

Slide 87 text

イマイチ 86/118

Slide 88

Slide 88 text

MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 87/118

Slide 89

Slide 89 text

utf8mb4_0900_ai_ci character_set_server のデフォルトが latin1 から utf8mb4 に こっちはそのまま使ってる日本人は少ないと思うので別にいいと思う けど ‐ character_set_server= utf8mb4 の時のデフォルトの照合順 序が変更になった utf8mb4_general_ci から utf8mb4_0900_ai_ci に ‐ 88/118

Slide 90

Slide 90 text

utf8mb4_0900_ai_ci collation mysql = MySQL ハハ != パパ びょういん ! = びようい ん != MySQL = M ySQL = != ≠ utf8mb4 _genera l_ci o o o x x o utf8mb4 _0900_ ai_ci o x x o o x utf8mb4 _ja_090 0_as_cs x o o o o o utf8mb4 _bin x o o o x o 89/118

Slide 91

Slide 91 text

utf8mb4_0900_ai_ci kamipoのハハ=パパ問題 ActiveRecordでデフォルトの照合順序を変更する \- Qiita ‐ びょういん=びよういん問題 MySQL Bugs: #79977: utf8mb4_unicode_520_ci don’t make sense for Japanese FTS ‐ イコールイコールノットイコール問題 MySQL Bugs: #92899: Incorrect uniqueness determination with equality symbols ‐ 問題 https://twitter.com/tmtms/status/546925668424896512 ‐ MySQL Bugs: #76553: Sushi\-Beer issue of MySQL with utf8mb4 ‐ 90/118

Slide 92

Slide 92 text

utf8mb4_0900_ai_ci 問題になりそうな場合は collation_server の変更を忘れず に 個人的には utf8mb4_bin, メールアドレスとかで大文字小文字を握り つぶしたいなら utf8mb4_general_ci かなぁ… ‐ これはMySQL 8.0の最初期から言ってきたことなので、み んな既に知っていることだといいな… 91/118

Slide 93

Slide 93 text

気を付け てね! 92/118

Slide 94

Slide 94 text

MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト 化 93/118

Slide 95

Slide 95 text

caching_sha2_password認証プラグイン 新規導入の認証プラグインがデフォルトになるというなかな かデカい これも稼働中に着火する系ではないのが救い ‐ MySQL 5.7.22とそれ以前のバージョンのクライアントには この認証プラグインが存在しない 古いバージョンのライブラリー && デフォルトの設定だと接続がで きない ‐ 94/118

Slide 96

Slide 96 text

caching_sha2_password認証プラグイン これも結構前から言ってきたし、だいたいにしてエラーにな るのでだいぶ浸透している感はある 日々の覚書: MySQL 8.0.4におけるデフォルト認証形式の変更 ‐ しかし接続できないことより罠いのは、「少なくとも最初の 1回はセキュアな方法で接続しなければならない」というク ライアントライブラリーの仕様 日々の覚書: MySQL 8.0のcaching_sha2_password + 非SSL接続 が転ける ‐ 95/118

Slide 97

Slide 97 text

気を付け てね! 96/118

Slide 98

Slide 98 text

MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 97/118

Slide 99

Slide 99 text

MySQL 8.0の予想外に良かったところ Instant ADD COLUMN ROLE 98/118

Slide 100

Slide 100 text

Instant ADD COLUMN MySQL 5.6とそれ以降の「オンラインALTER TABLE」とは 違うもの オンラインで(= テーブルへの書き込みを許容しながら)実行できる 点は一緒 ‐ 「既存の行の再構築を行わずにメタデータの調整だけでカラ ムを追加する」という超絶技術 99/118

Slide 101

Slide 101 text

Instant ADD COLUMN 100万行, 100MBくらいのテーブルに対して mysql80 20> ALTER TABLE t1 ADD c1 int, ALGORITHM= INSTANT; Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql80 20> ALTER TABLE t1 ADD c2 int, ALGORITHM= INPLACE; Query OK, 0 rows affected (3.43 sec) Records: 0 Duplicates: 0 Warnings: 0 100/118

Slide 102

Slide 102 text

INSTANT ADD COLUMN ALGORITHM = INSTANT ----system---- ----total-cpu-usage---- -dsk/total- ---system-- ------mem ory-usage----- --io/total- | time | usr sys idl wai hiq siq | read writ | int csw | used buff cach free | read writ | | 20-11 16:44:56 | 2 1 97 1 0 0 | 0 6409k | 877 996 | 692M 0 172M 127M | 0 222 | | 20-11 16:44:57 | 3 1 96 0 0 0 | 128k 394k | 1545 2509 | 692M 0 172M 127M | 8.00 63.0 | | 20-11 16:44:58 | 2 0 98 0 0 0 | 0 6410k | 901 982 | 692M 0 172M 127M | 0 225 | | 20-11 16:44:59 | 2 1 97 1 0 0 | 3260k 972k | 908 927 | 692M 0 175M 124M | 54.0 41.0 | | 20-11 16:45:00 | 2 0 98 0 0 0 | 0 0 | 641 772 | 692M 0 175M 124M | 0 0 | 17338 buffer_pages_written 2018-11-20 16:44:56 17347 buffer_pages_written 2018-11-20 16:44:57 17547 buffer_pages_written 2018-11-20 16:44:58 17577 buffer_pages_written 2018-11-20 16:44:59 17577 buffer_pages_written 2018-11-20 16:45:00 101/118

Slide 103

Slide 103 text

INSTANT ADD COLUMN ALGORITHM = INPLACE ----system---- ----total-cpu-usage---- -dsk/total- ---system-- ------memory-usage----- --io/total- | time | usr sys idl wai hiq siq | read writ | int csw | used buff ca ch free | read writ | | 20-11 16:45:00 | 2 0 98 0 0 0 | 0 0 | 641 772 | 692M 0 17 5M 124M | 0 0 | | 20-11 16:45:01 | 35 5 49 10 0 0 | 14M 78M | 14k 34k | 692M 0 17 5M 124M | 897 2150 | | 20-11 16:45:02 | 13 5 49 32 0 0 | 37M 51M | 9577 16k | 701M 0 20 5M 85.1M | 1213 3318 | | 20-11 16:45:03 | 19 8 49 23 0 0 | 14M 51M | 12k 18k | 693M 0 20 6M 91.7M | 245 5287 | | 20-11 16:45:04 | 3 2 85 10 0 0 | 6028k 31M | 6985 13k | 693M 0 21 1M 87.7M | 142 3098 | | 20-11 16:45:05 | 2 0 98 0 0 0 | 0 419k | 681 817 | 693M 0 21 1M 87.7M | 0 20.0 | 17577 buffer_pages_written 2018-11-20 16:45:00 18047 buffer_pages_written 2018-11-20 16:45:01 19139 buffer_pages_written 2018-11-20 16:45:02 21147 buffer_pages_written 2018-11-20 16:45:03 21591 buffer_pages_written 2018-11-20 16:45:04 21604 buffer_pages_written 2018-11-20 16:45:05 102/118

Slide 104

Slide 104 text

INSTANT ADD COLUMN どういう黒魔術使ってるんだってくらい速い MySQL 8.0: InnoDB now supports Instant ADD COLUMN | MySQL Server Blog ‐ Tencent Gamesがパッチを寄贈したらしい ぼく「さすが自分たちで使い倒している企業は俺たちが欲しいものをよくわかって いる」 ‐ バッファプールも全然触らなくてすごい 楽しくて笑えてくるレベル ‐ ENUM型の定義変更も ALGORITHM = INSTANT でできるらしい ですよ!!!1 103/118

Slide 105

Slide 105 text

これはいい ものだ 104/118

Slide 106

Slide 106 text

MySQL 8.0の予想外に良かったところ Instant ADD COLUMN ROLE 105/118

Slide 107

Slide 107 text

ROLE IPアドレス単位でアカウント作ってる人にはわかってもらえ るかしらん MySQL側ではホスト部を指定せずに、セキュリティーグループとか で接続元を絞ってる場合はそんなに嬉しくないと思う ‐ mysql> CREATE USER apuser@apserver1; mysql> GRANT ALL ON ap_db.* TO apuser@apserver1; mysql> CREATE USER apuser@apserver2; mysql> GRANT ALL ON ap_db.* TO apuser@apserver2; mysql> CREATE USER apuser@apserver3; mysql> GRANT ALL ON ap_db.* TO apuser@apserver3; .. 106/118

Slide 108

Slide 108 text

ROLE 「すいません、新機能はスキーマを分けて開発することに なったので、既存のアカウントが新スキーマにもアクセスで きるように設定してください」 ( ゚д゚) えっ mysql> GRANT ALL ON new_db.* TO apuser@apserver1; mysql> GRANT ALL ON new_db.* TO apuser@apserver2; mysql> GRANT ALL ON new_db.* TO apuser@apserver3; .. 107/118

Slide 109

Slide 109 text

ROLE 「すいません、新機能はサーバーもわけることになりまし た。既存のアカウントは今まで通りap_dbだけ、新サーバー 用のアカウントはap_dbの読み取りとnew_dbの読み書き権 限を」 ( ゚д゚) えっえっ mysql> REVOKE ALL ON new_db.* FROM apuser@apserver1; mysql> REVOKE ALL ON new_db.* FROM apuser@apserver2; mysql> REVOKE ALL ON new_db.* FROM apuser@apserver3; .. mysql> CREATE USER apuser@apserver11; mysql> GRANT ALL ON new_db.* TO apuser@apserver11; mysql> GRANT SELECT ON ap_db.* TO apuser@apserver11; .. 108/118

Slide 110

Slide 110 text

ROLE 「すいませんやっぱりスキーマの名前をへんk」 ( д ) ゚ ゚ ファー 109/118

Slide 111

Slide 111 text

ROLE mysql> CREATE ROLE ap_rw; mysql> GRANT ALL ON ap_db.* TO ap_rw; mysql> CREATE USER apuser@apserver1 DEFAULT ROLE ap_rw; mysql> CREATE USER apuser@apserver2 DEFAULT ROLE ap_rw; mysql> CREATE USER apuser@apserver3 DEFAULT ROLE ap_rw; .. 110/118

Slide 112

Slide 112 text

ROLE mysql> GRANT ALL ON new_db.* TO ap_rw; mysql> REVOKE ALL ON new_db.* FROM ap_rw; mysql> CREATE ROLE ap_ro; mysql> GRANT SELECT ON ap_db.* TO ap_ro; mysql> CREATE ROLE new_rw; mysql> GRANT ALL ON new_db.* TO new_rw; mysql> GRANT ap_ro TO new_rw; mysql> CREATE USER apuser@apserver11 DEFAULT ROLE new_rw; .. 111/118

Slide 113

Slide 113 text

ROLE IPアドレス単位でアカウントを作成している現場にはとても 便利だと思う MySQLアカウントのIPアドレスの制限をせずに、セキュリティーグ ループとかで制限する環境には特に嬉しくもないかも ‐ デフォルトロールのみだと「アカウントのグルーピング」に 留まるけれども ロールの継承 ‐ SET ROLE による sudo ちっくな動き ‐ この辺りを上手く使うと、ワンタイム権限の払い出しが楽になるかも ‐ 112/118

Slide 114

Slide 114 text

積極的に使っ ていきたい 113/118

Slide 115

Slide 115 text

MySQL 8.0の予想外に良かったところ Instant ADD COLUMN ROLE 114/118

Slide 116

Slide 116 text

まだまだあるぞ試してない新機能 RESOURCE GROUP CHECK制約 partial_revoke パラレルIndex READ JSONのパーシャルアップデート in binlog 115/118

Slide 117

Slide 117 text

まとめ Window関数 CTE(WITH句) 新しいデータディクショナリー utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 Instant ADD COLUMN ROLE 116/118

Slide 118

Slide 118 text

あなたと マイエスキューエル 今すぐ アップグレー ド 117/118

Slide 119

Slide 119 text

Any Questions and/or Suggestions? 118/118