免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3417 | 回复: 6

使用重启数据库的未认证DBCC dbreboot命令来移交表的所有权 [复制链接]

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2010-12-27 18:58 |显示全部楼层
本帖最后由 andkylee 于 2010-12-27 19:03 编辑

参考:http://www.dbainfo.net/one-undocument-dbcc-command-handover-table-ownership.htm
SQL Server很相似,Sybase ASE数据库有一些未认证的DBCC命令。日常的维护过程中,需要一些Sybase认证的、公开的DBCC命令来完成,比如:检查数据库或者表的一致性、物理存储分配一致性、重建索引等等。对于这些公开的DBCC命令,Sybase公司是提供技术支持保障的。那些未公开的也就是未认证的DBCC命令,仅限Sybase内部工程师使用;Sybase公司不提供技术支持也不会对于此产生的问题负责。

所以,不要在生产环境上使用未认证的DBCC命令。在测试环境上研究学习使用倒是可以的。

需要记住的是没人对这些未认证的DBCC产后的后果负责。

本篇介绍一个用来关闭或者重启某个用户数据库的未认证DBCC命令:dbcc dbreboot。顺便介绍一个修改对象所有者的方法。因为在ASE中对象的所有权是不能移交的,其它用户只有使用权。这点和中国土地权方面很类似吗?美国人信奉私有制,怎么设计出来这个数据库实现思路?呵呵,有点扯远了~~~

这边的测试环境是ASE15.0.3,我不确定从哪个ASE版本开始支持这个dbcc dbreboot命令的。

首先用isql连接到ASE15.0.3数据库,先打开在屏幕显示输出信息的选项,


dbcc traceon(3604)

go


先来查看一下dbcc dbreboot的用法:

执行dbcc help(dbreboot)可以查看使用方法


1> dbcc help(dbreboot)

2> go

dbreboot (report | reboot | reboot_norecovery | shutdown | shutdown_load |

restart | restart_norecovery, <dbname1> [, <dbname2> ...])



通过上面的使用方法,可以看到dbreboot命令只有两个参数:

1:可操作的类型:rebootshutdownrestart

2:被操作的用户数据库的名称,不支持数据库ID,也不支持系统数据库


先来查看一下用户数据库ddb下面都有哪些用户和对象


1>use ddb

2>go

1>select uid,name from sysusers where uid < 1000 order by uid

2>go


uid
name


———– ——————————


0 public


1 dbo


3 patrol


5 rep

(4 rows affected)


数据库ddb内有两个非系统用户:patrolrep


1>select uid,count(*) from sysobjects

2>group by uid

3>order by uid

4>go


uid


———– ———–


1
43


5
56

(2 rows affected)


用户dbo拥有43个对象,另外56个对象归用户rep所属。

下面开始将用户rep拥有的56个对象“移交”给其它的用户:patrol,这里移交的意思就是将对象的所有权转移给其它用户patrolSybase ASE中是不支持这么做的。官方的推荐的做法就是重建用户表及其它对象。我这里提供的方法是“非官方”的,或许会存在问题,不过我在多次测试后没发现问题。建议大家在测试开发环境上可以这么做。

但是,我感觉这个方法是可行的。在文章后面我将给出验证方法。

启用服务器选项“allow updates to system tables”来允许修改系统表,在用户事务内修改表数据来回退错误的操作步骤。


1>begin tran

2>go

1>update sysobjects

2>set uid = 3

3>where uid = 5

4>go

(56 rows affected)

1>commit

2>go


以上就将系统表sysobjects中记录对象拥有者uid的信息由rep改成了patrol。内存中的元数据信息是没有办法改的,如果马上进行查询数据库的操作会报错的,也就是说ASE服务器还是“固执”认为被修改所属者的那些表还是属于原来所有者的。如果让ASE认为被修改的这些表属于patrol而不是原来的rep了,方法是重新装载元数据信息。以前的ASE版本中可以通过重启ASE服务器,现在我们可以用dbcc dbreboot命令来重启某个用户数据库,而不是所有的库了。

执行dbcc dbreboot(“reboot”,ddb)shutdown是个系统关键字,需要加双引号。


1>dbcc dbreboot("reboot",ddb)

2>go

———- Shutting Down Database 'ddb' ———-

Msg 2202, Level 16, State 1:

Server 'TEST', Line 1:

You cannot start database shutdown from the database to be shut down.

———- Operation on Database 'ddb' Failed ———-

必须在master数据库内部执行这个命令:dbcc dbreboot("reboot",ddb)

1>use master

2>go

