Архивы: sql

доступ к базе данных на сервере возможен только из одного каталога

«Такая ошибка возникает при попытке загрузить версию 1С для SQL после того, как один из пользователей некорректно вышел из системы. В редких случаях эта ошибка может быть результатом некорректной установки конфигурации.»


Простой случай:

а)Принудительно остановить SQL-процесс можно с помощью SQL Enterprise Manager. В нем все активные процессы перечисленны в ветке “Management\Current Activity\Process Info”. Надо найти в списке справа процесс, который мешает жить, выделить его и в меню “Action” выбрать пункт “Kill Process”

б)Если пользователи работают по протоколу Named pipes, то можно просто закрыть файлы на SQL-сервере, открытые повисшим пользователем. Такие файлы имеют вид \PIPE\MSSQL$NAMEDSERVER\SQL\query. (смотреть в открытых файлах, управления компьютером)

в) Можно поступить жестче и выполнить скрипт:

USE [master]
ALTER DATABASE [наша база] SET OFFLINE WITH ROLLBACK IMMEDIATE

после выполнения скрипта рестарт службы SQL и выполнить скрипт:

USE [master]
ALTER DATABASE [наша база] SET ONLINE

Тяжелый случай:
косяк с самой базой. это печально.
Делаем бекап базы!!! (mdf и ldf файлики)

открываем query analizer
для начала переводим базу в сингл моде:

sp_dboption ‘ВАША БАЗА‘,’single user’, true

Чекаем базу:

DBCC CHECKDB (‘ВАША БАЗА‘, REPAIR_ALLOW_DATA_LOSS)

Если на этом все заканчивается, то поздравляю — вам повезло! Переводите в мультиюзер и вперед.

Если нет и говорит чтото подобное:
Server: Msg 602, Level 21, State 16, Line 1
Could not find row in sysindexes for database ID 7, object ID СТРАШНАЯЦЫФРА, index ID -1. Run DBCC CHECKTABLE on sysindexes.

Это очень печально
Узнаем что за таблица женской писей накрылась:

select object_name(СТРАШНАЯЦЫФРА)

Если это _1SCONNECT — поздравляю — это лечится.

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[_1SCONNECT]’) and OBJECTPROPERTY(id, N’IsUserTable’) = 1)
drop table [dbo].[_1SCONNECT]
GO

CREATE TABLE [dbo].[_1SCONNECT] (
[CONNECTUUID] [char] (36) NOT NULL
) ON [PRIMARY]
GO

затем:

EXEC sp_configure ‘allow updates’, ‘1’
RECONFIGURE WITH OVERRIDE
GO
delete from sysobjects where name=’dummy’
GO
EXEC sp_configure ‘allow updates’, ‘0’
RECONFIGURE WITH OVERRIDE
GO

потом снова:

DBCC CHECKDB (‘ВАША БАЗА‘, REPAIR_ALLOW_DATA_LOSS)

может выдать ошибки, но уже в других таблицах, если так — то все идет по плану.

Еще раз чекаем:

DBCC CHECKDB (‘ВАША БАЗА‘, REPAIR_ALLOW_DATA_LOSS)

Ошибок нет? Переводим в мульти-режим:

sp_dboption ‘ВАША БАЗА‘,’single user’, false

Наслаждаемся.
Сработало это по той причине что без данных из _1SCONNECT вполне можно жить и мы ее тупо грохнули и пересоздали. Если же такой косяк вызывает таблица с ценной информацией…

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 прибивает скульный файлик, прибивает папочку. Все счастливы, все довольны.

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