데이터베이스 메일 문제 해결
이 문서에서는 데이터베이스 메일 문제를 해결하는 방법을 제공합니다. 초기 문제 해결이 문제를 해결하지 못한 경우 고급 문제 해결을 사용합니다.
초기 데이터베이스 메일 문제 해결
기본 문제 해결 단계는 다음과 같습니다.
- DatabaseMail.exe 사용하여 이미 보내거나 보내려고 시도한 메일의 데이터베이스 메일 로그 및 sysmail(
sysmail_event_log
) 보기를 검토합니다. - 테스트 메일을 보냅니다. 테스트 메일을 성공적으로 보낸 경우 전송되지 않은 메시지의 세부 정보에 집중합니다. 테스트 메일을 보내지 않은 경우 테스트 메일 문제 해결에 집중하고 이전에 전송되지 않은 메일은 무시합니다.
- SMTP 서버 설정이 올바르지 않거나 메일을 보내는 데 사용되는 계정에 문제가 있다고 의심되는 경우 PowerShell을 사용하여 테스트 메일을 보냅니다.
- PowerShell을 사용하여 메일을 보내지 못하는 경우 SMTP 구성 문제가 될 수 있으며 SMTP 관리자가 필요합니다.
초기 데이터베이스 메일 문제 해결을 위해 다음 단계를 사용할 수 있습니다.
Msdb sysmail 시스템 뷰
자세한 단계를 살펴보기 전에 관련 데이터베이스 메일 시스템 보기를 간략하게 요약합니다.
가장 관련성이 큰 로깅은 msdb sysmail 시스템 뷰에서 발생합니다. 사용자 환경에서 직접 이러한 보기를 쿼리할 수 있습니다.
속성 형식 설명 sysmail_allitems View 데이터베이스 메일 제출된 모든 메시지를 나열합니다. sysmail_event_log View 데이터베이스 메일 외부 프로그램의 동작에 대한 메시지를 나열합니다. sysmail_faileditems View 데이터베이스 메일 보낼 수 없는 메시지에 대한 정보입니다. sysmail_mailattachments View 데이터베이스 메일 메시지에 대한 첨부 파일에 대한 정보입니다. sysmail_sentitems View 데이터베이스 메일 사용하여 보낸 메시지에 대한 정보입니다. sysmail_unsentitems View 데이터베이스 메일 현재 보내려는 메시지에 대한 정보입니다. 일부 오류는 Windows 애플리케이션 이벤트 로그에 기록됩니다.
1단계: sysmail_event_log 보기 확인
이 시스템 보기는 모든 데이터베이스 메일 문제를 해결하기 위한 시작점입니다.
데이터베이스 메일 sysmail_event_log
문제를 해결할 때는 전자 메일 오류와 관련된 이벤트를 검색합니다. 일부 메시지(예: 데이터베이스 메일 외부 프로그램의 실패)는 특정 전자 메일과 연결되지 않습니다.
Sysmail_event_log
에는 데이터베이스 메일 시스템에서 반환되는 각 Windows 또는 SQL Server 메시지에 대해 하나의 행이 포함되어 있습니다. SSMS(SQL Server Management Studio)에서 관리를 선택하고 데이터베이스 메일 마우스 오른쪽 단추로 클릭한 다음 데이터베이스 메일 로그 보기를 선택하여 다음과 같이 데이터베이스 메일 로그를 확인합니다.
다음 쿼리를 실행하여 다음을 수행합니다 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
다음 값이 있을 수 있습니다.
- 오류
- 경고
- 정보
- Success
필요한 이벤트 유형만 표시하려면 절을 사용하여 필터링합니다 WHERE
.
실패한 특정 메일 항목 확인
특정 전자 메일과 관련된 오류를 검색하려면 보기에서 실패한 전자 메일을 조회 mailitem_id
한 다음 관련 메시지를 검색합니다 mailitem_id
sysmail_event_log
.sysmail_faileditems
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
되면 전자 메일이 데이터베이스 메일 시스템에 제출되지 않고 보기에 sysmail_event_log
오류가 표시되지 않습니다. 문 수준 프로파일러 추적을 수집하고 발생한 오류를 해결해야 합니다.
개별 계정 배달 시도가 실패하면 데이터베이스 메일 메일 항목 배달이 성공하거나 실패할 때까지 다시 시도하는 동안 오류 메시지를 보관합니다. 결국 배달이 성공하면 누적된 모든 오류는 을 비롯한 account_id
별도의 경고로 기록됩니다. 전자 메일을 보낸 경우에도 경고가 발생할 수 있습니다. 배달이 결국 실패하면 모든 계정이 실패했기 때문에 이전의 모든 경고가 하나의 오류 메시지로 account_id
기록됩니다.
sysmail_event_log 로그인할 수 있는 문제
다음 문제가 로그인될 수 있습니다.sysmail_event_log
DATABASEMAIL.EXE SQL Server에 연결하지 못했습니다.
외부 프로그램이 msdb 테이블에 로그할 수 없는 경우 프로그램은 Windows 애플리케이션 이벤트 로그에 오류를 기록합니다.
SMTP 서버와 관련된 오류입니다.
- SMTP 서버에 연결하지 못했습니다.
- SMTP 서버로 인증하지 못했습니다.
- SMTP 서버에서 전자 메일 메시지를 거부합니다.
DatabaseMail.exe 예외입니다.
데이터베이스 메일 외부 실행 파일에 문제가 없는 경우 sysmail 시스템 보기로 이동합니다. 특정 전자 메일과 관련된 오류를 검색하려면 보기에서 실패한 전자 메일을 조회 mailitem_id
한 다음 관련 메시지를 검색합니다 mailitem_id
sysmail_event_log
.sysmail_faileditems
오류가 반환sp_send_dbmail
되면 전자 메일이 데이터베이스 메일 시스템에 제출되지 않고 보기에 sysmail_event_log
오류가 표시되지 않습니다.
2단계: sysmail_unsentitems, sysmail_sentitems 및 sysmail_faileditems 보기 확인
이러한 보기에서 특정 전자 메일에 문제가 있는지 확인하여 데이터베이스 메일이 전송되고 있는지, 큐에 갇혀 있는지 또는 전송에 실패하는지 확인할 수 있습니다.
msdb 데이터베이스의 내부 테이블에는 현재 상태와 함께 데이터베이스 메일 보낸 전자 메일 메시지 및 첨부 파일이 포함됩니다. 데이터베이스 메일 메시지가 처리될 때 이러한 테이블을 업데이트합니다.
Sysmail_mailitems
테이블은 다른 sysmail 뷰의 기본 테이블입니다. 뷰는 sysmail_allitems
테이블에 빌드되며 이러한 뷰의 상위 집합입니다.
참고 항목
프로덕션 msdb 데이터베이스를 백업하고 다른 테스트 시스템에 사용자 데이터베이스로 복원하는 경우 복원된 백업에서 sysmail 시스템 보기를 다시 만들 수 있습니다. 복원된 백업의 뷰 정의는 백업을 복원한 시스템의 msdb 데이터베이스를 참조합니다. Msdb 백업 섹션의 고객 msdb에서 sysmail 뷰를 다시 만들려면 스크립트를 참조하세요.
Sysmail_unsentitems
이 보기에는 상태가 전송되지 않거나 다시 시도하는 각 데이터베이스 메일 메시지에 대해 하나의 행이 포함됩니다.
이 뷰를 사용하여 전송 대기 중인 메시지 수와 해당 메시지가 메일 큐에 머문 시간을 확인할 수 있습니다. 일반적으로 전송되지 않은 메시지의 수는 적습니다. 정상 작업 중에 벤치마킹하여 정상적인 작업을 위해 메시지 큐에 있는 적절한 메시지 수를 확인할 수 있습니다.
msdb에서 sysmail_unsentitems
Service Broker 개체에 문제가 있는 경우 메일을 체크 인할 수도 있습니다. 또는 InternalMailQueue
큐를 ExternalMailQueue
사용하지 않도록 설정하거나 경로에 문제가 있는 경우 메일이 남아 있을 sysmail_unsentitmes
수 있습니다.
보내지 않거나 다시 시도하는 메시지는 여전히 메일 큐에 있으며 언제든지 전송될 수 있습니다. 메시지는 다음과 같은 이유로 들여쓰지 않은 상태를 가질 수 있습니다.
- 메시지가 새 메시지입니다. 메시지가 메일 큐에 배치되었지만 데이터베이스 메일 다른 메시지에서 작업 중이며 아직 이 메시지에 도달하지 않았습니다.
- 데이터베이스 메일 외부 프로그램이 실행되고 있지 않으며 메일이 전송되지 않습니다.
메시지는 다음과 같은 이유로 다시 시도 상태를 가질 수 있습니다.
- 데이터베이스 메일 메일을 보내려고 했지만 SMTP 메일 서버에 연결할 수 없습니다. 데이터베이스 메일 메시지를 보낸 프로필에 할당된 다른 데이터베이스 메일 계정을 사용하여 메시지를 계속 보내려고 합니다. 메일을 보낼 수 있는 계정이 없는 경우 데이터베이스 메일 매개 변수에 대해
Account Retry Delay
구성된 시간 동안 기다린 다음 메시지를 다시 보내려고 합니다. 데이터베이스 메일 매개 변수를 사용하여 메시지를 보내려고 시도한 횟수를 결정합니다. 데이터베이스 메일 메시지를 보내려고 하면 메시지는 다시 시도 상태로 유지됩니다. - 데이터베이스 메일 SMTP 서버에 연결하지만 오류가 발생합니다. SMTP 서버에서 반환되는 SMTP 오류 코드와 함께 제공되는 오류 메시지는 추가 문제 해결에 사용할 수 있습니다.
Sysmail_faileditems
전자 메일을 보내지 못했다는 것을 알고 있는 경우 직접 쿼리 sysmail_faileditems
할 수 있습니다. 받는 사람이 특정 메시지를 쿼리 sysmail_faileditems
하고 필터링하는 방법에 대한 자세한 내용은 데이터베이스 메일 함께 보낸 EMail 메시지의 상태 확인을 참조하세요.
데이터베이스 메일 사용하여 보낸 전자 메일 메시지의 상태를 확인하려면 다음 스크립트를 실행합니다.
-- 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 보기 확인
이 보기에는 데이터베이스 메일 제출된 각 첨부 파일에 대해 하나의 행이 포함됩니다. 데이터베이스 메일 첨부 파일에 대한 정보가 필요한 경우 이 보기를 사용합니다.
첨부 파일이 있는 메일을 보내는 데 문제가 있지만 첨부 파일이 있는 일부 메일이 성공적으로 전송되는 경우 이 보기를 통해 차이점을 확인할 수 있습니다.
4단계: SMTP 서버에 대한 데이터베이스 메일 구성 확인
데이터베이스 메일 문제를 해결하는 또 다른 단계는 SMTP 서버의 데이터베이스 메일 구성과 데이터베이스 메일 보내는 데 사용되는 계정을 확인하는 것입니다.
데이터베이스 메일 구성하는 방법에 대한 자세한 내용은 데이터베이스 메일 구성을 참조하세요.
데이터베이스 메일 구성
데이터베이스 메일 구성하려면 다음 단계를 수행합니다.
SSMS를 열고, 관리를 선택하고, 데이터베이스 메일 마우스 오른쪽 단추로 클릭하고, 데이터베이스 메일 구성을 선택합니다.
데이터베이스 메일 계정 및 프로필>관리를 선택합니다.
계정이 있는 경우 기존 계정 보기, 변경 또는 삭제를 선택하고 다음을 선택하고, 그렇지 않으면 새 계정 만들기를 선택합니다. 다음 스크린샷은 SMTP 서버에 연결하고 데이터베이스 메일 보내는 데 사용되는 계정 설정을 보여줍니다.
다음 사항에 특히 주의하세요.
서버 이름 및 포트 번호입니다. 서버 이름은 정규화된 도메인 이름이어야 하며 포트 번호는 정확해야 합니다. 일반적으로 기본 SMTP 포트는 25이지만 현재 SMTP 구성을 확인해야 합니다.
SSL. SMTP 서버에 SSL(Secure Sockets Layer) 또는 TLS(전송 계층 보안)가 필요한지 확인합니다.
SMTP 인증. 데이터베이스 엔진 서비스의 Windows 인증, 도메인 계정이 지정된 기본 인증 또는 익명 인증을 사용하고 있나요? 사용자 고유의 환경에서 SMTP 서버가 허용하는 항목을 확인해야 합니다. 도메인 계정이 지정된 경우(서비스 계정 또는 기본 인증) SMTP 서버에 대한 권한이 있어야 합니다.
구성을 사용하여 PowerShell을 사용하여 테스트 메일을 보낼 수 있습니다. PowerShell을 사용하여 테스트 전자 메일 보내기를 참조하세요.
데이터베이스 메일 시스템 매개 변수 확인
시스템 매개 변수를 확인하려면 다음 단계를 수행합니다.
SSMS를 열고, 관리를 선택하고, 데이터베이스 메일 마우스 오른쪽 단추로 클릭하고, 데이터베이스 메일 구성을 선택합니다.
시스템 매개 변수 보기를 선택 하거나 변경합니다.
다음 스크린샷은 시스템 매개 변수의 기본값을 보여줍니다. 고유한 시스템 매개 변수를 확인하고 문제를 해결하는 문제와 관련이 있는지 확인합니다.
5단계: 테스트 메일 보내기
이 섹션에서는 SSMS 및 PowerShell을 사용하여 테스트 데이터베이스 메일 보낼 수 있습니다.
데이터베이스 메일 테스트 전자 메일 보내기
테스트 이메일을 보내면 발생한 문제를 재현하고 데이터베이스 메일 보낼 수 있는지 여부를 확인하는 데 도움이 됩니다.
테스트 데이터베이스 메일 보내려면 관리를 선택하고 데이터베이스 메일 마우스 오른쪽 단추로 클릭한 다음 테스트 전자 메일 보내기를 선택합니다.
테스트 메일을 보낸 후 데이터베이스 메일 로그 및 sysmail 보기를 확인합니다.
- 테스트 메일이 성공적으로 전송되지 않은 경우 이 문서를 사용하여 전송되지 않는 이유를 해결합니다.
- 테스트 메일이 성공적으로 전송되었지만 아직 전송되지 않은 다른 메일에 문제가 있는 경우 전송되지 않는 전자 메일 메시지의 세부 정보에 초점을 맞춥니다. 실행 중인 실제
sp_send_dbmail
명령을 검토합니다. Transact-SQL 명령이 없는 경우 명령을 사용하여sql_batch_completed
sql_batch_started
XEvent 추적을 수집하고 열을 확인batch_text
합니다.
PowerShell을 사용하여 테스트 이메일 보내기
외부 프로세스를 사용하면 문제 해결에서 데이터베이스 메일 제외하고 계정 구성을 테스트할 수 있습니다. 예를 들어 PowerShell을 사용하여 테스트 메일을 보냅니다. PowerShell을 사용하여 테스트 메일을 보내지 못한 경우 데이터베이스 메일 문제가 아님을 나타냅니다.
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 개체에 문제가 있으면 데이터베이스 메일 작업이 실패할 수 있습니다. 일반적인 문제는 Service Broker 큐ExternalMailQueue
(및 InternalMailQueue
) 중 하나가 사용하지 않도록 설정되어 있다는 것입니다. 이 문제는 Service Broker에서 성공적으로 전송할 수 없는 포이즌 메시지로 인해 발생할 수 있습니다. 예를 들어 형식이 잘못된 XML입니다. 5번의 시도 후에 메시지를 보낼 수 없는 경우 "포이즌"으로 간주되며 포이즌 메시지가 제거될 때까지 큐가 비활성화됩니다. 포이즌 메시지가 큐에 있고 실패 시퀀스가 반복되므로 큐를 다시 사용하도록 설정해도 문제가 해결되지 않습니다. 포이즌 메시지에 대한 자세한 내용은 포이즌 메시지 처리를 참조 하세요.
다른 Service Broker 개체(예: Message Type
, Contract
Service
및Route
) 중 하나가 비활성화되거나 누락될 수도 있습니다. Service Broker 큐에는 큐와 연결된 활성화 프로시저가 있으므로 가능한 실패 지점입니다. 에서 msdb.sys.service_queues
열을 확인한 activation_procedure
다음 문제가 있는지 확인하는 데 사용할 sp_helptext
수 있습니다.
다음 쿼리를 실행한 다음 쿼리 결과의 두 번째 열 내용을 확인합니다.
SELECT CONVERT(VARCHAR(32),name) Name, 'exec sp_helptext ''' + activation_procedure + '''' ActivationProc_Code
FROM msdb.sys.service_queues
Service Broker 개체에 문제가 있는지 확인하려면 개체를 작동하는 데이터베이스 메일 구성과 비교하는 것이 좋습니다. 비교할 개체는 다음과 같습니다.
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
고급 데이터베이스 메일 문제 해결
고급 문제 해결은 다음 시나리오에 적용됩니다.
- 데이터베이스 메일 로그를 보면 데이터베이스 메일 충돌하고 원인은 완전히 설명되지 않습니다. DatabaseMail 프로세스가 시작되고 즉시 예외 메시지가 표시되고 DatabaseMail 프로세스가 종료되는 것을 볼 수 있습니다.
- 데이터베이스 메일 성공적으로 시작되지 않습니다. 보기에서 DatabaseMail 프로세스가 시작되었음을 알 수
sysmail_event_log
없습니다. - 초기 문제 해결은 문제를 해결하는 데 도움이 되지 않습니다.
고급 데이터베이스 메일 문제 해결을 위해 다음 방법을 사용할 수 있습니다.
고급 문제 해결을 위한 컬렉션
이 문제를 해결하려면 이러한 컬렉션 중 하나 이상이 필요할 수 있습니다.
방법 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 추적을 수집할 수 있습니다. 다음 스크린샷에 표시된 것처럼 일부 추가 이벤트, 특히 모든 broker 이벤트를 선택합니다.
Xevent 또는 SQL 추적 분석
데이터베이스 메일 보내면 일반적으로 Xevent 또는 Profiler 캡처에 5개의 다른 세션(SPID)이 표시됩니다.
sp_send_dbmail: Transact-SQL 문을 실행하면 메시지를 큐에
ExternalMailQueue
배치하는 데 사용되는 Service Broker 이벤트가 표시됩니다.DatabaseMail.exe 통해 SMTP 서버로 메시지를 보내기 위한 Service Broker 활성화 애플리케이션 이름은 "Microsoft SQL Server Service Broker 활성화"입니다.
데이터베이스 메일 외부 프로그램: 큐에서 메시지를 수신하고 SMTP 서버로
ExternalMailQueue
보낼 메시지를 준비하는 외부 데이터베이스 메일 프로그램입니다. 애플리케이션 이름은 "DatabaseMail - DatabaseMail - ID<PID>"입니다.데이터베이스 메일 외부 프로그램: 데이터베이스 메일 또 다른 연결입니다. 첫 번째 연결이 큐의 기존 메시지를 처리한 후 큐에
ExternalMailQueue
배치할 추가 메시지를 수신 대기하도록 연결이 만들어집니다. 큐 에 다른 메시지가 없으면 DatabaseMail.exe 종료되고 이 연결을 닫습니다.SMTP 서버에서 DatabaseMail.exe 통해 응답 메시지를 수신하기 위한 Service Broker 활성화입니다. 전송된 메일의 결과를 기록하도록 sysmail 테이블을 업데이트합니다.
많은 추적을 확인하여 예상 동작만 알 수 있습니다. 차이점을 아는 가장 좋은 방법은 추적을 성공적으로 전송된 데이터베이스 메일 중 하나와 비교하는 것입니다. 경우에 따라 데이터베이스 메일 보낼 수 있는 경우 추적을 성공한 추적과 비교하고 차이점을 확인하고 SPID에서 보고하는 오류를 확인합니다. 데이터베이스 메일 보낼 수 없는 경우 추적을 테스트 환경에서 성공적으로 전송된 추적과 비교합니다.
방법 4: 프로세스 모니터 이벤트 캡처 및 분석
프로세스 모니터 (Procmon)는 Windows Sysinternals 제품군의 일부입니다.
프로세스 모니터는 시끄러운 캡처를 생성합니다. 아무것도 놓치지 않으려면 캡처 프로세스 중에가 아니라 캡처된 후 데이터에 필터를 적용하는 것이 좋습니다. 일반적으로 데이터베이스 메일 문제의 재현을 중심으로 캡처를 대상으로 지정할 수 있으므로 캡처된 전체 데이터가 너무 크지 않습니다.
파일, 레지스트리, 네트워크, 프로세스 및 스레드 이벤트 캡처
procmon.exe 시작하면 즉시 데이터 캡처가 시작됩니다. GUI는 간단합니다. 문제를 재현할 준비가 될 때까지 이벤트 캡처를 중지해야 합니다. 파일>캡처 이벤트(Ctrl+E)를 선택하여 메뉴 항목의 선택을 취소하고 이벤트 컬렉션을 중지합니다. 지우개 아이콘을 선택하거나 Ctrl+X를 눌러 이미 캡처된 이벤트를 지웁다.
데이터베이스 메일 문제를 재현할 준비가 되면 다음 단계를 수행합니다.
- 이벤트 캡처를 시작하려면 파일>캡처 이벤트(Ctrl+E)를 선택합니다.
- 데이터베이스 메일 보내 문제를 재현해 봅니다.
- 이벤트 캡처를 중지하려면 파일>캡처 이벤트(Ctrl+E)를 선택합니다.
- 파일을 *로 저장합니다. PML.
프로세스 모니터 추적 분석
당신이 얻을 후 . PML 파일을 다시 프로세스 모니터를 사용하여 엽니다. 먼저 파일을 DatabaseMail.exe 필터링하고 프로세스를 sqlservr.exe. 그런 다음 필터 필터 > 를 선택하거나 필터 아이콘을 클릭하여 필터 메뉴를 엽니다.
프로세스 이름에 대해 sqlservr.exe 선택하고 DatabaseMail.exe 다음 항목을 추가합니다.
SQL XEvent 또는 추적 캡처의 경우와 마찬가지로 무엇을 찾아야 할지 즉시 명확하지는 않습니다. 일반적으로 분석을 시작하는 가장 좋은 방법은 성공적으로 전송된 데이터베이스 메일 대한 프러몬 캡처와 추적을 비교하는 것입니다. 이상적으로 추적을 문제가 발생한 동일한 환경에서 성공적으로 보낸 전자 메일과 비교하는 것이 좋습니다. 그러나 특정 환경에서 성공적으로 전송된 데이터베이스 메일 없는 경우 추적을 다른 환경에서 성공적으로 보낸 전자 메일과 비교합니다.
DatabaseMail.exe DLL을 로드하지 못하거나 DatabaseMail.exe.config 파일을 찾을 수 없는 경우 분석이 유용합니다.
방법 5: ProcDump 도구를 사용하여 예외 덤프 수집 및 분석
ProcDump 는 Windows Sysinternals 제품군의 일부이기도 합니다.
ProcDump는 DatabaseMail.exe 외부 프로그램의 메모리 덤프를 캡처하려고 할 때 유용합니다. 일반적으로 처리되지 않은 예외가 발생할 때 DatabaseMail.exe 문제를 해결하기 위해 ProcDump를 사용합니다.
ProcDump 구성
처리되지 않은 예외가 발생할 때 DatabaseMail.exe 덤프를 캡처하도록 ProcDump를 구성하려면 먼저 관리자 권한으로 명령 프롬프트를 엽니다. 그런 다음 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 드라이버).
- 또는
!analyze -v
명령을 사용하여 예외 레코드로 전환합니다.ecxr
.
스택이 있는 경우 일치하는 호출 스택에 대한 알려진 문제를 검색하기 시작합니다. 추가 도움이 필요한 경우 CSS 팀에 문의하세요.
방법 6: 시간 이동 디버깅 도구 사용
TTD(시간 이동 디버깅) 캡처는 일반적으로 어려운 문제의 최후의 수단입니다. WinDbg 미리 보기 디버거를 사용하여 가져올 수 있습니다. TTD에 대한 포괄적인 지침 및 정보는 작동 방식 및 분석 방법에 대한 시간 이동 디버깅을 참조하세요. 이 시점에 도달하면 CSS 팀에 문의해야 합니다. 그러나 이 섹션에서는 필요한 경우 TTD를 캡처하는 방법에 대한 지침을 제공합니다.
TTD 구성
여러 가지 이유로 DatabaseMail.exe TTD 캡처가 약간 어려울 수 있습니다. 첫째, DatabaseMail.exe 서비스로 무기한 실행되지는 않지만 SQL Server(sqlservr.exe) 프로세스에서 호출됩니다. 따라서 연결할 수는 없지만 매개 변수를 사용하여 -onLaunch
TTD를 구성하여 DatabaseMail.exe 시작할 때 캡처를 시작해야 합니다. 둘째, DatabaseMail.exe 다른 프로세스에서 호출되므로 디버그 자식 프로세스를 사용해야 합니다.