1>dbcc dbreboot("reboot",ddb)

2>go

———- Shutting Down Database 'ddb' ———-

———- Re-starting Database 'ddb' With Recovery ———-

Recovering database 'ddb'.

Started estimating recovery log boundaries for database 'ddb'.

Database 'ddb', checkpoint=(26118, 15), first=(26118, 15), last=(26125, 13).

Completed estimating recovery log boundaries for database 'ddb'.

Started ANALYSIS pass for database 'ddb'.

Completed ANALYSIS pass for database 'ddb'.

Started REDO pass for database 'ddb'. The total number of log records to process

is 237.

Redo pass of recovery has processed 1 committed and 2 aborted transactions.

Completed REDO pass for database 'ddb'.

Recovery of database 'ddb' will undo incomplete nested top actions.

Started filling free space info for database 'ddb'.

Completed filling free space info for database 'ddb'.

Started cleaning up the default data cache for database 'ddb'.

Completed cleaning up the default data cache for database 'ddb'.

Recovery complete.

Database 'ddb' is now online.

———- Operation on Database 'ddb' Completed Successfully ———-

现在,rep拥有的56个对象现在属于patrol用户了。开始验证一下吧。


1>use ddb

2>go

1>select uid,count(*) from sysobjects

2>group by uid

3>go


uid


———– ———–


1
43


3
56


(2 rows affected)


sysobjects表中uid5变成3了。

随便找两个表测试一下,


1>select top 2 id,user_name(uid) as username,name
from sysobjects

2>where type='U' and uid = 3

3>go


id
username


name




———– ——————————


—————————————————————————————————————

————————————————————————————————————————

————————


1392004959 patrol


config




912003249 patrol


conn_properties


(2 rows affected)


1>select count(*) from patrol.config

2>go



———–


25


(1 row affected)

1>select count(*) from patrol.conn_properties

2>go



———–


0


(1 row affected)


查询这两个表的数据是正常的。

切换到用patrol用户登录,


C:\Documents and Settings\Administrator>isql -Upatrol -Psybase -Stest

1> use ddb

2> go

1> select count(*) from config

2> go



———–


25


(1 row affected)


同样没有问题。再来验证一下,依赖用户表的

在用户表config上点右键,属性


        

依赖性 按钮,


可以看到一些存储过程依赖用户表config,没有什么问题。


查看依赖表config的其它对象用如下的SQL语句:


select U.name as username ,O.name as object_name, O.type as object_type


from dbo.sysdepends D, dbo.sysobjects O, dbo.sysusers U


where O.uid = U.uid and O.id = D.id and D.depid = object_id('patrol.config')


–and O.type = 'P'



查看自定义数据类型被引用的情况:


select user_name(T.uid) as datatype_owner,T.name as datatype_name, U.name as user_name,O.name as object_name,C.name as column_name ,O.type as object_type


from dbo.systypes T, dbo.sysusers U, dbo.syscolumns C, dbo.systypes P,dbo.sysobjects O


where T.uid = U.uid and T.usertype = C.usertype and C.id = O.id


and T.usertype >= 100 and T.type = P.type


and P.usertype = (select min(usertype) from ddb.dbo.systypes where type = T.type )



后面还有一些工作要做,使用下面的SQL语句查看数据库ddb内部有哪些表有uid这一列。下面的思路可能有点片面,但是,我感觉Sybase ASE内与用户编号相关的应该用uid这个列名吧?


select object_name(c.id) as object_name, o.type

from dbo.syscolumns c,dbo.sysobjects o

where  c.id = o.id and c.name='uid'

go



        

uid相关的对象有8个,排除最后一个视图:sysquerymetrics,需要处理其余7个系统表。

在我们的这个例子中,“移交”对象的所有权不涉及到修改用户表sysusers数据的情况,对象信息表sysobjects在上面已经修改过了,在ASE15.0.3文档中sysencryptkeys被解释为留作将来使用,sysusermessages用来存储用户自定义消息,sysqueryplans用来存储抽象查询计划,sysquerymetrics用来存储性能监控指标,这三张表(sysusermessagessysqueryplanssysquerymetrics)都都没有数据。

最后只剩下两张系统表:systypesysprotects需要进一步处理。


select uid,usertype,name from dbo.systypes

where uid = 5

go


发现系统表systypes存储了用户rep自定义的数据类型,


        

仿照前面修改sysobjectsuid相似的方法,改成systypes存储的rep创建的数据类型归patrol拥有。


use ddb

go

begin tran

go

update systypes

set uid = 3

where uid = 5

go

commit

go


