数据分支权限模型

每条 DATA BRANCH 命令现在要求对源对象和目标对象持有特定于操作类型的作用域权限。本文档说明每条分支操作的权限要求、用户可能遇到的错误消息以及受保护数据库机制。

说明

MatrixOne 对所有 DATA BRANCH SQL 命令强制执行细粒度的权限检查。每种操作类型需要对源和目标表或数据库持有特定级别的对象权限。权限模型还包括跨账号克隆限制、系统数据库保护以及防止意外删除的受保护数据库机制。

语法

权限模型通过标准的 SQL GRANTREVOKE 语句强制执行。以下是每条 DATA BRANCH 操作所需的权限模式。

DATA BRANCH CREATE TABLE

GRANT SELECT ON TABLE <source_db>.<source_table> TO <role>;
GRANT CREATE TABLE ON DATABASE <target_db> TO <role>;

DATA BRANCH CREATE DATABASE

GRANT SELECT ON TABLE <source_db>.<source_table> TO <role>;
GRANT CREATE DATABASE ON ACCOUNT * TO <role>;

DATA BRANCH DIFF

GRANT SELECT ON TABLE <db>.<target_table> TO <role>;
GRANT SELECT ON TABLE <db>.<base_table> TO <role>;
# 使用 OUTPUT AS <target_db>.<table> 时还需要:
GRANT CREATE TABLE ON DATABASE <target_db> TO <role>;

DATA BRANCH MERGE

GRANT SELECT ON TABLE <db>.<source_table> TO <role>;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE <db>.<destination_table> TO <role>;

DATA BRANCH PICK

GRANT SELECT ON TABLE <db>.<source_table> TO <role>;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE <db>.<destination_table> TO <role>;
GRANT SELECT ON TABLE <db>.<keys_table> TO <role>;

DATA BRANCH DELETE TABLE

GRANT DROP TABLE ON DATABASE <db> TO <role>;

DATA BRANCH DELETE DATABASE

GRANT DROP DATABASE ON ACCOUNT * TO <role>;

参数说明

权限

作用域

说明

SELECT

表级

允许从指定表读取行。源表的所有分支读取操作及 DIFF、MERGE、PICK 的双方均需要此权限。

CREATE TABLE

数据库级

允许在指定数据库中创建新表。DATA BRANCH CREATE TABLE 的目标数据库需要此权限。

CREATE DATABASE

账号级

允许在账号中创建新数据库。DATA BRANCH CREATE DATABASE 需要此权限。

INSERT

表级

允许向指定表插入新行。DATA BRANCH MERGEDATA BRANCH PICK 的目标表需要此权限。

UPDATE

表级

允许修改指定表中的现有行。DATA BRANCH MERGEDATA BRANCH PICK 的目标表需要此权限。

DELETE

表级

允许从指定表删除行。DATA BRANCH MERGEDATA BRANCH PICK 的目标表以及 REPLACE INTO 冲突路径上的目标表需要此权限。

DROP TABLE

数据库级

允许在指定数据库中删除表。DATA BRANCH DELETE TABLE 需要此权限。

DROP OBJECT

数据库级

允许在指定数据库中删除对象。可满足 DATA BRANCH DELETE TABLE 的要求。

DROP DATABASE

账号级

允许在账号中删除数据库。DATA BRANCH DELETE DATABASE 需要此权限。

DatabaseAll

数据库级

授予数据库级的所有权限。可满足作用于数据库的 CREATE TABLEDROP TABLEDROP OBJECT 要求。

DatabaseOwnership

数据库级

授予数据库的所有权级权限。可满足作用于数据库的 CREATE TABLEDROP TABLEDROP OBJECT 要求。

AccountAll

账号级

授予账号级的所有权限。可满足 DROP DATABASECREATE DATABASE 要求。

各操作的权限要求

DATA BRANCH CREATE TABLE

从源表创建分支表。

对象

所需权限

源表

SELECT

目标数据库

以下之一:CREATE TABLEDatabaseAllDatabaseOwnership

跨账号克隆需要快照。仅 sys 账号可以将表克隆到其他账号。

DATA BRANCH CREATE DATABASE

从源数据库创建分支数据库。

对象

所需权限

每个源表

SELECT

目标

CREATE DATABASE(通过标准 CREATE DATABASE 授权验证)

DATA BRANCH DELETE TABLE

删除分支表。目标必须是活跃的分支表(由先前的 DATA BRANCH CREATE TABLE 创建)。

对象

所需权限

目标数据库

以下之一:DROP TABLEDROP OBJECTDatabaseAllDatabaseOwnership

对于非系统数据库,表所有权也满足要求。

DATA BRANCH DELETE DATABASE

删除分支数据库。目标数据库中的所有表必须是活跃的分支表。

对象

所需权限

账号

以下之一:DROP DATABASEAccountAll

对于非系统数据库,数据库所有权也满足要求。

DATA BRANCH DIFF

比较两个表并输出差异。

对象

所需权限

目标表

SELECT

基准表

SELECT

OUTPUT AS 目标数据库

CREATE TABLE(仅持久化差异时要求)

DATA BRANCH MERGE

将源表的变更合并到目标表中。

对象

所需权限

源表

SELECT

目标表

SELECTINSERTUPDATEDELETE

DATA BRANCH PICK

按主键将源表中选定的行拷贝到目标表中。

对象

所需权限

源表

SELECT

目标表

SELECTINSERTUPDATEDELETE

KEYS 子查询表

SELECT

跨账号克隆限制

  • 从一个账号克隆表或数据库到另一个账号需要快照({snapshot = '<name>'}{timestamp = <expr>})。

  • sys 账号用户可以将表克隆到其他账号。

  • COPY GRANTS 不能与 TO ACCOUNT 一起使用。

系统数据库保护

非 sys 账号不能从系统数据库(mo_catalogsysteminformation_schema)克隆数据。任何账号都不能将数据克隆到系统数据库中。

受保护数据库

MatrixOne 支持 protected_databases 系统变量,可将指定数据库标记为受保护,防止意外删除。

SET GLOBAL protected_databases = 'db1,db2';

当数据库在 protected_databases 中列出时:

  • 对受保护数据库执行 DROP DATABASE 会被拒绝,即使用户拥有 DatabaseAllDatabaseOwnership 权限。

  • 对受保护数据库的其他操作(SELECT、INSERT、UPDATE、DELETE、CREATE TABLE、ALTER TABLE、CREATE VIEW)仍然可用,但仍受各自限制;其中,对 data-branch lineage 表执行 ALTER TABLE 时不能处于显式事务中。

  • 只有能够设置全局变量的用户才能修改 protected_databases

REPLACE INTO 的 DELETE 权限

REPLACE INTO 遇到唯一键冲突时,会在内部执行对冲突行的 DELETE。用户必须同时持有 DELETE 权限以及 SELECTINSERT 权限,REPLACE INTO 才能在冲突路径上成功执行。纯插入路径(无冲突,如 NULL 唯一值)无需 DELETE 权限即可成功。

示例

以下脚本把管理员准备步骤与 u_branch 用户实际执行的语句分开。mo-tester 会识别 -- @session 指令;手工验证时,应为指令包围的语句另开一个 u_branch 连接。

DROP DATABASE IF EXISTS dbbranchpriv;
CREATE DATABASE dbbranchpriv;
USE dbbranchpriv;

-- 创建分支操作的源表和数据
CREATE TABLE src_t(a INT PRIMARY KEY, b VARCHAR(20));
INSERT INTO src_t VALUES (1, 'one'), (2, 'two');

-- 创建 DIFF 操作的目标表
CREATE TABLE target_t(a INT PRIMARY KEY, b VARCHAR(20));
INSERT INTO target_t VALUES (1, 'ten'), (3, 'thirty');

-- 创建表级分支操作的快照
CREATE SNAPSHOT sp_t FOR TABLE dbbranchpriv src_t;
-- 创建对源表拥有 SELECT 权限、对数据库拥有 CREATE TABLE 权限的角色
CREATE ROLE r_branch;
GRANT SELECT ON TABLE dbbranchpriv.src_t TO r_branch;
GRANT SELECT ON TABLE dbbranchpriv.target_t TO r_branch;
GRANT CREATE TABLE ON DATABASE dbbranchpriv TO r_branch;
CREATE USER u_branch IDENTIFIED BY '111' DEFAULT ROLE r_branch;

-- 通过真实的 u_branch 连接执行以下语句
-- @session:id=1&user=sys:u_branch&password=111
-- DATA BRANCH CREATE TABLE:从源快照创建分支表
DATA BRANCH CREATE TABLE dbbranchpriv.branch_t FROM dbbranchpriv.src_t{snapshot="sp_t"};

-- 验证分支表包含源数据
SELECT COUNT(*) FROM dbbranchpriv.branch_t;

-- DATA BRANCH DIFF:比较两个表并输出差异
DATA BRANCH DIFF dbbranchpriv.target_t AGAINST dbbranchpriv.src_t OUTPUT COUNT;

-- 清理前返回管理员会话
-- @session

-- 错误示例:DATA BRANCH DELETE TABLE 在目标不是分支创建的表时失败
-- Expected-Success: false
DATA BRANCH DELETE TABLE dbbranchpriv.target_t;

-- 清理
DROP SNAPSHOT sp_t;
DROP USER u_branch;
DROP ROLE r_branch;
DROP DATABASE IF EXISTS dbbranchpriv;

错误消息

错误

原因

internal error: do not have privilege to execute the statement

尝试的分支操作缺少所需权限

internal error: non-sys account cannot clone data from system database

非 sys 账号尝试从 mo_catalogsysteminformation_schema 克隆

internal error: cannot clone data into system database

尝试克隆到系统数据库

internal error: DATA BRANCH DELETE target <name> is not an active branch table

DELETE 目标不是分支创建的表

internal error: DATA BRANCH DELETE target <name> is not an active branch database

DELETE 目标数据库没有活跃的分支表

invalid input: COPY GRANTS cannot be used with TO ACCOUNT

将 COPY GRANTS 与跨账号克隆组合使用

internal error: clone table between different accounts need a snapshot

跨账号克隆未提供快照

使用说明

  • 内部系统用户和启用 SkipCheckPrivilege 时会跳过权限检查。

  • DATA BRANCH CREATE DATABASE 在权限检查期间解析源表,以确保授权和执行使用相同的对象集。

  • 对于 DATA BRANCH DELETE TABLEDELETE DATABASE,系统会验证目标对象是否为活跃的分支对象(记录在 mo_catalog.mo_branch_metadata 中)。

  • 需要多个权限的分支操作会独立检查每个权限;缺少任一权限都会导致整个语句失败。