使用 Microsoft SQL Server 存储订阅数据

注意:

本文档假定 MS SQL Server 和 T-SQL 查询的基本知识。在尝试遵循本文档之前,管理员必须很方便地配置、使用和管理 SQL Server。

简介

ESENT 是 Windows 可以使用的嵌入式事务性数据库引擎。默认情况下,所有版本的 StoreFront 都支持使用内置 ESENT 数据库。如果将应用商店配置为使用 SQL 连接字符串,用户还可以连接到 Microsoft SQL Server 实例。

将 StoreFront 切换到使用 SQL 而非 ESENT 的主要优势是 T-SQL 更新语句允许您管理、修改或删除订阅记录。如果使用 SQL,则无需在对订阅数据执行细微更改时导出、修改和重新导入整个 ESENT 订阅数据。

要将现有订阅数据从 ESENT 迁移到 Microsoft SQL Server,需要将从 StoreFront 导出的平面 ESENT 数据转换为 SQL 友好格式以便批量导入。对于没有任何新订阅数据的新部署,不需要执行此步骤。数据转换步骤只需执行一次。本文介绍了可以在版本 3.5 之后的所有 StoreFront 版本中使用的受支持的配置,其中引入了本文中引用的 -STF PowerShell SDK。

注意:

由于网络中断,连接到 StoreFront 用于存储订阅数据的 SQL Server 实例失败,不会导致 StoreFront 部署无法使用。中断只会导致用户体验暂时降低;在恢复与 SQL Server 的连接之前,用户无法添加、删除或查看收藏的资源。在中断期间仍然可以枚举和启动资源。预期的行为与使用 ESENT 时 Citrix Subscription Store 服务停止时的行为相同。

提示:

使用 KEYWORDS:Auto 或 KEYWORDS:Mandatory 配置的资源在使用 ESENT 或 SQL 时的行为方式相同。用户首次登录时,如果其中一个关键字包含在用户的资源中,则会自动创建新的 SQL 订阅记录。

ESENT 和 SQL Server 的优势

ESENT SQL
默认设置,不需要添加任何配置即可使用 StoreFront“开箱即用”。 使用 T-SQL 查询可以轻松操作或更新更易于管理的数据和订阅数据。允许删除或更新每个用户的记录 允许通过简单的方法计算每个应用程序、Delivery Controller 或用户的记录。允许通过简单的方法删除已离开公司/组织的用户的不必要的用户数据。允许通过简单的方法更新 Delivery Controller 引用,例如当管理员切换到使用聚合或预配新的 Delivery Controller 时。
使用订阅同步和提取计划在不同的服务器组之间配置复制更加简单。请参阅配置订阅同步 与 StoreFront 分离,因此无需在 StoreFront 升级之前备份订阅数据,因为数据是在单独的 SQL Server 上维护的。订阅备份独立于 StoreFront,并使用 SQL 备份策略和机制。
不需要订阅管理时,SQL 非必需。如果订阅数据永远不需要更新,ESENT 可能会满足客户的需求。 由服务器组的所有成员共享的订阅数据的单个副本,因此服务器之间出现数据差异或数据同步问题的可能性较小。

ESENT 和 SQL Server 的缺点

ESENT SQL
没有简单的方法来轻松、精确地管理订阅数据。要求在导出的 .txt 文件中执行订阅操作。必须导出并重新导入整个订阅数据库。可能需要使用查找和替换技术更改数以千计的记录,此技术需要大量人力,并且可能容易出错。 需要基本的 SQL 专业知识和基础结构。可能需要购买 SQL 许可证,这会增加 StoreFront 部署的总拥有成本。尽管 Citrix Virtual Apps and Desktops 数据库实例也可以与 StoreFront 共享,以降低成本。
必须在服务器组中的每个 StoreFront 服务器上维护 ESENT 数据库的副本。在极少数情况下,此数据库可能会在服务器组内或不同服务器组之间脱离同步。 在服务器组之间复制订阅数据是一项重要的部署任务。它需要多个 SQL 实例和每个数据中心之间的事务复制。这需要专门的 MS SQL 专业知识。
  需要从 ESENT 进行数据迁移以及转换为 SQL 友好的格式。此过程仅需执行一次。
  可能需要额外的 Windows 服务器和许可证。
  部署 StoreFront 的额外步骤。