这样,rep自定义的数据类型就归patrol用户所有了。


下面查看关于sysproctects系统表的信息,这个表主要存储为用户、组和角色授予或撤消的权限的信息。


select * from sysprotects

where uid = 5 or grantor = 5

go



        

grantor列表示授予者的意思。其实只要将授予者由原来的rep改成现在的patrol即可,既然以前rep没有授予给其他用户权限,那么此处不需要进行修改了。

最后总结一下,在ASE15.0.3版本中,估计其它的ASE15.x也是大同小异,移交用户的所有权需要修改7个系统表的数据。在我的测试环境中仅修改了2个系统表(sysobjectssystypes)。这7个系统表是:sysobjects,systypes,sysusers,sysqueryplans,sysquerymetrics,sysprotects, sysencryptkeys

批量修改一遍就行了,


update sysobjects set uid = 3  where uid = 5

update systypes set uid = 3 where uid = 5

update sysusers set uid = 3 where uid = 5

update sysqueryplans set uid = 3 where uid = 5

update sysquerymetrics set uid = 3 where uid = 5

update sysprotects set uid = 3 where uid = 5

update sysencryptkeys set uid = 3 where uid = 5这个暂时不需要!


最后重启ASE数据库服务器或者只重启修改的那个用户数据库就可以了。

有什么不妥当的地方,欢迎指正!

论坛徽章:
33
ChinaUnix元老
日期:2018-07-04 15:10:362015年亚洲杯之阿联酋
日期:2015-02-06 17:15:532015亚冠之武里南联
日期:2015-06-06 15:40:252015亚冠之北京国安
日期:2015-06-17 15:42:412022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:322015亚冠之阿尔纳斯尔
日期:2015-09-20 09:42:1215-16赛季CBA联赛之北京
日期:2016-01-15 10:03:5915-16赛季CBA联赛之青岛
日期:2016-04-26 16:44:4915-16赛季CBA联赛之广夏
日期:2018-07-04 15:33:21C
日期:2016-10-25 16:12:142017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之同曦
日期:2017-02-22 22:41:10
发表于 2010-12-28 07:49 |显示全部楼层
把你的好东东给我传一份吧1

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-09 06:20:00数据库技术版块每日发帖之星
日期:2015-11-03 06:20:00数据库技术版块每日发帖之星
日期:2016-02-20 06:20:00数据库技术版块每日发帖之星
日期:2016-07-13 06:20:00数据库技术版块每日发帖之星
日期:2016-07-31 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2010-12-28 09:54 |显示全部楼层
我个人感觉——如果直接修改sysusers比较简单。
例如你这个例子就直接update sysusers set suid=(rep的suid) where uid=3和update sysusers set suid=(patrol的suid) where uid=5
这样直接就交换了两者的owner,而且也不需要重起db。

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-09 06:20:00数据库技术版块每日发帖之星
日期:2015-11-03 06:20:00数据库技术版块每日发帖之星
日期:2016-02-20 06:20:00数据库技术版块每日发帖之星
日期:2016-07-13 06:20:00数据库技术版块每日发帖之星
日期:2016-07-31 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2010-12-28 09:57 |显示全部楼层
另补充一下,你要检查的系统表应该还有一个—— sysusermessages

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2010-12-28 13:27 |显示全部楼层
本帖最后由 andkylee 于 2010-12-28 13:51 编辑

回复 4# Eisen


    文章中涉及到sysusermessages的这个修改了。不过我的测试环境中没有自定义用户消息,sysusermessages表里是空的。

论坛徽章:
6
水瓶座
日期:2014-06-04 03:34:37水瓶座
日期:2014-06-17 13:20:31数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-17 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
发表于 2010-12-28 13:51 |显示全部楼层
回复 3# Eisen


    交换suid只是更换了登录名,不能达到目的。
    需要交换uid。 uid列上有一个唯一索引ncsysusers2,交换的时候弄个中间值转化一下。我试了一下,改完后不用重启用户库。
但是移交对象的所有权是个单向的工作,交换uid会涉及很多“无辜”的。

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-09 06:20:00数据库技术版块每日发帖之星
日期:2015-11-03 06:20:00数据库技术版块每日发帖之星
日期:2016-02-20 06:20:00数据库技术版块每日发帖之星
日期:2016-07-13 06:20:00数据库技术版块每日发帖之星
日期:2016-07-31 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
发表于 2010-12-28 14:25 |显示全部楼层
嗯。是的,我那个做法就是全部交换两个login拥有的所有对象。你的比较灵活,可以挑一些出来个别交换。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP