SQL Server 2025 中的 T-SQL REST API 整合:簡化 T-SQL 快照備份

SQL Server 2025 提供功能強大的新功能,讓直接從 T-SQL 呼叫 REST API 變得更容易。在這裡,我們將探討如何搭配 Pure Storage API 使用,以調度快照作業。

Streamlining T-SQL Snapshot Backups

總結

This article takes you through the steps for using a T-SQL script to create application-consistent snapshots on FlashArray from within SQL Server, without needing any external tools or scripts. 

image_pdfimage_print

本文最初出現在 Anthony Nocentino 的部落格上。經作者的認可與同意,重新發表。

在這篇文章中,我會帶您了解 T-SQL 腳本,在 Pure Storage® FlashArray 上建立應用程式一致的快照,所有內容都來自 SQL Server,無需外部工具。SQL Server 2025 推出強大的新功能:sp_invoke_external_rest_endpoint儲存程序。這項增強功能讓直接從 T-SQL 呼叫 REST API 變得比以往更加容易。結合這項新功能與 Pure Storage API,我們就能順暢地調度快照作業,無需外部工具或指令碼。

如果您一直關注我的“使用 T-SQL 快照備份”系列,您知道這項功能為大型資料庫環境帶來巨大效益。今天,我們將探討如何利用 SQL Server 的外部 REST 端點功能,直接在 T-SQL 中實作,而不需使用 PowerShell。

並利用 SQL Server 呼叫外部 REST 端點的能力,因此不需要 PowerShell。

您可以在這裡取得完整的腳本。


在 SQL Server 2025 中啟用 REST 端點

首先,我們來確定可以連線到外部 REST 端點:

sp_configure 'external rest endpoint enabled', 1;
RECONFIGURE WITH OVERRIDE;

這啟用了 SQL Server REST 端點功能,這讓我們的 SQL Server 可以進行 REST API 外撥呼叫。這對於連接到 FlashArray 的 API 以觸發快照至關重要。

請注意,所有端點sp_invoke_external_rest_endpoint都必須使用 HTTPS 搭配 TLS 加密,且憑證必須受託管 SQL Server 執行個體的基礎作業系統所信任。

使用 FlashArray 驗證

接下來,我們將使用 SQL Server 2025 的新sp_invoke_external_rest_endpoint儲存程序,與 Pure Storage FlashArray 建立安全的工作階段。此功能代表 SQL Server 功能有重大進步,讓我們能夠直接從 T-SQL 進行 REST API 呼叫,而無需外部指令碼。

為了驗證 FlashArray,我們首先要向 FlashArray 的登入端點提交具有足夠權限的 API 權杖。成功驗證後,FlashArray 會傳回回應標頭中的 anx-auth-token,而回應標頭會成為本工作階段中所有後續 API 作業的工作階段認證。這種基於權杖的驗證模式為 API 互動提供了安全、限時機制,同時保持明確的操作稽核軌跡。

在下面的程式碼中,我們會執行此驗證請求,然後從 JSON 回應中擷取x-auth-token,以建立授權標頭,供後續 REST API 呼叫使用。

DECLARE @ret INT, @response NVARCHAR(MAX), @AuthToken NVARCHAR(100), @MyHeaders NVARCHAR(100);

EXEC @ret = sp_invoke_external_rest_endpoint
 @url = N'https://flasharray1.purestorage.com/api/2.36/login',
 @headers = N'{"api-token":"PASTE_YOUR_TOKEN_HERE"}',
 @response = @response OUTPUT;

PRINT 'Login Return Code: ' + CAST(@ret AS NVARCHAR(10))
PRINT 'Login Response: ' + @response

錯誤處理與金鑰擷取

接下來,我們將驗證登入成功與否,並擷取驗證權杖。如果 FlashArray 的退貨代碼不是 0,我們會列印錯誤訊息並退出。假設成功,我們將從登入回應中讀取驗證次數。請注意,金鑰必須包含雙引號"x-auth-token",以確保JSON_VALUE正確剖析。擷取後,我們會使用權杖來建立授權標頭,以便後續對陣列進行 REST API 調用。

if ( @ret <> 0 )
    BEGIN
        PRINT 'Error in REST call, unable to login to the array.'
        RETURN
    END

SET @AuthToken = JSON_VALUE(@response, '$.response.headers."x-auth-token"'); 
SET @MyHeaders = N'{"x-auth-token":"' + @AuthToken + '", "Content-Type":"application/json"}'

PRINT 'Headers: ' + @MyHeaders

凍結快照資料庫

關鍵步驟是:暫停資料庫寫入 I/O 以準備快照。此命令使用 SQL Server 2022 的 T-SQL 快照備份功能凍結資料庫上的寫入 I/O 作業。資料庫仍然可以讀取,但寫入作業會暫停,直到我們完成快照流程為止。如此可確保我們能取得應用程式一致的快照。

