針對 Database Mail 問題進行疑難排解
本文提供針對 Database Mail 問題進行疑難解答的方法。 如果 初始疑難解答 尚未解決您的問題,請使用 進階疑難解答。
初始 Database Mail 疑難解答
以下是基本疑難解答步驟:
- 檢閱 Database Mail 記錄和 sysmail (
sysmail_event_log
) 檢視已傳送或嘗試使用 DatabaseMail.exe 傳送的郵件。 - 傳送測試郵件。 如果成功傳送測試郵件,請專注於未傳送的郵件詳細數據。 如果未傳送測試郵件,請專注於針對測試郵件進行疑難解答,並忽略之前未成功傳送的郵件。
- 如果您懷疑 SMTP 伺服器設定不正確,或是用來傳送郵件的帳戶發生問題,請使用 PowerShell 來傳送測試郵件。
- 如果您無法使用PowerShell傳送郵件,可能是SMTP設定問題,而且需要SMTP系統管理員。
您可以使用下列步驟進行初始 Database Mail 疑難解答。
Msdb sysmail 系統檢視
在查看詳細步驟之前,以下是相關 Database Mail 系統檢視的快速摘要。
大部分相關的記錄都會發生在 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 目前正在嘗試傳送之訊息的相關信息。 某些錯誤會記錄在 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 記錄,如下所示:
執行下列查詢至 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
列可以有下列值:
- 錯誤
- 警告
- 資訊
- 成功
若要只顯示必要的事件類型,請使用 WHERE
子句來篩選。
檢查特定失敗的郵件專案
若要搜尋與特定電子郵件相關的錯誤,請在mailitem_id
檢視中sysmail_faileditems
查閱失敗的電子郵件,然後搜尋 與 中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 系統檢視。 若要搜尋與特定電子郵件相關的錯誤,請在mailitem_id
檢視中sysmail_faileditems
查閱失敗的電子郵件,然後搜尋 與 中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 備份一節中的腳本,在客戶 msdb 中重新建立 sysmail 檢視 。
Sysmail_unsentitems
此檢視會針對狀態為 未傳送 或 重試的每個 Database Mail 訊息,各包含一個數據列。
當您想要查看要傳送的訊息數量,以及郵件佇列中有多少訊息,請使用此檢視。 一般而言,未傳送訊息的數目很小。 您可以在正常作業期間進行效能評定,以判斷正常作業的訊息佇列中合理的訊息數目。
如果 msdb 中的 Service Broker 物件發生問題,您也可以檢查中的郵件 sysmail_unsentitems
。 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,請遵循下列步驟:
開啟 SSMS,選取 [管理],以滑鼠右鍵按兩下 [Database Mail],然後選取 [設定 Database Mail]。
選取 [管理 Database Mail 帳戶和配置檔>] [下一步]。
如果您有帳戶,請選取 [檢視]、[變更或刪除現有的帳戶],然後選取 [下一步],否則請選取 [建立新的帳戶]。 下列螢幕快照顯示用來連線到 SMTP 伺服器的帳戶設定,並傳送 Database Mail。
請特別注意:
伺服器名稱和埠號碼。 伺服器名稱必須是完整功能變數名稱,而且埠號碼必須正確無誤。 一般而言,預設 SMTP 埠為 25,但您需要檢查目前的 SMTP 組態。
SSL。 確認 SMTP 伺服器是否需要安全套接字層 (SSL) 或傳輸層安全性 (TLS)。
SMTP 驗證。 您是否使用 資料庫引擎 服務的 Windows 驗證、使用指定的網域帳戶進行基本身份驗證或匿名驗證? 您必須確認 SMTP 伺服器在您自己的環境中允許的內容。 如果指定網域帳戶(服務帳戶或基本身份驗證),它必須具有 SMTP 伺服器上的許可權。
您可以使用設定搭配 PowerShell 傳送測試郵件,請參閱 使用 PowerShell 傳送測試電子郵件。
檢查 Database Mail 系統參數
若要檢查系統參數,請遵循下列步驟:
開啟 SSMS,選取 [管理],以滑鼠右鍵按兩下 [Database Mail],然後選取 [設定 Database Mail]。
選取 [ 檢視或變更系統參數]。
下列螢幕快照顯示系統參數的預設值。 請注意任何唯一的系統參數,並判斷它們是否與您進行疑難解答的問題有關。
步驟 5:傳送測試郵件
本節可協助您使用 SSMS 和 PowerShell 來傳送測試 Database Mail。
使用 Database Mail 傳送測試電子郵件
傳送測試電子郵件可協助您嘗試重現您遇到的問題,並確認是否可以傳送任何 Database Mail。
若要傳送測試 Database Mail,請選取 [管理],以滑鼠右鍵按兩下 [Database Mail],然後選取 [ 傳送測試電子郵件...]。
傳送測試郵件之後,請檢查 Database Mail 記錄檔和 sysmail 檢視。
- 如果測試郵件未成功傳送,請使用這份文件來針對未傳送郵件的原因進行疑難解答。
- 如果測試郵件已成功傳送,但其他未傳送的郵件仍有問題,請專注於未傳送的電子郵件訊息詳細數據。 檢閱正在執行的實際
sp_send_dbmail
命令。 如果您沒有 Transact-SQL 命令,請使用sql_batch_completed
和sql_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 佇列 (ExternalMailQueue
和 InternalMailQueue
) 已停用。 此問題可能是因為無法在 Service Broker 中成功傳送的有害訊息所造成。 例如,格式不正確的 XML。 如果訊息在五次嘗試之後無法傳送,則會將其視為「有害」,而且佇列將會停用,直到移除有害訊息為止。 重新啟用佇列將無法解決問題,因為有害訊息仍在佇列中,而失敗順序只會重複。 如需有害訊息的詳細資訊,請參閱 有害訊息處理。
其他 Service Broker 物件之一(例如 Message Type
、 Contract
、 Service
和 Route
)也可能停用或遺失。 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 無法成功啟動。 您在檢視中看不到 DatabaseMail 行程。
sysmail_event_log
- 初始疑難解答 無法協助您解決問題。
您可以使用下列方法進行進階 Database Mail 疑難解答。
進階疑難解答的集合
若要解決問題,您可能需要一或多個這些集合。
方法 1:備份 msdb 資料庫
在與生產環境分開的環境中查詢 sysmail 檢視會很有説明。 在某些情況下,您可以備份 msdb 資料庫,然後還原至另一個實例。 sysmail 檢視全都會以 msdb 的參考來定義,因此即使查詢還原的 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 或 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 外部程式:這是從
ExternalMailQueue
佇列接收訊息並準備要傳送至 SMTP 伺服器的訊息的外部 Database Mail 程式。 應用程式名稱為 “DatabaseMail - DatabaseMail - Id<PID>”。Database Mail 外部程式:這是 Database Mail 的另一個連線。 第一個連線處理佇列上
ExternalMailQueue
現有的訊息之後,會建立連線以接聽佇列上要放置的其他訊息。 如果佇列上沒有其他訊息, DatabaseMail.exe 將會終止並關閉此連線。Service Broker 啟用,可透過DatabaseMail.exe從 SMTP 伺服器接收回應訊息。 它會更新 sysmail 數據表,以記錄傳送的郵件結果。
您只能藉由檢視許多追蹤來知道預期的行為。 了解差異的最佳方式是比較您的追蹤與其中一個成功傳送的 Database Mail。 如果您有時可以傳送 Database Mail,請比較追蹤與成功的追蹤、查看差異,並檢查 SPID 所報告的任何錯誤。 如果您無法傳送任何 Database Mail,請比較追蹤與測試環境中成功傳送的追蹤。
方法 4:擷取和分析進程監視器事件
進程監視器 (Procmon) 是 Windows Sysinternals 套件的一部分。
進程監視器會產生嘈雜的擷取。 為了不遺漏任何專案,最好在擷取數據之後,而不是在擷取過程中套用篩選。 通常,您可以將擷取設為 Database Mail 問題的重現目標,因此擷取的整體數據不會太大。
擷取檔案、登錄、網路、進程和線程事件
當您開始 procmon.exe時,它會立即開始擷取數據。 GUI 很簡單。 您必須停止擷取事件,直到您準備好重現問題為止。 選取 [檔案>擷取事件] [Ctrl+E] 取消選取功能表項並停止事件收集。 選取橡皮擦圖示,或按 Ctrl+X 清除已擷取的事件:
當您準備好重現 Database Mail 問題時,請遵循下列步驟:
- 選取 [檔案>擷取事件] [Ctrl+E] 以開始擷取事件。
- 嘗試傳送 Database Mail 以重現問題。
- 選取 [檔案>擷取事件] [Ctrl+E] 以停止擷取事件。
- 將檔案儲存為 *。PML。
分析行程監視器追蹤
取得 之後。PML 檔案,再次使用進程監視器加以開啟。 首先,將檔案篩選至 DatabaseMail.exe 和 sqlservr.exe 進程。 然後,選取 [ 篩選 > 篩選...] ,或單擊篩選圖示以開啟篩選功能表。
針對 [ 行程名稱],選取 [sqlservr.exe ] 和 [DatabaseMail.exe],然後新增這些專案:
就像 SQL XEvent 或 Trace 擷取的情況一樣,目前還不清楚要尋找的專案。 通常,開始分析的最佳方式是比較追蹤與成功傳送 Database Mail 的 Procmon 擷取。 在理想情況下,比較追蹤與從發生問題所在的相同環境成功傳送的電子郵件。 不過,如果未在特定環境中成功傳送 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的相同資料夾中。
分析例外狀況傾印
尋找例外狀況記錄,並檢查導致例外狀況的呼叫堆棧。
- 在 WinDbg 中開啟傾印檔案(下載適用於 Windows 的偵錯工具 - WinDbg - Windows 驅動程式)。
- 使用
.ecxr
或!analyze -v
命令切換至例外狀況記錄。
當您有堆疊時,請開始搜尋相符呼叫堆棧的已知問題。 如果您需要進一步的協助,請連絡 CSS 小組。
方法 6:使用時間移動偵錯工具
時間旅行偵錯 (TTD) 擷取通常是問題的最後手段。 您可以使用 WinDbg 預覽除錯程式 來 取得它。 如需 TTD 的完整指示和資訊,請參閱 時間移動 偵錯的運作方式和如何進行分析。 如果您到達這個點,您需要連絡 CSS 小組。 不過,本節提供如何在必要時擷取 TTD 的指示。
設定 TTD
基於數個原因,DatabaseMail.exe的TTD擷取可能有點困難。 首先, DatabaseMail.exe 不會無限期地以服務的形式執行,但它是由 SQL Server (sqlservr.exe) 行程叫用。 因此,您無法附加至它,但您必須使用 -onLaunch
參數來設定TTD,以在DatabaseMail.exe啟動時開始擷取它。 其次,因為 DatabaseMail.exe 是由另一個進程叫用,因此您必須使用 偵錯子進程。