动态物化视图(Delta Live MV)快速入门

更新时间:
复制 MD 格式

本文通过端到端示例,演示动态物化视图(Delta Live MV)如何基于源表的增量变更(INSERT、UPDATE、DELETE)自动完成物化视图刷新,无需全量重算。

动态物化视图(Delta Live Materialized View,以下简称 DLMV)是 MaxCompute 提供的增量物化视图能力。与传统物化视图的全量刷新方式不同,DLMV 通过捕获源表的 CDC(Change Data Capture,变更数据捕获)数据,仅对增量部分完成计算和更新,适用于分钟级的近实时数据加工场景。

需了解工作原理和核心优势,请参见功能介绍

前提条件

使用工具

工具

说明

DataWorks 数据开发(推荐)

可视化 SQL 开发平台,支持在线编辑和执行。

MaxCompute 客户端(odpscmd)

命令行工具,适合脚本化操作。

SQL分析

MaxCompute 控制台内嵌的轻量 SQL 编辑器。

操作步骤

版本设置(每次执行必须)

DLMV 使用特定的 SQL 引擎版本,每次执行 DLMV 相关 SQL 前,必须先执行以下设置:

SET odps.task.major.version = sql_flighting_dlmv;

如何验证版本是否生效:执行上述 set 语句后,如果后续 SQL 正常执行不报 ODPS-0123XXX 类错误,说明版本已生效。如果报错提示版本不支持或功能未开放,请通过工单联系我们。

步骤一:创建源表

DLMV 的源表必须是一张开启了 CDC 功能的 Delta Table(主键表)且必须定义 PRIMARY KEY。DLMV 需要通过主键来定位增量变更对应的目标行。

执行以下 SQL 创建源表。

-- 创建源表
CREATE TABLE IF NOT EXISTS t_department (
  dept_id     BIGINT NOT NULL PRIMARY KEY,
  name        STRING,
  description STRING
)
TBLPROPERTIES (
  'transactional'                      = 'true',
  'acid.cdc.mode.enable'               = 'true',
  'acid.cdc.build.async'               = 'false',
  'cdc.insert.into.passthrough.enable' = 'true'
)
LIFECYCLE 10;

关键属性说明如下。

属性

说明

transactional = true

将表声明为 Delta Table(事务表)。

acid.cdc.mode.enable = true

开启 CDC 功能,使表能够生成变更数据记录。

acid.cdc.build.async = false

CDC 数据同步构建。设为 false 表示 DML 执行完成后 CDC 数据立即可用,适合验证测试。

cdc.insert.into.passthrough.enable = true

允许对该表执行 INSERT INTO 操作。

步骤二:写入初始数据

INSERT OVERWRITE TABLE t_department
SELECT * FROM (
    VALUES
        (1001, 'HR Department', 'Human Resources'),
        (1002, 'IT Department', 'Information Technology'),
        (1003, 'Finance Department', 'Financial Management')
) AS t (dept_id, name, description);

-- 执行以下语句验证数据写入成功。
SELECT * FROM t_department;

-- 返回结果如下:
+------------+--------------------+------------------------+
| dept_id    | name               | description            |
+------------+--------------------+------------------------+
| 1003       | Finance Department | Financial Management   |
| 1001       | HR Department      | Human Resources        |
| 1002       | IT Department      | Information Technology |
+------------+--------------------+------------------------+

步骤三:创建动态物化视图

基于源表创建一个 DLMV,声明增量刷新模式。

本示例中 DLMV 的 SQL 逻辑为 SELECT * FROM t_department,系统可自动推导出继承自源表的主键为 dept_id,因此无需显式声明 PRIMARY KEY。

SET odps.task.major.version = sql_flighting_dlmv;

CREATE MATERIALIZED VIEW IF NOT EXISTS dlmv_department
LIFECYCLE 10
TBLPROPERTIES (
  'refresh_mode'         = 'incremental',
  'refresh_job_settings' = 'set odps.task.major.version=sql_flighting_dlmv;'
)
AS SELECT * FROM t_department;

关键属性说明如下。

属性

说明

refresh_mode = incremental

声明为增量刷新模式,即 DLMV。

refresh_job_settings

自动刷新时携带的会话参数。必须包含版本设置,否则自动刷新任务会因引擎版本不匹配而失败。

步骤四:验证初始数据

创建完成后,DLMV 会自动执行一次全量初始化。执行以下语句查看 DLMV 数据。

SELECT * FROM dlmv_department;

-- 返回结果如下:
+------------+--------------------+------------------------+
| dept_id    | name               | description            |
+------------+--------------------+------------------------+
| 1003       | Finance Department | Financial Management   |
| 1001       | HR Department      | Human Resources        |
| 1002       | IT Department      | Information Technology |
+------------+--------------------+------------------------+