ALTER DATABASE [TestDB1] SET SUSPEND_FOR_SNAPSHOT_BACKUP = ON

使用儲存快照

將寫入 I/O 凍結在資料庫中,我們已準備好在 FlashArray 上進行快照。下一步是呼叫保護群組快照REST端點,啟動保護群組的快照備份。

EXEC @ret = sp_invoke_external_rest_endpoint
 @url = N'https://flasharray1.purestorage.com/api/2.36/protection-group-snapshots',
 @headers = @MyHeaders,
 @payload = N'{"source_names":"aen-sql-25-a-pg"}',    
 @response = @response OUTPUT;

PRINT 'Snapshot Return Code: ' + CAST(@ret AS NVARCHAR(10))
PRINT 'Snapshot Response: ' + @response

這裡我們稱為 FlashArray 的 REST API 保護群組快照,以建立名為 aen-sql-25-a-pg 的保護群組快照。保護群組需要包含資料庫檔案儲存的所有磁碟區。FlashArray 將建立此保護群組中所有磁碟區的即時快照。

擷取快照名稱並建立備份

在下一個步驟中,我們使用 JSON_VALUE(@response,'$.result.items[0].name') 從 FlashArray 的 JSON 回應中擷取快照名稱。此名稱將包含在備份媒體說明中,作為僅中繼資料備份的一部分。如果 FlashArray 傳回成功代碼(傳回代碼 = 0),我們會使用備份資料庫指令和METADATA_ONLY選項繼續備份。如此可建立輕量備份檔案,僅包含資料庫中繼資料,並參考MEDIADESCRIPTION 中的 FlashArray 快照。將快照名稱儲存在 MEDIADESCRIPTION 中,在執行還原作業時,能更輕鬆地識別並定位對應的 FlashArray 快照。

如果快照操作失敗,我們會記錄錯誤訊息,並立即解除資料庫的暫停,以恢復正常寫入 I/O。

DECLARE @SnapshotName NVARCHAR(100)
SET @SnapshotName = JSON_VALUE(@response, '$.result.items[0].name')

if ( @ret = 0 ) 
    BEGIN
        BACKUP DATABASE [TestDB1] TO DISK='SnapshotBack.bkm' WITH METADATA_ONLY, MEDIADESCRIPTION=@SnapshotName
        PRINT 'Snapshot backup successful. Snapshot Name: ' + @SnapshotName
    END
ELSE 
    BEGIN
        ALTER DATABASE [TestDB1] SET SUSPEND_FOR_SNAPSHOT_BACKUP = OFF
        PRINT 'Error in REST call, snapshot backup failed. Database unsuspended.'
    END

檢查 SQL Server 錯誤日誌

若要驗證備份作業,我們會檢查 SQL Server 錯誤記錄。

SQL Server 錯誤日誌確認 TestDB1 資料庫成功備份僅中繼資料的快照。日誌顯示資料庫已暫停、寫入 I/O 已凍結,且快照是在安全恢復 I/O 之前拍攝。由於這是純中繼資料的備份,因此不會處理任何資料頁面;僅擷取中繼資料並寫入指定的 .bkmfile。如此可確保應用程式一致性的快照,並對資料庫可用性產生最小的影響。

EXEC xp_readerrorlog 0, 1, NULL, NULL, NULL, NULL, N'desc'

2025-05-09 12:03:25.120 Backup  BACKUP DATABASE successfully processed 0 pages in 0.004 seconds (0.000 MB/sec).
2025-05-09 12:03:25.090 Backup  Database backed up. Database: TestDB1, creation date(time): 2025/04/30(16:05:02), pages dumped: 394061770, first LSN: 80323:19757:39, last LSN: 80323:19774:1, number of dump devices: 1, device information: (FILE=12, TYPE=DISK: {'C:\Program Files\Microsoft SQL Server\MSSQL17.MSSQLSERVER\MSSQL\Backup\SnapshotBack.bkm'}). This is an informational message only. No user action is required.
2025-05-09 12:03:25.080 spid86  Database 'TestDB1' originally suspended for snapshot backup in session 86 successfully resumed in session 86.
2025-05-09 12:03:25.080 spid86  Database 'TestDB1' released suspend locks in session 86.
2025-05-09 12:03:25.080 spid86  I/O was resumed on database TestDB1. No user action is required.
2025-05-09 12:03:25.080 spid86  I/O is frozen on database TestDB1. No user action is required. However, if I/O is not resumed promptly, you could cancel the backup.
2025-05-09 12:03:22.110 spid86  Database 'TestDB1' successfully suspended for snapshot backup in session 86.
2025-05-09 12:03:22.110 spid86  I/O is frozen on database TestDB1. No user action is required. However, if I/O is not resumed promptly, you could cancel the backup.
2025-05-09 12:03:22.070 spid86  Database 'TestDB1' acquired suspend locks in session 86.
2025-05-09 12:03:22.070 spid86  Setting database option suspend_for_snapshot_backup to ON for database 'TestDB1'.

