为啥我的 tempdb 在服务器重新启动时会重置权限?

Posted

技术标签:

【中文标题】为啥我的 tempdb 在服务器重新启动时会重置权限?【英文标题】:Why does my tempdb reset permissions when the server is rebooted?为什么我的 tempdb 在服务器重新启动时会重置权限? 【发布时间】:2011-07-16 00:18:03 【问题描述】:

过去两次我们重启了我们的 sql server,我们的网站出现了宕机。原因似乎是因为 tempdb 正在重新创建,并且 ASPState 用户正在失去对 tempdb 的读/写权限(它是一个 ASP 站点,会话数据存储在 sql server 中)

直到大约两周前,这还不是问题。有谁知道如何防止 sql server 在重新启动后重置 tempdb 权限?或者为什么这只是最近才开始发生?我们使用的是 MS SQL Server 2005。

【问题讨论】:

你用什么(框架)版本的aspnet_regsql.exe来安装它,这样我就可以试试同样的了? 【参考方案1】:

首先,您不应该直接将权限分配给 tempdb。显而易见的原因是每次重新启动时都会重新创建它。

这实际上提出了一个问题:为什么您仍然需要对该数据库具有直接权限?

除了能够连接到 sql server 来创建临时表之外,您不需要任何权限。但是,如果您要在 tempdb 中创建真正的表,那么我强烈建议您将其更改为为此目的使用专用数据库。

更新 根据马丁的评论,我只能说哇。我什至都不会认为这是一种选择。

好的,现在我已经从震惊中恢复过来了。

在 sql server 中创建一个按计划执行的新作业。计划应设置为“SQL Server 代理启动时自动启动”。该作业应重新创建您必要的 tempdb 权限。

简而言之,当服务器重新启动时,SQL Server 代理将重新启动(前提是服务设置为这种方式)。当它重新启动时,它将启动这项工作,然后修复您的权限。我希望该站点仅比 SQL Server 完全重新启动所需的时间多几秒钟。

【讨论】:

这不是 OP 的代码。这是 AspState 安装的一个选项,如forums.asp.net/p/1250011/2307815.aspx 所述。在 tempdb 中存储瞬态数据在减少日志记录方面具有优势。 +1 刚刚注意到我链接到的线程提到必须重新创建权限,所以我认为这可能是“设计使然” - 不知道为什么它只会成为 OP 的问题。 @Martin:我猜他们已经安排了工作,但是 sql 代理已关闭或被不知道它是什么的 DBA 或前雇员删除谁想留下临别礼物 @Martin 没错,该数据库用于 ASP 的会话信息,并且是前段时间由其他人设置的【参考方案2】:

我知道这是一个老问题,但发现了一些有关 tempdb 在重新启动时的行为的新信息。 tempdb 本质上是从“模型”数据库重新创建的,这就是对它的所有更改都丢失的原因。如果您进行更改以保持更改,即使在重新启动后也对“模型”数据库进行与“临时数据库”相同的更改。 看看以下内容:Does tempdb Get Recreated From model at Startup?

【讨论】:

不错的一个。它确实非常适合我的情况,在这种情况下,SQL 服务器完全专用于具有异常权限需求的单个应用程序。【参考方案3】:

模型数据库用作 TempDB 的模板。将用户和权限添加到模型中,相同的用户和权限将在 TempDB 上使用。我并不是说这是适用于所有情况的最佳解决方案,但它适用于应用程序需要特定 TempDB 访问的情况。

【讨论】:

【参考方案4】:

在 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 

【讨论】:

【参考方案5】:

这是一个创建启动存储过程的脚本,它循环Logins 并在tempdb 中创建Users 作为db_owner。此脚本没有硬编码登录。

因此,即使在 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

【讨论】:

【参考方案6】:

每次启动服务时,SQL Server 中的 tempdb 数据库(根据我读过、听过或体验过的所有内容)都会完全删除并重新创建。因此,存储在该数据库中或写入该数据库的任何内容,包括角色、用户或其他访问权限设置,都将被清除。除非在实例启动时使用一些繁琐的代码来设置/重置它们,否则我认为您无法解决此问题。 (我不认为模型数据库中设置的任何内容在创建时都会复制到 tempdb,但我什至从未想过...)

是否将任何此类设置写入该数据库?您确定您的系统最近没有进行过更改或更新吗?可能相关的是,SQL 实例多久停止和重新启动一次? (如果不重新启动,SQL 会运行数月,如果不是很明智的话,这种情况并不少见......)

【讨论】:

以上是关于为啥我的 tempdb 在服务器重新启动时会重置权限?的主要内容,如果未能解决你的问题,请参考以下文章

为啥有些游戏在 iPhone 重新安装时会自动继续进行?

为啥我的 Flutter 应用在​​ iOS 上启动时会崩溃?

为啥我的 Tomcat 服务器在编译 JSP 时会抛出间歇性 404?

为啥我在启动我的 iPhone OS 应用程序时会收到“安全策略错误”?

为啥我在启动我的应用程序时会看到双状态栏?

为啥我的 Postgres 数据库工作了一段时间,然后重新启动后无法“启动服务器”?