部署方案

注意:

如果要支持用户订阅,在 StoreFront 中配置的每个应用商店都需要 ESENT 数据库或 Microsoft SQL 数据库。存储订阅数据的方法是在 StoreFront 中的商店级别设置的。

Citrix 建议所有应用商店数据库都驻留在同一 Microsoft SQL Server 实例上,以降低管理复杂性并缩小配置错误的范围。

多个应用商店可以共享同一个数据库,前提是它们都配置为使用相同的连接字符串。如果这些应用商店使用不同的 Delivery Controller 也没关系。共享数据库的多个应用商店的缺点是无法判断每个订阅记录对应的应用商店。

在具有多个应用商店的单个 StoreFront 部署中,技术上可以将两种数据存储方法组合起来。可以将一个应用商店配置为使用 ESENT,将另一个应用商店配置为使用 SQL。由于管理复杂性增加以及配置错误的范围,建议不要这样做。

有四种方案可用于在 SQL Server 中存储订阅数据:

方案 1:使用 ESENT 的单个 StoreFront 服务器或服务器组(默认)

默认情况下,自版本 2.0 以来的所有 StoreFront 版本都使用平面 ESENT 数据库在服务器组成员之间存储和复制订阅数据。服务器组的每个成员都维护订阅数据库的相同副本,该副本与服务器组的所有其他成员同步。此方案不需要执行任何其他步骤即可配置。此方案适用于大多数客户,这些客户不期望经常更改 Delivery Controller 名称,或者不需要对其订阅数据执行频繁的管理任务,例如删除或更新旧用户订阅。

方案 2:安装单个 StoreFront 服务器和本地 Microsoft SQL Server 实例

StoreFront 使用本地安装的 SQL Server 实例,并且两个组件位于同一服务器上。此方案适用于简单的单一 StoreFront 部署,在此类部署中,客户可能需要频繁更改 Delivery Controller 名称,或者需要对其订阅数据执行频繁的管理任务,例如删除或更新旧用户订阅,但不需要高可用性 StoreFront 部署。Citrix 不建议对服务器组使用此方案,因为它会在托管 Microsoft SQL 数据库实例的服务器组成员上造成单一故障点。此方案不适用于大型企业部署。

方案 3:配置为高可用性的 StoreFront 服务器组和专用 Microsoft SQL Server 实例(推荐)

所有 StoreFront 服务器组成员连接到同一个专用的 Microsoft SQL Server 实例或 SQL 故障转移群集。此方案是最适合大型企业部署的模型,在此类部署中,Citrix 管理员希望频繁更改 Delivery Controller 名称或希望对其订阅数据执行频繁的管理任务,例如删除或更新旧用户订阅并要求高可用性。

配置为高可用性的 StoreFront 服务器组和 SQL Server

方案 4:每个服务器组中的每个数据中心中的多个 StoreFront 服务器组和一个专用 Microsoft SQL Server 实例

注意:

这是一个高级配置。只有当您是熟悉事务复制的经验丰富的 SQL Server 管理员,并且具备成功部署事务复制的必要技能时才尝试此操作。

这与方案 3 相同,但将其扩展到不同的远程数据中心中需要多个 StoreFront 服务器组的情况。Citrix 管理员可以选择在相同或不同数据中心中的不同服务器组之间同步订阅数据。数据中心中的每个服务器组连接到自己的专用 Microsoft SQL Server 实例,以实现冗余、故障转移和性能。此方案需要大量额外的 Microsoft SQL Server 配置和基础结构。它完全依赖于 Microsoft SQL 技术来复制订阅数据及其 SQL 事务。

每个数据中心中的多个 StoreFront 服务器组和 SQL Server

资源

