針對 Database Mail 問題進行疑難解答

本文提供針對 Database Mail 問題進行疑難解答的方法。 如果 初始疑難解答 尚未解決您的問題,請使用 進階疑難解答

初始 Database Mail 疑難解答

以下是基本的疑難解答步驟:

  1. 檢視已傳送或嘗試使用DatabaseMail.exe傳送之郵件的 Database Mail 記錄和 sysmail sysmail_event_log () 檢視。
  2. 傳送測試郵件。 如果成功傳送測試郵件,請將焦點放在未傳送的郵件詳細數據。 如果未傳送測試郵件,請專注於對測試郵件進行疑難解答,並忽略之前未成功傳送的郵件。
  3. 如果您懷疑 SMTP 伺服器設定不正確,或用來傳送郵件的帳戶有問題,請使用 PowerShell 傳送測試郵件。
  4. 如果您無法使用PowerShell傳送郵件,可能是SMTP設定問題,而且需要SMTP系統管理員。

您可以使用下列步驟進行初始 Database Mail 疑難解答。

Msdb sysmail 系統檢視

在查看詳細步驟之前,以下是相關 Database Mail 系統檢視的快速摘要。

  1. 最相關的記錄會出現在 msdb sysmail 系統檢視中。 您可以直接在環境中查詢這些檢視。

    名稱 類型 描述
    sysmail_allitems 檢視 清單 提交至 Database Mail 的所有訊息。
    sysmail_event_log 檢視 清單 Database Mail 外部程序行為的相關訊息。
    sysmail_faileditems 檢視 Database Mail 無法傳送之訊息的相關信息。
    sysmail_mailattachments 檢視 Database Mail 訊息附件的相關信息。
    sysmail_sentitems 檢視 使用 Database Mail 傳送之訊息的相關信息。
    sysmail_unsentitems 檢視 Database Mail 目前正在嘗試傳送之訊息的相關信息。
  2. 有些錯誤會記錄在 Windows 應用程式事件記錄檔中。

步驟 1:檢查sysmail_event_log檢視

此系統檢視是針對所有 Database Mail 問題進行疑難解答的起點。

針對 Database Mail 進行疑難解答時,請在檢視中sysmail_event_log搜尋與電子郵件失敗相關的事件。 某些 (訊息,例如 Database Mail 外部程式) 失敗,不會與特定電子郵件相關聯。

Sysmail_event_log針對 Database Mail 系統所傳回的每個 Windows 或 SQL Server 訊息,各包含一個數據列。 在 SQL Server Management Studio (SSMS) 中,選取 [管理],以滑鼠右鍵按兩下 [Database Mail],然後選取 [檢視 Database Mail 記錄],以檢查 Database Mail 記錄,如下所示:

Database Mail 功能表中 [檢視 Database Mail 記錄項目的螢幕快照。

對執行下列查詢 sysmail_event_log

SELECT er.log_id AS [LogID],
  er.event_type AS [EventType],
  er.log_date AS [LogDate],
  er.description AS [Description],
  er.process_id AS [ProcessID],
  er.mailitem_id AS [MailItemID],
  er.account_id AS [AccountID],
  er.last_mod_date AS [LastModifiedDate],
  er.last_mod_user AS [LastModifiedUser]
FROM msdb.dbo.sysmail_event_log er
ORDER BY [LogDate] DESC

資料列 event_type 可以有下列值:

  • 錯誤
  • 警告
  • Information
  • 成功

若只要顯示必要的事件類型,請使用 子 WHERE 句進行篩選。

檢查特定失敗郵件專案

若要搜尋與特定電子郵件相關的錯誤,請在檢視中sysmail_faileditemsmailitem_id閱失敗的電子郵件,然後在 中sysmail_event_log搜尋與相關的mailitem_id訊息。

SELECT er.log_id AS [LogID], 
    er.event_type AS [EventType], 
    er.log_date AS [LogDate], 
    er.description AS [Description], 
    er.process_id AS [ProcessID], 
    er.mailitem_id AS [MailItemID], 
    er.account_id AS [AccountID], 
    er.last_mod_date AS [LastModifiedDate], 
    er.last_mod_user AS [LastModifiedUser],
    fi.send_request_user,
    fi.send_request_date,
    fi.recipients, fi.subject, fi.body
FROM msdb.dbo.sysmail_event_log er 
    LEFT JOIN msdb.dbo.sysmail_faileditems fi
ON er.mailitem_id = fi.mailitem_id
ORDER BY [LogDate] DESC

sp_send_dbmail傳回錯誤時,不會將電子郵件提交至 Database Mail 系統,而且該錯誤不會顯示在檢視中sysmail_event_log。 您應該收集語句層級分析工具追蹤,並針對您遇到的錯誤進行疑難解答。

當個別帳戶傳遞嘗試失敗時,Database Mail 會在重試嘗試期間保存錯誤訊息,直到郵件專案傳遞成功或失敗為止。 如果最後傳遞成功,所有累積的錯誤都會記錄為個別的警告,包括 account_id。 即使已傳送電子郵件,也可能造成警告。 如果最後傳遞失敗,所有先前的警告都會記錄為一則沒有的錯誤訊息, account_id 因為所有帳戶都失敗。

可能登入sysmail_event_log的問題

下列問題可能會記錄在 中 sysmail_event_log

  • DatabaseMail.exe連線到 SQL Server 失敗。

    如果外部程式無法記錄到 msdb 資料表,程式會將錯誤記錄到 Windows 應用程式事件記錄檔。

  • 與 SMTP 伺服器相關聯的失敗。

    • 無法連絡 SMTP 伺服器。
    • 無法向 SMTP 伺服器進行驗證。
    • SMTP 伺服器拒絕電子郵件訊息。
  • DatabaseMail.exe中的例外 狀況

如果外部可執行檔 Database Mail 沒有任何問題,請移至 sysmail 系統檢視。 若要搜尋與特定電子郵件相關的錯誤,請在檢視中sysmail_faileditemsmailitem_id閱失敗的電子郵件,然後在 中sysmail_event_log搜尋與相關的mailitem_id訊息。 從sp_send_dbmail傳回錯誤時,不會將電子郵件提交至 Database Mail 系統,而且該錯誤不會顯示在檢視中sysmail_event_log

步驟 2:檢查sysmail_unsentitems、sysmail_sentitems和sysmail_faileditems檢視

您可以檢查這些檢視是否有特定電子郵件的問題,以查看資料庫郵件是否正在傳送、卡在佇列中,或是無法傳送。

msdb 資料庫中的內部數據表包含從 Database Mail 傳送的電子郵件訊息和附件,以及其目前的狀態。 Database Mail 會在處理訊息時更新這些數據表。

Sysmail_mailitems table 是其他 sysmail 檢視的基表。 檢視 sysmail_allitems 是建置在數據表上,並且是這些檢視的超集。

注意事項

如果您備份生產 msdb 資料庫,並還原至另一個測試系統作為用戶資料庫,您可以在還原的備份中重新建立 sysmail 系統檢視。 還原備份中的檢視定義會參考您還原備份所在系統上的 msdb 資料庫。 請參閱 Msdb 備份一節中的腳本,以在 customer msdb 中重新建立 sysmail 檢視。

Sysmail_unsentitems

此檢視針對狀態為未傳送重試的每個 Database Mail 訊息各包含一個數據列。

當您想要查看等候傳送的郵件數目,以及郵件佇列中的訊息已存在多久時,請使用此檢視。 一般而言,未傳送的訊息數目很小。 您可以在正常作業期間進行效能評定,以判斷消息佇列中正常作業的合理訊息數目。

如果 msdb 中的 sysmail_unsentitems Service Broker 物件有問題,您也可以在 中檢查郵件。 ExternalMailQueue如果 或 InternalMailQueue 佇列已停用,或路由發生問題,郵件可能會保留在 中sysmail_unsentitmes

未傳送重試的 郵件仍在郵件佇列中,而且可能隨時傳送。 訊息可能會因為下列原因而具有 未傳送 狀態:

  • 訊息是新的。 雖然郵件已放在郵件佇列上,但Database Mail 正在處理其他訊息,但尚未到達此訊息。
  • Database Mail 外部程式未執行,且未傳送任何郵件。

訊息可能會因為下列原因而具有 重試 狀態:

  • Database Mail 嘗試傳送郵件,但無法連絡 SMTP 郵件伺服器。 Database Mail 會繼續嘗試使用指派給傳送訊息之配置檔的其他 Database Mail 帳戶來傳送訊息。 如果沒有任何帳戶可以傳送郵件,Database Mail 會等候為 Account Retry Delay 參數設定的時間長度,然後嘗試再次傳送郵件。 Database Mail 使用 參數來判斷嘗試傳送訊息的次數。 當 Database Mail 嘗試傳送訊息時,訊息會維持重試狀態。
  • Database Mail 連線到 SMTP 伺服器,但發生錯誤。 SMTP 伺服器所傳回的 SMTP 錯誤碼和任何隨附的錯誤訊息都可以用於進一步的疑難解答。

Sysmail_faileditems

如果您知道無法傳送電子郵件,您可以直接查詢 sysmail_faileditems 。 如需依收件者查詢sysmail_faileditems和篩選特定郵件的詳細資訊,請參閱檢查以 Database Mail 傳送的電子郵件訊息狀態

若要檢查使用 Database Mail 傳送的電子郵件訊息狀態,請執行下列腳本:

-- Show the subject, the time that the mail item row was last  
-- modified, and the log information.  
-- Join sysmail_faileditems to sysmail_event_log   
-- on the mailitem_id column.  
-- In the WHERE clause list items where danw was in the recipients,  
-- copy_recipients, or blind_copy_recipients.  
-- These are the items that would have been sent to Jane@contoso.com
 
SELECT items.subject, items.last_mod_date, l.description 
FROM dbo.sysmail_faileditems AS items  
INNER JOIN dbo.sysmail_event_log AS l ON items.mailitem_id = l.mailitem_id  
WHERE items.recipients LIKE '%Jane%'    
    OR items.copy_recipients LIKE '%Jane%'   
    OR items.blind_copy_recipients LIKE '%Jane%'  
GO  

Sysmail_sentitems

如果您要尋找最後一封電子郵件成功傳送的時間,您可以依下列方式查詢 sysmail_sentitems 和排序 sent_date

SELECT ssi.sent_date, * 
FROM msdb.dbo.sysmail_sentitems ssi
ORDER BY ssi.sent_date DESC

如果已成功傳送特定類型的郵件,但其他類型則未成功傳送,此檢視可協助您找出差異。

步驟 3:檢查sysmail_mailattachments檢視

這個檢視會針對提交至 Database Mail 的每個附件,各包含一個數據列。 當您需要 Database Mail 附件的相關信息時,請使用此檢視。

如果您無法傳送含有附件的郵件,但某些含有附件的郵件已成功傳送,此檢視可協助您找出差異。

步驟 4:檢查 SMTP 伺服器的 Database Mail 組態

另一個協助解決 Database Mail 問題的步驟是檢查 SMTP 伺服器的 Database Mail 組態,以及用來傳送 Database Mail的帳戶。

如需如何設定 Database Mail 的詳細資訊,請參閱設定 Database Mail

設定 Database Mail

若要設定 Database Mail,請遵循下列步驟:

  1. 開啟 SSMS,選取 [管理],以滑鼠右鍵按兩下 [Database Mail],然後選取 [設定 Database Mail]

    Database Mail 功能表中設定 Database Mail 記錄項目的螢幕快照。

  2. 取 [管理 Database Mail 帳戶和配置檔>][下一步]

  3. 如果您有帳戶,請選 取 [檢視、變更或刪除現有的帳戶], 然後選取 [ 下一步],否則選取 [建立新帳戶]。 下列螢幕快照顯示用來連線到 SMTP 伺服器並傳送 Database Mail 的帳戶設定。

    在 [資料庫郵件設定精靈] 中管理現有帳戶的螢幕快照。

請特別注意:

  • 伺服器名稱和埠號碼。 伺服器名稱必須是完整功能變數名稱,且埠號碼必須正確無誤。 一般而言,預設 SMTP 連接埠是 25,但您需要檢查目前的 SMTP 組態。

  • Ssl。 確認 SMTP 伺服器是否需要安全套接字層 (SSL) 或傳輸層安全性 (TLS) 。

  • SMTP 驗證。 您是使用 Database Engine 服務的 Windows 驗證、具有指定網域帳戶的基本身份驗證,還是匿名驗證? 您需要確認 SMTP 伺服器在您自己的環境中允許的內容。 如果在服務帳戶或基本驗證) (指定網域帳戶,它就必須擁有 SMTP 伺服器的許可權。

您可以使用設定以 PowerShell 傳送測試郵件,請參閱 使用 PowerShell 傳送測試電子郵件

檢查 Database Mail 系統參數

若要檢查系統參數,請遵循下列步驟:

  1. 開啟 SSMS,選取 [管理],以滑鼠右鍵按兩下 [Database Mail],然後選取 [設定 Database Mail]

  2. 取 [檢視或變更系統參數]

下列螢幕快照顯示系統參數的預設值。 請注意任何唯一的系統參數,並判斷它們是否與您要進行疑難解答的問題相關。

在 [資料庫郵件設定精靈] 中設定系統參數的螢幕快照。

步驟 5:傳送測試郵件

本節可協助您使用 SSMS 和 PowerShell 傳送測試 Database Mail。

使用 Database Mail 傳送測試電子郵件

傳送測試電子郵件可協助您嘗試重現您遇到的問題,並確認是否可以傳送任何 Database Mail。

若要傳送測試 Database Mail,請選取 [管理],以滑鼠右鍵按兩下 [Database Mail],然後選取 [傳送測試電子郵件...]

以滑鼠右鍵按兩下 [Database Mail] 之後顯示的 [傳送測試電子郵件] 選項螢幕快照。

傳送測試郵件之後,請檢查 Database Mail 記錄和 sysmail 檢視。

  • 如果測試郵件未成功傳送,請使用這份文件來針對為何未傳送它進行疑難解答。
  • 如果測試郵件已成功傳送,但其他未傳送的郵件仍有問題,請將焦點放在未傳送的電子郵件詳細數據。 檢閱正在執行的實際 sp_send_dbmail 命令。 如果您沒有 Transact-SQL 命令,請使用 sql_batch_completedsql_batch_started 命令來收集 XEvent 追蹤,並查看數據 batch_text 行。

使用PowerShell傳送測試電子郵件

使用外部程式可協助您從疑難解答排除 Database Mail,並測試帳戶組態。 例如,使用PowerShell傳送測試郵件。 如果您無法使用PowerShell傳送測試郵件,則表示這不是 Database Mail問題。

如果從 PowerShell 傳送的郵件因為相同的 SMTP 伺服器設定和認證而失敗,則可能表示問題出在 SMTP 伺服器上。

  • 根據您的環境變更下列參數,然後執行下列腳本:

    $EmailFrom = "dbmail@contoso.com"
    $EmailPass = "Y0reP@ssw0rd"
    $EmailTo = "email_alias@contoso.com"
    $Port = 587
    $Subject = "Test From PowerShell"
    $Body = "Did this work?"
    $SMTPServer = "smtp.contoso.com"
    
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $Port)
    $SMTPClient.EnableSsl = $true
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($EmailFrom, $EmailPass);
    $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body) 
    
  • 如果您的 SMTP 伺服器允許匿名驗證,請使用標準埠 25,而且不需要 SSL。 執行下列指令碼:

    $EmailFrom = "dbmail@contoso.com"
    $EmailTo = "email_alias@contoso.com"
    $Port = 25
    $Subject = "Test From PowerShell (Anonymous Auth, no SSL)"
    $Body = "Did this work?"
    $SMTPServer = "smtp.contoso.com"
    
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $Port)
    $SMTPClient.EnableSsl = $true
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($EmailFrom, $EmailPass);
    $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body) 
    

