Очистка баз GFI MailArchiver/MailEssentials

У меня на внешних почтовых серверах используется связка Exchange/GFI MailEssentials/Symantec Mail Security.
В GFI MailEssentials имеется крайне полезный фуекция по архивированию всего почтового траффика с очень удобным web-интерфейсом. Используется при этом база, размещённая в MS SQL сервере. Структуру таблиц можно посмотреть здесь.
Почтовый трафик архивируется при этом немаленький, и базу приходится периодически бэкапить и вычищать старые записи. В принципе можно раз в несколько месяцев пересоздавать базу заново, но на мой взгляд, это не спортивно =). Таким образом стоит задача – написать скрипт, который бы бэкапил базу в известное хранилище и после этого удалял старые записи. После некоторых изысканий получился следующий скрипт:

# Задаём некоторые переменные
$server = "SERVER_NAME" # Имя сервера на котором работает база
$base = "DATABASE_NAME" # Имя базы (в моем случае GFILogs2)
$date = (Get-Date).AddMonths(-3).Date # Дата до которой мы удаляем записи из базы
$path = "PATH_TO_BACKUP" # Куда мы будем бэкапить базу

# Создаем SQL запрос, выполняющий бэкап базы и очистку таблиц GFI ME
$query = "backup database [$base] to disk = '$path' with init
use [$base]
delete from [gfi].[arc_in] where [date] < convert( datetime, '$date' )
delete from [gfi].[arc_out] where [date] < convert( datetime, '$date' )
delete from [gfi].[log_as] where [date] < convert( datetime, '$date' )
delete from [gfi].[log_as_neutral] where [date] < convert( datetime, '$date' )
delete from [gfi].[log_in] where [date] < convert( datetime, '$date' )
delete from [gfi].[log_out] where [date] < convert( datetime, '$date' )
delete from [gfi].[arc_in_att] where [id] not in (select [id] from [gfi].[arc_in])
delete from [gfi].[arc_in_bodies] where [id] not in (select [id] from [gfi].[arc_in])
delete from [gfi].[arc_out_att] where [id] not in (select [id] from [gfi].[arc_out])
delete from [gfi].[arc_out_bodies] where [id] not in (select [id] from [gfi].[arc_out])
delete from [gfi].[log_in_att] where [id] not in (select [id] from [gfi].[log_in])
delete from [gfi].[log_out_att] where [id] not in (select [id] from [gfi].[log_out])"

# Подключаемся к SQL серверу используя текущую учетку
$SQLConnection = New-Object System.Data.SqlClient.SqlConnection("Data Source=$server;
Integrated Security=SSPI")
$SQLConnection.Open()

# Создаем SQL команду для запуска бэкапа
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($query, $SQLConnection)
$SQLCommand.CommandTimeout = 200000

# Выполняем….
$SQLCommand.ExecuteNonQuery()

# Закрываем соединение
$SQLConnection.Close()

Во время написания и отладки скрипта выплыла одна тонкость – по умолчанию таймаут скрипта составляет 30 секунд, а так как база приличная по размерам – то скрипт вылетал по таймауту. Пришлось вручную в параметр $SQLCommand.CommandTimeout = 200000 прописать достаточно большое значение.

Leave a Reply

Your email address will not be published. Required fields are marked *