可以从 https://github.com/citrix/sample-scripts/tree/master/storefront 下载以下脚本来帮助您:

配置脚本

  • Set-STFDatabase.ps1 - 为每个应用商店设置 MS SQL 连接字符串。在 StoreFront 服务器上运行。

  • Add-LocalAppPoolAccounts.ps1 - 授予本地 StoreFront 服务器的应用程序池对 SQL 数据库的读取和写入访问权限。在 SQL Server 上运行方案 2。

  • Add-RemoteSFAccounts.ps1 - 授予服务器组中的所有 StoreFront 服务器对 SQL 数据库的读取和写入访问权限。在 SQL Server 上运行方案 3。

  • Create-StoreSubscriptionsDB-2016.sql - 创建 SQL 数据库和架构。在 SQL Server 上运行。

数据转换和导入脚本

  • Transform-SubscriptionDataForStore.ps1 - 将 ESENT 中的现有订阅数据导出并转换为 SQL 友好的格式以便导入。

  • Create-ImportSubscriptionDataSP.sql - 创建一个存储过程来导入 Transform-SubscriptionDataForStore.ps1 转换的数据。使用 Create-StoreSubscriptionsDB-2016.sql 创建数据库架构后,在 SQL Server 上运行此脚本一次。

在 SQL Server 上配置 StoreFront 服务器的本地安全组

方案 2:安装单个 StoreFront 服务器和本地 Microsoft SQL Server 实例

在 Microsoft SQL Server 上创建一个名为 <SQLServer>\StoreFrontServers 的本地安全组,并为 IIS APPPOOL\DefaultAppPoolIIS APPPOOL\Citrix Receiver for Web 添加虚拟帐户以允许本地安装的 StoreFront 读取和写入 SQL。此安全组在创建应用商店订阅数据库架构的 .SQL 脚本中引用,因此请确保组名称匹配。

可以下载脚本 Add-LocalAppPoolAccounts.ps1 来帮助您。

在运行 Add-LocalAppPoolAccounts.ps1 脚本之前安装 StoreFront。该脚本取决于查找 IIS APPPOOL\Citrix Receiver for Web 虚拟 IIS 帐户的能力,该帐户在安装并配置 StoreFront 之前不存在。IIS APPPOOL\DefaultAppPool 是通过安装 IIS Web 服务器角色自动创建的。

# Create Local Group for StoreFront servers on DB Server
$LocalGroupName = "StoreFrontServers"
$Description = "Contains StoreFront Server Machine Accounts or StoreFront AppPool Virtual Accounts"

# Check whether the Local Group Exists
if ([ADSI]::Exists("WinNT://$env:ComputerName/$LocalGroupName"))
{
    Write-Host "$LocalGroupName already exists!" -ForegroundColor "Yellow"
}
else
{
Write-Host "Creating $LocalGroupName local security group" -ForegroundColor "Yellow"

# Create Local User Group
$Computer = [ADSI]"WinNT://$env:ComputerName,Computer"
$LocalGroup = $Computer.Create("group",$LocalGroupName)
$LocalGroup.setinfo()
$LocalGroup.description = $Description
$Localgroup.SetInfo()
Write-Host "$LocalGroupName local security group created" -ForegroundColor "Green"
}
$Group = [ADSI]"WinNT://$env:ComputerName/$LocalGroupName,group"

# Add IIS APPPOOL\DefaultAppPool
$objAccount = New-Object System.Security.Principal.NTAccount("IIS APPPOOL\DefaultAppPool")
$StrSID = $objAccount.Translate([System.Security.Principal.SecurityIdentifier])
$DefaultSID = $StrSID.Value

$Account = [ADSI]"WinNT://$DefaultSID"
$Group.Add($Account.Path)

# Add IIS APPPOOL\Citrix Receiver for Web
$objAccount = New-Object System.Security.Principal.NTAccount("IIS APPPOOL\Citrix Receiver for Web")
$StrSID = $objAccount.Translate([System.Security.Principal.SecurityIdentifier])
$WebRSID = $StrSID.Value