步骤五:模拟源表增量变更

对源表执行 INSERT、UPDATE、DELETE 操作,模拟真实业务中的数据变更。

SET odps.task.major.version = sql_flighting_dlmv;

-- 新增一条记录
INSERT INTO t_department VALUES (1004, 'Marketing', 'Marketing Department');

-- 更新一条记录
UPDATE t_department SET description = 'HR and Admin' WHERE dept_id = 1001;

-- 删除一条记录
DELETE FROM t_department WHERE dept_id = 1003;

步骤六:增量刷新 DLMV

执行以下语句手动触发一次增量刷新。系统将只处理步骤五中产生的增量变更,而非全量重算。

SET odps.task.major.version = sql_flighting_dlmv;

ALTER MATERIALIZED VIEW dlmv_department REBUILD;

步骤七:验证增量刷新结果

SELECT * FROM dlmv_department;

-- 返回结果如下:
+------------+---------------+------------------------+
| dept_id    | name          | description            |
+------------+---------------+------------------------+
| 1004       | Marketing     | Marketing Department   |  -- 新增记录。
| 1001       | HR Department | HR and Admin           |  -- description 已从 Human Resources 更新为 HR and Admin。
| 1002       | IT Department | Information Technology |  -- dept_id = 1003 已删除。
+------------+---------------+------------------------+

步骤八:查看刷新历史

通过以下语句查看 DLMV 的刷新记录,确认刷新状态和耗时。

SELECT * FROM delta_live_mv_refresh_history('dlmv_department');

-- 返回示例:
+--------------+-------------+------+--------------------+------------------+-------------+---------------------+-------+-----------------+--------------+---------------+---------------+-----------------+----------------+--------------------------+---------------------+
| project_name | schema_name | name | refresh_start_time | refresh_end_time | instance_id | duration_in_seconds | state | refresh_trigger | refresh_mode | error_message | source_tables | numinsertedrows | numdeletedrows | refresh_mode_reason_code | refresh_mode_reason |
+--------------+-------------+------+--------------------+------------------+-------------+---------------------+-------+-----------------+--------------+---------------+---------------+-----------------+----------------+--------------------------+---------------------+
| *testproject | default     | dlmv_department | 2026-07-01T17:19:07.37 | 2026-07-01T17:19:55.108 | 20260701091907370gkrrqdpv0gg | 47                  | TERMINATED | MANUAL          | INCREMENTAL  |               | [{"table_name":"*test_project.default.t_department","table_id":"757f8****fe012c","lsn":"0000000000000006","tx_id":"182****1794"}] | 2               | 2              | NULL                     | NULL                |
+--------------+-------------+------+--------------------+------------------+-------------+---------------------+-------+-----------------+--------------+---------------+---------------+-----------------+----------------+--------------------------+---------------------+

返回字段说明如下。

字段

说明

refresh_start_time

刷新开始时间。

refresh_end_time

刷新结束时间。

state

刷新状态:RUNNING(执行中)、TERMINATED(成功)、FAILED(失败)。

refresh_mode

本次刷新模式:FULL(全量)或 INCREMENTAL(增量)。

duration_in_seconds

刷新耗时(秒)。

numInsertedRows

本次刷新写入的行数。

numDeletedRows

本次刷新删除的行数。

步骤九:清理测试资源

POC 测试完成后,执行以下语句清理资源,避免产生不必要的存储费用。

-- 先删除DLMV(需在源表之前删除)
DROP MATERIALIZED VIEW IF EXISTS dlmv_department;

-- 再删除源表
DROP TABLE IF EXISTS t_department;

请先删除 DLMV,再删除源表。如果先删除源表,可能导致 DLMV 状态异常。

进阶:创建分区 DLMV

分区 DLMV 可按批次管理增量数据(如按天分区),适合生产环境中的近实时入仓场景。以下示例基于同一张源表t_department,演示分区 DLMV 的创建和刷新。

分区 DLMV 与非分区 DLMV 区别

image

区别项

非分区 DLMV

分区 DLMV

BUILD DEFERRED

可选

必须(当前分区 MV 仅支持此模式)

PRIMARY KEY

可自动推导,通常无需声明

必须显式声明(BUILD DEFERRED 下不做推导)

分区值

通过 get_setting() 函数动态传入

刷新方式

ALTER MV REBUILD;

ALTER MV REBUILD PARTITION(pt = ...);

创建分区 DLMV

SET odps.task.major.version = sql_flighting_dlmv;

