使用重启数据库的未认证DBCC命令来移交表的所有权

ASE 15.7 新增了命令可以将数据库对象的所有权从一个所有者移交给另一个所有者。

比如将表customer的所有权从dbo移交给bill,使用命令: alter table dbo.customer modify owner bill

不仅仅限于表,还有其它数据库对象包括:视图、存储过程、用户定义函数、默认值、规则、自定义数据类型、加密密钥等;

一次性可以授予多个数据库对象:

1、将 bill 拥有的所有表的所有权都移交给 eric:
    alter table bill.* modify owner eric preserve permissions

2、将 bill 拥有的所有对象的所有权都移交给 eric:
    alter all bill.* modify owner eric preserve permissions

preserve permissions:针对这些对象的所有显式授予或撤消的权限都将被保留,并且权限的 grantor 将更改为新的所有者。-------------------------------------------------------------------------------------------------------------------------------------------------------

以下提供的方法适用于低于ASE 15.7的版本!

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数据库服务器或者只重启修改的那个用户数据库就可以了。

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

 

  • 本文链接地址:http://www.dbainfo.net/one-undocument-dbcc-command-handover-table-ownership.htm
  • 本文为dbainfo个人原创,请在尊重作者劳动成果的前提下进行转载;
  • 转载务必注明原始出处 : Sybase数据库技术,数据库恢复专家
  • 对《使用重启数据库的未认证DBCC命令来移交表的所有权》有何疑问或见解,请在本文下方发表;
  • 对网站还有其他问题或建议,请提交在留言板,谢谢!
    1. joseph
      2011-01-11 15:05:24

      good

    2. 站长工具
      2011-01-20 04:56:40

      博主的文章很不错,我是站长工具-站长精灵的作者,一款专业的SEO工具软件(可以帮您提高博客的流量),想跟您交换个链接,不知可否

    :wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)