$Account = [ADSI]"WinNT://$WebRSID"
$Group.Add($Account.Path)

Write-Host "AppPools added to $LocalGroupName local group" -ForegroundColor "Green"

使用 SQL Server 配置管理器在本地 SQL 实例中启用命名管道。StoreFront 与 SQL Server 之间的进程间通信需要命名管道。

已启用命名管道的屏幕截图

确保正确配置 Windows 防火墙规则以允许使用特定端口或动态端口建立 SQL Server 连接。请参阅 Microsoft 文档,了解如何在您的环境中执行此操作。

提示:

如果连接到本地 SQL 实例失败,请检查 localhost 或连接字符串中使用的 <hostname> 是否解析为正确的 IPv4 地址。Windows 可能会尝试使用 IPv6 而非 IPv4,并且 localhost 的 DNS 解析可能会返回 ::1 而非正确的 StoreFront 和 SQL Server 的 IPv4 地址。可能需要在主机服务器上完全禁用 IPv6 网络堆栈才能解决此问题。

方案 3:StoreFront 服务器组和专用 Microsoft SQL Server 实例

在 Microsoft SQL Server 上创建一个名为 <SQLServer>\StoreFrontServers 的本地安全组,并添加 StoreFront 服务器组的所有成员。此安全组稍后在 Create-StoreSubscriptionsDB-2016.sql 脚本中引用,该脚本将在 SQL 中创建订阅数据库架构。

StoreFront 服务器安全组屏幕截图

将所有 StoreFront 服务器组域计算机帐户添加到 <SQLServer>\StoreFrontServers 组中。如果 SQL Server 使用 Windows 身份验证,则只有组中列出的 StoreFront 服务器域计算机帐户才能读取和写入 SQL 中的订阅记录。脚本 Add-RemoteSFAccounts.ps1 中提供的以下 PowerShell 函数将创建本地安全组,并向其添加两个名为 StoreFrontSQL1 和 StoreFrontSQL2 的 StoreFront 服务器。

function Add-RemoteSTFMachineAccounts
{
[CmdletBinding()]
param([Parameter(Mandatory=$True)][string]$Domain,
[Parameter(Mandatory=$True)][array]$StoreFrontServers)

# Create Local Group for StoreFront servers on DB Server
$LocalGroupName = "StoreFrontServers"
$Description = "Contains StoreFront Server Machine Accounts or StoreFront AppPool virtual accounts"

# Check whether the Local Security Group already exists
if ([ADSI]::Exists("WinNT://$env:ComputerName/$LocalGroupName"))
{
    Write-Host "$LocalGroupName already exists!" -ForegroundColor "Yellow"
}
else
{
    Write-Host "Creating $LocalGroupName local group" -ForegroundColor "Yellow"

    # Create Local Security Group
    $Computer = [ADSI]"WinNT://$env:ComputerName,Computer"
    $LocalGroup = $Computer.Create("group",$LocalGroupName)
    $LocalGroup.setinfo()
    $LocalGroup.description = $Description
    $Localgroup.SetInfo()
Write-Host "$LocalGroupName local group created" -ForegroundColor "Green"
}
Write-Host "Adding $StoreFrontServers to $LocalGroupName local group" -ForegroundColor "Yellow"

foreach ($StoreFrontServer in $StoreFrontServers)
{
    $Group = [ADSI]"WinNT://$env:ComputerName/$LocalGroupName,group"
    $Computer = [ADSI]"WinNT://$Domain/$StoreFrontServer$"
    $Group.Add($Computer.Path)
}
Write-Host "$StoreFrontServers added to $LocalGroupName" -ForegroundColor "Green"
}
Add-RemoteSTFMachineAccounts -Domain "example" -StoreFrontServers @("StoreFrontSQL1","StoreFrontSQL2")

在 Microsoft SQL Server 中为每个应用商店配置订阅数据库架构

