“小问题”这三个字在数据库这个领域里往往是骗人的。它骗你的是表面看服务没宕、权限没崩、数据也能查到可就是登录慢、查询卡、连接池报错、隔三差五死锁每一个单拎出来都让人觉得“这能有多大事”合在一起却能让我在工位上坐一下午。作为一名长期跟数据库打交道的开发者兼半个DBA我几乎每周都要处理一两件这类“小问题”。这些年攒下来的经验是大部分看似偶然的小坑背后都写着清晰的固定原因。我打算把踩过的坑、排查过的真实场景整理成一份能直接拿来对着查的笔记从Oracle、MySQL、SQL Server到SQLite从连接池、字符集到执行计划和死锁尽量写得像坐你旁边给你讲排查过程一样。无论你是刚学会增删改查的新手还是已经能写存储过程的开发这份记录应该都能帮你少走几次弯路。1. 先说结论为什么越小的数据库问题越耗时间1.1 一次让我加班的Oracle登录“小事故”有次生产环境报障说数据库“卡了”开发催得很急。我第一反应是看服务器负载CPU 10%、内存充足、磁盘IO正常完全不像机房要出大问题的样子。再在服务器本地用sqlplus登录结果也是半天才返回提示符这时候才猜到问题恐怕不是资源不够而是登录这个环节本身就慢。后来查来查去监听器正常tnsping也通但登录就是卡住十几秒。最后在sqlnet.ora里看到一个不起眼的配置SQLNET.INBOUND_CONNECT_TIMEOUT倒不是这个参数本身的问题——Oracle在收到客户端连接后会尝试对客户端IP做反向DNS解析如果内网环境里DNS解析不了就会一直等到超时登录自然就慢。把反向解析处理掉再把命名解析路径弄干净之后再登录就是秒回。事后我把这段经历记成了一条笔记标题就叫“数据库——小问题”。那天加班的原因表面是“连库慢”实际是“反向DNS解析超时”你说它小它真不大可要在没有头绪的情况下瞎试一晚上都不够。1.2 排查小问题别只盯着数据库本身这类事情碰多了我总结出一个规律数据库的“小问题”往往是跨层问题得先确定是哪一层出了问题。网络层、连接层、会话层、执行层每一层都有可能让你看到同一个现象但根因完全不同。打个比方家里水龙头水流变小你光盯着龙头开关没用可能是总阀没全开可能是水管里有气也可能是水压本身就低。数据库排查也是一样的逻辑先ping和telnet端口看网络通不通再看监听和数据库进程活不活再看会话在等什么最后才轮到SQL和索引。我习惯把排查顺序固定成一张思维里的检查单网络连通性、服务进程、监听/实例状态、活跃会话与等待事件、SQL执行计划。按这个顺序走大多数“小问题”都能在一小时内收敛到根因而不是东试一下西试一下。这个方法论看着不起眼但它才是解决80%数据库问题的真正钥匙。1.3 动手前先备好的三样东西第一样是数据库自带的诊断入口。Oracle可以看alert日志、v$session和v$sqlareaMySQL可以看performance_schema、sys库还有慢查询日志SQL Server有动态管理视图和错误日志SQLite虽小也有自带的sqlite3命令行。第二样是系统层的工具top看CPUiostat看磁盘sar看历史负载tcpdump抓网络包这些都是在数据库之外定位问题的利器。第三样是一个趁手的图形客户端DBeaver、Navicat、DB Browser for SQLite我都用过各有各的顺手以前也见过一类体积很轻的DBx数据库管理工具临时在客户机器上看个数据很方便但要操作正式生产环境我建议你还是用主流稳定且持续维护的客户端。备好这三样再开工你会发现排查不是靠感觉而是靠证据。很多人一听“数据库问题”就紧张其实你只要按着证据链走鬼见愁的小问题也能变成有迹可循的流程题。2. 连接登录异常从Oracle到MySQL再到SQL Server2.1 Oracle登录缓慢sqlnet.ora和反向解析的坑回到刚才那次Oracle登录慢。除了反向解析其实sqlnet.ora里还有几个参数值得关注。SQLNET.INBOUND_CONNECT_TIMEOUT控制服务端等待客户端完成认证的时间默认几十秒如果客户端环境本身有问题这个超时会导致登录失败提示超时SQLNET.OUTBOUND_CONNECT_TIMEOUT控制客户端连服务端的超时一般也不建议设得太小。NAMES.DIRECTORY_PATH默认会有TNSNAMES、EZCONNECT等解析方式如果你只用tnsnames.ora把路径设置成TNSNAMES,EZCONNECT就够了别让解析过程在LDAP或其他方式上浪费时间。修改sqlnet.ora前我建议先备份原文件改完用lsnrctl reload让监听重载再拿测试客户端验证。生产环境尤其别手快先在测试库上模拟一遍。另外监听日志listener.log也可能越积越大历史上见过几十GB的监听日志拖慢登录的案例定期切割和清理日志也算是在“小问题”排查里容易被忽视的一环。2.2 MySQL连接池报错连接到底去哪了连接池报错几乎是高并发应用的经典开场白。应用日志里出现类似Connection pool exhausted的提示意思是连接池里的连接都被拿完了。我第一次遇到时第一反应是“池子开小了吧”把maxActive从50一路调到500结果数据库的连接数直接被打爆问题没解决反而更严重。后来冷静下来用show full processlist一看发现几个连接长时间Sleep在那里对应的代码在事务里查询之后没有真正提交或者创建了Statement却没有关闭。用大白话讲就是借出去的伞一直没还池子里能借的就越来越少。定位到具体会话后把对应的SQL和事务找出来修正代码里关闭连接和提交事务的逻辑再把连接池参数调回合理值问题才真正解决。SHOW VARIABLES LIKE max_connections; SHOW STATUS LIKE Threads_connected; SHOW FULL PROCESSLIST;正确的排查顺序应该先看这两组状态数据库端连接上限和当前线程数再看应用连接池参数是否合理最后看是否有长事务占着连接不还。连接池不是越大越好合理的maxPoolSize要结合单条SQL耗时和业务QPS去估算。我试过最稳的方式是先给定一个初始值然后在压测里观察数据库线程数和响应时间逐步微调而不是拍脑袋调大。2.3 新版SQL Server装好了Navicat却连不上有次同事装了一台新的SQL Server安装过程很顺利但Navicat就是连不上去。报错提示“能ping通但端口连不上”之类。我们一层层查下来发现是不起眼的服务配置问题SQL Server默认安装后TCP/IP协议可能处于禁用状态只有共享内存和命名管道是开的。所以本地用SSMS能连远程客户端就连不上。解决办法很简单打开SQL Server配置管理器在“SQL Server网络配置”里把TCP/IP启用顺便记下端口号默认1433再到防火墙里放行这个端口。如果用的是命名实例还要确认SQL Server Browser服务也在运行否则客户端解析不到动态端口。另一个高频坑是登录模式如果实例只开了Windows身份验证SQL账号登不上需要改成混合模式并给账号授权。这一类问题的排查顺序我固定是服务有没有跑端口通不通协议开没开认证模式对不对。按这个顺序走基本十分钟能找出原因。很多朋友一上来怀疑密码错了其实密码只是最后一道关卡。2.4 登录配置的底线端口、账号与白名单处理登录类“小问题”多了我形成了一些底线习惯。第一生产环境数据库别把默认端口完全裸奔在外面能改端口就改能限制来源IP就在防火墙或云安全组里限制。第二root、sa这类最高权限账号不允许远程直接登录日常账号按业务拆开最小权限原则不是空话是为了出事时能快速定位。第三统一账号命名和密码轮换节奏避免“谁都在用同一个账号”一旦出了问题连是谁执行的根本没法追溯。安全这块做在前面后续很多登录异常排查起来也会更干净——日志里你能清清楚楚看到是哪个账号、哪个来源IP在作怪而不是一堆杂乱的共享连接混在一起。我也见过不少团队因为一个共享账号连审计都做不了最后只能全部重置那才是真正的“小问题”变大工程。3. 数据“没出来”不等于丢字符集、唯一约束、结构修改的坑3.1 乱码的真相字符集三层不一致数据库里最容易被误判成“数据丢了”的小问题就是乱码。看着屏幕上一堆问号大多数人第一反应是数据坏了实际上往往是字符集在客户端、连接、服务器三层之间不一致。用MySQL举个例子服务器端表结构是utf8mb4但应用连接串没有指定charset客户端的character_set_client可能是latin1或gbk中文写进去再读出来就成了乱码。我排查时会先执行show variables like character%;看三层状态再用HEX()把某个字段的值打出来确认真实存储的字节是对的还是源头就错了。如果字节对得上那是读出过程中的转换问题如果字节本身就是错的那是写入端的问题。解决手法很简单连接串里明确指定字符集比如JDBC里的characterEncodingutf8或者命令行登录后执行set names utf8mb4;让客户端、连接、结果三层统一。Oracle这边同理靠NLS_LANG环境变量确保客户端字符集和服务端一致。很多老项目里乱码的根子就是NLS_LANG没设好或者设得比Windows系统区域还随意。3.2 给已有重复数据的字段加唯一约束“明明数据量不多为什么加唯一索引就是加不上”这个问题我听过太多次。MySQL在给已有数据的字段加唯一索引时如果字段里已经存在重复值DDL会直接报错提示类似Duplicate entry。此时你要先承认一个现实这个字段本身不适合直接做唯一约束除非先处理重复数据。我处理过一次真实的重复数据场景。先跑一条分组查询看哪些值重复SELECT col, COUNT(*) FROM table_name GROUP BY col HAVING COUNT(*) 1;把重复值和对应主键拉出来再和业务方确认去重规则。一般是保留每个重复值里ID最小的一条把其余更新或删除。这里特别提醒一句去重之前一定做好备份最好连外键关联也查一遍否则删了主表数据子表里的关联记录还在那可就不只是“小问题”了。处理干净后ALTER TABLE ... ADD UNIQUE KEY才有可能顺利通过。如果业务上非得保留历史重复可以考虑设计联合唯一约束或者让这个字段变成一个“预留字段状态位”的组合本质上是用规则去规避数据冲突而不是硬着头皮去造一个不可能成立的唯一性。3.3 ALTER TABLE卡在Waiting for metadata lock另一个很常见的“小事故”是执行ALTER TABLE修改表结构结果语句一直卡在那里show processlist一看等待事件是Waiting for table metadata lock。这个现象的意思是执行ALTER的会话在等这张表的元数据锁而锁被另一个会话拿住了。很多时候拿住锁的并不是什么大动作只是一个在长事务里跑过这张表的查询事务没提交锁就不释放。排查入口是information_schema.innodb_trx看trx_started时间把最早那个长事务找出来SELECT * FROM information_schema.innodb_trx\G如果确认是历史遗留的僵尸事务可以和业务协商后KILL掉ALTER就能继续。经验是做DDL之前先看当前有没有活跃会话在操作这张表尤其是长事务生产环境最好在业务低峰期窗口操作再配合pt-online-schema-change这类工具做在线变更风险会小很多。3.4 大表DDL的稳妥姿势这几年的运维实践中我对“大表DDL”越来越谨慎。MySQL 8.0之前ALTER TABLE对某些操作可能要重建整张表期间长时间锁表对线上业务影响很大。所以对大表加字段、加索引我倾向于用在线工具先建一个新表在后台慢慢同步数据再切换表名。如果手头没有自动化工具也至少要选一个业务读多写少的时间窗口执行并盯住processlist。另外每次结构变更前先导出表结构、记录当前表行数变更后马上校验行数和索引状态。这些都是小动作但在出“小问题”的时候这些小动作能帮你快速回滚避免把事故放大成灾难。我见过太多人把ALTER TABLE当成“改一行配置”结果凌晨两点还在跟metadata lock搏斗。4. 查询慢不全是SQL的锅索引、执行计划与等待事件4.1 同一个JOIN为什么你的慢有段时间我帮一个报表团队排查慢查询一条订单表和用户表的JOIN在别人环境里秒回到他们服务器上要跑五十多秒。第一反应是数据量不同一对比结果差不多那就是别的差异。用EXPLAIN一看订单表是ALL全表扫描用户表是eq_ref走主键索引——按理说这配置还行问题出在订单表本身没有user_id索引JOIN时就要逐行地回查用户表代价直接爆炸。后来在订单表的user_id上加了个普通索引同样一条SQL跑下来不到一秒。这事的教训是JOIN快慢的大头不在SQL写得多漂亮而在连接列上有没有索引、驱动表选得对不对。MySQL优化器一般会选小表驱动大表但WHERE条件复杂时它也有判断错的时候此时可以用STRAIGHT_JOINMySQL或加hintOracle的/* LEADING */强制改变驱动顺序不过要确保你对数据分布有把握别强行指定反而更差。4.2 EXPLAIN怎么读从type、key到rows很多人看EXPLAIN只盯着有没有用到索引其实要连贯起来看几列。type列代表访问类型从好到差大致是system、const、eq_ref、ref、range、index、ALL。看到ALL就要警惕说明在扫全表。key列告诉我们实际用的索引possible_keys是候选但只有key才是真正落地的选择。rows是优化器估算的扫描行数虽然只是估算但数量级差异很能说明问题。配合EXPLAIN FORMATJSON还能看到更细的代价分析比如哪一步的cost最高有没有using filesort或using temporary这些都是性能杀手。我习惯改完SQL就把新旧两个执行计划截图对比一下确认rows和type确实改善了再上线。很多“小问题”就藏在你看不见的额外排序和临时表里光看语句花不了几十毫秒一看执行计划才发现排序耗了几秒。4.3 索引失效的五个高频场景索引失效也是个经典“小问题”明明建了索引SQL还是慢。汇总一下我排过的最高频场景对索引字段用了函数。比如WHERE YEAR(create_time)2024这个写法让索引彻底歇菜改成范围条件WHERE create_time 2024-01-01 AND create_time 2025-01-01索引就能走。隐式类型转换。字符串字段存的是数字查询不带引号MySQL会悄悄做类型转换索引也就废了。检查时留意EXPLAIN里type是不是从ref变成了ALL。OR条件。一个条件能走索引另一个不能优化器可能直接放弃索引。改成UNION或者确保OR两边都有合适的索引。LIKE前导通配符。WHERE name LIKE %张三%除非用全文索引或特殊优化否则普通B树索引帮不上忙。能改成前缀匹配就改。联合索引乱序。联合索引(A, B, C)要求查询时从A开始匹配最左前缀跳过A直接查C是不行的。设计联合索引时要考虑查询条件的实际组合。这五个场景里最坑的是隐式转换因为执行计划看上去像是用了索引实际却是全扫。每回遇到这种问题我都建议把EXPLAIN的type列和key列一起看别只看有没有出现索引名。5. 死锁与并发一个容易被低估的“小问题”5.1 一次典型死锁的完整复盘死锁这个词听起来严重但你打开日志看到的往往就是一句Deadlock found when trying to get lock; try restarting transaction。事务A和事务B各拿了一把锁又互相等对方手里的锁。我一般用一个转账场景来给同事讲这个事会话A先更新用户1的余额再更新用户2的余额会话B反过来先更新用户2的余额再更新用户1的余额。两个事务并发执行到一半A握着用户1的锁等用户2B握着用户2的锁等用户1谁都不让经典死锁就出现了。数据库会自动检测到并回滚其中一方让另一方继续这也是为什么很多死锁初看只是“偶尔报错”重试一下就好了。想复现这个场景也很简单开两个MySQL命令行窗口手动BEGIN再交叉执行UPDATE就能在控制台看到死锁报错。理解了原理再去分析代码里的加锁顺序思路会变得特别清晰。要是你没见过真正的死锁现场建议先自己搭个环境造一次比看十篇文档都管用。5.2 快速定位死锁的三个入口定位死锁我常用三个入口。MySQL下最直接的是SHOW ENGINE INNODB STATUS\G里面有一大块LATEST DETECTED DEADLOCK记录了死锁发生的两个事务、它们持有的锁和等待的锁连涉及的表和行都能看到。其次是information_schema里的innodb_trx、innodb_lock_waits、innodb_locks三张表可以实时找出当前处于锁等待中的事务和阻塞它的源头。还有一个实用参数是innodb_print_all_deadlocksON让MySQL把每次检测到的死锁直接写到错误日志不用等SHOW的时候才能拿出来。SQL Server这边可以用dm_tran_locks和dm_exec_requests配合Oracle则看v$lock和v$session_wait。国产的达梦、人大金仓这类库很多系统视图设计上都向Oracle或MySQL的思路上靠你从这两个方向入手基本能对上号。很多朋友问我国产库出了锁等待怎么办我的建议很简单先找到系统视图对应的等待事件再按老库的经验切进去。5.3 绕开死锁的四条实操策略绕开死锁比定位死锁更重要。我现在做代码评审时一眼扫过去就能嗅到死锁风险第一加锁顺序必须统一。多个事务操作多张表或多行时按固定顺序去加锁最常见的做法是统一按主键大小先小后大。第二锁粒度能小就别大。避免在无索引字段上做UPDATE或SELECT ... FOR UPDATE那会直接锁住一大片行甚至整张表。第三事务时间要短。事务里别穿插外部API调用或大量计算锁在手上攥得越久和别人撞车的概率越大。第四考虑乐观锁。高并发读多写少场景用版本号或时间戳做乐观控制很多死锁的土壤就消失了。这套策略不是万能的但能把死锁概率从“时不时报一次”降到“几乎碰不到”剩下的交给数据库自动检测和业务重试机制兜底。真正代码级别的死锁修复其实改的是设计习惯而不是在SQL后面硬塞一个重试注解。6. 工具链与兼容性很多问题其实出在打开方式6.1 Access 64位驱动报错的经典场面很多人从Excel往Access或SQL Server导数据时会遇到一个让我记忆深刻的报错没有在本地计算机注册Microsoft.ACE.OLEDB.12.0或者提示你先安装Access数据库64位系统驱动程序。这个问题的根源在于Office或者说数据访问组件OLEDB Provider的位数和你的程序位数不匹配。比如你机器是64位系统但装了32位Office默认的ACE驱动就是32位这时如果一个64位的程序去调它就会报找不到注册的提供程序。解决办法是去微软官网下载对应版本的Access Database Engine按实际情况安装相应位数的驱动。不过这里有个坑如果同一台机器里已经有32位Office再装64位ACE驱动时可能被系统拒绝提示检测到已有32位组件有些朋友会用命令行加/passive强行装但我建议先想清楚自己的程序到底跑在什么位数上再决定装哪个。这个问题听起来一点都不“数据库”但它确实卡住过很多人我把它写进来是想提醒数据库周边工具的位数、版本、运行库也是“小问题”高发区。6.2 SQLite文件用什么打开怎么快速看数据“SQLite数据库用哪个管理打开”这个问题经常有人问。SQLite是单文件数据库后缀通常是.db、.sqlite、.sqlite3很多人拿到文件第一步就困惑了。我的建议是临时看数据用DB Browser for SQLite图形化、免安装双击打开就能看到表结构和数据日常开发我喜欢用DBeaver它对SQLite、MySQL、PostgreSQL这些都能一把梭命令行环境里sqlite3本身就是最轻量的选择一套下来干净利落sqlite3 test.db .tables SELECT * FROM users LIMIT 10;至于不少人问DBx这类小工具能不能用我给个中性评价这类小巧工具适合在别人的机器上临时连一下看个数据、跑个查询确实方便但大型生产环境我建议还是用主流稳定且持续维护的客户端避免因为工具本身的问题误伤数据。工具讲究顺手但更讲究责任边界。6.3 EDA软件里元器件数据库怎么接到了硬件领域我也没少被“小问题”纠缠。有些做电路设计的朋友会在Altium Designer里建立本地元器件数据库目标是让原理图里的元器件参数直接从数据库读取而不是手工填一堆参数。方法是先把元器件参数整理成Excel或SQLite之类的数据源再在Altium里新建一个Database Library文件通过ODBC数据源把表字段和Symbol链接起来。OrCAD里也是类似的逻辑先配好系统DSN再在配置对话框里指定连接。这里的报错大多是三类ODBC驱动位数不匹配、DSN名称对不上、数据库文件路径带空格或中文导致读取失败。如果你在Altium或OrCAD里配置报错我建议先到Windows的“ODBC数据源管理器”里把连通性测通再回到软件里配这样能快速缩小范围。这类问题跟数据库本身关系不大但卡起人来一点不含糊。6.4 迁移和同步从Excel导库到增量同步数据迁移同步也是“小问题”的密集区。最简单的场景是把Excel导入数据库小数据量直接用Navicat的导入向导即可数据量大一点的Excel我通常用Python的pandas加to_sql期间注意把datetime列的类型和空值处理干净真正海量数据时MySQL用LOAD DATA INFILESQL Server用BULK INSERT比逐行insert快好几个数量级。表与表之间的同步如果只做一次性的全量DataX这类工具很成熟如果要持续同步业务库的变化那就要上Canal监听binlog或者用Flink CDC原理是解析变更日志把增量数据搬到数仓或者下游系统。这两年还冒出了向量数据库做语义搜索和AI应用的embedding检索时确实优势明显但别一听流行就上先想清楚自己的数据形态是不是非结构化、查询场景是不是向量相似度。时序场景则会偏好TDEngine这类原生时序库它在C绑定里支持预处理接口比如taos_stmt_prepare批量写入性能比一条条insert高出不少本质上和关系数据库里用PreparedStatement的道理是一样的。一谈到迁移同步我的建议永远是先在测试环境跑通、核对行数再上生产过程里随时记录一份回滚方案。不然一个“小问题”同步错了数据修复起来可就不是小时级别了。7. 常见问题速查表与我的保命原则7.1 一张表查完大多数“小问题”下面这张表是我这些年自用的列出来大家直接对照。遇到问题先查表能省不少时间。现象常见原因快速定位解决建议Oracle登录卡顿反向DNS解析超时查看sqlnet.ora、监听日志调整解析方式限制超时连接池耗尽连接未归还或长事务show full processlist、Threads_connected检查代码释放连接合理配置池参数Navicat连不上SQL ServerTCP/IP未启用或认证模式查看配置管理器、端口启用协议、开防火墙、改混合认证中文乱码字符集三层不一致show variables like character%连接串指定utf8mb4或set names加唯一约束失败已有重复数据GROUP BY ... HAVING COUNT(*)1先清理重复再建唯一索引ALTER卡住metadata lock被长事务占用innodb_trxKILL阻塞事务或低峰期执行查询突然变慢索引失效或驱动表选错EXPLAIN查看type和rows修正SQL或用hint调执行计划业务偶发死锁加锁顺序不统一SHOW ENGINE INNODB STATUS统一加锁顺序缩短事务Excel导入报驱动错误OLEDB位数不匹配查看系统和Office位数安装对应位数的ACE驱动这张表看着简单每条背后都对应过一次真实的加班体验。把现象、原因、定位、解决四列串起来其实你就养成了“按证据链排查”的肌肉记忆。7.2 我踩过最深的三个坑经验都是拿踩坑换的。我挑三个最典型的写出来算是替大家提前过一遍雷区。第一个坑是盲目调大连接池。那年我觉得连接池耗尽就是池子开小了一口气把maxActive从50调到500结果数据库的线程数飙到几百等待时间不降反升还差点把实例拖垮。后来发现真正原因是某段代码里创建的Statement一直没关闭连接被死占着。调参救不了代码缺陷先定位占用者才是正路。第二个坑是去重不够谨慎。给业务去重时我按“保留最小ID”的逻辑删了一批重复记录结果几天后关联表里出现一堆孤儿数据因为子表引用的是被删掉的那条主键。从此我养成了先查外键依赖、先备份、再动手的习惯。删数据这件事不管看起来多小的清理都要当成一次生产变更对待。第三个坑是改表结构不备份。有次直接从测试库拷贝了一份结构到生产执行真以为自己是个老手没问题结果因为生产数据里有漏网的重复值唯一索引创建直接失败还好语句本身就处于阻塞状态没造成数据破坏但吓得我后背冒汗。从那以后任何DDL之前我都会先导出一份结构备份并且确认线上没有长事务占用。7.3 几条想写给后来人的大实话经历了这些“小问题”之后我最深的体会是大部分数据库问题的答案其实都在现场里不在网上。报错信息、执行计划、锁等待、日志时间戳这些第一手材料比任何经验都可靠。遇到问题别急着搜索先把自己能拿到的证据收集齐再按网络、服务、会话、SQL的顺序拆解基本不需要靠猜。另外慢慢养成记录的习惯吧。哪怕只是把某次排查用过的命令和结论写进一份个人笔记攒上一年你就会发现自己变成了团队里那个“遇到数据库小问题都能很快搞定”的人。数据库这个行当经验和排查方法论才是最硬的通货。我到现在还会在笔记里加上一条“数据库——小问题”提醒自己别被表面现象骗了也别被情绪消耗了。如果你也正被某个看着不大、查起来却想砸键盘的问题卡住先深呼吸按这篇笔记的思路把门类拆开再对症下药。真要实在排查不出至少把报错原文、执行语句、当时的锁等待全部截图存好这些材料比我分享的经验更能救你。
阅读完成 · 觉得有帮助?