다음을 통해 공유


데이터베이스 메일 문제 해결

이 문서에서는 데이터베이스 메일 문제를 해결하는 방법을 제공합니다. 초기 문제 해결이 문제를 해결하지 못한 경우 고급 문제 해결을 사용합니다.

초기 데이터베이스 메일 문제 해결

기본 문제 해결 단계는 다음과 같습니다.

  1. DatabaseMail.exe 사용하여 이미 보내거나 보내려고 시도한 메일의 데이터베이스 메일 로그 및 sysmail(sysmail_event_log) 보기를 검토합니다.
  2. 테스트 메일을 보냅니다. 테스트 메일을 성공적으로 보낸 경우 전송되지 않은 메시지의 세부 정보에 집중합니다. 테스트 메일이 전송되지 않은 경우 테스트 메일 문제 해결에 집중하고 이전에 성공적으로 전송되지 않은 메일은 무시합니다.
  3. SMTP 서버 설정이 올바르지 않거나 메일을 보내는 데 사용되는 계정에 문제가 있는 경우 PowerShell을 사용하여 테스트 메일을 보냅니다.
  4. PowerShell을 사용하여 메일을 보내지 못하는 경우 SMTP 구성 문제일 수 있으며 SMTP 관리자가 필요합니다.

초기 데이터베이스 메일 문제 해결에 다음 단계를 사용할 수 있습니다.

Msdb sysmail 시스템 뷰

자세한 단계를 살펴보기 전에 관련 데이터베이스 메일 시스템 보기에 대한 간략한 요약은 다음과 같습니다.

  1. 가장 관련성이 큰 로깅은 msdb sysmail 시스템 뷰에서 발생합니다. 이러한 뷰는 사용자 환경에서 직접 쿼리할 수 있습니다.

    이름 유형 설명
    sysmail_allitems 보기 데이터베이스 메일 제출되는 모든 메시지를 Lists.
    sysmail_event_log 보기 데이터베이스 메일 외부 프로그램의 동작에 대한 메시지를 Lists.
    sysmail_faileditems 보기 데이터베이스 메일 보낼 수 없는 메시지에 대한 정보입니다.
    sysmail_mailattachments 보기 데이터베이스 메일 메시지에 대한 첨부 파일에 대한 정보입니다.
    sysmail_sentitems 보기 데이터베이스 메일 사용하여 보낸 메시지에 대한 정보입니다.
    sysmail_unsentitems 보기 데이터베이스 메일 현재 보내려는 메시지에 대한 정보입니다.
  2. 일부 오류는 Windows 애플리케이션 이벤트 로그에 기록됩니다.

1단계: sysmail_event_log 보기 확인

이 시스템 보기는 모든 데이터베이스 메일 문제를 해결하기 위한 시작점입니다.

데이터베이스 메일 문제를 해결할 때는 보기에서 sysmail_event_log 전자 메일 오류와 관련된 이벤트를 검색합니다. 일부 메시지(예: 데이터베이스 메일 외부 프로그램의 실패)는 특정 전자 메일과 연결되지 않습니다.

Sysmail_event_log에는 데이터베이스 메일 시스템에서 반환하는 각 Windows 또는 SQL Server 메시지에 대해 하나의 행이 포함됩니다. SQL Server Management Studio(SSMS)에서 관리를 선택하고 데이터베이스 메일 마우스 오른쪽 단추로 클릭한 다음 데이터베이스 메일 로그 보기를 선택하여 다음과 같이 데이터베이스 메일 로그를 검사.

데이터베이스 메일 메뉴의 데이터베이스 메일 로그 항목 보기 스크린샷

다음 쿼리를 실행하여 를 실행합니다.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 사용하여 필터링합니다.

실패한 특정 메일 항목 확인

특정 전자 메일과 관련된 오류를 검색하려면 보기에서 sysmail_faileditems 실패한 전자 메일의 를 조회 mailitem_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오류가 반환되면 전자 메일이 데이터베이스 메일 시스템에 제출되지 않고 오류가 보기에 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 시스템 뷰로 이동합니다. 특정 전자 메일과 관련된 오류를 검색하려면 보기에서 sysmail_faileditems 실패한 전자 메일의 를 조회 mailitem_id 한 다음 에서 sysmail_event_log관련 메시지를 검색합니다mailitem_id. 에서 sp_send_dbmail오류가 반환되면 전자 메일이 데이터베이스 메일 시스템에 제출되지 않고 오류가 보기에 sysmail_event_log 표시되지 않습니다.