以下是我們上述使用的列印對帳單輸出。快照備份成功完成:系統通過 FlashArray 驗證,暫停 TestDB1 凍結 I/O,建立快照(aen-sql-25-a-pg.17),恢復 I/O,並完成僅中繼資料的備份,所有備份都透過 SQL Server 日誌和 API 回應進行確認。

Login Return Code: 0
Login Response: {"response":{"status":{"http":{"code":200,"description":""}},"headers":{"Date":"Fri, 09 May 2025 12:03:22 GMT","Content-Length":"37","Content-Type":"application\/json","Server":"nginx","x-auth-token":"75b2b984-a238-44ce-adbd-ff19decab148","strict-transport-security":"max-age=31536000; includeSubDomains;","content-security-policy":"frame-ancestors 'none'","x-frame-options":"DENY","x-content-type-options":"nosniff","x-xss-protection":"1; mode=block","x-request-id":"bdc6bbff70105c00fdeac8b0a1af565c"}},"result":{"items":[{"username":"anocentino"}]}}

Headers: {"x-auth-token":"75b2b984-a238-44ce-adbd-ff19decab148", "Content-Type":"application/json"}

Database 'TestDB1' acquired suspend locks in session 86.
I/O is frozen on database TestDB1. No user action is required. However, if I/O is not resumed promptly, you could cancel the backup.
Database 'TestDB1' successfully suspended for snapshot backup in session 86.

Snapshot Return Code: 0
Snapshot Response: {"response":{"status":{"http":{"code":200,"description":""}},"headers":{"Date":"Fri, 09 May 2025 12:03:22 GMT","Content-Length":"340","Content-Type":"application\/json","Server":"nginx","x-auth-token":"75b2b984-a238-44ce-adbd-ff19decab148","strict-transport-security":"max-age=31536000; includeSubDomains;","content-security-policy":"frame-ancestors 'none'","x-frame-options":"DENY","x-content-type-options":"nosniff","x-xss-protection":"1; mode=block","x-request-id":"e3089939224baca84d6ad69b485855de"}},"result":{"items":[{"name":"aen-sql-25-a-pg.17","id":"32e86de3-a3ee-3ae0-f74c-4bf5a7f74744","space":null,"source":{"name":"aen-sql-25-a-pg","id":"b6660b61-a8de-ae1b-cb65-e3045d13b5ba"},"suffix":"17","destroyed":false,"created":1746792202183,"pod":{"name":null,"id":null},"time_remaining":null,"eradication_config":{"manual_eradication":"enabled"}}]}}

I/O was resumed on database TestDB1. No user action is required.
Database 'TestDB1' released suspend locks in session 86.
Database 'TestDB1' originally suspended for snapshot backup in session 86 successfully resumed in session 86.
Processed 0 pages for database 'TestDB1', file 'test_data_01' on file 12.
Processed 0 pages for database 'TestDB1', file 'test_data_02' on file 12.
Processed 0 pages for database 'TestDB1', file 'test_data_03' on file 12.
Processed 0 pages for database 'TestDB1', file 'test_data_04' on file 12.
Processed 0 pages for database 'TestDB1', file 'test_data_05' on file 12.
Processed 0 pages for database 'TestDB1', file 'test_data_06' on file 12.
Processed 0 pages for database 'TestDB1', file 'test_data_07' on file 12.
Processed 0 pages for database 'TestDB1', file 'test_data_08' on file 12.
BACKUP DATABASE successfully processed 0 pages in 0.004 seconds (0.000 MB/sec).

Snapshot backup successful. Snapshot Name: aen-sql-25-a-pg.17

總結

本範例強調 SQL Server 2025 的新sp_invoke_external_rest_endpoint程序如何改變備份自動化。在此之前,與儲存系統整合需要 PowerShell 或外部工具。現在,我們可以從 T-SQL 原生進行 REST API 呼叫,簡化工作流程並降低複雜性。

主要優點:

  • 原生 REST 整合:最後,我們可以直接從 T-SQL 進行 API 呼叫,而不必跳到 PowerShell 或其他指令碼語言
  • 簡化自動化:在一個地方建立您的整個備份工作流程 – 無需在不同工具之間切換更多內容
  • 降低相依性:消除 SQL Server 與儲存系統之間的中間層,減少活動零件,減少潛在的故障點
  • 提升安全性:在 SQL Server 內而非外部指令碼檔案中集中進行驗證
  • 更好的效能:在 SQL Server 內執行作業,意味著管理成本更低,執行時間更快

此功能可消除情境切換,並將現代化自動化功能導入資料庫引擎。只需確保安全儲存 API 權杖,並在生產中實施適當的錯誤處理。

總而言之,SQL Server 2025 的 REST 整合對於管理複雜、大規模環境的 DBA 來說,是一大成功。