使用 HammerDB 对 SQL Server 执行负载测试

本教程演示了如何使用 HammerDB 在 Google Compute Engine SQL Server 实例上执行负载测试。您可以通过学习以下教程来了解如何安装 SQL Server 实例:

您可以使用多种负载测试工具。其中一些是免费的开源工具,而另一些则需要许可。 HammerDB 是一种开源工具,通常很适合演示 SQL Server 数据库的性能。本教程介绍了使用 HammerDB 的基本步骤,不过,您也可以使用其他工具,但应该选择最适合特定工作负载的工具。

目标

  • 配置 SQL Server 以进行负载测试。
  • 安装并运行 HammerDB。
  • 收集运行时统计信息。
  • 运行 TPC-C 负载测试。

费用

除了在 Compute Engine 上运行的任何现有 SQL Server 实例外,本教程还使用了 Google Cloud Platform (GCP) 的可计费组件,包括:

  • Google Compute Engine
  • Windows Server

您可以使用价格计算器根据您的预计使用情况来估算费用。点击提供的链接即可查看本教程中使用的产品的估算费用(平均每天 16 美元)。 Cloud Platform 新用户可能有资格申请免费试用

准备工作

  1. 登录您的 Google 帐号。

    如果您还没有 Google 帐号,请注册新帐号

  2. 选择或创建 Google Cloud Platform 项目。

    转到“管理资源”页面

  3. 确保您的 Google Cloud Platform 项目已启用结算功能。

    了解如何启用结算功能

  4. 如果您未在本地计算机上使用 Windows,请通过 FusionLabs 安装一个第三方 RDP 客户端,例如 Chrome RDP

配置 SQL Server 实例以进行负载测试

在开始之前,您应该仔细检查您的 Windows 防火墙规则是否设置为允许接收来自您创建的新 Windows 实例的 IP 地址的流量。然后,请您按照以下步骤创建一个新数据库以进行 TPCC 负载测试,并配置一个用户帐号:

  1. 右键点击 SQL Server Management Studio 中的数据库文件夹,然后选择新建数据库
  2. 将新的数据库命名为“TPCC”。
  3. 将数据文件的初始大小设置为 190000 MB,并将日志文件大小设置为 65000 MB。
  4. 点击省略号按钮以将自动增长限制设置为更大的值,如以下屏幕截图所示:

    设置自动增长限制

  5. 将数据文件大小上限设置为无限制(文件每次增大 64MB)。

  6. 将日志文件设置为禁止自动增长。

  7. 点击确定

    更改自动增长对话框

  8. 新建数据库对话框的左侧窗格中,选择选项页面。

  9. 兼容性等级设置为 SQL Server 2012 (110)

  10. 恢复模式设置为简单,以防止负载填满事务日志。

    将恢复模式设置为“简单”

  11. 点击确定以创建 TPCC 数据库,此操作可能需要几分钟才能完成。

  12. 预配置的 SQL Server 映像仅启用了 Windows 身份验证,因此您需要按照本指南中的说明在 SSMS 中启用混合模式身份验证。

  13. 按照以下步骤在具有 DBOwner 权限的数据库服务器上创建新的 SQL Server 用户帐号。将该帐号命名为“loaduser”并为其提供安全密码。

  14. 使用 Get-NetIPAddress 命令行开关记下您的 SQL Server 内部 IP 地址,因为使用内部 IP 对于性能和安全性很重要。

安装 HammerDB

您可以直接在您的 SQL Server 实例上运行 HammerDB。但是,为获得更准确的测试结果,请创建一个新的 Windows 实例并远程测试 SQL Server 实例。

创建实例

请按照以下步骤创建一个新的 Compute Engine 实例:

  1. 在 Google Cloud Platform Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 名称设置为 hammerdb-instance

  3. 机器类型至少设置为数据库实例具备的 CPU 数量的一半。

  4. 启动磁盘部分,点击更改以开始配置您的启动磁盘。

  5. 操作系统映像标签中,选择 Windows Server 2012 R2

  6. 启动磁盘类型部分中,选择标准永久性磁盘

  7. 点击选择

  8. 点击创建

安装软件

创建好实例后,将 RDP 添加到新的 Windows Server 实例并安装以下软件:

运行 HammerDB

安装 HammerDB 之后,请运行 hammerdb.bat 文件。HammberDB 不会显示在“开始”菜单的应用列表中。可使用以下命令运行 HammerDB:

