孤立的SQL用户
问题
最近公司很多数据库在上云,也有一部分在下云。这期间出现了很多问题,其中一个比较恶心的问题就是“孤立用户”。当数据库备份还原以后用以前的用户发现不能登录。一开始以为是登录账号没有创建,然后重新创建登录账号,然后再授权给数据库,此时又出错,说用户已经存在。我这才引起注意,开始搜索这个资料,原来这就是因为臭名昭著的孤立用户引起的。
什么是孤立的SQL用户?
那么孤立用户又是什么东西那?一个孤立用户就是一个数据库用户,同时没有SQL Server的登录权限。
在实际生产中有很多产生孤立用户的原因,最为主要的方式就是备份还原到不同的服务器实例时。还原数据库的时候回将数据库和用户一同还原到新的数据库上,但是服务器的登录账户却没有一同还原(也不需要这么做)。如果数据库相同服务器那么皆大欢喜,因为用户没有变。如果是不同服务器,此时登录账户中没有了数据库用的名称,即使你创建了相同的名称但是他们的ID也是不同的导致他们不能关联起来。此时就导致了数据库的用户被孤立,也不能访问。此时我们需要做的就是找出孤立用户修改或者删除重建。
下图中是外国网友列出可能的产生孤立用户的原因(很详细):

