本文通过端到端示例,演示动态物化视图(Delta Live MV)如何基于源表的增量变更(INSERT、UPDATE、DELETE)自动完成物化视图刷新,无需全量重算。
动态物化视图(Delta Live Materialized View,以下简称 DLMV)是 MaxCompute 提供的增量物化视图能力。与传统物化视图的全量刷新方式不同,DLMV 通过捕获源表的 CDC(Change Data Capture,变更数据捕获)数据,仅对增量部分完成计算和更新,适用于分钟级的近实时数据加工场景。
需了解工作原理和核心优势,请参见功能介绍。
前提条件
已开通并创建MaxCompute项目。
具备在 MaxCompute 项目中创建表(CreateTable)和修改表(Alter)的权限。详情请参见MaxCompute权限。
使用工具
工具 | 说明 |
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;关键属性说明如下。
属性 | 说明 |
| 将表声明为 Delta Table(事务表)。 |
| 开启 CDC 功能,使表能够生成变更数据记录。 |
| CDC 数据同步构建。设为 |
| 允许对该表执行 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;关键属性说明如下。
属性 | 说明 |
| 声明为增量刷新模式,即 DLMV。 |
| 自动刷新时携带的会话参数。必须包含版本设置,否则自动刷新任务会因引擎版本不匹配而失败。 |
步骤四:验证初始数据
创建完成后,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 |
+--------------+-------------+------+--------------------+------------------+-------------+---------------------+-------+-----------------+--------------+---------------+---------------+-----------------+----------------+--------------------------+---------------------+返回字段说明如下。
字段 | 说明 |
| 刷新开始时间。 |
| 刷新结束时间。 |
| 刷新状态:RUNNING(执行中)、TERMINATED(成功)、FAILED(失败)。 |
| 本次刷新模式:FULL(全量)或 INCREMENTAL(增量)。 |
| 刷新耗时(秒)。 |
| 本次刷新写入的行数。 |
| 本次刷新删除的行数。 |
步骤九:清理测试资源
POC 测试完成后,执行以下语句清理资源,避免产生不必要的存储费用。
-- 先删除DLMV(需在源表之前删除)
DROP MATERIALIZED VIEW IF EXISTS dlmv_department;
-- 再删除源表
DROP TABLE IF EXISTS t_department;请先删除 DLMV,再删除源表。如果先删除源表,可能导致 DLMV 状态异常。
进阶:创建分区 DLMV
分区 DLMV 可按批次管理增量数据(如按天分区),适合生产环境中的近实时入仓场景。以下示例基于同一张源表t_department,演示分区 DLMV 的创建和刷新。
分区 DLMV 与非分区 DLMV 区别

区别项 | 非分区 DLMV | 分区 DLMV |
BUILD DEFERRED | 可选 | 必须(当前分区 MV 仅支持此模式) |
PRIMARY KEY | 可自动推导,通常无需声明 | 必须显式声明(BUILD DEFERRED 下不做推导) |
分区值 | 无 | 通过 |
刷新方式 |
|
|
创建分区 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;关键语法说明如下。
语法 | 说明 |
| 显式声明主键。因为 BUILD DEFERRED 模式下系统不会自动推导 PK,必须手动指定。 |
| 创建时仅生成表结构,不执行数据初始化。数据通过后续 REBUILD 写入。 |
| 声明 |
|
|
刷新指定分区
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 逻辑同时支持增量计算和全量计算,兼顾低延迟和高吞吐需求。
工作原理

DLMV vs 传统物化视图

后续操作
完成快速入门后,可参考以下文档深入了解动态物化视图:
操作 | 说明 |
了解 DLMV 的完整功能,包括分区 DLMV、自动刷新、PK 推导规则等。 | |
了解 CDC 的详细机制和 table_changes 函数用法。 | |
了解如何通过 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)。