使用 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

Pricing Calculator 可根據您預計的使用量來產生預估費用。提供的連結可讓您查看本教學課程中所用產品的預估費用,每天平均可能為 16 美元。 Cloud Platform 的新使用者可能會符合免費試用的申請資格。

事前準備

  1. 登入您的 Google 帳戶。

    如果您沒有帳戶,請申請新帳戶

  2. 選取或建立 Google Cloud Platform 專案。

    前往「Manage resources」(管理資源) 頁面

  3. 請確認您已啟用 Google Cloud Platform 專案的計費功能。

    瞭解如何啟用計費功能

  4. 如果您的本機並非使用 Windows,請安裝第三方 RDP 用戶端 (例如 FusionLabs 提供的 Chrome RDP)。

設定 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. 將 [Compatibility level] (相容性層級) 設為 [SQL Server 2012 (110)]

  10. 將 [Recovery model] (復原模式) 設為 [Simple] (簡單),如此負載才不會填滿交易記錄。

    將復原模式設為簡易

  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 Platform 主控台中,前往「VM 執行個體」頁面。

    前往「VM 執行個體」頁面

  2. 將「Name」(名稱) 設為「hammerdb-instance」

  3. 將「Machine type」(機器類型) 設為資料庫執行個體 CPU 數的一半以上。

  4. 在「Boot disk」(開機磁碟) 部分中,按一下 [Change] (變更) 開始設定開機磁碟。

  5. 在「OS 映像檔」(OS images) 分頁中,選擇 [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. 按兩下「Benchmark」面板上的 [SQL Server]
  2. 選擇 [TPC-C],這是「Transaction Processing Performance Council - Benchmark C」(交易處理效能委員會 - 基準 C) 的縮寫。以下內容擷取自 TPC.org 網站
    TPC-C 涉及五種不同類型與複雜度的並行交易,無論是線上執行或排入佇列以延遲執行的交易均包含在內。資料庫提供九種資料表,記錄範圍與資料規模廣泛。TPC-C 是依每分鐘交易數 (tpmC) 計算。
  3. 按一下 [OK] (確定)。

    設定 TPC-C 基準選項

  4. 在 [Benchmark] (基準) 面板中,依序按一下 [SQL Server] 旁的 [+] 以展開選項。

  5. 在「TPC-C」下方,按一下 [Schema Build] (結構定義建構),然後按兩下 [Options] (選項)。

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

    設定 TPC-C 版本選項

  7. 針對 [Schema] (結構定義) 選項,選擇 [Updated] (已更新),如此可建立更理想的 TPC-C 結構定義,提供更適當的結構與更完善的索引。

  8. 在此案例中,「Number of Warehouses」(規模) 設為「2000」,但您不用設到這麼高,因為建立 2000 個倉儲需要花上好幾小時的時間。有些指南會建議,為每個 CPU 設定 10 至 100 個倉儲。就本教學課程來說,請將此值設為核心數的 10 倍:16 核心的執行個體就設為「160」。

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

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

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

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

建立驅動程式指令碼

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

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

設定 TPC-C 驅動程式選項)

建立虛擬使用者

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

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

收集執行階段統計資料

HammerDB 與 SQL Server 不會直接為您收集詳細的執行階段統計資料。雖然這些統計資料就藏在 SQL Server 中,但需要定期擷取與計算來取得。如果您尚未設定程序或工具來協助您擷取這些資料,可透過下方程序擷取測試時的一些實用指標資訊。結果將會寫入 Windows temp 目錄的 CSV 檔案中。您可以透過 [Paste Special] > [Paste CSV] 選項,將資料複製至 Google 試算表。

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

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

清理

完成 SQL Server 負載測試教學課程後,即可清除您在 Google Cloud Platform 上建立的資源,之後才不會遭到收費。下列各節將說明如何刪除或關閉這些資源。

刪除專案

如要避免被收費,最簡單的方法就是刪除您在教學課程中建立的專案。

如何刪除專案:

  1. 前往 GCP 主控台的「Projects」(專案) 頁面。

    前往專案頁面

  2. 在專案清單中選取要刪除的專案,然後按一下 [Delete] (刪除)
  3. 在對話方塊中輸入專案 ID,按一下 [Shut down] (關閉) 即可刪除專案。

刪除執行個體

刪除 Compute Engine 執行個體:

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Compute Engine