使用 HammerDB 執行 SQL Server 負載測試

本教學課程說明如何使用 HammerDB 在 Compute Engine SQL Server 執行個體上執行負載測試。您可以透過下列教學課程瞭解如何安裝 SQL Server 執行個體:

可以使用的負載測試工具有很多。有些是免費的開放原始碼工具,有些則需要授權。HammerDB 一般而言是能夠良好展現 SQL Server 資料庫效能的開放原始碼工具。雖然本教學課程提供的是 HammerDB 的基本使用步驟,但可以使用的工具還有很多,您應選擇最適合您工作負載的工具。

設定 SQL Server 執行個體以進行負載測試

開始之前,請先確認 Windows 防火牆規則已設為允許來自您建立之新 Windows 執行個體 IP 位址的流量。接著,透過下列步驟為 TPCC 負載測試建立新資料庫並設定使用者帳戶:

  1. 以滑鼠右鍵按一下 SQL Server Management Studio 中的 [Databases] (資料庫) 資料夾,然後選擇 [New Database] (新增資料庫)。
  2. 將新的資料庫命名為「TPCC」。
  3. 將資料檔案的初始大小設為 190,000 MB,並將記錄檔的初始大小設為 65,000 MB。
  4. 按一下省略符號按鈕 (如以下螢幕擷取畫面所示),以便將「Autogrowth」(自動成長) 限制設為更高的值:

    設定自動成長限制

  5. 將資料檔案設為會以 64 MB 的幅度無限制成長。

  6. 將記錄檔設為停用自動成長。

  7. 按一下 [OK] (確定)。

  8. 在「New Database」(新增資料庫) 對話方塊的左側窗格中,選擇 [Options] (選項) 頁面。

  9. 將「相容性層級」設為「SQL Server 2022 (160)」

  10. 將「復原模式」設為「簡單」,這樣負載才不會填滿交易記錄。

    將復原模式設為簡單

  11. 按一下 [OK] (確定) 以建立 TPCC 資料庫,這可能需要幾分鐘才能完成。

  12. 預先設定的 SQL Server 映像檔僅有啟用 Windows 驗證,因此您需要依照這個指南在 SSMS 內啟用混合模式驗證。

  13. 按照步驟在具有 DBOwner 權限的資料庫伺服器上建立新的 SQL Server 使用者帳戶。請將帳戶命名為「loaduser」,並設定安全的密碼。

  14. 使用 Get-NetIPAddress commandlet 記錄 SQL Server 內部 IP 位址,因為使用內部 IP 對於效能與安全性至關重要。

安裝 HammerDB

您可以直接在 SQL Server 執行個體上執行 HammerDB。然而,為了要讓測試更加準確,請另外建立 Windows 執行個體並遠端測試 SQL Server 執行個體。

建立執行個體

按照下列步驟建立新的 Compute Engine 執行個體:

  1. 前往 Google Cloud 控制台的「Create an instance」(建立執行個體) 頁面。

    前往「建立執行個體」

  2. 在「Name」(名稱) 中輸入 hammerdb-instance

  3. 在「Machine configuration」(機器設定) 區段中,選取 CPU 數量至少是資料庫執行個體一半的機器類型。

  4. 在「Boot disk」(開機磁碟) 專區中,按一下「Change」(變更),然後執行下列操作:

    1. 在「Public images」(公開映像檔) 分頁中,選擇 Windows Server 作業系統。
    2. 在「版本」清單中,按一下「Windows Server 2022 Datacenter」
    3. 在「Boot disk type」(開機磁碟類型) 清單中,選取「Standard persistent disk」(標準永久磁碟)
    4. 如要確認開機磁碟選項,請按一下「Select」(選取)
  5. 如要建立並啟動 VM,請按一下 [Create] (建立)

安裝軟體

準備就緒後,請使用 RDP 用戶端連線至新的 Windows Server 執行個體,並安裝下列軟體:

執行 HammerDB

安裝 HammerDB 後,執行 hammerdb.bat 檔案。HammberDB 不會顯示在「開始」選單的應用程式清單中。請透過下列指令執行 HammerDB:

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

VERSION 替換為已安裝的 HammerDB 版本。

建立連線與結構定義