在您的 Microsoft SQL Server 上创建一个命名实例,供 StoreFront 使用。将 .SQL 脚本中的路径设置为与 SQL 版本的安装位置或其数据库文件的存储位置相对应。示例脚本 Create-StoreSubscriptionsDB-2016.sql 使用 SQL Server 2016 Enterprise。

通过右键单击数据库,然后选择新建数据库,使用 SQL Server Management Studio (SSMS) 创建空数据库。

新建数据库屏幕截图

键入数据库名称以匹配您的应用商店,或选择其他名称,例如 STFSubscriptions

在运行脚本之前,对于 StoreFront 部署中的每个应用商店,请修改示例脚本中的引用以匹配您的 StoreFront 和 SQL 部署。例如,修改:

  • 为您创建的每个数据库命名,以便与 USE [STFSubscriptions] 中的 StoreFront 中的商店名称相匹配。

  • 将数据库 .mdf 和 .ldf 文件的路径设置为数据库的存储位置。

    C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\STFSubscriptions.mdf

    C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\STFSubscriptions.ldf

  • 在脚本中设置对 SQL Server 名称的引用:

    CREATE LOGIN [SQL2016\StoreFrontServers] FROM WINDOWS;

    ALTER LOGIN [SQL2016\StoreFrontServers]

运行脚本。成功配置架构后,将创建三个数据库表: SchemaDetails订阅用户

创建的新数据表屏幕截图

下面的数据库示意图显示了 Create-StoreSubscriptionsDB-2016.sql 脚本创建的订阅数据库架构:

订阅数据库架构示意图

为每个 StoreFront 应用商店配置 SQL Server 连接字符串

场景 1

提示:

存储在 ESENT 数据库中的磁盘上的原始订阅数据不会被销毁或删除。如果您决定从 Microsoft SQL Server 还原到使用 ESENT,则可以删除存储连接字符串并简单地切换回使用原始数据。ESENT 中将不存在 SQL 用于应用商店时创建的任何其他订阅,并且用户将看不到这些新的订阅记录。所有原始订阅记录仍将存在。

在应用商店上重新启用 ESENT 订阅

打开 PowerShell ISE 并选择以管理员身份运行

使用 -UseLocalStorage 选项指定要在以下方面重新启用 ESENT 订阅的应用商店:

$SiteID = 1
$StoreVirtualPath = "/Citrix/Store1"

# Sets SQL DB Connection String
$StoreObject = Get-STFStoreService -SiteID $SiteID -VirtualPath $StoreVirtualPath

# Removes the SQL DB Connection string and reverts back to using ESENT
Set-STFStoreSubscriptionsDatabase -StoreService $StoreObject -UseLocalStorage
Get-STFStoreSubscriptionsDatabase -StoreService $StoreObject

方案 2、3 和 4

打开 PowerShell ISE 并选择以管理员身份运行

指定要为使用 $StoreVirtualPath 设置连接字符串的应用商店

$SiteID = 1
$VirtualPath= "/Citrix/Store1"
$DBName = "Store1"
$DBServer = "SQL2016Ent"
$DBLocalServer = "localhost"
$DBInstance = "StoreFrontInstance"

# For a remote database instance
$ConnectionString = "Server=$DBServer$SQLInstance;Database=$DBName;Trusted_Connection=True;" Database=$DBName;Trusted_Connection=True;"

# For a locally installed database instance
$ConnectionString = "$DBLocalServer$SQLInstance;Database=$DBName;Trusted_Connection=True;"

# Sets SQL DB Connection String
$StoreObject = Get-STFStoreService -SiteID $SiteID -VirtualPath "/Citrix/Store"
Set-STFStoreSubscriptionsDatabase -StoreService $StoreObject -ConnectionString $ConnectionString
Get-STFStoreSubscriptionsDatabase -StoreService $StoreObject

如果要将部署中的每个应用商店全部配置为使用 SQL 连接字符串,请对其重复执行此过程。

将现有数据从 ESENT 迁移到 Microsoft SQL Server

