移动由 GitLab 管理的仓库
- Tier: Free, Premium, Ultimate
- Offering: GitLab Self-Managed
您可以将所有由 GitLab 管理的仓库移动到另一个文件系统或另一台服务器。
在 GitLab 实例中移动数据
推荐使用 GitLab API 来移动 Git 仓库:
- 在服务器之间。
- 在不同的存储之间。
- 从单节点 Gitaly 到 Gitaly Cluster (Praefect)。
更多信息,请参阅:
- 为 Gitaly 配置额外存储。此示例配置了名为
storage1和storage2的额外存储。 - API 文档 详细说明了用于查询和调度项目仓库移动的端点。
- API 文档 详细说明了用于查询和调度代码片段仓库移动的端点。
- API 文档 详细说明了用于查询和调度群组仓库移动的端点。
- 迁移到 Gitaly Cluster (Praefect)。
移动仓库
GitLab 仓库可以与项目、群组和代码片段相关联。每种类型都有独立的 API 来调度相应仓库的移动。要移动 GitLab 实例上的所有仓库,必须为每种类型和每个存储调度移动。
在移动过程中,每个仓库都会被设为只读。在移动完成之前,仓库不可写入。
要移动仓库:
- 确保 GitLab 实例可以访问所有本地和集群存储。在此示例中,它们是
<original_storage_name>和<cluster_storage_name>。 - 配置仓库存储权重,以便新存储接收所有新项目。这可以防止在迁移过程中在现有存储上创建新项目。
- 为以下内容调度仓库移动:
- 如果启用了 Geo,请重新同步所有仓库。
移动所有项目
要使用 API 移动所有项目:
-
使用 API 为存储分片上的所有项目调度仓库存储移动。例如:
curl --request POST --header "Private-Token: <your_access_token>" \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \ "https://gitlab.example.com/api/v4/project_repository_storage_moves" -
使用 API 查询最近的仓库移动。响应将指示以下情况之一:
- 移动已成功完成。
state字段为finished。 - 移动正在进行中。重新查询仓库移动,直到其成功完成。
- 移动失败。大多数故障是暂时的,可以通过重新调度移动来解决。
- 移动已成功完成。
-
移动完成后,使用 API 查询项目 并确认所有项目都已移动。不应返回任何
repository_storage字段设置为旧存储的项目。例如:curl --header "Private-Token: <your_access_token>" --header "Content-Type: application/json" \ "https://gitlab.example.com/api/v4/projects?repository_storage=<original_storage_name>"或者,使用 rails 控制台 确认所有项目都已移动。在 rails 控制台中运行以下命令:
ProjectRepository.for_repository_storage('<original_storage_name>') -
根据需要为每个存储重复此操作。
移动所有代码片段
要使用 API 移动所有代码片段:
-
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \ "https://gitlab.example.com/api/v4/snippet_repository_storage_moves" -
查询最近的仓库移动。 响应将指示以下情况之一:
- 移动已成功完成。
state字段为finished。 - 移动正在进行中。重新查询仓库移动,直到其成功完成。
- 移动失败。大多数故障是暂时的,可以通过重新调度移动来解决。
- 移动已成功完成。
-
移动完成后,使用 rails 控制台 确认所有代码片段都已移动。不应为原始存储返回任何代码片段。在 rails 控制台中运行以下命令:
SnippetRepository.for_repository_storage('<original_storage_name>') -
根据需要为每个存储重复此操作。
移动所有群组
- Tier: Premium, Ultimate
- Offering: GitLab Self-Managed
要使用 API 移动所有群组:
-
为存储分片上的所有群组调度仓库存储移动。 例如:
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ --header "Content-Type: application/json" \ --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \ "https://gitlab.example.com/api/v4/group_repository_storage_moves" -
查询最近的仓库移动。 响应将指示以下情况之一:
- 移动已成功完成。
state字段为finished。 - 移动正在进行中。重新查询仓库移动,直到其成功完成。
- 移动失败。大多数故障是暂时的,可以通过重新调度移动来解决。
- 移动已成功完成。
-
移动完成后,使用 rails 控制台 确认所有群组都已移动。不应为原始存储返回任何群组。在 rails 控制台中运行以下命令:
GroupWikiRepository.for_repository_storage('<original_storage_name>') -
根据需要为每个存储重复此操作。
迁移到另一个 GitLab 实例
如果您要迁移到新的 GitLab 环境,使用 API 不是一个可行的选择,例如:
- 从单节点 GitLab 迁移到横向扩展架构。
- 从您私有数据中心中的 GitLab 实例迁移到云提供商。
本文档的其余部分将介绍一些将所有仓库从 /var/opt/gitlab/git-data/repositories 复制到 /mnt/gitlab/repositories 的方法。
我们来看三种场景:
- 目标目录为空。
- 目标目录包含仓库的过时副本。
- 如何处理数千个仓库。
我们列出的每种方法都可能会或将会覆盖目标目录 /mnt/gitlab/repositories 中的数据。请不要混淆源和目标。
所有情况下的推荐方法
对于 Gitaly 或 Gitaly Cluster (Praefect) 目标,应使用 GitLab 的备份和恢复功能。Gitaly 在 GitLab 服务器上以数据库的形式访问、管理和存储 Git 仓库。使用 rsync 等工具直接访问和复制 Gitaly 文件可能会导致数据丢失。
没有其他方法适用于 Gitaly Cluster (Praefect) 目标。
目标目录为空:使用 tar 管道
对于 Gitaly 目标,如果目标目录 /mnt/gitlab/repositories 为空,请使用 tar 管道。此方法开销低,并且 tar 通常已预装在您的系统上。
对于 Gitaly Cluster (Praefect) 目标,请改用推荐方法。
但是,无法恢复中断的 tar 管道;如果发生这种情况,则必须再次复制所有数据。
sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
tar -C /mnt/gitlab/repositories -xf -'如果您想查看进度,请将 -xf 替换为 -xvf。
tar 管道到另一台服务器
对于 Gitaly 目标,您可以使用 tar 管道将数据复制到另一台服务器。如果您的 git 用户可以通过 SSH 以 git@newserver 的身份访问新服务器,则可以通过 SSH 传输数据。
对于 Gitaly Cluster (Praefect) 目标,请使用推荐方法。
sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
ssh git@newserver tar -C /mnt/gitlab/repositories -xf -'如果您想在数据通过网络传输之前对其进行压缩(这会消耗 CPU 周期),可以将 ssh 替换为 ssh -C。
目标目录包含仓库的过时副本:使用 rsync
使用 rsync 迁移 Git 数据可能会导致数据丢失和仓库损坏。
这些说明正在审核中。
如果目标目录已包含仓库的部分或过时副本,则使用 tar 再次复制所有数据效率低下。对于 Gitaly 目标,请改用 rsync。
对于 Gitaly Cluster (Praefect) 目标,请使用推荐方法。
此实用程序要么已安装在您的系统上,要么可以使用 apt 或 yum 进行安装。
sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
/mnt/gitlab/repositories'上一条命令中的 /. 非常重要,没有它,您可能会在目标目录中得到错误的目录结构。
如果您想查看进度,请将 -a 替换为 -av。
单次 rsync 到另一台服务器
使用 rsync 迁移 Git 数据可能会导致数据丢失和仓库损坏。
这些说明正在审核中。
对于 Gitaly 目标,如果源系统上的 git 用户拥有对目标服务器的 SSH 访问权限,则可以使用 rsync 通过网络发送仓库。
对于 Gitaly Cluster (Praefect) 目标,请使用推荐方法。
sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
git@newserver:/mnt/gitlab/repositories'