在應用程式執行時,首先設定連線以建構結構定義。

  1. 按兩下「Benchmark」面板上的 [SQL Server]
  2. 選取「TPROC-C」。 以下內容擷取自 HammerDB 網站
    TPROC-C 是在 HammerDB 中實作的 OLTP 工作負載,衍生自 TPROC-C 規格,並經過修改,可在任何支援的資料庫環境中,以簡單且符合成本效益的方式執行 HammerDB。HammerDB TPROC-C 工作負載是衍生自 TPROC-C 基準標準的開放原始碼工作負載,因此無法與已發布的 TPROC-C 結果比較,因為這些結果符合 TPROC-C 基準標準的子集,而非完整標準。HammerDB 工作負載 TPROC-C 的名稱代表「衍生自 TPC『C』規格的交易處理基準」。
  3. 按一下「確定」

    設定 TPROC-C 基準選項

  4. 按一下「結構定義」,然後按兩下「選項」

  5. 在表單中填入您的 IP 位址、使用者名稱和密碼等資訊 (如下圖所示):

    設定 TPROC-C 建構選項

  6. SQL Server ODBC 驅動程式設為 SQL Server 適用的 ODBC 驅動程式 18

  7. 在本例中,「倉庫數量」(規模) 設為 460,但您可以選擇其他值。有些指南會建議,為每個 CPU 設定 10 至 100 個倉儲。就本教學課程來說,請將此值設為核心數的 10 倍:16 核心的執行個體就設為「160」。

  8. 針對「Virtual Users to Build Schema」,選擇用戶端 vCPU 數量的 1 至 2 倍之間的數值。您可以點選滑桿旁的灰色長條來增加數值。

  9. 清除「使用 BPC 選項」

  10. 按一下「確定」

  11. 按兩下「Schema Build」(結構定義建構) 部分下的「Build」(建構) 選項,以建立結構定義並載入資料表。完成後,按一下畫面正上方的紅色手電筒圖示來刪除虛擬使用者並移至下個步驟。

如果您是利用 Simple 復原模式建立資料庫,此時您可能會想要改回 Full,以取得更準確的實際工作環境測試。這項變更只有在您完成完整或差異備份來觸發新的記錄鏈結後才會生效。

建立驅動程式指令碼

HammerDB 使用驅動程式指令碼自動化調度管理 SQL 陳述式至資料庫的流程以產生所需負載。

  1. 在「Benchmark」(基準) 面板中,展開 [Driver Script] 部分,並按兩下 [Options] (驅動程式指令碼)。
  2. 認設定符合您在 [Schema Build] (結構定義建構) 對話方塊中使用的設定。
  3. 選擇「Timed Driver Script」
  4. [Checkpoint when complete] (完成後選項核點) 會強制資料庫在測試結束時將一切資訊寫入磁碟,因此請只在您要連續執行多次測試時,再勾選這個選項。
  5. 為確保測試能完整執行,請將「Minutes of Rampup Time」(查核時間 (分鐘)) 設為 5,並將「Minutes for Test Duration」(測試時間長度 (分鐘)) 設為 20。
  6. 按一下 [OK] (確定) 以結束對話方塊。
  7. 在「Benchmark」面板的「Driver Script」區段中,按兩下 [Load]以啟動驅動程式指令碼。

設定 TPROC-C 驅動程式選項

建立虛擬使用者

建立與實際情況類似的負載,通常需要有多位不同的使用者來執行指令碼。請為測試建立幾位虛擬使用者。

  1. 展開「虛擬使用者」區段,然後按兩下「選項」
  2. 如果您將倉儲數量 (規模) 設為 160,那麼請將「Virtual Users」設為 16,因為 TPROC-C 指南建議使用 10 倍的比例來避免資料列遭到鎖定。請選取 [Show Output] 核取方塊,以啟用主控台的錯誤訊息。
  3. 按一下 [OK] (確定)。

收集執行階段統計資料

HammerDB 和 SQL Server 無法輕鬆為您收集詳細的執行階段統計資料。雖然這些統計資料就藏在 SQL Server 中,但需要定期擷取與計算來取得。如果您尚未設定程序或工具來協助您擷取這些資料,可透過本節的程序在測試時擷取一些實用指標。結果將會寫入 Windows temp 目錄的 CSV 檔案中。您可以透過「選擇性貼上」 >「貼上 CSV」選項,將資料複製至 Google 試算表。

如要採用此程序,您必須先暫時啟用 OLE Automation 程序才能將檔案寫入磁碟。測試完成後記得停用該程序:

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

執行 TPROC-C 負載測試

在 SQL Server Management Studio 中,使用下列指令碼執行收集程序:

Use master
Go
exec dbo.sp_write_performance_counters

請在您安裝 HammerDB 的 Compute Engine 執行個體中,使用 HammerDB 應用程式來啟動測試:

  1. 在「Benchmark」(基準) 面板中,按兩下「Virtual Users」(虛擬使用者) 下方的 [Create] (建立) 以建立虛擬使用者,如此將會啟動「Virtual User Output」(虛擬使用者輸出) 分頁。
  2. 按兩下 [Create] (建立) 項正下方的 [Run] (啟動)。
  3. 測試完成後,您會在「Virtual User Output」分頁標籤中看到「每分鐘交易數」(TPM) 的計算結果。
  4. 您可以在 c:\Windows\temp 目錄中找到收集程序的結果。
  5. 將這些值儲存到 Google 試算表,並利用這些值來比較多次測試。