Skip to content

Commit ed7a959

Browse files
Add new summaries
1 parent 812c758 commit ed7a959

File tree

4 files changed

+188
-0
lines changed

4 files changed

+188
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
layout: post
3+
---
4+
# 坑爹的字符集问题:踩到了 MySQL 的 bug - V2EX
5+
- URL: [原文](https://www.v2ex.com/t/1133409)
6+
- Added At: 2025-05-22 01:19:39
7+
- [Link To Text](_posts/2025-05-22-坑爹的字符集问题:踩到了-mysql-的-bug---v2ex_raw.md)
8+
9+
## TL;DR
10+
在使用`utf8mb4_bin`校对规则的MySQL/OceanBase中,由于换行符小于空格,导致`like 'abc%'`查询在有索引的情况下无法匹配包含换行符的数据。`explain`显示查询被优化为范围查询,但范围计算错误。该问题已报告给MySQL但尚未解决,作者将持续关注并更新进展。
11+
12+
13+
## Summary
14+
1. **问题发现**:同事在MySQL测试中发现使用`like`查询无法匹配到数据。
15+
16+
2. **问题代码**
17+
- 创建表结构:`create table t1 ( c1 varchar(16), key idx (c1) ) collate=utf8mb4_bin;`
18+
- 插入数据:`insert into t1 values ('000\n'), ('123\n'), ('abc\n');`
19+
- 查询语句:`select * from t1 where c1 like 'abc%';`
20+
- 预期结果:应该匹配出 `'abc\n'`,但实际查询结果为空。
21+
22+
3. **OceanBase验证**:在OceanBase上执行相同语句,结果也为空。
23+
24+
4. **索引影响**
25+
- 删除索引后:`alter table t1 drop index idx;`
26+
- 再次查询:`select * from t1 where c1 like 'abc%';`
27+
- 查询结果:成功匹配到 `'abc\n'`,说明索引导致了查询异常。
28+
29+
5. **Explain分析**
30+
- 使用`explain format=tree`分析带索引的查询:
31+
- 查询优化为范围查询:`Covering index range scan on t1 using idx over ('abc' <= c1 <= 'abc?????????????')`
32+
- 后面的`?`实际是`0xff`
33+
34+
6. **校对规则**
35+
- 设置连接校对规则:`set collation_connection=utf8mb4_bin;`
36+
- 比较`'abc\n'``'abc'`的大小:`select 'abc\n' < 'abc';`
37+
- 结果显示`'abc\n' < 'abc'`为真,即`'abc\n'`小于`'abc'`
38+
39+
7. **字符集信息**
40+
- 查看`utf8mb4_bin`的校对规则:`show collation like 'utf8mb4_bin';`
41+
- `Pad_attribute``PAD SPACE`,表示长度对齐时补空格。
42+
- 空格(`0x20`)比换行符(`0x0a`)大。
43+
44+
8. **问题结论**:在`utf8mb4_bin`校对规则下,`'abc\n'`小于`'abc'`,导致`like 'abc%'`的范围查询优化出现问题。
45+
46+
9. **Bug状态**
47+
- 已向MySQL提交patch,但未被关注。
48+
- 其他patch已被合并,但此问题仍然存在。
49+
50+
10. **未来计划**:如果问题得到解决,将会更新进展。
51+
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
layout: post
3+
---
4+
Title: 坑爹的字符集问题:踩到了 MySQL 的 bug - V2EX
5+
6+
URL Source: https://www.v2ex.com/t/1133409
7+
8+
Published Time: 2025-05-22T00:33:27Z
9+
10+
Markdown Content:
11+
昨天的 [/t/1133223](https://www.v2ex.com/t/1133223) 吸引了大家不少的讨论,今天我来说一个工作上遇到的问题。
12+
13+
准确地说,这个问题是 MySQL 字符集中的校对规则出了 BUG ,字符集本身是无辜的。
14+
15+
这个 bug 现在都还在,欢迎大家验证哈。
16+
17+
* * *
18+
19+
故事是这样的。
20+
21+
同事在连 MySQL 库做测试时发现了一个诡异的现象:查不到匹配的数据。
22+
23+
相关语句简化如下(主键等字段已省略):
24+
25+
```
26+
create table t1 ( c1 varchar(16), key idx (c1) ) collate=utf8mb4_bin;
27+
28+
insert into t1 values ('000\n'), ('123\n'), ('abc\n');
29+
30+
select * from t1 where c1 like 'abc%';
31+
```
32+
33+
这怎么看,都应该匹配出 `'abc\n'`,对吧?
34+
35+
事实情况是:
36+
37+
```
38+
mysql> select * from t1 where c1 like 'abc%';
39+
Empty set (0.00 sec)
40+
```
41+
42+
天塌了,查出来竟然是空的。
43+
44+
然后我拿同样的语句在 OceanBase 上跑了一下,竟然也是空。(两眼一黑)
45+
46+
* * *
47+
48+
可能会有人说,那肯定是你写的语句有问题,或者 utf8mb4_bin 就这样,吧啦吧啦。
49+
50+
那如果这样呢:
51+
52+
```
53+
mysql> alter table t1 drop index idx;
54+
Query OK, 0 rows affected (0.001 sec)
55+
Records: 0 Duplicates: 0 Warnings: 0
56+
57+
mysql> select * from t1 where c1 like 'abc%';
58+
+------+
59+
| c1 |
60+
+------+
61+
| abc
62+
|
63+
+------+
64+
1 row in set (0.001 sec)
65+
```
66+
67+
哎,索引删了就好了。
68+
69+
总不能说,加个索引,能把结果集搞没吧。那肯定 bug 了。
70+
71+
* * *
72+
73+
那到底是咋回事呢:带上索引,我们 explain 看一下。
74+
75+
```
76+
mysql> explain format=tree select * from t1 where c1 like 'abc%' \G
77+
*************************** 1. row ***************************
78+
EXPLAIN: -> Filter: (t1.c1 like 'abc%') (cost=0.46 rows=1)
79+
-> Covering index range scan on t1 using idx over ('abc' <= c1 <= 'abc?????????????') (cost=0.46 rows=1)
80+
81+
1 row in set (0.001 sec)
82+
```
83+
84+
原来这个前置匹配,因为有索引,优化为了范围查询。后面的一串 `?` 其实是 `0xff`,没什么问题。
85+
86+
那看下 `'abc\n'``'abc'` 呢?
87+
88+
```
89+
mysql> set collation_connection=utf8mb4_bin;
90+
Query OK, 0 rows affected (0.000 sec)
91+
92+
mysql> select 'abc\n' < 'abc';
93+
+-----------------+
94+
| 'abc\n' < 'abc' |
95+
+-----------------+
96+
| 1 |
97+
+-----------------+
98+
1 row in set (0.000 sec)
99+
```
100+
101+
再次两眼一黑。我倒,怎么会这样。这是什么排序规则。看下 utf8mb4_bin 吧。
102+
103+
```
104+
mysql> show collation like 'utf8mb4_bin';
105+
+-------------+---------+----+---------+----------+---------+---------------+
106+
| Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute |
107+
+-------------+---------+----+---------+----------+---------+---------------+
108+
| utf8mb4_bin | utf8mb4 | 46 | | Yes | 1 | PAD SPACE |
109+
+-------------+---------+----+---------+----------+---------+---------------+
110+
1 row in set (0.001 sec)
111+
```
112+
113+
`Pad_attribute``PAD SPACE`,表示对齐长度时,后面补空格。这下就说通了。空格是 `0x20`,换行符是 `0x0a``\n` 比 `` 小。
114+
115+
所以!!虽然反直觉,在 utf8mb4_bin 下,`'abc\n'` 就是 `'abc'` 小!
116+
117+
**结论:`like 'abc%'` 的范围查询优化有问题。**
118+
119+
* * *
120+
121+
关于这个 bug ,我已经向 MySQL 提交了 patch ,但是似乎没有得到关注。我看了下更新日志,我提的另一个 patch 已经被合入,但是这个问题依然还在。看来涉及到字符集,这个坑麻烦到他们都不想处理了。
122+
123+
![Image 1](https://i.imgur.com/UASkTDJ.png)_[ 同一时间提交的代码已经合入 ]_
124+
125+
![Image 2](https://i.imgur.com/AUjpBmz.png)_[ 这个问题还是打开的 ]_
126+
127+
* * *
128+
129+
如果哪天他们合入或者解决了,我再 append 新的进展。
130+

data.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,5 +310,11 @@
310310
"title": "终端AI利器:两款效率神器助你码力十足",
311311
"url": "https://programnotes.cn/ai-in-terminal/",
312312
"timestamp": 1747645952
313+
},
314+
{
315+
"month": "202505",
316+
"title": "坑爹的字符集问题:踩到了 MySQL 的 bug - V2EX",
317+
"url": "https://www.v2ex.com/t/1133409",
318+
"timestamp": 1747876906
313319
}
314320
]

summary.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
读取 bookmark-collection 中的书签,使用 jina reader 获取文本内容,然后使用 LLM 总结文本。详细实现请参见 process_changes.py。需要和 bookmark-collection 中的 Github Action 一起使用。
33

44
## Summarized Bookmarks
5+
- (2025-05-22) [坑爹的字符集问题:踩到了 MySQL 的 bug - V2EX](_posts/202505/2025-05-22-%E5%9D%91%E7%88%B9%E7%9A%84%E5%AD%97%E7%AC%A6%E9%9B%86%E9%97%AE%E9%A2%98%EF%BC%9A%E8%B8%A9%E5%88%B0%E4%BA%86-mysql-%E7%9A%84-bug---v2ex.md)
56
- (2025-05-19) [终端AI利器:两款效率神器助你码力十足](_posts/202505/2025-05-19-%E7%BB%88%E7%AB%AFai%E5%88%A9%E5%99%A8%EF%BC%9A%E4%B8%A4%E6%AC%BE%E6%95%88%E7%8E%87%E7%A5%9E%E5%99%A8%E5%8A%A9%E4%BD%A0%E7%A0%81%E5%8A%9B%E5%8D%81%E8%B6%B3.md)
67
- (2025-05-19) [现在农村老年入怎么样才能平稳过完余生 - V2EX](_posts/202505/2025-05-19-%E7%8E%B0%E5%9C%A8%E5%86%9C%E6%9D%91%E8%80%81%E5%B9%B4%E5%85%A5%E6%80%8E%E4%B9%88%E6%A0%B7%E6%89%8D%E8%83%BD%E5%B9%B3%E7%A8%B3%E8%BF%87%E5%AE%8C%E4%BD%99%E7%94%9F---v2ex.md)
78
- (2025-05-16) [aipotheosis-labs/aci](_posts/202505/2025-05-16-aipotheosis-labs-aci.md)

0 commit comments

Comments
 (0)