Database Mail лёг после CU1 для SQL Server 2025: чинить сервер — полдела, что делать с накопившейся очередью
Вы обновили SQL Server, через две недели заметили, что почта с сервера не приходит, поставили исправленный CU — и новые письма пошли. А те, что накопились за время регрессии, так и лежат в msdb непрочитанными никем. Ниже — что именно сломалось в первом выпуске CU1, как правильно долечить сервер, как разобрать залежавшуюся очередь и почему я почти никогда не отправляю такие письма «пачкой заново».
Письма пошли, а девятнадцать дней тишины никуда не делись
Ситуация до боли типовая. Плановое окно, накатили свежий кумулятивный апдейт, сервис поднялся, базы отвечают, все довольны. Через две-три недели кто-то вскользь говорит: «а мне давно не приходят письма о бэкапах». И тут выясняется, что не приходят они вообще никому и ни о чём — ни падения регламентных заданий, ни отчёты, ни рассылки из прикладной системы, которая ходит через sp_send_dbmail.
Причина в конкретной регрессии. Первый выпуск Cumulative Update 1 для SQL Server 2025 — KB5074901 от 15 января 2026 года, продуктовая версия 17.0.4005.7 (файловая 2025.170.4005.7) — ломал Database Mail. Симптом задокументирован дословно: «Could not load file or assembly 'Microsoft.SqlServer.DatabaseMail.XEvents, Version=17.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.» Внешняя программа Database Mail не может подтянуть сборку XEvent-логирования и просто не отрабатывает отправку.
Важная деталь, которую многие пропускают: этим же болел не только 2025-й. Первый выпуск CU23 для SQL Server 2022 — KB5074819, тоже от 15 января 2026 года, версия 16.0.4235.2 — падал с той же самой ошибкой и той же самой сборкой версии 17.0.0.0. Так что если у вас зоопарк из 2022 и 2025, проверять надо оба контура. 29 января Microsoft перевыпустила оба пакета: KB5078298 (17.0.4006.2) для 2025 и KB5078297 (16.0.4236.2) для 2022.
Сразу отделю эту регрессию от «обычных» почтовых проблем, с которыми её часто путают. DatabaseMail.exe — отдельное приложение на .NET Framework: оно запускается активацией очереди Service Broker, читает свой DatabaseMail.exe.config и само ходит на SMTP. Когда почта ломается из-за TLS (релей перестал принимать старые протоколы, на сервере не включено использование TLS 1.2 для .NET Framework, не отмечен флажок SSL в учётной записи Database Mail), в sysmail_event_log появляются ошибки соединения или аутентификации с SMTP, а письма уходят в retrying и failed. Здесь картина другая: внешний процесс падает ещё до обращения к релею на загрузке сборки XEvents. Поэтому крутить реестр SChannel и перевыпускать сертификаты релея при таком тексте ошибки бесполезно — лечится только сборкой.
Проверить, на чём вы сидите, — минута:
SELECT SERVERPROPERTY('ProductVersion') AS build,
SERVERPROPERTY('ProductLevel') AS lvl,
SERVERPROPERTY('ProductUpdateLevel') AS cu,
SERVERPROPERTY('ProductUpdateReference') AS kb;Если в build видите 17.0.4005.7 или 16.0.4235.2 — вы в зоне поражения, и почта у вас лежит прямо сейчас, даже если вы этого ещё не знаете.
- 17.0.4005.7 — SQL Server 2025, CU1 первого выпуска (KB5074901), Database Mail сломан
- 17.0.4006.2 — SQL Server 2025, CU1 перевыпущенный (KB5078298), исправлено
- 16.0.4235.2 — SQL Server 2022, CU23 первого выпуска (KB5074819), Database Mail сломан
- 16.0.4236.2 — SQL Server 2022, CU23 перевыпущенный (KB5078297), исправлено
Чиним сервер: три законных пути и один популярный миф
Microsoft описывает ровно три сценария, и все они рабочие. Первый — снести первоначальный CU через «Программы и компоненты» → «Просмотр установленных обновлений», откатившись на предыдущую сборку. Второй — поставить перевыпущенный пакет поверх первоначального CU, без всякого отката: это официально поддерживаемый путь, и на практике он самый быстрый. Третий — просто накатить любой более поздний CU: исправление вошло во все последующие кумулятивные обновления, и предыдущее состояние значения не имеет.
Я в девяти случаях из десяти выбираю второй вариант — установку исправленного пакета поверх. Откат CU на боевом SQL — это лишний рестарт, лишний риск словить проблему на обратном пути и лишние полчаса простоя, а выигрыша тут нет никакого. Перед установкой проверяю хеш дистрибутива, чтобы не поймать половину скачанного файла:
certutil -hashfile SQLServer2025-KB5078298-x64.exe SHA256
# ожидаем 436CCE96F805C12348809FA791E3A8839BB6D3BB408A5E0EFF6886D053B448EFА теперь миф. «Поставил исправление — почта сама разгребёт очередь». Не разгребёт. Формулировка Microsoft однозначная: письма, поставленные в очередь Database Mail во время работы первоначального выпуска, автоматически не отправляются повторно ни после удаления обновления, ни после установки CU с исправлением. Ретрай там на уровне попыток отправки конкретного аккаунта, а не «перепроиграть всё, что скопилось за три недели». Так что после патча вы получаете рабочую почту и отдельно — кладбище неотправленного в msdb.
И ещё два пункта, на которых стабильно спотыкаются. Первое: после починки Database Mail перезапустите службу SQL Server Agent. Microsoft в инструкции по настройке почты агента прямо требует перезапуск SQL Server Agent после включения или смены почтового профиля, и на практике после починки Database Mail без этого шага уведомления операторам нередко продолжают не приходить. Второе: убедитесь, что очереди Service Broker ExternalMailQueue и InternalMailQueue в msdb включены — по документации Microsoft очередь отключается, если сообщение не удаётся обработать пять раз подряд (poison message), и тогда письма так и висят в sysmail_unsentitems.
- `net stop SQLSERVERAGENT && net start SQLSERVERAGENT` (для именованного экземпляра — `SQLAgent$ИМЯ`)
- `EXEC msdb.dbo.sysmail_help_status_sp;` — запущена ли Database Mail (STARTED / STOPPED)
- `EXEC msdb.dbo.sysmail_start_sp;` — поднять объекты Service Broker, если остановлены
- `SELECT name, is_receive_enabled, is_activation_enabled FROM msdb.sys.service_queues WHERE name IN ('ExternalMailQueue','InternalMailQueue');` — не отключились ли очереди
- `EXEC msdb.dbo.sp_send_dbmail @profile_name = N'<профиль>', @recipients = N'admin@example.com', @subject = N'test';` — тестовое письмо, затем снова смотрим `sysmail_event_log`
Что на самом деле лежит в msdb и как это увидеть
Database Mail хранит всё в msdb, и это хорошая новость: вы ничего не потеряли, письма физически на месте. Есть представление sysmail_allitems — все сообщения, поданные на отправку, с полями recipients, subject, body, body_format, send_request_date, sent_status. Есть срезы по статусу: sysmail_sentitems, sysmail_unsentitems, sysmail_faileditems. Есть журнал внешней программы — sysmail_event_log, именно там и будет лежать текст про ненайденную сборку XEvents.
Первым делом снимаю картину по окну аварии — от даты установки битого CU до даты, когда почта поехала снова:
SELECT sent_status,
COUNT(*) AS cnt,
MIN(send_request_date) AS first_seen,
MAX(send_request_date) AS last_seen
FROM msdb.dbo.sysmail_allitems
WHERE send_request_date >= '20260116'
AND send_request_date < '20260204'
GROUP BY sent_status
ORDER BY cnt DESC;Потом смотрю журнал внешней программы, чтобы убедиться, что причина именно та, а не, скажем, отвалившийся SMTP-релей:
SELECT TOP (50) log_date, event_type, description
FROM msdb.dbo.sysmail_event_log
ORDER BY log_id DESC;И только потом — самое полезное: разложить неотправленное по темам. Почти всегда 90 % очереди — это однотипный машинный шум, и понять это надо до того, как вы решите «переслать всё».
SELECT LEFT(subject, 60) AS subj_head,
COUNT(*) AS cnt,
MIN(send_request_date) AS first_seen,
MAX(send_request_date) AS last_seen
FROM msdb.dbo.sysmail_allitems
WHERE sent_status <> 'sent'
AND send_request_date >= '20260116'
GROUP BY LEFT(subject, 60)
ORDER BY cnt DESC;- `sysmail_allitems` — всё, что подавалось на отправку, с телом письма и получателями
- `sysmail_unsentitems` — то, что система всё ещё считает «в процессе отправки»
- `sysmail_faileditems` — то, что помечено как неудача
- `sysmail_event_log` — журнал внешней программы Database Mail, здесь текст ошибки со сборкой
- `sysmail_mailattachments` — вложения: имя файла, размер и сами байты в столбце `attachment` (varbinary(max))
Отправлять ли заново: моё правило трёх корзин
Короткий ответ: массово — нет. Я ни разу не видел случая, когда «залить всю очередь обратно» дало пользу. Вы получаете лавину писем с датами двух-трёхнедельной давности, у которых нет никакого контекста; половина из них — уже неактуальные тревоги, вторая половина утонет в первой. Люди перестают читать эту почту вообще, и следующее настоящее падение вы пропустите уже по-человечески, а не из-за бага в CU.
Раскладываю всё, что залежалось, по трём корзинам. Первая — мониторинг состояния: падения регламентных заданий, алерты, отчёты о бэкапах, проверки CHECKDB, свободное место. Эти письма пересылать бессмысленно, они описывают состояние, которого уже нет. Их надо не переслать, а пересчитать заново по факту: посмотреть текущее состояние и один раз отправить сводку «вот что произошло за окно тишины, вот что из этого до сих пор не в порядке».
Вторая корзина — деловая переписка, которую сервер порождал по поручению людей: акты сверки контрагентам, отчёты руководителям, счета, выгрузки для бухгалтерии. Вот это переотправлять обязательно и адресно. Человек на той стороне ждёт документ и не в курсе, что у вас там был неудачный CU. Здесь важно не молча вбросить письмо трёхнедельной давности, а добавить одну строку в начало: «Письмо задержалось из-за технического сбоя на нашей стороне, документ актуален на такую-то дату».
Третья корзина — то, что уже неактуально и не должно уходить никуда: тестовые прогоны, письма отключённым сотрудникам, дубли, рассылки по проектам, которые за это время закрылись. По моему опыту это спокойно 15–25 % очереди, и молча отправить их наружу — отдельный способ создать себе проблему.
- Мониторинг и алерты — не пересылать, пересчитать текущее состояние и отправить одну сводку
- Деловые письма людям и контрагентам — переслать адресно, с пометкой о задержке
- Мусор и неактуальное — пометить и не отправлять, но не удалять до конца разбора
- Спорное — показать владельцу процесса, а не решать за него
Разбор из практики: садовый центр на 28 рабочих мест
Условно — садовый центр «Огород и двор»: 28 рабочих мест, розничный зал, склад саженцев и небольшая бухгалтерия. Один SQL Server 2025 под базами 1С (торговля и бухгалтерия), резервное копирование баз 1С сделано заданиями SQL Server Agent: ночной полный бэкап, дифференциальный днём и журнал транзакций каждый час. Уведомление оператору о сбое любого из этих заданий шло через Database Mail на общий ящик администратора и главного бухгалтера. Обновления ставил приходящий администратор из WSUS, в ночь на 17 января, — и в бой уехал ровно первый выпуск CU1, 17.0.4005.7. Сервис поднялся, 1С работала, никто ничего не заметил.
Тревогу подняли 4 февраля — главбух спросила, почему поставщик рассады не получил акт сверки, который 1С отправляла через обработку, использующую sp_send_dbmail. Сняли картину по msdb: в окне с 17 января по 4 февраля в sysmail_allitems лежало 587 писем со статусом, отличным от sent. Разложили по темам — пропорция вышла характерная: 456 писем (78 %) от SQL Agent о завершении заданий, 57 — ночные отчёты о бэкапах баз 1С, 38 — проверки свободного места на диске с резервными копиями, 19 — выгрузки остатков для закупщика и всего 17 писем настоящей деловой переписки: акты сверки поставщикам и два отчёта владельцу.
Самое неприятное было не в почте. Пересчитали фактическое состояние по msdb.dbo.sysjobhistory и msdb.dbo.backupset — и выяснилось, что за эти 19 дней дважды падало задание бэкапа журнала транзакций бухгалтерской базы 1С (22 и 29 января, оба раза из-за переполнения диска с копиями), и оба раза уведомление оператору честно легло в очередь и там осталось. То есть реальная цена бага была не «письма не пришли», а «две дырки в цепочке журнальных копий бухгалтерии никто не видел почти три недели». Плюс еженедельная проверка целостности DBCC CHECKDB падала на первом шаге из-за того же места на диске, и об этом тоже никто не узнал.
Чем закончилось. Поставили KB5078298 поверх первоначального пакета, без отката, один перезапуск службы в обеденное окно, 20 минут. Перезапустили агента, проверили sysmail_help_status_sp и отправили тестовое письмо. Из 587 писем переотправили 17 — точечно, по фильтру на тему, с пометкой о задержке; выгрузки остатков перегенерировали свежим запуском; на все алерты и отчёты сделали одну сводку на страницу и отправили её владельцу и главбуху. Место на диске с копиями расчистили, сделали внеочередной полный бэкап обеих баз 1С и запустили цепочку журнальных копий заново. Остальные 570 писем пометили и через две недели вычистили штатной процедурой.
- Окно тишины: 17.01–04.02.2026, 19 дней
- Писем в очереди: 587, из них деловых — 17 (2,9 %)
- Переотправлено: 17 писем адресно + 1 сводка вместо 551 алерта и отчёта; 19 выгрузок перегенерировано
- Скрытая цена: 2 пропущенных падения бэкапа журнала базы 1С и 3 недели без CHECKDB
Как переотправить то, что действительно нужно
Никакой штатной команды «отправь заново вот эти mailitem_id» в Database Mail нет — и не появится. Единственный поддерживаемый способ — прочитать сохранённые письма из sysmail_allitems и подать их в sp_send_dbmail заново. Ключевое требование к такому скрипту — узкий фильтр. Не sent_status <> 'sent' по всему окну, а конкретная тема, конкретный получатель, конкретный диапазон дат. Я всегда сначала выполняю SELECT с тем же WHERE, глазами смотрю выборку и только потом меняю его на отправку.
SET NOCOUNT ON;
DECLARE @id INT, @prof SYSNAME, @to NVARCHAR(MAX),
@subj NVARCHAR(255), @body NVARCHAR(MAX), @fmt VARCHAR(20),
@body_out NVARCHAR(MAX);
DECLARE c CURSOR LOCAL FAST_FORWARD FOR
SELECT i.mailitem_id, p.name, i.recipients, i.subject, i.body, i.body_format
FROM msdb.dbo.sysmail_allitems AS i
JOIN msdb.dbo.sysmail_profile AS p ON p.profile_id = i.profile_id
WHERE i.sent_status <> 'sent'
AND i.send_request_date >= '20260117'
AND i.send_request_date < '20260204'
AND i.subject LIKE N'Акт сверки%' -- узкий фильтр, а не «всё подряд»
ORDER BY i.send_request_date;
OPEN c;
FETCH NEXT FROM c INTO @id, @prof, @to, @subj, @body, @fmt;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @body_out = CASE WHEN @fmt = 'HTML'
THEN N'<p>Письмо задержано из-за технического сбоя на нашей стороне.</p>' + @body
ELSE N'Письмо задержано из-за технического сбоя на нашей стороне.' + CHAR(13) + CHAR(10) + @body END;
EXEC msdb.dbo.sp_send_dbmail
@profile_name = @prof,
@recipients = @to,
@subject = @subj,
@body = @body_out,
@body_format = @fmt;
WAITFOR DELAY '00:00:02'; -- не долбим релей пачкой
FETCH NEXT FROM c INTO @id, @prof, @to, @subj, @body, @fmt;
END
CLOSE c; DEALLOCATE c;Три честных ограничения, о которых надо знать заранее. Первое — вложения. В sysmail_allitems поле file_attachments содержит только список имён файлов через точку с запятой. Сами байты сохранены в msdb и видны в представлении sysmail_mailattachments (столбец attachment), но sp_send_dbmail принимает вложения только как пути к файлам — значит, их пришлось бы сначала выгрузить на диск, например через bcp. Если исходные файлы ещё лежат по тем же путям, проще передать @file_attachments заново; если нет — честнее пересобрать отчёт свежим запуском задания, чем реанимировать двухнедельные байты. Второе — письма с @query: они формировались из результата запроса, и «тот же» запрос сегодня даст другие цифры. Такое переотправлять нельзя, только перегенерировать с явной датой в теме.
Третье — скорость. Не выливайте несколько сотен писем в релей за минуту: почти любой почтовый шлюз воспримет это как всплеск и либо притормозит вас, либо отправит партию в спам, и вы уже второй раз за месяц объясняете, почему письма не дошли. Пауза в пару секунд между письмами и разбивка на партии по 50–100 решают вопрос. И только когда всё разобрано и отправлено, включайте обратно чистку msdb:
DECLARE @cut DATETIME = DATEADD(DAY, -90, GETDATE());
EXEC msdb.dbo.sysmail_delete_mailitems_sp @sent_before = @cut;
EXEC msdb.dbo.sysmail_delete_log_sp @logged_before = @cut;- Сначала `SELECT` с тем же `WHERE`, потом отправка — никогда наоборот
- Фильтр по теме и получателю, а не по одному лишь статусу
- Письма с `@query` не пересылать, а перегенерировать
- Партии по 50–100 писем с паузой, иначе релей решит, что вы рассылка
Чтобы тишина больше не была незаметной
Главный вывод этой истории не про Database Mail и даже не про конкретный CU. Он про то, что канал уведомлений сам себя не мониторит. Девятнадцать дней сервер молчал, и никто не заметил — потому что «нет писем» неотличимо от «всё хорошо». Это надо чинить архитектурно, и чинится оно на удивление дёшево.
Что я ставлю у себя и клиентам. Во-первых, счётчик залежавшейся очереди прямо в систему мониторинга — простой T-SQL-элемент данных, который проверяется раз в 10 минут и триггерится при значении больше нуля дважды подряд:
SELECT COUNT(*)
FROM msdb.dbo.sysmail_allitems
WHERE sent_status IN ('unsent','retrying','failed')
AND send_request_date > DATEADD(HOUR, -2, GETDATE());Во-вторых, письмо-пульс: задание раз в час отправляет служебное письмо на технический ящик, а на стороне почтовика или мониторинга стоит правило «нет пульса два часа — алерт». Это ровно тот случай, когда алерт про отсутствие события важнее алерта про событие.
В-третьих — политика обновлений. Я не сторонник «ставить CU в день выхода» и не сторонник «сидеть на RTM три года». Разумная середина: боевые экземпляры едут на кумулятивных обновлениях с задержкой в две-четыре недели после публикации, а тестовый экземпляр — сразу. Именно эта задержка и спасала бы от январской истории: между первым выпуском 15 января и перевыпуском 29 января прошло ровно две недели. Отдельно — не пускайте SQL-обновления в автоматику WSUS без окна и без человека: в садовом центре обновление уехало в бой само, ночью, и в этом половина проблемы.
И последнее, самое простое. Выключите уведомления об успешном выполнении заданий. Оставьте только падения, предупреждения и еженедельную сводку. Когда почта с сервера приходит два раза в неделю, а не сорок раз в день, её читают — и «что-то давно ничего не приходило» звучит уже на третий день, а не на девятнадцатый.
- Элемент мониторинга на длину неотправленной очереди в msdb
- Письмо-пульс раз в час + внешнее правило «нет пульса — алерт»
- Задержка 2–4 недели между выходом CU и раскаткой в бой, тестовый экземпляр — сразу
- SQL-обновления вручную, в окне, а не автоматом из WSUS
- Уведомления только о падениях; успешные прогоны — в еженедельную сводку
Частые вопросы
Как быстро понять, затронут ли мой сервер?
Выполните `SELECT SERVERPROPERTY('ProductVersion')`. Версии 17.0.4005.7 (SQL Server 2025, KB5074901) и 16.0.4235.2 (SQL Server 2022, KB5074819) — поражённые. Дополнительно посмотрите `msdb.dbo.sysmail_event_log`: там будет прямой текст об ошибке загрузки сборки Microsoft.SqlServer.DatabaseMail.XEvents версии 17.0.0.0.
Обязательно ли откатывать битый CU перед установкой исправления?
Нет. Microsoft прямо допускает установку перевыпущенного пакета поверх первоначального выпуска — для SQL Server 2025 это KB5078298, для SQL Server 2022 KB5078297. Также подойдёт любой более поздний кумулятивный апдейт: исправление вошло во все последующие CU независимо от того, какая версия стоит сейчас.
Уйдут ли письма сами, если просто подождать после установки исправления?
Не уйдут. Формулировка Microsoft однозначна: сообщения, поставленные в очередь Database Mail при установленном первоначальном выпуске, автоматически повторно не отправляются ни после удаления обновления, ни после установки CU с исправлением. Новые письма пойдут, старые останутся лежать в msdb.
Письма вообще сохранились или потеряны безвозвратно?
Сохранились. Тела, темы и получатели лежат в msdb и видны через `msdb.dbo.sysmail_allitems` — пока их не вычистила процедура `sysmail_delete_mailitems_sp` или ваше собственное обслуживание. Поэтому первым делом отключите чистку msdb, а уже потом разбирайте очередь.
Стоит ли переотправлять всю очередь разом?
Не стоит. Основную массу составляют устаревшие уведомления о состоянии, которые больше не описывают реальность и только заглушат важное. Мониторинговые письма лучше заменить одной сводкой, пересчитанной по фактическому состоянию, а адресно переотправить только деловую переписку — обычно это единицы процентов от объёма очереди.
Почему после починки почты уведомления от SQL Server Agent всё равно не приходят?
Microsoft требует перезапускать SQL Server Agent после включения или смены почтового профиля, и после починки Database Mail это стоит сделать в любом случае. Затем проверьте, что очереди Service Broker в msdb не отключены: `SELECT name, is_receive_enabled, is_activation_enabled FROM msdb.sys.service_queues WHERE name IN ('ExternalMailQueue','InternalMailQueue')`, и что `sysmail_help_status_sp` показывает STARTED.
Может ли причина быть в TLS 1.2, а не в CU?
Может, но симптомы разные. Проблемы TLS видны в `sysmail_event_log` как ошибки соединения или аутентификации с SMTP-сервером, письма копятся в статусе `retrying` или `failed`. Регрессия первого выпуска CU1 даёт ошибку загрузки сборки Microsoft.SqlServer.DatabaseMail.XEvents версии 17.0.0.0 — её не лечат ни настройки TLS для .NET Framework, ни смена порта релея, только исправленная сборка KB5078298 или более поздний CU.
Нужно ли ставить именно перевыпущенный CU1, если уже вышли следующие обновления?
Нет. Исправление вошло во все последующие кумулятивные обновления SQL Server 2025, начиная с CU2 (17.0.4015.4, KB5075211). Если окно всё равно планируется, разумнее сразу поставить актуальный CU из таблицы сборок на learn.microsoft.com, предварительно проверив его раздел Known issues.
Источники
- Microsoft Learn — Cumulative update 1 for SQL Server 2025 (KB5078298) — Раздел «Summary» / блок Important: перевыпуск 29.01.2026, версия 17.0.4006.2; первоначальный выпуск KB5074901 от 15.01.2026, версия 17.0.4005.7; текст ошибки Microsoft.SqlServer.DatabaseMail.XEvents 17.0.0.0; прямое указание, что письма из очереди не отправляются повторно автоматически. https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2025/cumulativeupdate1
- Microsoft Learn — Cumulative Update 23 for SQL Server 2022 (KB5078297) — Тот же дефект Database Mail в первоначальном выпуске KB5074819 от 15.01.2026, версия 16.0.4235.2; исправление в версии 16.0.4236.2 от 29.01.2026. https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2022/cumulativeupdate23
- Microsoft Learn — SQL Server 2025 build versions (KB5005684) — Таблица сборок: CU1 17.0.4006.2 (KB5078298, 29.01.2026), далее CU2 17.0.4015.4 (KB5075211) и последующие CU, содержащие исправление. https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2025/build-versions
- Microsoft Learn — Database Mail Messaging Objects — Перечень объектов msdb: представления sysmail_allitems, sysmail_sentitems, sysmail_unsentitems, sysmail_faileditems, sysmail_event_log и процедуры sp_send_dbmail, sysmail_start_sp, sysmail_delete_mailitems_sp, sysmail_delete_log_sp. https://learn.microsoft.com/en-us/sql/relational-databases/database-mail/database-mail-messaging-objects
- Microsoft Learn — Troubleshoot Database Mail issues — Разбор sysmail_event_log, статусы unsent/retrying/failed, отключение очередей ExternalMailQueue/InternalMailQueue из-за poison message, тестовая отправка. https://learn.microsoft.com/en-us/troubleshoot/sql/tools/troubleshoot-database-mail-issues
- Microsoft Learn — Configure SQL Server Agent Mail to Use Database Mail — Включение почтового профиля агента и обязательный перезапуск SQL Server Agent. https://learn.microsoft.com/en-us/sql/relational-databases/database-mail/configure-sql-server-agent-mail-to-use-database-mail
- Microsoft Learn — sp_send_dbmail (Transact-SQL) — Параметры @profile_name, @recipients, @subject, @body, @body_format, @file_attachments, @query — использованы в скрипте адресной переотправки. https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-send-dbmail-transact-sql
- Brent Ozar — SQL Server 2025 CU1 is Off to a Rough Start — Независимое подтверждение: оба пакета (SQL Server 2025 CU1 и SQL Server 2022 CU23) были отозваны из-за отказа Database Mail с ошибкой загрузки сборки Microsoft.SqlServer.DatabaseMail.XEvents. https://www.brentozar.com/archive/2026/01/sql-server-2025-cu1-is-off-to-a-rough-start/
