TL;DR
- タイトルが全て
- インデックスの情報は考慮しないのでインデックスが違ってもチェックサムは一致する
- 最終的に行ごとのチェックサムを合計しているので行の順番が違ってもチェックサムは一致する
CHECKSUM TABLE は不思議なちからでテーブルのチェックサムを計算しているかのように思えるかも知れないがさにあらず。
実に地味に1行1フィールドずつ読んでチェックサムを取っている。
https://github.com/mysql/mysql-server/blob/mysql-8.0.36/sql/sql_table.cc#L18745-L18904
field_listに結果セットのカラム情報みたいなのを突っ込んで
thd->send_result_metadata
を呼ぶところはまさに結果セットのカラム情報を作っているところ。for (table = tables; table; table = table->next_local)
ってことはCHECKSUM TABLEって複数のテーブル一括指定できるのかなって思ったらやっぱりできるprotocol->start_row()
が「ここから結果セットの行を始めるよ」,protocol->store(table_name, system_charset_info)
が「次のカラムにtable_name
をsystem_charset_info
の文字コードで入れるよ」HA_HAS_CHECKSUM
はストレージエンジンが持つ属性(ha_table_flags
)の一つでなんかMyISAMっぽいなと思ったらやっぱりMyISAM専用だった。これが立ってると直接ストレージエンジンからCHECKSUMを返せるらしい- https://github.com/mysql/mysql-server/blob/mysql-8.0.36/sql/handler.h#L314-L317
- https://dev.mysql.com/doc/refman/8.0/ja/create-table.html#:~:text=%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82-,CHECKSUM,%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AF%E3%80%81%E3%81%93%E3%81%AE%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%B5%E3%83%A0%E3%82%92%E3%83%AC%E3%83%9D%E3%83%BC%E3%83%88%E3%81%97%E3%81%BE%E3%81%99%E3%80%82%20(MyISAM%20%E3%81%AE%E3%81%BF%E3%80%82),-%5BDEFAULT%5D%20COLLATE
CHECKSUM = 1
なんてテーブルオプション知らなかった…
HA_HAS_CHECKSUM
を持っていない(InnoDBは常に持っていない) かCHECKSUM TABLE .. EXTENDED
で指定している場合は愚直なループに突っ込んでいくhttps://github.com/mysql/mysql-server/blob/mysql-8.0.36/sql/sql_table.cc#L18821-L18874
1行ずつ読んで、1カラムずつ右にずらしながらcrc32の値を足し続けるらしい
ということは、データ型が同じ扱いになるやつや行の順番には関係がないので 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 件のコメント :
コメントを投稿