CREATE MATERIALIZED VIEW IF NOT EXISTS part_dlmv_department
PRIMARY KEY(dept_id)        -- 必须显式声明PK(BUILD DEFERRED下无法自动推导)
LIFECYCLE 10
BUILD DEFERRED              -- 仅生成表结构,不立即刷新数据
PARTITIONED BY (pt)         -- 声明分区列
TBLPROPERTIES (
  'refresh_mode'         = 'incremental',
  'refresh_job_settings' = 'set odps.task.major.version=sql_flighting_dlmv;'
)
AS SELECT *, get_setting('odps.custom.setting.department.pt') AS pt FROM t_department;

关键语法说明如下。

语法

说明

PRIMARY KEY(dept_id)

显式声明主键。因为 BUILD DEFERRED 模式下系统不会自动推导 PK,必须手动指定。

BUILD DEFERRED

创建时仅生成表结构,不执行数据初始化。数据通过后续 REBUILD 写入。

PARTITIONED BY (pt)

声明 pt 为分区列。

get_setting('odps.custom.setting.department.pt')

  • 动态获取会话变量的值作为分区值。前缀 odps.custom.setting. 是 MaxCompute 自定义变量的命名规范。

  • get_setting() 函数的作用类似于离线调度中的 ${bizdate} 参数。每次刷新时通过 SET 语句传入不同的值,实现按天/按批次写入不同分区。

刷新指定分区

SET odps.task.major.version = sql_flighting_dlmv;

-- 设置本次刷新的分区值
SET odps.custom.setting.department.pt = 20260526;

-- 刷新指定分区
ALTER MATERIALIZED VIEW part_dlmv_department REBUILD PARTITION(pt = get_setting('odps.custom.setting.department.pt'));

验证分区数据

SELECT * FROM part_dlmv_department WHERE pt = '20260526';

-- 返回结果如下:
-- 预期返回源表当前的全部数据,并且每行都带有分区列 pt = 20260526
+------------+---------------+------------------------+----------+
| dept_id    | name          | description            | pt       |
+------------+---------------+------------------------+----------+
| 1004       | Marketing     | Marketing Department   | 20260526 |
| 1001       | HR Department | HR and Admin           | 20260526 |
| 1002       | IT Department | Information Technology | 20260526 |
+------------+---------------+------------------------+----------+

清理分区 DLMV

DROP MATERIALIZED VIEW IF EXISTS part_dlmv_department;

功能介绍

  • 核心优势

    • 声明式 SQL:用标准 SQL 定义数据加工逻辑,系统自动完成增量计算,无需手动编写增量处理代码。

    • 成本高效:仅处理增量数据,计算量远小于全量刷新。

    • 增全量一体:同一份 SQL 逻辑同时支持增量计算和全量计算,兼顾低延迟和高吞吐需求。

  • 工作原理

    image

  • DLMV vs 传统物化视图

    image

后续操作

完成快速入门后,可参考以下文档深入了解动态物化视图:

操作

说明

动态物化视图(Delta Live MV)

了解 DLMV 的完整功能,包括分区 DLMV、自动刷新、PK 推导规则等。

CDC(邀测)

了解 CDC 的详细机制和 table_changes 函数用法。

流对象(Stream)

了解如何通过 Stream 对象消费增量数据。

周期调度任务(邀测)

了解如何配置定时任务自动处理增量数据。

常见问题

执行 SQL 时报错:版本不支持

现象:返回 ODPS-0123xxx 类错误或提示功能不支持。

解决

  • 确认 SQL 最前面已加上 set odps.task.major.version = sql_flighting_dlmv;

  • 确认当前账号已开通 DLMV 。

增量刷新时报错:CDC 数据过期

现象:REBUILD 时报错提示增量查询范围超过保留时间。

原因:两次刷新的间隔超过了源表的 CDC 数据保留时间(默认 24 小时)。

解决:增大源表的 CDC 保留时间。

ALTER TABLE t_department SET TBLPROPERTIES(
  'acid.data.retain.hours' = '168',
  'cdc.data.retain.hours'  = '168'
);

acid.data.retain.hours(表数据保留时间)必须大于或等于 cdc.data.retain.hours(CDC 数据保留时间)。两者最大值均为 168 小时(7天)。

创建 DLMV 时 Primary Key 相关错误

现象:创建 DLMV 时提示需要主键。

原因:DLMV 要求自身是一张主键表。当系统无法从 SQL 逻辑推导出主键时,需要显式声明。

解决:在 CREATE MATERIALIZED VIEW 语句中添加 PRIMARY KEY 声明。

CREATE MATERIALIZED VIEW IF NOT EXISTS dlmv_example
PRIMARY KEY(your_key_column)   -- 显式声明主键
TBLPROPERTIES ('refresh_mode' = 'incremental', ...)
AS SELECT ...;

主键推导规则详情请参见动态物化视图(Delta Live MV)