Архивы: smbclient

bacula, бэкап mssql баз и грабли (а также питоны, самбаклиенты и все-все-все)

Недавненько отстроил бакулу на бекапирование всего самого ценного (нажитого родной конторой непосильным трудом).
И вдруг, ВНЕЗАПНО, выяснилось что одиночные файлов (ну собственно blablabla.sql) бакула бекапит как-то странно. Т.е. то-ли вообще не бекапит, то-ли хрен пойми что делает. По крайней мере в bat в version browser’е их не видать. Из консоли они также  не разворачивались (No full backup говорит). Бида :(

Решение пришло поэтапно:
Первый.
Для начала порыскав по просторам интернетов выудил следующее решение как организовать бекап mssql запросами с линухов.
Найденная статья.
В реальности не все так радостно. Бекапить таким способом нельзя. Ибо BACKUP DATABASE в транзакции не идет. Пичалька :(

Скрипт был яростно поправлен (полный листинг будет ниже) и бекапирование было вынесено за транзакцию.

Второй этап.
Собственно суть проблемы была в том, что одиночные файлы не бекапяццо. Значит будем бекапить папки. Но MSSQL сам папки создавать не умеет (хранимые процедуры не наш вариант). Нам на помощь спешит smbclient и питоновский import sys!

В итоге получили следующее:
Бекапим mssql бакулой. HowTo.

ставим питон и его компонент для мсскуля:
apt-get install python-pymssql

ставим самбаклиента:
apt-get install smbclient

создаем наш мега-скриптик
touch /etc/bacula/scripts/mssql

Ну естественно даем на него нужные права, он же у нас выполняемый должен быть.
cmhod +x /etc/bacula/scripts/mssql

mcedit /etc/bacula/scripts/mssql

пишем в него следующее:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Импортируем библиотеку для работы с MSSQL
import pymssql
import sys
# Импортируем библиотеку для работы с шеллом
import os
#параметры командной строки получаем
ahost = sys.argv[1] + «.vashdomen.ru»   #сервер где живет mssql
auser = sys.argv[2]                                       #mssql юзер
apassword = sys.argv[3]                               #пароль mssql юзера
awheredisk = sys.argv[4]                              #диск на который будем выгружать
awhere = sys.argv[5]                                     # папка в которую будем выгружать
adatabase = sys.argv[6]                                #наша база

# Соединение с БД.
con = pymssql.connect(host=ahost, user=auser, password=apassword, database=adatabase)

# Создаем курсор для работы с соединением
cur = con.cursor()

###создаем папку с именем базы
#главное тут не напутать с количеством слешей и бекслешей
#данные заменяем на свои (их конечно тоже можно вынести в командную строку, но я не стал, мне удобнее так.
#мегюзер должен иметь соответствующие права на файлы на mssql серваках
os.system(«smbclient -U=vashdomen.ru\\\\megauser%megapassword //»+ahost+»/»+awheredisk+»$ -c ‘cd «+awhere+»; md «+adatabase+»‘»)

#формируем запрос
query=»BACKUP DATABASE » + adatabase + » TO DISK = ‘» + awheredisk + «:\\» + awhere + «\\» + adatabase +»\\» + adatabase +».sql’ WITH INIT»
#сначала завершим транзакцию (она по умолчанию открылась сама, а нам этого не надо, иначае бекап не пройдет)
cur.execute(«commit tran»)
#выполняем запрос
cur.execute(query)
#ну и восстановим транзакцию на всякий (может оно и не нужно)
cur.execute(«begin tran»)

# соединение закрываем
con.close()

Создаем еще один файлик. Он будет прибирать каку после бекапа:
touch /etc/bacula/scripts/mssqldel
cmhod +x /etc/bacula/scripts/mssqldel
mcedit /etc/bacula/scripts/mssqldel
Пишем в него следующее:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os
ahost = sys.argv[1] + «.vashdomen.ru»
auser = sys.argv[2]                 #   эти два ключа нам по сути не нужны,
apassword = sys.argv[3]         #  но я их не убирал. так. на будущее
awheredisk = sys.argv[4]
awhere = sys.argv[5]
adatabase = sys.argv[6]

### удаляем папку с бекапом с именем базы
#конектимся. идем в нужную папку. удаляем файл. идем на уровень выше, удаляем папку.
os.system(«smbclient -U=vashdomen.ru\\\\megauser%megapassword //»+ahost+»/»+awheredisk+»$ -c ‘cd «+awhere+»; cd «+adatabase+»; rm «+adatabase+».sql; cd ..; rmdir «+adatabase+» ‘»)

В конфиге бакулы (у меня они кстати разбиты на много мелких, как это сделать — напишу в следующем посте) правим нашу job’у:
#mssql backup

Job {
….
RunBeforeJob =»/etc/bacula/scripts/mssql your-server mssqluser passsword d backup yourdatabase»
RunAfterJob =»/etc/bacula/scripts/mssqldel your-server mssqluser passsword d backup yourdatabase»

}

d — диск на который бекапится, backup — папка которую должна на этом диске быть и на которую у megauser‘а из листинга выше должны быть права.

Соответственно в файлсете (в бакуловском конфиге) описываем что бакула будет забирать:

FileSet {

Include {


File = D:/BACKUP/yourdatabase
#слеши именно в эту сторону, все правильно
}
}

Как это все работает.
Бакула запускает job, тот сначала дергает RunBeforeJob, т.е. запускает наш скрипт mssql, тот в свою очередь дергает самбаклиента и создает нужную ему папочку, затем в питоном дергается mssql-сервер. mssql-сервер вываливает в эту папочку скульный файл.
Бакула продолжает джобу и забирает файлсет.
После дергает RunAfterJob. mssqldel прибивает скульный файлик, прибивает папочку. Все счастливы, все довольны.

Продолжение статьи тут