GA

2024/03/05

MySQLのCHECKSUM TABLEは特別なことをせずに愚直に行を全部読んでチェックサムを取っている

TL;DR

  • タイトルが全て
  • インデックスの情報は考慮しないのでインデックスが違ってもチェックサムは一致する
  • 最終的に行ごとのチェックサムを合計しているので行の順番が違ってもチェックサムは一致する

CHECKSUM TABLE は不思議なちからでテーブルのチェックサムを計算しているかのように思えるかも知れないがさにあらず。
実に地味に1行1フィールドずつ読んでチェックサムを取っている。

https://github.com/mysql/mysql-server/blob/mysql-8.0.36/sql/sql_table.cc#L18745-L18904

ということは、データ型が同じ扱いになるやつや行の順番には関係がないので CHECKSUM TABLE が通ることがある…?

  • PKあり vs PKなし、データ型いっしょ、行の順番違う

    • CHECKSUMいっしょ
mysql80 40> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` bigint unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 40> SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `num` bigint unsigned NOT NULL,
  `val` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 40> SELECT * FROM t1;
+-----+------+
| num | val  |
+-----+------+
|   1 | one  |
|   2 | two  |
+-----+------+
2 rows in set (0.00 sec)

mysql80 40> SELECT * FROM t2;
+-----+------+
| num | val  |
+-----+------+
|   2 | two  |
|   1 | one  |
+-----+------+
2 rows in set (0.00 sec)

mysql80 40> CHECKSUM TABLE t1, t2;
+-------+------------+
| Table | Checksum   |
+-------+------------+
| d1.t1 | 4082666774 |
| d1.t2 | 4082666774 |
+-------+------------+
2 rows in set (0.00 sec)
  • varchar vs char, 行の順番一緒

    • 違うのになる
mysql80 40> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `val` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 40> SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `val` char(32) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 40> CHECKSUM TABLE t1, t2;
+-------+------------+
| Table | Checksum   |
+-------+------------+
| d1.t1 | 1816645479 |
| d1.t2 | 2736998372 |
+-------+------------+
2 rows in set (0.00 sec)
  • varchar(32) vs varchar(255), 行の順番一緒

    • 同じのになる
mysql80 40> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `val` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 40> SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `val` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

mysql80 40> CHECKSUM TABLE t1, t2;
+-------+------------+
| Table | Checksum   |
+-------+------------+
| d1.t1 | 1816645479 |
| d1.t2 | 1816645479 |
+-------+------------+
2 rows in set (0.00 sec)

あなたの知らない CHECKSUM TABLE の世界

0 件のコメント :

コメントを投稿