要将现有 ESENT 数据迁移到 SQL,需要执行一个两步数据转换过程。提供了两个脚本来帮助您执行这一一次性操作。如果 StoreFront 和 SQL 实例中的连接字符串配置正确,则所有新订阅都会以正确的格式在 SQL 中自动创建。迁移后,历史 ESENT 订阅数据将转换为 SQL 格式,用户还可以查看其先前订阅的资源。

示例:同一域用户的四个 SQL 订阅

同一域用户的四个 SQL 订阅

步骤 1 使用 Transform-SubscriptionDataForStore.ps1 脚本将 ESENT 数据转换为 SQL 友好的格式以便批量导入

登录到要从中转换 ESENT 数据的 StoreFront 服务器。

服务器组的任何成员都适用,前提是这些成员都包含相同数量的订阅记录。

打开 PowerShell ISE 并选择以管理员身份运行

运行将 <StoreName>.txt 文件从 ESENT 数据库导出到当前用户桌面的脚本 Transform-SubscriptionDataForStore.ps1

PowerShell 脚本对处理的每个订阅行提供详细反馈,以帮助调试并帮助您评估操作是否成功。这可能需要很长时间才能处理。

脚本完成后,转换后的数据将写入到当前用户的桌面上的 <StoreName>SQL.txt。该脚本汇总了唯一用户记录的数量和处理的订阅总数。

对要迁移到 SQL Server 的每个应用商店重复执行此过程。

步骤 2 使用 T-SQL 存储过程批量 SQL 导入转换后的数据

每个应用商店的数据必须一次导入一个应用商店。

将在步骤 1 中创建的 <StoreName>SQL.txt 文件从 StoreFront 服务器的桌面复制到 Microsoft SQL Server 上的 C:\,并将其重命名为 SubscriptionsSQL.txt。

Create-ImportSubscriptionDataSP.sql 脚本将创建一个 T-SQL 存储过程以批量导入订阅数据。该将本将删除每个唯一用户的重复条目,以便将生成的 SQL 数据正确规范化并拆分为正确的表。

在执行 Create-ImportSubscriptionDataSP.sql 之前,请更改 USE [STFSubscriptions] 以匹配要在其下创建存储过程的数据库。

使用 SQL Server Management Studio 打开 Create-ImportSubscriptionDataSP.sql 文件,并在其中执行代码。此脚本将 ImportSubscriptionDataSP 存储过程添加到您之前创建的数据库中。

成功创建存储过程后,SQL 控制台中将显示以下消息,并将 ImportSubscriptionDataSP 存储过程添加到数据库中:

Commands completed successfully.

添加到数据库的存储过程

右键单击存储过程以执行该过程,然后选择执行存储过程并单击确定

执行存储过程屏幕截图

返回值 0 表示所有数据都已成功导入。导入时的任何问题都会记录到 SQL 控制台。存储过程成功运行后,将 Transform-SubscriptionDataForStore.ps1 提供的订阅记录的总数和唯一用户与下面两个 SQL 查询的结果进行比较。两个总数应匹配。

来自转换脚本的订阅总数应与 SQL 报告的总数相匹配

SELECT COUNT(*) AS TotalSubscriptions
FROM [Subscription]

转换脚本中的唯一用户数应与 SQL 报告的用户表中的记录数相匹配

SELECT COUNT(*) AS TotalUsers
FROM [User]

如果转换脚本显示 100 个唯一用户和 1000 条总订阅记录,SQL 应在成功迁移后显示相同的两个数字。

登录 StoreFront 以检查现有用户是否能够查看其订阅数据。当用户订阅或取消订阅其资源时,将在 SQL 中更新现有订阅记录。还会在 SQL 中创建新用户和订阅记录。

步骤 3 对导入的数据运行 T-SQL 查询

注意:

所有 Delivery Controller 名称都区分大小写,并且必须与 StoreFront 中使用的大小写和名称完全匹配。

-- Get all SQL subscription records
Use [STFSubscriptions]
SELECT * FROM [Subscription]
SELECT * FROM [User]
-- Get all subscription records for a particular user SID
Use [STFSubscriptions]
SELECT * FROM [Subscription]
INNER JOIN [User]
ON [Subscription].[user_id] = [User].[id]
WHERE [User].[username] = 'S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx'

