Почему мои разрешения tempdb сбрасываются при перезагрузке сервера?

последние два раза мы перезагрузили наш sql server, наш веб-сайт пошел вниз. Причина, по-видимому, заключается в том, что tempdb воссоздается, а пользователь ASPState теряет разрешение на чтение / запись в tempdb (это сайт ASP, а данные сеанса хранятся в sql server)

Это не было проблемой до двух недель назад. Кто-нибудь знает, как я могу запретить sql server сбрасывать разрешения tempdb после перезагрузки? И почему это только началось недавно? Мы используем MS SQL Server 2005.

6 ответов


во-первых, вы не должны назначать разрешения на tempdb напрямую. По очевидным причинам он воссоздается при каждой перезагрузке.

что на самом деле вызывает вопрос: зачем вам вообще нужны прямые разрешения на эту базу данных?

вам не нужны никакие разрешения, кроме возможности подключения к sql server для создания временных таблиц. Однако, если вы создаете реальные таблицы в tempdb, то я настоятельно рекомендую вам изменить это, чтобы использовать выделенная база данных для этой цели.

обновление
Основываясь на комментарии Мартина, все, что я могу сказать, это wow. Я бы никогда даже не подумал, что это был бы вариант.

Хорошо, теперь, когда я оправился от шока.

создайте новое задание в sql server, которое выполняется по расписанию. Расписание должно быть установлено на "запуск автоматически при запуске агента SQL Server". Задание должно воссоздать необходимый tempdb разрешения.

короче говоря, при перезагрузке сервера агент SQL Server будет перезапущен (при условии, что служба установлена таким образом). Когда он перезапустится, он запустит эту работу, которая затем исправит ваши разрешения. Я бы ожидал, что сайт останется на несколько секунд больше, чем требуется для полного перезапуска SQL server.


Я знаю, что это старый вопрос, но нашел новую информацию о поведении tempdb при перезапуске. Tempdb по существу воссоздается из БД "модели", и именно поэтому все изменения в нем теряются. Если вы внесете изменения для сохранения изменений даже после перезагрузки, внесите те же изменения в БД "модель", что и в "tempdb". Взглянуть на следующее: tempdb воссоздается из модели при запуске?


база данных модели используется в качестве шаблона для TempDB. Добавьте пользователей и разрешения для модели, и тот же пользователь и разрешения будут использоваться в TempDB. Я не говорю, что это оптимальное решение для каждого случая, но оно сработало для меня в ситуации, когда приложению нужен специальный доступ к TempDB.


создайте сценарий запуска на sql Server, как показано ниже:

use master
go
drop proc AddAppTempDBOwner
go
create proc AddAppTempDBOwner as
declare @sql varchar(200)
select @sql = 'use tempdb' + char(13)
+ 'exec sp_addrolemember ''db_owner'', ''app'''
exec (@sql)
go
exec sp_procoption 'AddAppTempDBOwner', 'startup', 'true'
go 

база данных tempdb в SQL server (из всего, что я когда-либо читал, слышал или испытывал) полностью отброшена и воссоздана каждый раз, когда служба запускается. Таким образом, все, что хранится в этой базе данных или записывается в нее, включая роли, пользователей или другие параметры прав доступа, будет уничтожено. За исключением некоторого суетливого кода для установки / сброса их всякий раз, когда экземпляр запускается, я не думаю, что вы можете обойти это. (Я не думаю все, что установлено в базе данных модели, получает скопирован в tempdb, когда он создан, но я никогда даже не думал об этом...)

записываются ли такие настройки в эти базы данных? Вы уверены, что ваша система не была недавно изменена или обновлена для этого? Возможно, актуально, как часто экземпляр SQL останавливается и перезапускается? (Это не редкость-если не мудро-для SQL работать в течение нескольких месяцев, если не yers без перезагрузки...)


вот скрипт для создания хранимой процедуры запуска, которая выполняет цикл Логинов и создает пользователи на базы данных tempdb как предопределенной. Этот скрипт не имеет harcoded Логинов.

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

USE [master]
GO
IF EXISTS ( SELECT *
FROM sysobjects
WHERE  id = object_id(N'AddUsersToTempDb')
    and OBJECTPROPERTY(id, N'IsProcedure') = 1 )
BEGIN
    DROP PROCEDURE AddUsersToTempDb
END
GO
CREATE PROCEDURE AddUsersToTempDb
AS
DECLARE @loginname as NVARCHAR(100);
DECLARE Login_Cursor CURSOR FOR  
    SELECT loginname
FROM master..syslogins
OPEN Login_Cursor;
FETCH NEXT FROM Login_Cursor INTO @loginname;
WHILE @@FETCH_STATUS = 0  
    BEGIN
    IF (@loginname <> 'sa' AND (NOT @loginname LIKE '##%') AND (NOT @loginname LIKE '%\%'))
    BEGIN
        PRINT @loginname
        IF EXISTS(SELECT * FROM [tempdb].sys.database_principals WHERE type_desc = 'SQL_USER' AND name = @loginname)
        PRINT '  - user already exists'
    ELSE
        BEGIN
            PRINT '  - creating user'
            DECLARE @Sql VARCHAR(MAX)
            SET @Sql =
            'USE Tempdb' + char(13) + 
            'CREATE USER ' + @loginname + ' FOR LOGIN ' + @loginname  + char(13) +
            'EXEC sp_addrolemember db_owner, ' + @loginname
            EXEC (@Sql)
        END
    END
    FETCH NEXT FROM Login_Cursor INTO @loginname;
END;
CLOSE Login_Cursor;
DEALLOCATE Login_Cursor;
GO

EXEC sp_procoption 'AddUsersToTempDb', 'startup', 'true' 
GO