从TFS迁移到VSTS - dbo.tbl_Content上需要采取措施

时间:2018-03-22 09:04:26

标签: git tfs azure-devops

我们计划很快从内部部署TFS迁移到VSTS。在迁移之前,我已经运行了先决条件验证任务,并获得了当前TPC数据库大小超过最大DacPac限制的警告。

下面提供了数据库验证的片段:

The full database size is       187411 MB.
The database metadata  size is   28145 MB.
The database blob size is       159266 MB.
The top 10 largest tables are:

===================================================
Table name                               Size in MB
dbo.tbl_Content                          168583
dbo.tbl_BuildInformation2                3233

===================================================
The File owners are:
===================================================
Owner                                    Size in MB
Build+Git                                67410
TeamTest                                 59261
VersionControl                           18637

从上面可以明显看出,dbo.tbl_Content表是过多数据库大小的主要贡献者,从VSTS操作的角度来看,Build + Git和TeamTest是主要的罪魁祸首。因此,我的目的是专注于上述对象,以便清理任何数据库以减小大小。

问题是,我怎样才能以最有效和最好的方式在上述三个对象上实现这一目标--dbo.tbl_Content,Build + Git和TeamTest?

2 个答案:

答案 0 :(得分:0)

我已经写了一篇广泛的文章,介绍了在导入之前清理TFS的所有方法:

但是请记住,还有一条备用路径需要在Azure中安装SQL Server和TFS / Azure DevOps Server的临时IaaS服务器设置。该路径可能比尝试清理您拥有的路径更为简单和快捷,并且同样受到支持。


提取以下内容:

要为迁移准备TFS项目集合,您可能需要删除(陈旧的)旧数据以首先减小数据库大小。

大多数操作已在此处记录。这份最新的支持通知单中也可以找到有助于检测您的空间分配位置的查询。

删除旧工作区

删除工作区和架子集可以大大减少迁移和升级时间。要么使用tf命令行,要么使用TFS SideKicks之类的工具来识别和删除它们。

构建结果

不仅生成结果,而且经常被忽略,实际的生成记录会占用大量数据。使用tfsbuild destroy(XAML)永久删除构建记录。过去,我遇到过一些客户,他们的数据库中有180万个“隐藏”构建,并删除了它们,从而节省了大量的数据。这些记录保存在仓库中。

如果您遇到tfsbuild的执行速度非常慢的情况,请为系统中的每个构建you may need this patched version it has a few fixes that prevent it from trying to download all the build logs仅仅获取构建ID。

旧团队项目

当然,销毁旧团队项目可能会返回很多数据。您不需要发送给天蓝色的任何帮助。您也可以考虑拆分集合,而放弃旧项目。如果您再次需要该数据,则可以选择分离该集合并将其存储在某个位置。

冗余文件

已删除的分支是一种非常常见的隐藏大小猪。在TFVC中删除内容时,它们实际上并没有被删除,只是被隐藏了。查找已删除的文件,尤其是旧的开发或功能分支可以为您提供很多数据。使用tf destroy摆脱它们。

您可能还希望在nuget软件包文件夹中查找已签入的文件夹,这些文件夹也可以迅速占用很多空间。

代码镜头索引

Team Foundation Server 2013引入了TFVC控制文件的服务器端索引,以允许Visual Studio直接在UI中访问有关谁更改了哪些文件的数据。服务器端索引可以根据您的代码库和搅动的大小而快速增长。

您可以通过tfsconfig codeindex命令控制索引。您最多可以指定要建立索引/indexHistoryPeriod:#months的时间,最多要删除索引/destroyCodeIndex或排除特定的有问题的文件/ignoreList:add $/path

在产品内部,Code Lens也被称为Code Sense和Code Index。

More can be found here

如果删除索引超时,you read this post on StackOverflow with additional guidance。请注意,不支持在TFS集合数据库上手动运行SQL。

测试附件

是的,尤其是当您使用测试附件时,它们可能会变得疯狂起来,具体取决于您的TFS版本是使用内置的测试附件清理功能还是使用TFS电动工具中的测试附件清理器。

XAML构建

构建定义本身不会占用大量数据库空间,但是构建结果可能会占用很多空间。但是,这些已在上一节中介绍过。

过去,我不得不修补tfbuid.exe以处理(非常)大量的构建记录,因为它倾向于尝试在本地执行删除操作之前获取所有构建数据。您可能需要依靠TFS客户端对象模型来获得类似的结果。

Git存储库

由于强制推送或删除分支,您的git存储库中的数据可能无法再访问。 Git中的某些数据也可能会更有效地打包。要清理您的存储库,您必须在本地克隆它们,清理它们,从TFS中删除远程存储库,然后将清理后的副本推送到新的存储库中(您可以使用与旧存储库相同的名称)。这样做将破坏现有构建定义的引用,您将必须对其进行修复。在进行此操作时,您还可以运行BFG repo Cleaner并转换存储库以使Git-LFS支持能够更优雅地处理存储库中的大型二进制文件。

git clone --mirror https://tfs/project/repo
# optionally run BFG repo cleaner at this 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年前的冲刺项目)也可以删除。 My colleague René has a nice tool that allows you to bulk-destroy by first creating the appropriate work item query

确保运行清理作业

TFS通常不会立即从数据库中删除数据,在许多情况下,它只是将内容标记为已删除以供以后处理。要强制立即进行清理,请在Project Collection数据库上运行以下存储过程:

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

最后的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

答案 1 :(得分:0)

我的 TFS 2015 服务器托管了多个 GIT 存储库,其中一些具有非常大的文件(带有 LFS)。使用 TFS Web 界面,我删除了一些在 tbl_content 中占用大量存储空间的测试存储库,我注意到文件没有从数据库中删除。

我几乎尝试了所有方法。 tf delete 没用,因为 repo 已经被删除了。 存储过程 prc_* 没有太大帮助。刚刚从 50 GB 减少到 41 GB

正确清理 tbl_content 数据库的唯一方法是执行 SQL 查询:

DELETE FROM tbl_content WHERE ResourceId IN (SELECT A.[ResourceId]  
  FROM [dbo].[tbl_Content] As A
  WHERE A.ResourceId NOT IN (SELECT X.ResourceId FROM tbl_filemetadata as X)
  AND A.ResourceId NOT IN (SELECT Y.ResourceId from tbl_filereference as Y))

这个过程花了半个多小时。之后,我执行了数据库收缩。现在表大小为 17 GB。

现在我将所有 GIT 存储库从 TFS 移动到自托管的 Gitea 服务器。与贪婪且不可维护的 TFS 相比,非常轻量级和高效的服务器......

相关问题