-- Get total number of Subscription records for a particular user SID
Use [STFSubscriptions]
SELECT COUNT(Subscription.id)
FROM [Subscription]
INNER JOIN [User]
ON [Subscription].[user_id] = [User].[id]
WHERE [User].[username] = 'S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx'
-- Get all subscription records for a particular delivery controller
Use [STFSubscriptions]
SELECT * FROM [Subscription]
WHERE [resource_id] LIKE 'DeliveryController.%'

-- OR for aggregated resources use the name of the aggregation group
Use [STFSubscriptions]
SELECT * FROM [Subscription]
WHERE [resource_id] LIKE 'DefaultAggregationGroup.%'

-- Get all subscription records for a particular application
Use [STFSubscriptions]
SELECT * FROM [Subscription]
WHERE [resource_id] = ' DeliveryController.Application'

使用 T-SQL 更新或删除现有订阅记录

免责声明:

所有示例 SQL 更新和删除语句的使用风险完全由您自行承担。因错误使用提供的示例而导致您的订阅数据的任何丢失或意外更改,Citrix 概不负责。提供以下 T-SQL 语句作为启用要执行的简单更新的指南。在尝试更新订阅或删除过时的记录之前,备份 SQL 数据库完全备份中的所有订阅数据。未能执行必要的备份可能会导致数据丢失或损坏。在对生产数据库执行您自己的 T-SQL UPDATE 或 DELETE 语句之前,请对虚拟数据或远离实时生产数据库的生产数据的冗余副本对其进行测试。

注意:

所有 Delivery Controller 名称都区分大小写,并且必须与 StoreFront 中使用的大小写和名称完全匹配。

-- Update the delivery controller used in all subscriptions.
Use [STFSubscriptions]
UPDATE [Subscription]
SET [resource_id] = REPLACE(resource_id,'OldDeliveryController.','NewDeliveryController.')
WHERE [resource_id] LIKE 'OldDeliveryController.%'

-- OR for aggregated resources use the name of the aggregation group
Use [STFSubscriptions]
UPDATE [Subscription]
SET [resource_id] = REPLACE(resource_id,'OldDeliveryController.','DefaultAggregationGroup.')
WHERE [resource_id] LIKE 'OldDeliveryController.%'
-- Delete all subscription records for a particular Delivery Controller
Use [STFSubscriptions]
DELETE FROM [Subscription]
WHERE [resource_id] LIKE 'DeliveryController.%'

-- OR for aggregated resources use the name of the aggregation group
Use [STFSubscriptions]
DELETE FROM [Subscription]
FROM [Subscription]
WHERE [resource_id] LIKE 'DefaultAggregationGroup.%'

-- Delete all subscription records for a particular application
Use [STFSubscriptions]
DELETE FROM [Subscription]
FROM [Subscription]
WHERE [resource_id] LIKE '%.Application'

-- Delete all subscription records for an application published via a specific delivery controller
Use [STFSubscriptions]
DELETE FROM [Subscription]
FROM [Subscription]
WHERE [resource_id] = 'DeliveryController.Application'
-- Delete all subscription records for a particular user SID
Use [STFSubscriptions]
DELETE FROM [Subscription]
INNER JOIN [User]
ON [Subscription].[user_id] = [User].[id]
WHERE [User].[username] = 'S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx'

Use [STFSubscriptions]
DELETE FROM [User]
WHERE [User].[username] = 'S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-xxxx'
-- Delete ALL subscription data from a particular database and reset the primary key clustered index to start numbering from 0.
-- USE WITH EXTREME CARE AND NOT ON LIVE PRODUCTION DATABASES.
-- Can be useful whilst debugging data import issues to start with a clean database.

Use [STFSubscriptions]
DELETE FROM [Subscription]
DBCC CHECKIDENT ([Subscription], RESEED, 0)
DELETE FROM [User]
DBCC CHECKIDENT ([User], RESEED, 0)