查找数据库中的孤立用户
我打算写一个脚本实现两个主要目的,一是找到一个实例内所有的孤立用户;第二是按需求删除这些用户。从网上找了不少脚本和博客发现都不能实现。所以我自己写了一个亲测可用。这个脚本的麻烦在于当删除用户时,这个用户拥有自己的对象,并且不能drop掉,只能先删除这个对象或者改变对象和用户之间的关系。在下面的例子中所有的用户拥有一个架构,脚本必须去处理这个用户的架构。用脚本实现把孤立用户存储到一个临时表内,然后根据临时表的用户信息删除架构和用户。
查找孤立用户的脚本
Use master
Go
Create Table #Orphans
(
RowID int not null primary key identity(1,1) ,
TDBName varchar (100),
UserName varchar (100),
UserSid varbinary(85)
)
SET NOCOUNT ON
DECLARE @DBName sysname, @Qry nvarchar(4000)
SET @Qry = ''
SET @DBName = ''
WHILE @DBName IS NOT NULL
BEGIN
SET @DBName =
(
SELECT MIN(name)
FROM master..sysdatabases
WHERE
/** to exclude named databases add them to the Not In clause **/
name NOT IN
(
'model', 'msdb',
'distribution'
) And
DATABASEPROPERTY(name, 'IsOffline') = 0
AND DATABASEPROPERTY(name, 'IsSuspect') = 0
AND name > @DBName
)
IF @DBName IS NULL BREAK Set @Qry = 'select ''' + @DBName + ''' as DBName, name AS UserName,
sid AS UserSID from [' + @DBName + ']..sysusers
where issqluser = 1 and (sid is not null and sid <> 0x0)
and suser_sname(sid) is null order by name'
Insert into #Orphans Exec (@Qry) End
Select * from #Orphans
如何删除用户(这部分切记酌情使用,先与使用人员或者DBA确认孤立用户已经用了再进行删除。并确认其架构对象不收影响)
接着上面的脚本,我们把用户从临时表中取出来进行循环处理。
Declare @SQL as varchar (200)
Declare @DDBName varchar (100)
Declare @Orphanname varchar (100)
Declare @DBSysSchema varchar (100)
Declare @From int
Declare @To int
Select @From = 0, @To = @@ROWCOUNT
from #Orphans
--Print @From
--Print @To
While @From <= @To
Begin
Set @From = @From + 1 Select @DDBName = TDBName, @Orphanname = UserName from #Orphans
Where RowID = @From Set @DBSysSchema = '[' + @DDBName + ']' + '.[sys].[schemas]'
print @DBsysSchema
Print @DDBname
Print @Orphanname
set @SQL = 'If Exists (Select * from ' + @DBSysSchema
+ ' where name = ''' + @Orphanname + ''')
Begin
Use ' + @DDBName
+ ' Drop Schema [' + @Orphanname + ']
End'
print @SQL
Exec (@SQL) Begin Try
Set @SQL = 'Use ' + @DDBName
+ ' Drop User [' + @Orphanname + ']'
Exec (@SQL)
End Try
Begin Catch
End Catch End Drop table #Orphans
脚本中需要注意的事项
首先如果有些数据库的孤立用户不想处理那么在插入临时表时可以提前通过NOT IN语句排除数据库。在删除的孤立用户同时,也会删除孤立用户拥有的架构。需要引起注意。这个脚本将不会检查其他可能被用户拥有的对象。我已经在sql server 2005/2008/2014上进行了测试,请大家知悉。
总结
在上云或者数据库迁移的时候一旦发现这类错误往往会出现一些难以预料的问题,我建议。可以先用查询的语句进行查询看看具体哪些用户是孤立用户,哪些需要区别对待,在进行其他处理。脚本是大大减少了自己挨个查询的时间,但是也提高了风险,请大家酌情使用。
孤立的SQL用户的更多相关文章
- SQL中迁移sql用户及密码脚本
SQL中迁移sql用户及密码脚本 编写人:CC阿爸 2014-6-20 在日常SQL数据库的操作中,常常需要迁移数据库或重装服务器,这时候,一些之前建立的login账户,必须重新建立,以下可以通过 ...
- 模拟SQL用户 EXECUTE AS USER
EXECUTE AS USER= @domain SELECT SUSER_NAME(), USER_NAME(); REVERT 以下语句可以模拟SQL用户,具体使用场景自行脑补.
- sql用户权限
登录 1)右键根目录属性 点下面的sql server 和 windows 身份验证模式 2)安全性右键新建,选择登陆 去掉 那个"用户下次登陆是必须改密码" ,下面默认数据库改为 ...
- 【翻译】Flink Table Api & SQL — 用户定义函数
本文翻译自官网:User-defined Functions https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/tabl ...
- SQL——用户定义函数
根据用户定义函数返回值的类型,可将用户定义函数分为如下三个类别: (1) 返回值为可更新表的函数 若用户定义函数包含单个 SELECT 语句且该语句可更新,则该函数返回的表也可更新,这样的函数称为内嵌 ...
- sql 用户相关命令
查看所有用户 select distinct concat(user, '@', host,';') as userList from mysql.user; select #查找 distinct ...
- SQL用户存在则更新不存在则插入
1.添加索引(一般是唯一索引,我的是联合唯一索引): alter table T_Cart add unique index(goods_id,user_id); 2.SQL /* * 保存购物车(如 ...
- SQL 用户定义表类型,在存储过程里使用数据类型作參数
在数据库编程里使用数据类型,能够提高代码的重用性.它们常常被使用在方法和存储过程中.使用数据类型,我们能够避免在存储过程里定义一串的參数,让人眼花缭乱,它就相当于面向对象语言里.向一个方法里传入一个对 ...
- SQL 用户定义表类型,在存储过程里使用表类型,表参数作参数
.定义表类型SUTDENTTYPE,包含三个字段,分别对应学生表的NAME,SEX和PHONE.之所以如此创建,我是准备在插入新学生数据的存储过程中,以它为参数. GO CREATE TYPE S ...
随机推荐
- [学习OpenCV攻略][004][播放AVI视频]
cvCreateFileCapture(文件路径) 创建一个影音文件录像机,返回值为CvCapture类型,用于读取视频文件 cvQuerFrame(视频) 将下一帧视频文件载入内存,当CvCaptu ...
- JQuery的deferred对象学习总结
什么是deferred? 可以帮助我们按规定的顺序执行函数,比如说我们ajax请求数据之后,对dom进行数据填充,那我们就要先执行完ajax,拿到数据之后才能进行dom数据填充,所以这就是一个顺序执行 ...
- spring定时任务执行两次 项目重复初始化 项目启动两次
tomcat/config/server.xml中Host标签Context节点的问题 项目里quartz定时器总是被执行2次,通过打印发现原来项目被加载了两次,所以项目下的Listener被重复加载 ...
- OKMX6Q ffmpeg & ffserver
通过ltib在根文件系统中增加mplayer和ffmpeg后,拟使用ffmpeg从摄像头(/dev/video0)采集视频. 刚开始使用了: ffmpeg -f video4linux2 -s 320 ...
- 通过自定义的URL Scheme启动你的App
iPhone SDK可以把你的App和一个自定义的URL Scheme绑定.该URL Scheme可用来从浏览器或别的App启动你的App. 如何响应从别的App里发给你的URL Scheme申请,由 ...
- Java常用的框架
一.SpringMVC http://blog.csdn.net/evankaka/article/details/45501811 Spring Web MVC是一种基于Java的实现了Web MV ...
- hdevelop (halcon)处理大分辨率图像问题
HALCON 的ide有2种模式:hdevelop 和hdevelop xl hdevelop 适用于普通分辨率的图像,小于等于 32k x 32k : hdevelop xl适用于大分辨率的图像,大 ...
- 未找到约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryServiceRequiredTypeIdentity匹配的导出的解决办法
未找到约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryServiceRequiredTypeIdentity Micros ...
- [转]linux下centos服务器安全设置
引言: 我们必须明白:最小的权限+最少的服务=最大的安全 所以,无论是配置任何服务器,我们都必须把不用的服务关闭.把系统权限设置到最小话,这样才能保证服务器最大的安全.下面是CentOS服务器安全设置 ...
- i2c总线的oled12864屏的u8x8运用总结
github网址链接 https://github.com/olikraus/u8g2/wiki/u8x8reference#print 用到的库文件 #ifdef U8X8_HAVE_HW_SPI ...