C:\Program Files\HammerDB-2.20\hammerdb.bat

创建连接和架构

应用运行后,您首先要配置连接来构建架构。

  1. 基准面板中,双击 SQL Server
  2. 选择 TPC-C(这是一个缩写词,其全称是 Transaction Processing Performance Council - Benchmark C)。在 TPC.org 网站中:
    TPC-C 包含五个不同类型和复杂度的并发事务,这些事务既可以在线执行也可以排队等待延期执行。该数据库由九种类型的表格组成,其中包含各种记录和总体大小。TPC-C 的单位是每分钟处理的事务数 (tpmC)。
  3. 点击 OK

    设置 TPC-C 基准选项

  4. 基准面板中,点击 SQL Server 旁边的 + 以展开选项。

  5. TPC-C 下方,点击架构构建,然后双击选项

  6. 使用您的 IP 地址、用户名和密码填写表单,如下图所示。

    设置 TPC-C 构建选项

  7. 对于架构选项,选择已更新,这样将创建一个采用更合适的结构和更合理的索引的 TPC-C 架构。

  8. 在这种情况下,仓库数量(规模)会设置为 2000,不过您不必将此数值设置得过大,因为系统需要几个小时才能创建 2000 个仓库。部分准则建议为每个 CPU 创建 10 到 100 个仓库。在本教程中,您可将此值设置为核数量的 10 倍:对于 16 核的实例,可将此值设置为 160。

  9. 对于构建架构的虚拟用户数,请选择一个介于客户端 vCPU 数量 1 到 2 倍之间的数字。如需增大该数字,请点击滑块旁边的灰色条。

  10. 点击 OK

  11. 双击架构构建部分下方的构建选项以创建架构并加载表格。此操作完成后,点击屏幕顶部中心的红色闪光灯图标以销毁虚拟用户并转到下一步。

如果您使用“Simple”恢复模式创建数据库,则可能需要在此时将模式更改回“Full”,以获得更准确的生产场景测试结果。请注意,只有您执行完整备份或差异备份以触发新日志链启动后,此操作才会生效。

创建驱动程序脚本

HammerDB 使用驱动程序脚本将 SQL 语句流调控至数据库,以生成所需的负载。

  1. 基准面板中,展开驱动程序脚本部分,然后双击选项
  2. 验证设置是否与您在架构构建对话框中使用的设置一致。
  3. 选择定时测试驱动程序脚本
  4. 完成时的检查点选项会强制数据库在测试结束时将所有内容写入磁盘,因此请仅在计划连续运行多个测试时,才选中此选项。
  5. 为确保测试完整而全面,请将预热启动时间的分钟数设置为 5,将测试持续时间的分钟数设置为 20。
  6. 点击确定以退出对话框。
  7. 基准面板的驱动程序脚本部分,双击加载以激活驱动程序脚本。

设置 TPC-C 驱动程序选项)

创建虚拟用户

要创建真实的负载,通常需要您以多个不同的用户身份来运行脚本。因此,请为测试创建若干虚拟用户。

  1. 展开虚拟用户部分,然后双击选项
  2. 如果您将仓库数量(规模)设置为 160,则将虚拟用户设置为 16,因为 TPC-C 准则建议采用 10 倍比例以防止行锁定。选择显示输出复选框后,错误消息将能够显示在控制台中。
  3. 点击 OK

收集运行时统计信息

HammerDB 和 SQL Server 无法轻松为您收集详细的运行时统计信息。虽然统计信息可在 SQL Server 的深层获取,但您需要定期捕获这些信息并进行计算。如果您没有可捕获此数据的过程或工具,请使用以下过程以在测试过程中收集一些有用的指标。结果将写入 Windows temp 目录中的 CSV 文件中。您可以使用选择性粘贴 > 粘贴 CSV 选项将数据复制到 Google 表格中。

要使用此过程,您首先必须临时启用 OLE 自动化过程以将文件写入磁盘。请注意,在测试后应停用此设置:

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO

以下是在 SQL Server Management Studio 中创建 sp_write_performance_counters 过程的代码。在开始负载测试之前,您应在 Management Studio 中执行此过程。

USE [master]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

