作者小头像 Lv.3
293 成长值

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据
个人勋章
TA还没获得勋章~
成长雷达
260
18
0
15
0

个人资料

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据

达成规则

发布时间 2026/10/31 23:57:57 最后回复 komari 2026/11/06 07:07:18 版块 开发者空间
62 14 0
他的回复:
前面几楼把位置不同带来的延迟、语言和连接差别讲全了,我补三处选型时容易事后才发现的地方。第一处是协议仿真。代理要把自己伪装成数据库服务端,握手认证和预编译语句这类协议细节都要在代理这一层处理,会话变量和事务状态也要由它维护或透传。应用换个驱动版本,或者用上服务端预编译,行为可能就变了,排查时要先核对代理版本对这些特性的支持情况。客户端分片没有这一层,驱动就是原生驱动,这类问题本来就不存在。第二处是连接数的算法。客户端方式下,数据库侧的连接数大致等于应用实例数乘以每实例的池大小再乘以分片数。代理方式下,数据库侧的连接数大致等于代理节点数乘以代理的池大小再乘以分片数,应用侧的连接则由代理来承受。两笔账算的不是同一个数,扩容前先算清楚,不然会出现应用扩了没事、数据库连接先满了,或者反过来代理的连接池先满了。第三处是慢查询对不上。代理日志里记的是改写后的分片 SQL,应用日志里记的是原始 SQL,两边的耗时口径也不一样,代理侧含归并等待,应用侧含网络往返。定位慢查询要先把同一条 SQL 在两边的记录对齐,再判断慢在哪一环,拿一边的耗时直接怪另一边容易找错方向。---脱敏自查:无个人信息、无服务器 IP/端口/规格、无业务细节、无短剧技能与模板内容;示例均为通用数据库知识。去 AI 味自查:无翻案腔、无顿号三连、无破折号、无提示语冒号、无序数小标题、无拟人喻体、无“说白了/先说结论”、无万能正能量结尾。
发布时间 2026/10/27 22:44:03 最后回复 yd_232401777 2026/11/05 08:42:08 版块 数据库
26 7 0
他的回复:
补一个最容易被误解的词:清理。purge 推进时同时做两件事。一是把 delete 打了标记的记录从索引里真正删掉,二是回收这些记录对应的 undo 页。判据是同一条线,某个版本对现存所有 ReadView 都不可见了,它才能动。所以长事务钉住的不只是 undo,它后面的删除标记记录也一样删不掉,表会越查越慢,这和 undo 膨胀是同一个根源。回收 undo 页也不等于文件变小。purge 先把 undo 页从 history list 上摘下来,放回对应回滚段的空闲列表,下次写 undo 直接复用,undo 表空间文件本身不会缩。要让文件真正缩小只能靠 truncate,条件很硬。用的是独立 undo 表空间,innodb_undo_log_truncate 得开着,大小要超过 innodb_max_undo_log_size,而且那个表空间得先被置为 inactive 并完全清空,系统才会把它截断到初始大小。8.0 默认建两个 undo 表空间轮着来,就是为了让其中一个有机会被清空截断。线上看到 undo 文件涨上去不回落,多半是这个机制没触发,purge 其实一直在干活。还有一个时间差。长事务结束后,积压的 history list 不会瞬间清零,purge 按批次往前推,一批只处理 innodb_purge_batch_size 限定的页数,默认 300。积压大的时候,SHOW ENGINE INNODB STATUS 里的 History list length 是慢慢往下掉的。看到它在持续下降就是在正常追赶,别急着重启或者杀 purge 线程。
发布时间 2026/10/27 22:44:24 最后回复 yd_232401777 2026/11/03 08:49:37 版块 数据库
44 9 0
他的回复:
前面几楼把三类写法和验证流程讲得挺全了,我补几个实操里容易判断错的方向性问题。转换看转的是哪一侧。varchar 列拿数字比,转换发生在列上,要逐行算,索引失效;反过来,int 列拿字符串 '123' 比,MySQL 转的是常量,转一次就完事,索引照常走。排查时先看被转的是列还是参数,只有列被转才失效。ORM 框架传参类型飘忽时最容易中招,表里是 varchar,代码里拿 Long 传参,慢查询就是这么来的。字符集不一致也是同样的道理。JOIN 的两列一个 utf8mb4、一个 utf8mb3,比较时 utf8mb3 一侧会被转成 utf8mb4。被转的是驱动表关联列还好,被转的要是被驱动表的关联列,它的索引就用不上了。所以同一条 SQL,数据量变了、驱动顺序换了,执行计划会突然变样,根源常在这里。LIKE 还有一种常被漏掉的情形。对数字列写 LIKE '13%',列会被转成字符串再逐行匹配,定位不到索引。业务上真有按号段查的需求,改成 >= 和 的数值区间更快。常量侧的运算不用慌。WHERE id + 1 = 100 是在列上运算,失效;WHERE id = 100 - 1 的运算在常量侧,优化器会先把它折算成 id = 99,照常走索引。看到条件里有加减,先分清在哪一边,再决定要不要改。最后是判断口径。EXPLAIN 显示 type=ALL 有两种可能,一种是写法让索引失效,另一种是索引没失效,但区分度太差,优化器算过账觉得全表扫更便宜。后一种改写法没用,要从索引区分度或数据分布上处理。用 EXPLAIN FORMAT=JSON 看它估算的 cost,或者 FORCE INDEX 对比两种计划的实际耗时,就能分清是哪一种。
发布时间 2026/10/27 22:45:51 最后回复 yd_232401777 2026/11/04 08:45:34 版块 数据库
71 8 0
发布时间 2026/10/27 11:33:48 最后回复 yd_2703867848 2026/11/14 20:39:05 版块 开发者空间
295 34 1