步驟 6:檢查 sysmail Service Broker 物件

msdb 中的 Service Broker 物件問題可能會導致 Database Mail 作業失敗。 常見的問題是其中一個 Service Broker 佇列 (ExternalMailQueueInternalMailQueue) 已停用。 這個問題可能是因為無法在 Service Broker 中成功傳送有害訊息所造成。 例如,格式不正確的 XML。 如果在五次嘗試之後無法傳送訊息,則會將其視為「有害」,而且會停用佇列,直到移除有害訊息為止。 重新啟用佇列無法解決問題,因為有害訊息仍在佇列中,而失敗順序只會重複。 如需有害訊息的詳細資訊,請參閱 有害訊息處理

其中一個其他 Service Broker 物件 (例如 Message TypeContractServiceRoute) 也可能會停用或遺失。 Service Broker 佇列具有與佇列相關聯的啟用程式,因此可能是失敗點。 您可以檢查 中 activation_procedure 的數據 msdb.sys.service_queues行,然後使用 sp_helptext 來檢查是否有任何問題。

執行下列查詢,然後檢查查詢結果的第二個數據行的內容。

SELECT CONVERT(VARCHAR(32),name) Name, 'exec sp_helptext ''' + activation_procedure + '''' ActivationProc_Code 
FROM msdb.sys.service_queues

若要判斷 Service Broker 物件是否有任何問題,最好比較物件與正常運作的 Database Mail 組態。 以下是您應該與下列項目比較的物件:

  • Message Types
    • {//www.microsoft.com/databasemail/messages}SendMail
    • {//www.microsoft.com/databasemail/messages}SendMailStatus
  • Contracts
    • www.microsoft.com/databasemail/contracts/SendMail/v1.0
  • Queues
    • dbo.ExternalMailQueue
    • dbo.InternalMailQueue
  • Services
    • ExternalMailService
    • InternalMailService
  • Routes

進階 Database Mail 疑難解答

進階疑難解答適用於下列案例:

  • 當您查看 Database Mail 記錄時,Database Mail 損毀,而且原因並未完整說明。 您會看到 DatabaseMail 行程啟動 後會立即出現例外狀況訊息,然後顯示 DatabaseMail 進程正在關閉
  • Database Mail 無法成功啟動。 您不會在檢視中sysmail_event_log看到 DatabaseMail 程式已啟動
  • 初始疑難解答 無法協助您解決問題。

您可以使用下列方法進行進階 Database Mail 疑難解答。

進階疑難解答的集合

若要解決問題,您可能需要其中一或多個集合。

方法 1:備份 msdb 資料庫

在不同於生產環境中查詢 sysmail 檢視會很有説明。 在某些情況下,您可以備份 msdb 資料庫,然後還原至另一個實例。 系統會使用 msdb 的參考來定義 sysmail 檢視,因此即使在還原的 msdb 備份中查詢時,檢視也會參考您實例中的 msdb 系統資料庫。 若要從生產 msdb 重新建立 sysmail 檢視,請使用下列腳本在用戶資料庫中重新建立 sysmail 檢視。

/* sysmail_allitems */

USE [msdb_customer]
GO

PRINT 'Creating view sysmail_allitems in msdb backup from customer...'
GO
IF (EXISTS (SELECT *
            FROM [msdb_customer].dbo.sysobjects
            WHERE (NAME = N'sysmail_allitems')
              AND (TYPE = 'V')))
  DROP VIEW sysmail_allitems
GO

CREATE VIEW sysmail_allitems
AS
SELECT mailitem_id, profile_id, recipients, copy_recipients, blind_copy_recipients, subject, body, body_format, importance, sensitivity, file_attachments,
       attachment_encoding, query, execute_query_database, attach_query_result_as_file, query_result_header, query_result_width, query_result_separator,
       exclude_query_output, append_query_error, send_request_date, send_request_user, sent_account_id,
       CASE sent_status 
          WHEN 0 THEN 'unsent' 
          WHEN 1 THEN 'sent' 
          WHEN 3 THEN 'retrying' 
          ELSE 'failed' 
       END AS sent_status,
       sent_date, last_mod_date, last_mod_user       
FROM [msdb_customer].dbo.sysmail_mailitems 
WHERE (send_request_user = SUSER_SNAME()) OR (ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) = 1) 

GO

/* sysmail_sentitems */

USE [msdb_customer]
GO

PRINT 'Creating view sysmail_sentitems in msdb backup from customer...'
GO
IF (EXISTS (SELECT *
            FROM [msdb_customer].dbo.sysobjects
            WHERE (NAME = N'sysmail_sentitems')
              AND (TYPE = 'V')))
  DROP VIEW sysmail_sentitems
GO

CREATE VIEW sysmail_sentitems
AS
SELECT * FROM [msdb_customer].dbo.sysmail_allitems WHERE sent_status = 'sent'

GO

/* sysmail_unsentitems */

USE [msdb_customer]
GO

PRINT 'Creating view sysmail_unsentitems in msdb backup from customer...'
GO
IF (EXISTS (SELECT *
            FROM [msdb_customer].dbo.sysobjects
            WHERE (NAME = N'sysmail_unsentitems')
              AND (TYPE = 'V')))
  DROP VIEW sysmail_unsentitems
GO

CREATE VIEW sysmail_unsentitems
AS
SELECT * FROM [msdb_customer].dbo.sysmail_allitems WHERE (sent_status = 'unsent' OR sent_status = 'retrying')

GO

/* sysmail_faileditems */

USE [msdb_customer]
GO

PRINT 'Creating view sysmail_faileditems in msdb backup from customer...'
GO
IF (EXISTS (SELECT *
            FROM [msdb_customer].dbo.sysobjects
            WHERE (NAME = N'sysmail_faileditems')
              AND (TYPE = 'V')))
  DROP VIEW sysmail_faileditems
GO

CREATE VIEW sysmail_faileditems
AS
SELECT * FROM [msdb_customer].dbo.sysmail_allitems WHERE sent_status = 'failed'

GO

/* sysmail_event_log */
USE [msdb_customer]
GO
PRINT 'Creating view sysmail_event_log in msdb backup from customer...'
GO
IF (EXISTS (SELECT *
            FROM [msdb_customer].dbo.sysobjects
            WHERE (NAME = N'sysmail_event_log')
              AND (TYPE = 'V')))
  DROP VIEW sysmail_event_log
GO
CREATE VIEW sysmail_event_log
AS
SELECT log_id,
       CASE event_type 
          WHEN 0 THEN 'success' 
          WHEN 1 THEN 'information' 
          WHEN 2 THEN 'warning' 
          ELSE 'error' 
       END as event_type,
       log_date, description, process_id, sl.mailitem_id, account_id, sl.last_mod_date, sl.last_mod_user
FROM [msdb_customer].[dbo].[sysmail_log]  sl
WHERE (ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) = 1) OR 
      (EXISTS ( SELECT mailitem_id FROM [msdb_customer].[dbo].[sysmail_allitems] ai WHERE sl.mailitem_id = ai.mailitem_id ))

GO

如需 sysmail 檢視的詳細資訊,請參閱 sysmail 系統檢視 一節。

方法 2:檢查 Windows 應用程式事件記錄檔

如果外部 DatabaseMail.exe 程式無法登入 msdb 資料表,程式會將錯誤記錄到 Windows 應用程式事件記錄檔。 此外,如果 DatabaseMail.exe 遇到例外狀況,也會記錄例外狀況。 雖然例外狀況堆疊通常相同,但請檢查事件記錄檔,以查看是否有任何其他堆疊資訊存在。

有時候,當您針對 DatabaseMail.exe 損毀進行疑難解答時,可能會發現記錄指出已建立 Windows 錯誤報告傾印,如下所示:

<datetime stamp>,Information,0,1001,Windows Error Reporting,Viewpoint.contoso.com,"Fault bucket , type 0
Event Name: APPCRASH
Response: Not available
Cab Id: 0
Problem signature:
P1: DatabaseMail.exe
P2: 11.0.2100.60
P3: 4f35e1a1
P4: KERNELBASE.dll
P5: 6.3.9600.18725
P6: 59380775
P7: c0000142
P8: 00000000000ece60
P9: 
P10: 
Attached files:
These files may be available here:
C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_DatabaseMail.exe_deaadc12935831f6bbfe9bdcb0cbf864374426c1_807e7507_337982fd
Analysis symbol: 
Rechecking for solution: 0
Report Id: <Report Id>
Report Status: 4100
Hashed bucket:"

您可以擷取在 中顯示 AppCrash_DatabaseMail.exe_* 的所有檔案 。\WER\ReportQueue 路徑。 如需傾印分析建議,請參閱 ProcDump 分析 一節。

方法 3:收集和分析 XEvent 或 SQL Server 追蹤

您可以收集正在系統上執行之 Transact-SQL 命令的追蹤,以查看其中是否有任何一個失敗。

設定 PSSDiag 工具

您可以使用 PSSDiag 來收集 [一般效能] 範本下的 XEvent 或 SQL Server 追蹤。 如下列螢幕快照所示,選取一些其他事件,特別是所有訊息代理程式事件。

啟用 XEvent 索引標籤上所有訊息代理程式事件的 Pssdiag 工具螢幕快照。

分析 Xevent 或 SQL 追蹤

傳送 Database Mail 時,您通常會在 Xevent 或 Profiler 擷取中看到五個不同的會話 (SPID) 。

  • sp_send_dbmail:執行 Transact-SQL 語句之後,您會看到用來將訊息放在佇列上的 ExternalMailQueue Service Broker 事件。

  • 透過DatabaseMail.exe傳送訊息 至 SMTP 伺服器的 Service Broker 啟 。 應用程式名稱為「Microsoft SQL Server Service Broker 啟用」。

  • Database Mail 外部程式:這是外部 Database Mail 程式,可接收來自佇列的ExternalMailQueue訊息,並準備要傳送至 SMTP 伺服器的訊息。 應用程式名稱為 “DatabaseMail - DatabaseMail - Id<PID>”。

  • Database Mail 外部程式:這是來自 Database Mail 的另一個連線。 在第一個連接處理佇列上的 ExternalMailQueue 現有訊息之後,會建立連線以接聽要放在佇列上的其他訊息。 如果佇列上沒有其他訊息, DatabaseMail.exe 將會終止並關閉此連線。

  • 透過DatabaseMail.exe從 SMTP 伺服器接收回應訊息的 Service Broker 啟 用。 它會更新 sysmail 數據表,以記錄所傳送郵件的結果。

您只能藉由檢視許多追蹤來知道預期的行為。 了解差異的最佳方式是比較您的追蹤與其中一個成功傳送的 Database Mail。 如果您有時可以傳送 Database Mail,請比較追蹤與成功的追蹤、查看差異,並檢查SPID所報告的任何錯誤。 如果您無法傳送任何 Database Mail,請比較追蹤與測試環境中成功傳送的追蹤。

方法 4:擷取和分析進程監視器事件

進程監視器 (程式) 是 Windows Sysinternals 套件的一部分。

進程監視器會產生雜訊擷取。 若要不錯過任何專案,最好是在擷取數據之後套用篩選條件,而不是在擷取程式期間套用篩選。 一般而言,您可以針對 Database Mail 問題的重現來鎖定擷取,因此擷取的整體數據不會太大。

擷取檔案、登錄、網路、進程和線程事件

當您開始 procmon.exe時,它會立即開始擷取數據。 GUI 很簡單。 您必須停止擷取事件,直到準備好重現問題為止。 選取 [檔案>擷取事件 (Ctrl+E) 以取消核取功能表項並停止事件收集。 選取橡皮擦圖示,或按 Ctrl+X 清除已擷取的事件:

程序代碼工具的螢幕快照,其中顯示已清除所有事件。

當您準備好重現 Database Mail 問題時,請遵循下列步驟:

  1. 選取 [檔案>擷取事件 (Ctrl+E) 以開始擷取事件。
  2. 請嘗試傳送 Database Mail 以重現問題。
  3. 選取 [檔案>擷取事件 (Ctrl+E) 以停止擷取事件。
  4. 將檔案儲存為 *。Pml。

分析行程監視器追蹤

取得 之後。PML 檔案,再次使用進程監視器加以開啟。 首先,將檔案篩選至 DatabaseMail.exesqlservr.exe 程式。 然後,選取 [ 篩選篩選 > ] ,或單擊篩選圖示以開啟篩選功能表。

針對 [行程名稱],選 取 [sqlservr.exe ], 然後DatabaseMail.exe,然後新增下列專案:

顯示篩選 database.exe 程式工具的螢幕快照。

就像 SQL XEvent 或追蹤擷取的情況一樣,要尋找的內容並不明顯。 通常,開始分析的最佳方式是比較追蹤與 Procmon 擷取,以取得成功傳送的 Database Mail。 在理想情況下,請將追蹤與問題發生所在相同環境中成功傳送的電子郵件進行比較。 不過,如果沒有在特定環境中成功傳送 Database Mail,請將追蹤與在另一個環境中成功傳送的電子郵件進行比較。

DatabaseMail.exe 無法載入 DLL 或找不到 DatabaseMail.exe.config 檔案時,分析會很有用。

方法 5:使用 ProcDump 工具收集和分析例外狀況傾印

ProcDump 也是 Windows Sysinternals 套件的一部分。

當您嘗試擷取DatabaseMail.exe外部程式的記憶體轉儲時 ProcDump 非常有用。 一般而言,當DatabaseMail.exe遇到未處理的例外狀況時 ,您會 使用 ProcDump 進行疑難解答。

設定 ProcDump

若要設定 ProcDump 以在遇到未處理的例外 狀況 時擷取DatabaseMail.exe傾印,請先以系統管理員許可權開啟命令提示字元。 然後,使用下列命令,讓 ProcDump 擷取 DatabaseMail.exe 程序的傾印:

c:\Sysinternals> procdump -ma -t DatabaseMail.exe -w e2

您會在指令視窗中看到下列輸出:

ProcDump v9.0 - Sysinternals process dump utility
Copyright (C) 2009-2017 Mark Russinovich and Andrew Richards
Sysinternals - www.sysinternals.com
 
Waiting for process named DatabaseMail.exe...

然後重現問題。 傾印會建立在您執行 ProcDump.exe的相同資料夾中。

分析例外狀況傾印

尋找例外狀況記錄,並檢查導致例外狀況的呼叫堆棧。

  1. 在 WinDbg 中開啟傾印檔案 (下載適用於 Windows 的偵錯工具 - WinDbg - Windows 驅動 程式) 。
  2. 使用 .ecxr!analyze -v 命令切換至例外狀況記錄。

當您擁有堆疊時,請開始搜尋相符呼叫堆棧的已知問題。 如果您需要進一步的協助,請連絡 CSS 小組。

方法 6:使用時間移動偵錯工具

時間移動偵錯 (TTD) 擷取通常是解決困難問題的最後手段。 您可以使用 WinDbg 預覽除錯程式取得它。 如需 TTD 的完整指示和資訊,請 參閱時間移動偵 錯其運作方式和如何進行分析。 如果您到此時間點,您必須連絡 CSS 小組。 不過,本節提供如何在必要時擷取 TTD 的指示。

設定 TTD

基於數個原因,TTD 擷 取DatabaseMail.exe 可能有點困難。 首先, DatabaseMail.exe 不會無限期地以服務身分執行,而是由 SQL Server (sqlservr.exe) 程式叫用。 因此,您無法附加至它,但您必須使用 -onLaunch 參數來設定TTD,以在 DatabaseMail.exe 啟動時開始擷取它。 其次,因為 DatabaseMail.exe 是由另一個進程叫用,所以您需要使用 偵錯子進程