/***
LogFile path has to be in a directory that SQL Server can Write To.
*/
CREATE PROCEDURE [dbo].[sp_write_performance_counters] @LogFile varchar (2000) = 'C:\\WINDOWS\\TEMP\\sqlPerf.log', @SecondsToRun int =1600, @RunIntervalSeconds int = 2

AS

BEGIN
--File writing variables
DECLARE @OACreate INT, @OAFile INT, @FileName VARCHAR(2000), @RowText VARCHAR(500), @Loops int, @LoopCounter int, @WaitForSeconds varchar (10)
--Variables to save last counter values
DECLARE @LastTPS BIGINT, @LastLRS BIGINT, @LastLTS BIGINT, @LastLWS BIGINT, @LastNDS BIGINT, @LastAWT BIGINT, @LastAWT_Base BIGINT, @LastALWT BIGINT, @LastALWT_Base BIGINT
--Variables to save current counter values
DECLARE @TPS BIGINT, @Active BIGINT, @SCM BIGINT, @LRS BIGINT, @LTS BIGINT, @LWS BIGINT, @NDS BIGINT, @AWT BIGINT, @AWT_Base BIGINT, @ALWT BIGINT, @ALWT_Base BIGINT, @ALWT_DIV BIGINT, @AWT_DIV BIGINT

SELECT @Loops = case when (@SecondsToRun % @RunIntervalSeconds) > 5 then @SecondsToRun / @RunIntervalSeconds + 1 else @SecondsToRun / @RunIntervalSeconds end
SET @LoopCounter = 0
SELECT @WaitForSeconds = CONVERT(varchar, DATEADD(s, @RunIntervalSeconds , 0), 114)
SELECT @FileName = @LogFile + FORMAT ( GETDATE(), '-MM-dd-yyyy_m', 'en-US' ) + '.txt'

--Create the File Handler and Open the File
EXECUTE sp_OACreate 'Scripting.FileSystemObject', @OACreate OUT
EXECUTE sp_OAMethod @OACreate, 'OpenTextFile', @OAFile OUT, @FileName, 2, True, -2

--Write the Header
EXECUTE sp_OAMethod @OAFile, 'WriteLine', NULL,'Transactions/sec, Active Transactions, SQL Cache Memory (KB), Lock Requests/sec, Lock Timeouts/sec, Lock Waits/sec, Number of Deadlocks/sec, Average Wait Time (ms), Average Latch Wait Time (ms)'
--Collect Initial Sample Values
SET ANSI_WARNINGS OFF
SELECT
  @LastTPS= max(case when counter_name = 'Transactions/sec' then cntr_value end),
  @LastLRS = max(case when counter_name = 'Lock Requests/sec' then cntr_value end),
  @LastLTS = max(case when counter_name = 'Lock Timeouts/sec' then cntr_value end),
  @LastLWS = max(case when counter_name = 'Lock Waits/sec' then cntr_value end),
  @LastNDS = max(case when counter_name = 'Number of Deadlocks/sec' then cntr_value end),
  @LastAWT = max(case when counter_name = 'Average Wait Time (ms)' then cntr_value end),
  @LastAWT_Base = max(case when counter_name = 'Average Wait Time base' then cntr_value end),
  @LastALWT = max(case when counter_name = 'Average Latch Wait Time (ms)' then cntr_value end),
  @LastALWT_Base = max(case when counter_name = 'Average Latch Wait Time base' then cntr_value end)
FROM sys.dm_os_performance_counters
WHERE counter_name IN (
'Transactions/sec',
'Lock Requests/sec',
'Lock Timeouts/sec',
'Lock Waits/sec',
'Number of Deadlocks/sec',
'Average Wait Time (ms)',
'Average Wait Time base',
'Average Latch Wait Time (ms)',
'Average Latch Wait Time base') AND instance_name IN( '_Total' ,'')
SET ANSI_WARNINGS ON
WHILE @LoopCounter <= @Loops
BEGIN
WAITFOR DELAY @WaitForSeconds
SET ANSI_WARNINGS OFF
SELECT
  @TPS= max(case when counter_name = 'Transactions/sec' then cntr_value end)   ,
  @Active = max(case when counter_name = 'Active Transactions' then cntr_value end)   ,
  @SCM = max(case when counter_name = 'SQL Cache Memory (KB)' then cntr_value end)   ,
  @LRS = max(case when counter_name = 'Lock Requests/sec' then cntr_value end)   ,
  @LTS = max(case when counter_name = 'Lock Timeouts/sec' then cntr_value end)   ,
  @LWS = max(case when counter_name = 'Lock Waits/sec' then cntr_value end)   ,
  @NDS = max(case when counter_name = 'Number of Deadlocks/sec' then cntr_value end)   ,
  @AWT = max(case when counter_name = 'Average Wait Time (ms)' then cntr_value end)   ,
  @AWT_Base = max(case when counter_name = 'Average Wait Time base' then cntr_value end)   ,
  @ALWT = max(case when counter_name = 'Average Latch Wait Time (ms)' then cntr_value end)   ,
  @ALWT_Base = max(case when counter_name = 'Average Latch Wait Time base' then cntr_value end)
