本指南的最新版本位于我的博客上:在迁移到 VSTS 之前清理您的团队项目集合。对于最新版本的 Azure DevOps Server 来说,该指南仍然非常准确。
鉴于您需要将最大的表减少 150GB,我想知道 DACPAC 是否是一个选择。也就是说,清理 TFS 实例始终是个好主意。除非您设法剥离足够的数据以真正从收缩中获得任何好处,否则您的第一步不会有太大帮助。
您确定的行动确实会有所帮助,大多数已经记录在这里。还可以帮助检测空间分配位置的查询在最近的支持票中找到.
删除旧工作区
删除工作区和搁置集可以大大减少迁移和升级时间。要么使用tf
命令行或利用类似的工具TFS 助手识别并删除这些。
构建结果
不仅仅是构建结果,而且经常被忽视的实际构建记录也会占用大量数据。使用tfsbuild destroy
(XAML) 永久删除构建记录。过去,我遇到过一些客户,他们的数据库中有 180 万个“隐藏”构建,删除它们会减少相当多的数据。这些记录保存在仓库里。
老团队项目
当然,销毁旧的团队项目可以返还大量数据。任何不需要发送到 azure 的内容都会有帮助。你也可以考虑拆分集合并留下旧项目。如果您再次需要该数据,您可以选择分离该集合并将其存储在某个地方。
冗余文件
删除的分支是一种非常常见的隐藏大小问题。当删除 TFVC 中的内容时,它们实际上并没有被删除,它们只是被隐藏了。查找已删除的文件,尤其是旧的开发或功能分支可以为您返回大量数据。使用tf destroy
摆脱他们。
您可能还想查找签入的 nuget 包文件夹,这些文件夹也可以快速占用大量空间。
测试附件
哦,是的,特别是当您使用测试附件时,这些附件可能会疯狂增长,具体取决于您的 TFS 版本,可以使用内置的测试附件清理功能,也可以使用TFS 电动工具测试附件清洁器.
XAML 构建
构建定义本身不会占用大量数据库空间,但构建结果可能会占用大量数据库空间。但这些已在前一节中介绍过。
Git 存储库
您的 git 存储库中可能有由于强制推送或删除分支而无法再访问的数据。 Git 中的某些数据也有可能被更有效地打包。要清理存储库,您必须在本地克隆它们,清理它们,从 TFS 中删除远程存储库,然后将清理后的副本推送到新存储库(可以使用与旧存储库相同的名称)。这样做会破坏现有构建定义的引用,您必须修复它们。当您这样做时,您还可以运行BFG repo Cleaner 并转换存储库以启用 Git-LFS 支持更优雅地处理存储库中的大型二进制文件。
git clone --mirror <<repo>>
# optionally run BFG repo cleaner at thi s point
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git repack -adf
# Delete and recreate the remote repository with the same name
git push origin --all
git push origin --tags
工作项目(附件)
工作项目可以收集大量数据,尤其是当人们开始向其附加大型附件时。您可以使用witadmin destroywi
删除附件过大的工作项。要保留工作项,但删除其附件,您可以从当前工作项中删除附件,然后克隆它。克隆后,销毁旧的工作项以清理附件。
您不再需要的旧工作项目(例如 6 年前的冲刺项目)也可以删除。我的同事雷内有一个很好的工具,允许您通过首先创建适当的工作项查询来批量销毁.
确保运行清理作业
TFS 通常不会直接从数据库中删除数据,在许多情况下,它只是将内容标记为已删除以供最新处理。要强制立即进行清理,请在项目集合数据库上运行以下存储过程:
EXEC prc_CleanupDeletedFileContent 1
# You may have to run the following command multiple times, the last
# parameter is the batch size, if there are more items to prune than the
# passed in number, you will have to run it multiple times
EXEC prc_DeleteUnusedFiles 1, 0, 100000
其他有用的查询
要确定每个部分中存储了多少数据,您可以运行一些有用的查询名词实际查询取决于您的 TFS 版本,但由于您正在准备迁移,我怀疑您目前使用的是 TFS 2017 或 2018。
找到最大的表:
SELECT TOP 10 o.name,
SUM(reserved_page_count) * 8.0 / 1024 SizeInMB,
SUM(CASE
WHEN p.index_id <= 1 THEN p.row_count
ELSE 0
END) Row_Count
FROM sys.dm_db_partition_stats p
JOIN sys.objects o
ON p.object_id = o.object_id
GROUP BY o.name
ORDER BY SUM(reserved_page_count) DESC
查找最大的内容贡献者:
SELECT Owner =
CASE
WHEN OwnerId = 0 THEN 'Generic'
WHEN OwnerId = 1 THEN 'VersionControl'
WHEN OwnerId = 2 THEN 'WorkItemTracking'
WHEN OwnerId = 3 THEN 'TeamBuild'
WHEN OwnerId = 4 THEN 'TeamTest'
WHEN OwnerId = 5 THEN 'Servicing'
WHEN OwnerId = 6 THEN 'UnitTest'
WHEN OwnerId = 7 THEN 'WebAccess'
WHEN OwnerId = 8 THEN 'ProcessTemplate'
WHEN OwnerId = 9 THEN 'StrongBox'
WHEN OwnerId = 10 THEN 'FileContainer'
WHEN OwnerId = 11 THEN 'CodeSense'
WHEN OwnerId = 12 THEN 'Profile'
WHEN OwnerId = 13 THEN 'Aad'
WHEN OwnerId = 14 THEN 'Gallery'
WHEN OwnerId = 15 THEN 'BlobStore'
WHEN OwnerId = 255 THEN 'PendingDeletion'
END,
SUM(CompressedLength) / 1024.0 / 1024.0 AS BlobSizeInMB
FROM tbl_FileReference AS r
JOIN tbl_FileMetadata AS m
ON r.ResourceId = m.ResourceId
AND r.PartitionId = m.PartitionId
WHERE r.PartitionId = 1
GROUP BY OwnerId
ORDER BY 2 DESC
如果文件容器是问题所在:
SELECT CASE WHEN Container = 'vstfs:///Buil' THEN 'Build'
WHEN Container = 'vstfs:///Git/' THEN 'Git'
WHEN Container = 'vstfs:///Dist' THEN 'DistributedTask'
ELSE Container
END AS FileContainerOwner,
SUM(fm.CompressedLength) / 1024.0 / 1024.0 AS TotalSizeInMB
FROM (SELECT DISTINCT LEFT(c.ArtifactUri, 13) AS Container,
fr.ResourceId,
ci.PartitionId
FROM tbl_Container c
INNER JOIN tbl_ContainerItem ci
ON c.ContainerId = ci.ContainerId
AND c.PartitionId = ci.PartitionId
INNER JOIN tbl_FileReference fr
ON ci.fileId = fr.fileId
AND ci.DataspaceId = fr.DataspaceId
AND ci.PartitionId = fr.PartitionId) c
INNER JOIN tbl_FileMetadata fm
ON fm.ResourceId = c.ResourceId
AND fm.PartitionId = c.PartitionId
GROUP BY c.Container
ORDER BY TotalSizeInMB DESC