2016-03-01 58 views
1

我有一个用例,我需要阻止访问模式中的所有对象暂时,同时我执行一些大规模更改。我计划以架构所有者的身份执行更改。一旦完成,我想要启用访问权限。我目前正在探索两个选项,并希望知道您的想法,以确定哪一个更好:暂时禁止访问Oracle中的模式:锁账户与撤销授予

  1. 锁定所有针对目标模式中的数据库对象的帐户。
  2. 撤消对数据库对象的授权,并因此阻止外部用户使用它。

有没有更好的办法?我希望过程尽可能平滑,并确保在更改正在进行时没有人能够达到目标架构。

+0

这是更改DDL还是对象编译?如在中,您试图阻止的真正问题是您关心阻止您的更改的活动会话吗?它是否正确? –

+0

其DDL以及DML更改。是的,我们希望阻止用户在我们这样做时防止他们使用陈旧的数据。 –

回答

0

触发器。这个触发器适用于除dba角色的用户以外的所有人。

CREATE OR REPLACE TRIGGER logon_audit_trigger 
    AFTER LOGON 
    ON DATABASE 
DECLARE 
BEGIN 
    raise_application_error (-20001, 'You cannot login.'); 
END; 

如果你想知道谁在哪里试图登录。您可以从SYS_CONTEXT获取这些信息。

SELECT SYS_CONTEXT ('USERENV', 'SESSION_USER') 
    FROM DUAL; 
+0

谢谢。但我真正的问题是哪种方法更好,为什么 –

0

你可以考虑停顿数据库。阻止用户或撤销权限的缺点是用户会收到错误(您无权访问或无法登录等)。停顿数据库意味着活动会话将完成他们的工作,但会一直挂起,直到数据库停顿。然后,您执行修改并保证没有任何东西可以阻止您独占访问您正在更新的对象。在更新之后(或者在对有问题的对象锁定之后,甚至在更新期间),取消数据库的静音。

当然,这种方法的缺点是,这是跨越整个数据库而不是仅仅一个模式。这样做的好处是您的用户不会遇到任何错误消息,并且如果您将DML转换为DDL(如下所述)以大大缩短停机时间窗口,那么大多数用户的体验应该不会超过几秒钟不活动。

有一个很好的写在静止数据库在Oracle FAQ。您必须让您的DBA参与静默数据库并将您的更改生效,因为只有系统或sys可以执行此操作。

对于DML,您可以考虑在停机时间窗口开始之前用您想要的数据创建一个新表。然后,当停机时间窗口开始时,重命名旧表,将新表重命名为旧表,重新创建权限,以获得更快的停机时间窗口(因为这有效地将DML更新转换为DDL)。 Tom Kyte讨论了这种方法here

此外,不言而喻,在上述过程的测试环境中进行适当的测试应该完成,这将消除此过程中的任何疑难杂症,并且让您很清楚系统需要多长时间默默无闻。