在部署 Geo 架构后,会遇到很多数据无法进行同步的问题,大部分是因为项目本身存在问题或者已经不存在,但数据库中存在残留记录。
常见类型数据的清理
在迁移或者升级 GitLab 时,会有很多孤儿数据或废弃数据需要进行清理。
清理 Abuse reports
使用 rails console 执行命令进行清理:
# 直接使用网页链接中的数字 ID 进行查询删除即可
report = AbuseReport.find(1)
report.destroy
清理 Snippet repository
查看同步的报错,在主节点数据库执行 SQL 查询:
select snippet_id, snippet_project_id, verification_failure, snippet_project_id, snippet_organization_id from snippet_repositories;
Snippet 仓库分为两种:
- ProjectSnippet
- PersonalSnippet
前者绑定项目,后者绑定个人。查询和清理的方法略有不同,使用 rails console 执行命令进行清理:
# 获取某个项目 Snippet(假设 ID 为 123)
snippet = ProjectSnippet.find(123)
# 获取对应的 Repository 对象
repo = snippet.repository
# 查看仓库的路径和相关信息
repo.full_path # 仓库的完整路径
repo.disk_path # 存储在磁盘上的相对路径
repo.project # 所属的项目
repo.repository_storage # 存储位置(如 default)
repo.repository_storage_path # 实际路径
或
# 获取某个用户 Snippet(假设 ID 为 456)
snippet = PersonalSnippet.find(456)
# 获取对应的 Repository 对象
repo = snippet.repository
# 查看仓库的路径和相关信息
repo.full_path
repo.disk_path
repo.repository_storage
repo.repository_storage_path
查询所有的 snippet 仓库 ID 或 Path,可以执行:
ProjectSnippet.all.each do |s|
puts "#{s.id} => #{s.repository.disk_path}"
end
或
PersonalSnippet.all.each do |s|
puts "#{s.id} => #{s.repository.disk_path}"
end
对于仓库 snippet 存储路径,可以使用命令反查:
Gitlab::GitalyClient::StorageSettings['default']['path']
搭建 Geo 后,如果遇到报错 Error during verification: Repository does not exist
的 PersonalSnippet:
# 找出无效的 PersonalSnippet
invalid_snippets = PersonalSnippet.all.select do |s|
begin
!s.repository.exists?
rescue => e
puts "Error checking snippet #{s.id}: #{e.message}"
true
end
end
# 确认这些是否已经丢失
invalid_snippets.each { |s| puts "Missing repo for PersonalSnippet ##{s.id}" }
# Dry run 检查删除项
invalid_snippets.each do |s|
puts "Would delete PersonalSnippet ##{s.id} (#{s.title})"
end
# 删除无效 PersonalSnippet
invalid_snippets.each do |s|
puts "Deleting PersonalSnippet ##{s.id}"
s.destroy!
end
补充:以上逻辑也同样适用于 ProjectSnippet,只需将 PersonalSnippet 替换为 ProjectSnippet 关键字。
如果实例中存在大量代码片段,可以分批执行,防止内存不足:
invalid_snippets = []
PersonalSnippet.find_each(batch_size: 100) do |s|
invalid_snippets << s unless s.repository.exists? rescue true
end
其他可用类型及销毁
所有 geo 中涉及的对象类型,可以在官方手册中找到
通用的删除逻辑是
对象类型.find(id).destroy
建议实际删除前只查询,确认后再删除。
附录
参考链接
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2025-07-31 15:24 PM
有没有其他类型的清理方式?比如用户或者空仓库