2단계: sysmail_unsentitems, sysmail_sentitems 및 sysmail_faileditems 보기 확인

특정 전자 메일과 관련된 문제에 대해 이러한 보기를 검사 데이터베이스 메일이 전송되고 있는지, 큐에 갇혀 있는지 또는 전송되지 않는지 확인할 수 있습니다.

msdb 데이터베이스의 내부 테이블에는 현재 상태 함께 데이터베이스 메일 보낸 전자 메일 메시지 및 첨부 파일이 포함됩니다. 데이터베이스 메일 메시지가 처리될 때 이러한 테이블을 업데이트합니다.

Sysmail_mailitems table은 다른 sysmail 뷰의 기본 테이블입니다. 뷰는 sysmail_allitems 테이블에 빌드되며 이러한 보기의 상위 집합입니다.

참고

프로덕션 msdb 데이터베이스를 백업하고 다른 테스트 시스템에 사용자 데이터베이스로 복원하는 경우 복원된 백업에서 sysmail 시스템 보기를 다시 만들 수 있습니다. 복원된 백업의 뷰 정의는 백업을 복원한 시스템의 msdb 데이터베이스를 참조합니다. Msdb 백업 섹션의 고객 msdb에서 sysmail 뷰를 다시 만들려면 스크립트를 참조하세요.

Sysmail_unsentitems

이 보기에는 상태 전송되지 않거나다시 시도하는 각 데이터베이스 메일 메시지에 대해 하나의 행이 포함됩니다.

전송 대기 중인 메시지 수와 메일 큐에 있는 기간을 확인하려면 이 보기를 사용합니다. 일반적으로 전송되지 않은 메시지의 수는 적습니다. 정상 작업 중에 벤치마킹하여 정상 작업에 대한 메시지 큐의 적절한 메시지 수를 확인할 수 있습니다.

msdb의 Service Broker 개체에 sysmail_unsentitems 문제가 있는 경우 에서 메일을 검사 수도 있습니다. 또는 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 서버의 데이터베이스 메일 구성과 데이터베이스 메일 보내는 데 사용되는 계정을 검사 것입니다.

데이터베이스 메일 구성하는 방법에 대한 자세한 내용은 데이터베이스 메일 구성을 참조하세요.

데이터베이스 메일 구성

데이터베이스 메일 구성하려면 다음 단계를 수행합니다.

  1. SSMS를 열고 관리를 선택하고 데이터베이스 메일 마우스 오른쪽 단추로 클릭한 다음 데이터베이스 메일 구성을 선택합니다.

    데이터베이스 메일 메뉴에서 데이터베이스 메일 로그 항목 구성의 스크린샷

  2. 데이터베이스 메일 계정 및 프로필> 관리를선택합니다.

  3. 계정이 있는 경우 기존 계정 보기, 변경 또는 삭제를 선택하고 다음을 선택하고, 그렇지 않으면 새 계정 만들기를 선택합니다. 다음 스크린샷은 SMTP 서버에 연결하고 데이터베이스 메일 보내는 데 사용되는 계정 설정을 보여줍니다.

    데이터베이스 메일 구성 마법사의 기존 계정 관리 스크린샷

다음 사항에 특히 주의하세요.

  • 서버 이름 및 포트 번호입니다. 서버 이름은 정규화된 도메인 이름이어야 하며 포트 번호는 정확해야 합니다. 일반적으로 기본 SMTP 포트는 25이지만 현재 SMTP 구성을 검사 합니다.

  • Ssl. SMTP 서버에 SSL(Secure Sockets Layer) 또는 TLS(전송 계층 보안)가 필요한지 확인합니다.

  • SMTP 인증. 데이터베이스 엔진 서비스의 Windows 인증, 도메인 계정이 지정된 기본 인증 또는 익명 인증을 사용하고 있나요? SMTP 서버가 사용자 고유의 환경에서 허용하는 것을 확인해야 합니다. 도메인 계정이 지정된 경우(서비스 계정 또는 기본 인증) SMTP 서버에 대한 권한이 있어야 합니다.

구성을 사용하여 PowerShell을 사용하여 테스트 메일을 보낼 수 있습니다. PowerShell을 사용하여 테스트 메일 보내기를 참조하세요.

