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

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

2019/05/23 Middlewares Deep Talks
https://middlewaresdeeptalkstokyo20190.splashthat.com/

0deae06ab5d86b39feeec2e23a30b88a?s=128

yoku0825

May 23, 2019
Tweet

Transcript

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

  2. 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
  3. 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
  4. 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
  5. すごい () 4/118

  6. 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
  7. すごい () 6/118

  8. GA #と は 7/118

  9. \こんばんは/ yoku0825@とある企業のDBA オラクれない ‐ ポスグれない ‐ マイエスキューエる ‐ 生息域 Twitter:

    @yoku0825 ‐ Blog: 日々の覚書 ‐ 日本MySQLユーザ会 ‐ MySQL Casual ‐ 8/118
  10. ぼくらが8.0に 至ったみちの り(踏破) 9/118

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

  12. 前日譚か ら半年 11/118

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

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

  15. インスタンスの特徴 2011年にMySQL 5.5でサービス開始 文字コードは (3バイト) UTF-8 ‐ 接続元アプリケーションはJava ‐ テーブルは

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    ‐ 「メンテナンス日程は新規開発のリリースメンテと合わせてやること になりました」 ‐ 28/118
  30. という訳 で 29/118

  31. 開発開始時 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
  32. スレーブから先にバージョンを上げて 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
  33. 上げて 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
  34. 上げて 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
  35. 開発が終わり 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
  36. データコンバートのリハーサルがされ 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
  37. カットーバー当日 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
  38. データのコンバートが終わってから 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
  39. ガシャッ 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
  40. やった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
  41. :(;゙゚’ω゚’): な んか俺が考えて たのと違う 40/118

  42. 今もこのまま動いています 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
  43. この過程で気が付い たMySQL 8.0の良 いところ/悪いとこ ろをそっと伝えます 42/118

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

    ‐ 43/118
  45. MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数

    Window関数 CTE(WITH句) 式インデックス 44/118
  46. MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 45/118

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

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

    47/118
  49. MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数

    Window関数 CTE(WITH句) 式インデックス 48/118
  50. 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
  51. SELECT .. FOR UPDATE SKIP LOCKED キュー的な処理向き Q4Mのようにwaitしてくれる訳ではなくて、自前でスピン する必要がある InnoDBの特性をそのまま使えるのはすごく良いんだけれど

    この令和の時代にMySQLでキューを新しく実装することが あるんだろうか…? 50/118
  52. イマイチ 51/118

  53. MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数

    Window関数 CTE(WITH句) 式インデックス 52/118
  54. 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
  55. JSON_TABLE関数 今までのJSON関数と違うのは、「JSONの配列型の部分を行 として扱ってFROM句サブクエリーにできること」 JSON型は使ってるけど、飽くまでアプリケーション側でシ リアライズするよなぁ… 固定の要素をカラムに切り出すだけならgenerated columnで十分だ し ‐ 54/118

  56. イマイチ 55/118

  57. MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数

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

  62. 61/118

  63. MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数

    Window関数 CTE(WITH句) 式インデックス 62/118
  64. 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
  65. 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
  66. CTE(WITH句) 管理画面とか分析的なクエリーは見通しが良くなった しかしまあそういう分析的なクエリーってMySQL遅いよ ね… 書けるようになったし速度も改善されているんだけど、やっぱりそこ まで劇的に速くなったわけではない ‐ もともと分析クエリーをMySQLでさばいていたので、見通 しが良くなっただけでも良かったとしよう 65/118

  67. まあまあ 66/118

  68. MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数

    Window関数 CTE(WITH句) 式インデックス 67/118
  69. 式インデックス 事前に計算できる(= 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
  70. ( ゚д゚) 69/118

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

    71/118
  73. イマイチ 72/118

  74. MySQL 8.0に期待していたこと SELECT .. FOR UPDATE SKIP LOCKED JSON_TABLE 関数

    Window関数 CTE(WITH句) 式インデックス 73/118
  75. MySQL 8.0で危ういと思っていたこと 新しいデータディクショナリー SQLパーザーのリファクタリング SET PERSIST utf8mb4_0900_ai_ci caching_sha2_password 認証プラグインのデフォルト化 74/118

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

  77. 新しいデータディクショナリー 全てのテーブルへのアクセスのベースになるので、 「新機 能 使わなければ 大丈夫」 といった五七五が効かない 何かあった時に回避が難しい ‐ ド新規で作ったテーブルはちゃんとテストされているだろう

    けど、特にMySQL 5.7未満からアップグレードを重ねてき たMySQLには㌧でもないテーブル定義が埋まっていたりす る 何故かテーブルコメントがSJISで書かれたテーブル ‐ lower_case_table_names= 1と相性が悪い… ‐ 76/118
  78. 予想通り 77/118

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

  80. SQLパーザーのリファクタリング 地味に(?)リファクタしたらしい MySQL 8.0: Refactoring and Improving the Parser |

    MySQL Server Blog ‐ それはそれで良いんだけど、これも全アクセスの礎になって 回避しようがない部分… Window関数やCTEの追加でごりっと手を入れるからついで に(?)リファクタなのかなあ 5.7の時もパーザーのリファクタはやりたいって言ってたしなあ ‐ 79/118
  81. SQLパーザーのリファクタリング 拍子抜けするくらい何もなかった パーザーとは関係ないところで、今まで通ってた管理用のクエリーが 通らなくなった(廃止になった構文がある)とか予約語が増えたとか はある ‐ 偉いぞ 80/118

  82. よかった 81/118

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

  84. SET PERSIST SET GLOBAL は現在の設定値を更新するだけで mysqld を再起 動すると揮発する 永続化させたければ自分で my.cnf

    を更新しないといけない ‐ SET PERSIST は現在の設定値を更新した上で $datadir/ mysqld-auto.cnf に変更内容を記録する SQLインターフェイスだけで設定の永続化までやってくれる ‐ 83/118
  85. 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
  86. SET PERSIST MySQL開発チームの中の人とかは、「my.cnfを編集できな い、SQLインターフェイスしかないマネージドなMySQLで も設定変更を可能に」的なことを言っていたけど そもそも SET GLOBAL や SET

    PERSIST に必要なSuper権限を認めてい ないマネージドMySQLとか ‐ 提供している側からすれば「どっちが優先されるの問題」でエンド ユーザーに混乱を招く原因になりかねないとか ‐ 稼働中にいきなり着火する系ではないのが救い 85/118
  87. イマイチ 86/118

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

  89. utf8mb4_0900_ai_ci character_set_server のデフォルトが latin1 から utf8mb4 に こっちはそのまま使ってる日本人は少ないと思うので別にいいと思う けど ‐

    character_set_server= utf8mb4 の時のデフォルトの照合順 序が変更になった utf8mb4_general_ci から utf8mb4_0900_ai_ci に ‐ 88/118
  90. 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
  91. 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
  92. utf8mb4_0900_ai_ci 問題になりそうな場合は collation_server の変更を忘れず に 個人的には utf8mb4_bin, メールアドレスとかで大文字小文字を握り つぶしたいなら utf8mb4_general_ci

    かなぁ… ‐ これはMySQL 8.0の最初期から言ってきたことなので、み んな既に知っていることだといいな… 91/118
  93. 気を付け てね! 92/118

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

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

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

    日々の覚書: MySQL 8.0のcaching_sha2_password + 非SSL接続 が転ける ‐ 95/118
  97. 気を付け てね! 96/118

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

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

  100. Instant ADD COLUMN MySQL 5.6とそれ以降の「オンラインALTER TABLE」とは 違うもの オンラインで(= テーブルへの書き込みを許容しながら)実行できる 点は一緒

    ‐ 「既存の行の再構築を行わずにメタデータの調整だけでカラ ムを追加する」という超絶技術 99/118
  101. 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
  102. 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
  103. 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
  104. INSTANT ADD COLUMN どういう黒魔術使ってるんだってくらい速い MySQL 8.0: InnoDB now supports Instant

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

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

  107. 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
  108. 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
  109. 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
  110. ROLE 「すいませんやっぱりスキーマの名前をへんk」 ( д ) ゚ ゚ ファー 109/118

  111. 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
  112. 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
  113. ROLE IPアドレス単位でアカウントを作成している現場にはとても 便利だと思う MySQLアカウントのIPアドレスの制限をせずに、セキュリティーグ ループとかで制限する環境には特に嬉しくもないかも ‐ デフォルトロールのみだと「アカウントのグルーピング」に 留まるけれども ロールの継承 ‐

    SET ROLE による sudo ちっくな動き ‐ この辺りを上手く使うと、ワンタイム権限の払い出しが楽になるかも ‐ 112/118
  114. 積極的に使っ ていきたい 113/118

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

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

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

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

  119. Any Questions and/or Suggestions? 118/118