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
相关产品推荐
相关产品推荐