데이터베이스 메일 시스템 매개 변수 확인

시스템 매개 변수를 검사 단계를 수행합니다.

  1. SSMS를 열고 관리를 선택하고 데이터베이스 메일 마우스 오른쪽 단추로 클릭한 다음 데이터베이스 메일 구성을 선택합니다.

  2. 시스템 매개 변수 보기 또는 변경을 선택합니다.

다음 스크린샷은 시스템 매개 변수의 기본값을 보여줍니다. 고유한 시스템 매개 변수를 확인하고 문제를 해결하는 문제와 관련이 있는지 확인합니다.

데이터베이스 메일 구성 마법사의 시스템 매개 변수 구성 스크린샷

5단계: 테스트 메일 보내기

이 섹션에서는 SSMS 및 PowerShell을 사용하여 테스트 데이터베이스 메일 보내는 데 도움이 됩니다.

데이터베이스 메일 사용하여 테스트 이메일 보내기

테스트 이메일을 보내면 발생한 문제를 재현하고 데이터베이스 메일 보낼 수 있는지 여부를 확인하는 데 도움이 됩니다.

테스트 데이터베이스 메일 보내려면 관리를 선택하고 데이터베이스 메일 마우스 오른쪽 단추로 클릭한 다음 테스트 전자 메일 보내기...를 선택합니다.

데이터베이스 메일 마우스 오른쪽 단추로 클릭한 후 표시되는 테스트 메일 보내기 옵션의 스크린샷

테스트 메일을 보낸 후 데이터베이스 메일 로그 및 sysmail 보기를 검사.

  • 테스트 메일이 성공적으로 전송되지 않은 경우 이 문서를 사용하여 전송되지 않는 이유를 해결합니다.
  • 테스트 메일이 성공적으로 전송되었지만 아직 전송되지 않은 다른 메일에 문제가 있는 경우 전송되지 않는 전자 메일 메시지의 세부 정보에 집중합니다. 실행 중인 실제 sp_send_dbmail 명령을 검토합니다. Transact-SQL 명령이 없는 경우 및 sql_batch_started 명령을 사용하여 sql_batch_completed 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 큐(ExternalMailQueueInternalMailQueue) 중 하나가 사용하지 않도록 설정되어 있다는 것입니다. 이 문제는 Service Broker에서 성공적으로 전송할 수 없는 포이즌 메시지로 인해 발생할 수 있습니다. 예를 들어 형식이 잘못된 XML입니다. 5번의 시도 끝에 메시지를 보낼 수 없는 경우 "포이즌"으로 간주되며 포이즌 메시지가 제거될 때까지 큐가 비활성화됩니다. 포이즌 메시지가 여전히 큐에 있고 실패 시퀀스가 반복되므로 큐를 다시 사용하도록 설정해도 문제가 resolve 않습니다. 포이즌 메시지에 대한 자세한 내용은 포이즌 메시지 처리를 참조하세요.

다른 Service Broker 개체 중 하나(예: Message Type, Contract, ServiceRoute)도 사용하지 않도록 설정되거나 누락될 수 있습니다. 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 프로세스가 종료됨이 표시됩니다.
  • 데이터베이스 메일 성공적으로 시작되지 않습니다. 보기에서 sysmail_event_logDatabaseMail 프로세스가 시작된 것을 볼 수 없습니다.
  • 초기 문제 해결은 문제를 resolve 데 도움이 되지 않습니다.

고급 데이터베이스 메일 문제 해결에 다음 방법을 사용할 수 있습니다.

고급 문제 해결을 위한 컬렉션

이 문제를 해결하려면 이러한 컬렉션 중 하나 이상이 필요할 수 있습니다.

방법 1: msdb 데이터베이스 백업

프로덕션과 별개인 환경에서 sysmail 뷰를 쿼리하는 것이 유용할 수 있습니다. 경우에 따라 msdb 데이터베이스를 백업한 다음 다른 instance 복원할 수 있습니다. sysmail 뷰는 모두 msdb에 대한 참조로 정의되므로 복원된 msdb 백업에서 쿼리하는 경우에도 뷰는 instance 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 탭의 모든 broker 이벤트가 사용하도록 설정된 Pssdiag 도구의 스크린샷

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를 눌러 이미 캡처된 이벤트를 지웁 수 있습니다.

