Oracle 21c区块链表默认仅OWNER有全部权限,其他用户包括DBA均需显式授权;INSERT与SELECT必须分别授予且不可转授,不支持RLS、VPD和物化视图;最小权限应仅授INSERT,禁用SELECT以保障审计隔离。

Oracle 21c 的区块链表(CREATE BLOCKCHAIN TABLE)本身不支持 UPDATE 或 DELETE,所有写入都通过 INSERT 追加并哈希链接,天然具备防篡改性。但「多用户访问控制」不是靠区块链机制自动实现的——它完全依赖 Oracle 原有的权限体系,且有关键限制:区块链表不支持行级安全策略(RLS)、虚拟私有数据库(VPD),也不能被物化视图引用。配置必须绕过这些盲区,直击权限粒度与角色设计。
区块链表创建后默认谁有访问权?
刚执行 CREATE BLOCKCHAIN TABLE t_bct (id NUMBER, data VARCHAR2(100)) 的用户,自动成为该表的 OWNER,拥有全部对象权限(SELECT、INSERT、ALTER、DROP)。但其他用户默认无任何权限,包括 SELECT —— 即使是 DBA 角色成员,也需显式授权。
-
INSERT权限必须单独授予,不能靠RESOURCE角色隐含获得 -
SELECT和INSERT必须分别授权,不存在“只读但不可写”的中间态角色 - 区块链表不支持
GRANT ... WITH GRANT OPTION,权限不可转授
如何给业务用户分配最小可用权限?
典型场景:应用用户 app_user 只需向区块链表写入交易记录,不查历史。这时不能简单 GRANT SELECT, INSERT ON t_bct TO app_user,否则破坏审计隔离。正确做法是拆开授权,并绑定会话级约束:
- 仅执行
GRANT INSERT ON t_bct TO app_user,禁用SELECT - 若需验证写入结果,改用带
RETURNING子句的INSERT,例如:INSERT INTO t_bct (id, data) VALUES (1, 'tx-001') RETURNING id INTO :out_id;
- 避免创建公共同义词(
CREATE PUBLIC SYNONYM),防止未授权用户通过别名发现表存在 - 检查
app_user是否被意外赋予SELECT ANY TABLE系统权限——区块链表仍受其影响
为什么不能对区块链表启用行级安全(RLS)?
Oracle 明确文档指出:DBMS_RLS.ADD_POLICY 对区块链表返回错误 ORA-05721: cannot add security policy to blockchain table。根本原因是区块链表的存储引擎绕过了常规数据块管理,其内部结构(如链头块、事务摘要区)不兼容 RLS 的谓词注入机制。
- 替代方案:在应用层做访问过滤,或前置视图(但注意——区块链表不能作为视图基表)
- 若必须按用户隔离数据,应建多个区块链表(如
t_bct_user_a、t_bct_user_b),而非依赖单表内策略 - 审计线索只能靠
AUDIT INSERT ON t_bct捕获,无法按用户条件动态开启/关闭
DBA 审计和权限回收的实操要点
区块链表的不可变性不等于权限不可逆。DBA 需定期清理冗余授权,尤其警惕跨模式误授:
- 查当前所有授权:
SELECT grantee, privilege, owner, table_name FROM dba_tab_privs WHERE table_name = 'T_BCT';
- 回收权限必须用原授权者身份,或
DBA;REVOKE INSERT ON t_bct FROM app_user立即生效,已插入数据不受影响 - 注意:
DROP USER ... CASCADE会连带删除其创建的区块链表,无回收站保护 - 区块链表不参与 Flashback Drop,误删只能从备份恢复
真正容易被忽略的是:区块链表的 INSERT 操作仍走完整事务流程,会占用 UNDO 表空间并生成 REDO 日志——权限放开不等于资源无代价。在高吞吐场景下,务必监控 v$blockchain_table_stats 中的链增长速率与哈希计算延迟,而不是只盯着权限是否开了。











