You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SonarQube从6.7.1升级至7.0时,迁移脚本#1908执行超时求助

解决SonarQube 6.7.1升级到7.0时Oracle数据库脚本卡住的问题

我之前帮不少用户处理过SonarQube升级到7.0时Oracle数据库上这个脚本卡住的情况,结合你的数据规模(12.8百万行project_measures表),核心问题就是默认的删除操作没有利用高效索引,导致全表扫描耗时极长,甚至无限期卡住。对应的代码逻辑是删除属于特定人员/文件类型度量,且关联快照不存在的记录。

下面是一步步的解决方案:

1. 先暂停升级进程

如果当前SonarQube还卡在这个迁移步骤,先把服务停掉,避免数据库锁一直占用着,影响后续操作。

2. 给数据库加临时索引优化性能

在Oracle里,给project_measures和snapshots表加两个临时索引,让数据库能快速定位要删除的记录,不用全表扫:

CREATE INDEX idx_pm_metric_sid ON project_measures(metric_id, snapshot_id);
CREATE INDEX idx_sid ON snapshots(id);

3. 手动执行删除逻辑

直接运行迁移脚本对应的删除语句(代替自动执行的步骤):

DELETE FROM project_measures pm
WHERE pm.metric_id IN (
    SELECT id FROM metrics WHERE name IN (
        'files', 'lines', 'ncloc', 'functions', 'classes', 'directories',
        'comment_lines', 'comment_lines_density', 'duplicated_lines',
        'duplicated_lines_density', 'duplicated_blocks', 'complexity',
        'function_complexity', 'class_complexity', 'file_complexity',
        'person_authors', 'person_commits', 'person_lines', 'person_lines_changed'
    )
)
AND NOT EXISTS (
    SELECT 1 FROM snapshots s WHERE s.id = pm.snapshot_id
);

要是想先知道大概要删多少行,可以先跑这个查询:

SELECT COUNT(*) FROM project_measures pm
WHERE pm.metric_id IN (
    SELECT id FROM metrics WHERE name IN (
        'files', 'lines', 'ncloc', 'functions', 'classes', 'directories',
        'comment_lines', 'comment_lines_density', 'duplicated_lines',
        'duplicated_lines_density', 'duplicated_blocks', 'complexity',
        'function_complexity', 'class_complexity', 'file_complexity',
        'person_authors', 'person_commits', 'person_lines', 'person_lines_changed'
    )
)
AND NOT EXISTS (
    SELECT 1 FROM snapshots s WHERE s.id = pm.snapshot_id
);

4. 删掉临时索引

手动删除完成后,记得把刚才加的临时索引删掉,不然会影响后续数据库的性能:

DROP INDEX idx_pm_metric_sid;
DROP INDEX idx_sid;

5. 重启升级流程

做完上面这些,重新启动SonarQube服务,升级会跳过已经手动执行的这个迁移步骤,继续往下走。

额外提醒

  • 千万要先备份数据库,别嫌麻烦,万一操作出问题能回滚。
  • 如果你的Oracle开了归档模式,删这么多数据会生成大量归档日志,得确保归档目录有足够空间。
  • 要是删除还是慢,试试分批删,每次删10000条,循环到删完为止:
DECLARE
  v_rows NUMBER;
BEGIN
  LOOP
    DELETE FROM project_measures pm
    WHERE pm.metric_id IN (
        SELECT id FROM metrics WHERE name IN (
            'files', 'lines', 'ncloc', 'functions', 'classes', 'directories',
            'comment_lines', 'comment_lines_density', 'duplicated_lines',
            'duplicated_lines_density', 'duplicated_blocks', 'complexity',
            'function_complexity', 'class_complexity', 'file_complexity',
            'person_authors', 'person_commits', 'person_lines', 'person_lines_changed'
        )
    )
    AND NOT EXISTS (
        SELECT 1 FROM snapshots s WHERE s.id = pm.snapshot_id
    )
    AND ROWNUM <= 10000;
    
    v_rows := SQL%ROWCOUNT;
    COMMIT;
    EXIT WHEN v_rows = 0;
  END LOOP;
END;
/

内容的提问来源于stack exchange,提问作者clausfod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:45:40