备案站点的 MVCC 长事务与表膨胀治理
作者:备案源头内容团队内容审核:备案源头内容团队更新于 2026年9月29日
数据量没怎么变,磁盘占用却一路涨
这类问题最容易让人摸不着头脑:业务数据量没有明显增长,数据库占用的磁盘空间却在持续攀升,查询也越来越慢。排查了索引、排查了慢 SQL,最后发现根因既不在索引也不在查询——是某个事务开着几个小时甚至几天没有提交或回滚,导致数据库内部本该被清理的旧数据版本一直清理不掉,越堆越多。这是多版本并发控制(MVCC)机制下一个经常被忽视的运维盲区。
关键要点
- MVCC 通过保留数据的多个历史版本来实现读写不互相阻塞,但这些旧版本必须靠及时的清理机制才能被真正回收,不会自动消失。
- 一个挂起很久的事务,会让清理机制无法判断"这些旧版本是否已经没有人需要",进而导致清理停滞,膨胀持续累积。
- 表膨胀不只是占空间,还会拖慢几乎所有扫描该表的查询,因为查询要跳过大量已经作废但尚未清理的版本数据。
- 长事务的来源不总是显而易见的大批量操作,应用层一个被忘记提交的连接、一次挂起的人工确认,都可能是罪魁祸首。
MVCC:用多版本换来的读写不互斥
多版本并发控制的核心思路是:每次修改数据不是直接覆盖旧值,而是生成一个新版本,旧版本继续保留一段时间,这样正在读取旧版本的查询不会被写入阻塞,写入也不需要等待读取完成。这个机制让数据库能同时支撑高并发的读写操作,但它有一个隐含的前提:旧版本迟早要被清理掉,否则数据库里会永远堆积着大量没人再需要的历史版本。
清理机制判断一个旧版本能不能被回收,依据的是"是否还有活跃事务可能需要看到这个旧版本"。这就引出了问题的核心:只要有一个事务处于活跃状态(哪怕它本身根本没有在读那些旧版本对应的数据),清理机制出于安全考虑,也无法判断这个事务未来会不会需要这些旧版本,只能把清理动作往后推迟。
一个挂起的长事务,如何拖垮整库清理
一个正常提交或回滚很快的事务,不会对清理机制造成什么影响。但如果某个事务因为某种原因开着不提交——可能是应用代码有 bug 忘记提交、可能是一次长时间挂起的人工审批流程占用了同一个数据库连接、也可能是一次批量任务的事务范围设计得过大——这个事务存在的每一分钟,都会阻止清理机制回收在这段时间里产生的所有旧版本数据,不只是这个事务自己涉及的表,往往是整个数据库范围内的清理进度都会受到影响。
更麻烦的是,这个问题具有滞后性和隐蔽性:长事务本身可能已经结束,但它造成的膨胀不会自动消失,需要清理机制重新运行起来才能追回来;而膨胀造成的性能下降往往是逐渐累积的,很难在早期被察觉,直到查询普遍变慢或磁盘告警触发才被重视。
表膨胀的连锁性能代价
膨胀带来的不只是磁盘空间的浪费,它会实实在在地拖慢数据库的日常运行:
| 影响维度 | 具体表现 |
|---|---|
| 全表扫描类查询 | 需要跳过大量已经作废的旧版本数据才能找到有效数据,扫描量远超实际数据量 |
| 索引效率 | 索引本身也会膨胀,索引扫描的效率随之下降,慢查询排查见 慢查询定位与索引优化 |
| 缓存命中率 | 同样大小的缓存能容纳的有效数据变少,因为里面掺杂了大量无用的旧版本 |
| 磁盘 IO | 读取同样数量的有效数据需要更多的磁盘 IO,具体的磁盘层面影响见 磁盘 IO 与文件系统运维 |
| 备份与恢复耗时 | 膨胀的表让备份文件体积虚高,恢复演练耗时也随之拉长,见 数据备份与容灾 |
这也是为什么"数据库突然变慢"排查到最后,经常发现问题出在一张看起来数据量正常、实际上体积虚高好几倍的表上——表面看到的行数正常,磁盘上实际占用的空间却因为大量未清理的旧版本而远超预期。
揪出罪魁祸首:找到那个挂起的长事务
排查表膨胀问题的关键动作是找到那个阻挡清理进度的长事务,而不是一上来就对表做手动清理(手动清理在长事务还存在的情况下同样无效,因为限制清理进度的根本原因还没解除)。
排查思路:
- 查看当前活跃事务列表,按事务开始时间排序,最早开始且仍未结束的事务通常就是嫌疑对象。
- 确认这个事务对应的应用连接来自哪个服务、执行的是什么操作,结合应用日志定位具体的业务代码路径。
- 区分是正常的长时间批量操作,还是异常挂起:如果是预期内的大批量任务,需要评估是否应该拆分成更小的事务批次;如果是异常挂起(比如应用崩溃后连接没有正常释放),需要终止这个僵死的连接。
处理完当前的长事务后,还需要主动触发一次清理,让数据库回收之前积压的旧版本,而不是被动等待自然的清理周期慢慢追上进度,尤其在膨胀已经比较严重的情况下,主动干预能明显加快恢复速度。
应用层容易被忽视的长事务来源
长事务不总是来自看得见的大批量脚本,很多时候源头藏在应用代码里不容易被注意到的地方:
- 事务里夹了远程调用:调用第三方接口、发消息、等待另一个服务的响应,这段等待时间全部被算进了事务的存活时间,具体的治理原则见 数据库连接池与连接数治理 中关于事务边界收敛的讨论。
- 异常处理路径遗漏了提交或回滚:某个分支逻辑在出现异常时直接返回,却没有走到正常的事务结束逻辑,导致连接带着一个悬空的事务被归还连接池,之后可能被复用又可能一直挂着。
- 交互式或人工审批流程占用同一个数据库事务:等待人工确认的过程可能长达数分钟甚至更久,如果这段等待被设计在同一个数据库事务范围内,就是一个典型的长事务隐患,正确做法是把审批等待环节从事务里拆出来,用状态机而不是事务本身来串联多个步骤。
- 调试或临时排查时手动开启的事务忘记结束:运维或开发人员手动连接数据库调试,开启了一个事务但忘记提交或回滚就断开了连接,这类情况在权限收敛不到位的环境里更容易发生,操作规范见 运维权限治理与操作审计。
常见坑
- 表膨胀了直接做手动清理,却没找到并结束背后的长事务:清理动作在长事务还存在时基本无效,白白浪费一次操作窗口。
- 事务里包含远程调用或人工确认环节:等待时间全部计入事务存活时间,是最隐蔽的长事务来源之一。
- 异常处理路径遗漏事务的显式结束:连接带着悬空事务被归还连接池,问题在不经意间持续发生。
- 只监控磁盘使用率,不监控活跃事务的持续时间:等到磁盘告警触发时,膨胀往往已经持续了很久。
- 批量任务用一个大事务处理海量数据:任务运行期间整个数据库的清理进度都被阻塞。
常见问题
表膨胀了,直接扩容磁盘是不是就能解决问题?
扩容磁盘只是延缓了空间耗尽的时间,不解决查询变慢的根本问题,因为膨胀的表依然需要扫描大量无效的旧版本数据。真正的解决方式是找到并处理导致膨胀的长事务,再通过清理机制回收空间。
怎么判断一个事务是不是"异常挂起"而不是正常的长时间操作?
看这个事务在等待什么:如果它正在执行一个明确的、预期会耗时较长的批量操作,通常是正常的(但也应该评估是否可以拆分);如果它长时间处于空闲状态、没有任何 SQL 在执行,很可能是应用连接没有正确关闭事务导致的异常挂起,应该优先排查并终止。
表膨胀之后,性能会自动恢复吗?
不会自动恢复。即使触发了清理机制回收了旧版本占用的空间,表和索引的物理结构可能依然保持着膨胀后的状态(空间被标记为可重用,但不会自动收缩),如果膨胀已经比较严重,往往需要额外的重建操作才能让表恢复到紧凑的状态,这类操作和普通的表结构变更一样需要谨慎规划,见 数据库变更与在线 DDL 实践。
怎么提前发现潜在的长事务问题,而不是等到表已经明显膨胀?
把"最长活跃事务的持续时间"做成一项常规监控指标,超过预设阈值就告警,而不是等到磁盘空间或查询性能出问题才回头排查,指标接入方式见 备案网站监控告警体系。
资料来源
主流关系型数据库关于多版本并发控制机制与清理进程的官方文档,以及数据库运维领域关于表膨胀成因与治理的公开技术资料。本文为通用运维说明,仅供参考,具体机制以实际数据库版本为准。
相关阅读
网站访问日志留存与安全合规运维要点
为什么要留日志:这是法定要求 《网络安全法》第二十一条明确要求网络运营者"采取监测、记录网络运行状态、网络安全事件的技术措施,并按照规定留存相关的网络日志不少于六个月"。已完成备案、对外提供服务的网站属于网络运营者范畴,日志留存不是可选项,而是基础合规义务。 应留存哪些日志 | 日志类型 | 记录内容 | 主要用途 …
网站新增域名如何补充接入备案
企业在原有网站基础上新增域名,比如启用新的品牌域名或拼音域名指向同一网站时,不能直接绑定使用,而是需要在原备案基础上补充办理新增域名的接入手续。 新增域名前的准备工作 新增域名前,建议先确认该域名已经完成实名认证,可以通过 Whois查询 核对域名的注册信息和实名状态,避免因域名信息未实名导致接入申请被退回。同时确认…
备案信息年度核查该如何配合应对
部分省份的通信管理部门会对辖区内已备案网站开展年度或不定期核查,核查方式包括系统比对、电话回访、短信确认等,目的是确认备案信息与网站实际运营情况是否一致。 核查通常关注哪些内容 年度核查一般围绕主体信息、网站信息、接入信息三个维度展开,具体可以对照下表自查: | 核查维度 | 常见核查点 | | --- | --- …
备案号在网站上的规范展示与使用要求
网站完成备案只是第一步,备案号在页面上的展示方式同样需要长期维护,很多主体正是因为展示细节不规范,在日常巡查或年度核查中被要求整改。 展示位置与基本要求 通常做法是将备案号放置在网站首页底部,文字需清晰可辨、不被图片或广告遮挡,且格式应与下发的备案号文本保持一致,不能随意增减字符或调整顺序。是否需要加超链接指向查询入…
备案注销之后重新申请要注意什么
有些主体在此前因业务调整、接入商变更等原因注销了原有备案,之后又因新的业务需要重新申请备案。这种“二次备案”与首次备案在流程上大体相似,但有几个环节容易被忽略。 重新申请前的自查 重新申请前,建议先用 ICP备案查询 确认原备案是否确实已经完成注销,避免出现原备案未彻底清空、新申请与旧记录冲突的情况。同时检查计划使用…
备案信息变更有没有时效要求
备案不是办理完成后就一劳永逸的事项,主体信息、网站信息或联系方式一旦发生变化,通常需要在信息变化后的一定时间内完成变更提交,具体时限以属地管局要求为准。 哪些变化需要及时申报 常见需要变更的情形包括:主办单位名称或证件信息变化、网站负责人更换、联系电话或邮箱失效、网站域名调整、网站内容服务类型发生实质变化等。这类变更…
公司迁址之后备案地址信息如何更新
企业办公地址或注册地址发生变化后,备案信息中登记的地址项也需要相应更新,尤其是当迁址涉及跨区、跨市甚至跨省时,办理流程会比同城内迁址更复杂一些。 迁址后需要关注的信息 迁址后首先要确认工商登记信息是否已经完成同步变更,备案地址一般以工商登记的最新地址为准。可以先用 ICP备案查询 查看当前登记的主办单位地址,与最新的…
备案预留手机号邮箱变更该如何更新
备案信息中登记的手机号和邮箱,是管局与接入服务商联系网站负责人的主要渠道,用于发送核查通知、验证短信、审核结果等重要信息。这些联系方式一旦更换却未同步更新,容易导致关键通知被漏收。 常见需要更新的场景 负责人更换手机号或离职导致原号码停用; 企业邮箱系统迁移,原邮箱地址不再使用; 备案负责人变更,联系方式随之更换。 …