FROM sys.dm_os_performance_counters
WHERE counter_name IN (
'Transactions/sec',
'Active Transactions',
'SQL Cache Memory (KB)',
'Lock Requests/sec',
'Lock Timeouts/sec',
'Lock Waits/sec',
'Number of Deadlocks/sec',
'Average Wait Time (ms)',
'Average Wait Time base',
'Average Latch Wait Time (ms)',
'Average Latch Wait Time base') AND instance_name IN( '_Total' ,'')
SET ANSI_WARNINGS ON

SELECT  @AWT_DIV = case when (@AWT_Base - @LastAWT_Base) > 0 then (@AWT_Base - @LastAWT_Base) else 1 end ,
    @ALWT_DIV = case when (@ALWT_Base - @LastALWT_Base) > 0 then (@ALWT_Base - @LastALWT_Base) else 1 end

SELECT @RowText = '' + convert(varchar, (@TPS - @LastTPS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, @Active) + ', ' +
          convert(varchar, @SCM) + ', ' +
          convert(varchar, (@LRS - @LastLRS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@LTS - @LastLTS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@LWS - @LastLWS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@NDS - @LastNDS)/@RunIntervalSeconds) + ', ' +
          convert(varchar, (@AWT - @LastAWT)/@AWT_DIV) + ', ' +
          convert(varchar, (@ALWT - @LastALWT)/@ALWT_DIV)

SELECT  @LastTPS = @TPS,
    @LastLRS = @LRS,
    @LastLTS = @LTS,
    @LastLWS = @LWS,
    @LastNDS = @NDS,
    @LastAWT = @AWT,
    @LastAWT_Base = @AWT_Base,
    @LastALWT = @ALWT,
    @LastALWT_Base = @ALWT_Base

EXECUTE sp_OAMethod @OAFile, 'WriteLine', Null, @RowText

SET @LoopCounter = @LoopCounter + 1

END

--CLEAN UP
EXECUTE sp_OADestroy @OAFile
EXECUTE sp_OADestroy @OACreate
print 'Completed Logging Performance Metrics to file: ' + @FileName

END

GO

运行 TPC-C 负载测试

在 SQL Server Management Studio 中,使用以下脚本执行收集过程:

Use master
Go
exec dbo.sp_write_performance_counters

在安装了 HammerDB 的 Compute Engine 实例上,使用 HammerDB 应用启动测试:

  1. 基准面板的虚拟用户下方,双击创建以创建虚拟用户,这将激活虚拟用户输出标签。
  2. 双击创建选项正下方的运行以启动测试。
  3. 测试完成后,您将在虚拟用户输出标签中看到每分钟处理的事务数 (TPM) 计算结果。
  4. 您可以在 c:\Windows\temp 目录中找到您的收集过程的结果。
  5. 将所有这些值保存到 Google 表格中,然后使用这些值来比较多个测试运行项。

清理

学完 SQL Server 负载测试教程后,您可以清理在 Google Cloud Platform 上创建的资源,这样日后就无需为这些资源支付费用了。以下部分介绍了如何删除或关闭这些资源。

删除项目

最简单的避免支付费用的方法是删除您为本教程创建的项目。

要删除项目,请运行以下命令:

  1. 在 GCP Console 中,转到“项目”页面。

    转到“项目”页面

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除实例

要删除 Compute Engine 实例,请运行以下命令:

  1. 在 GCP Console 中,转到“虚拟机实例”页面。

    转到“虚拟机实例”页面

  2. 点击 要删除的实例旁边的复选框。
  3. 点击页面顶部的删除按钮以删除实例。

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Compute Engine