모든 이벤트가 지워지는 것을 보여 주는 프로시먼 도구의 스크린샷.

데이터베이스 메일 문제를 재현할 준비가 되면 다음 단계를 수행합니다.

  1. 이벤트 캡처를 시작하려면 파일>캡처 이벤트(Ctrl+E) 를 선택합니다.
  2. 데이터베이스 메일 보내 문제를 재현해 보세요.
  3. 이벤트 캡처를 중지하려면 파일>캡처 이벤트(Ctrl+E) 를 선택합니다.
  4. 파일을 *로 저장합니다. Pml.

프로세스 모니터 추적 분석

를 받은 후 입니다. PML 파일을 다시 프로세스 모니터를 사용하여 엽니다. 먼저 파일을 DatabaseMail.exesqlservr.exe 프로세스로 필터링합니다. 그런 다음 필터 필터 > ... 를 선택하거나 필터 아이콘을 클릭하여 필터 메뉴를 엽니다.

프로세스 이름에서 sqlservr.exe 선택하고 를DatabaseMail.exe다음 항목을 추가합니다.

필터링된 database.exe 보여 주는 프로시먼 도구의 스크린샷

SQL XEvent 또는 추적 캡처의 경우와 마찬가지로 무엇을 찾아야 할지 즉시 명확하지는 않습니다. 일반적으로 분석을 시작하는 가장 좋은 방법은 성공적으로 전송된 데이터베이스 메일 대한 프러몬 캡처와 추적을 비교하는 것입니다. 이상적으로 추적을 문제가 발생한 동일한 환경에서 보낸 전자 메일과 비교하는 것이 좋습니다. 그러나 특정 환경에서 성공적으로 전송된 데이터베이스 메일 없는 경우 추적을 다른 환경에서 성공적으로 보낸 전자 메일과 비교합니다.

DatabaseMail.exe DLL을 로드하지 못하거나 DatabaseMail.exe.config 파일을 찾을 수 없는 경우 분석이 유용합니다.

방법 5: ProcDump 도구를 사용하여 예외 덤프 수집 및 분석

ProcDump 는 Windows Sysinternals 제품군의 일부이기도 합니다.

ProcDump는 DatabaseMail.exe 외부 프로그램의 메모리 덤프를 캡처하려고 할 때 유용합니다. 일반적으로 ProcDump를 사용하여 처리되지 않은 예외가 발생하는DatabaseMail.exe 문제를 해결합니다.

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실행한 동일한 폴더에 만들어집니다.

예외 덤프 분석

예외 레코드를 찾아 예외로 이어지는 호출 스택을 검사합니다.

  1. WinDbg에서 덤프 파일을 엽니다(Windows용 디버깅 도구 다운로드 - WinDbg - Windows 드라이버).
  2. 또는 !analyze -v 명령을 사용하여 예외 레코드로 .ecxr 전환합니다.

스택이 있는 경우 일치하는 호출 스택에 대해 알려진 문제를 검색하기 시작합니다. 추가 도움이 필요한 경우 CSS 팀에 문의하세요.

방법 6: 시간 이동 디버깅 도구 사용

TTD(시간 이동 디버깅) 캡처는 일반적으로 어려운 문제에 대한 최후의 수단입니다. WinDbg 미리 보기 디버거를 사용하여 가져올 수 있습니다. TTD에 대한 포괄적인 지침 및 정보는 작동 방식 및 분석 방법에 대한 시간 이동 디버깅 을 참조하세요. 이 시점에 도달하면 CSS 팀에 문의해야 합니다. 그러나 이 섹션에서는 필요한 경우 TTD를 캡처하는 방법에 대한 지침을 제공합니다.

TTD 구성

여러 가지 이유로 DatabaseMail.exe TTD 캡처가 약간 어려울 수 있습니다. 첫째, DatabaseMail.exe 서비스로 무기한 실행되지 않지만 SQL Server(sqlservr.exe) 프로세스에서 호출됩니다. 따라서 연결할 수는 없지만 매개 변수를 사용하여 TTD를 -onLaunch 구성하여 DatabaseMail.exe 시작할 때 캡처를 시작해야 합니다. 둘째, DatabaseMail.exe 다른 프로세스에서 호출되므로 디버그 자식 프로세스를 사용해야 합니다.