Skip to main content
如果可刷新materialized view的刷新未通过 ClickHouse Keeper 协调,它就不会记住上次刷新的时间,因此服务器一就绪便可能再次刷新。如果服务器上有大量此类视图,或这些视图基于大型数据集,就可能恰好在服务器最难承受负载的时候,同时触发大量全量数据刷新。

哪些视图会保留其刷新计划?

对于 Replicated 数据库中的视图,刷新由 ClickHouse Keeper 统一协调。在 ClickHouse Cloud 中,Shared 数据库也是如此。在这两种 Cloud 数据库中,APPEND 家族的视图均可通过 SETTINGS all_replicas = 1 选择退出协调;而在开源 ClickHouse 服务器上,只有 Replicated 数据库具备这种协调机制。未经协调的视图仅在内存中记录上次刷新时间,因此无论采用何种常规刷新计划,服务器重启后该视图都会处于逾期状态。RANDOMIZE FOR 也无法将这些刷新错开执行。

额外的刷新还可能导致数据重复

APPEND 视图会再追加一份完整结果。未经协调的 APPEND INCREMENTAL 视图在重启时会丢失内存中的游标 (除非其事务性目标已提交该游标) ,因而会重新处理之前已经追加过的行。 按下文所述分批启动可以限制同时运行的刷新数量,但这些刷新依然会执行。对于 APPEND 视图,只要在其下一次刷新本就到期时再启动,即可避免额外的追加。而对于已丢失游标的 APPEND INCREMENTAL 视图,调整启动时机并无帮助:无论它下次何时运行,都会重新处理整个源表并追加结果。因此,在能够消化或删除重复行之前,请让其保持停止状态。

服务器启动时让所有视图保持停止状态

在服务器自身的 settings profile 中设置 stop_refreshable_materialized_views_on_startup。该 profile 即 system_profile 所指定的 profile;若未指定,则依次回退到 default_profile 和 default。此设置为 Experimental:
/etc/clickhouse-server/users.d/refreshable_materialized_views.xml
该示例使用默认的 default profile。如果您使用了自定义的 system_profile,请将其替换为该 profile。 SYSTEM STOP VIEWS 无法替代这种做法,因为它所设置的停止状态在重启后不会保留。

逐个启动视图

SYSTEM START VIEWS 会一次性启动所有视图,同样会造成负载突增。因此,请按名称逐个启动视图,待其刷新完成后再启动下一个。可通过 system.view_refreshes 查看这些视图。在 ClickHouse Cloud 中,该系统表仅记录本节点的数据,因此需要逐一检查每个节点:
启动视图只会恢复其调度,与 SYSTEM REFRESH VIEW 不同,它本身不会额外触发刷新。如果某个视图的刷新时间在其停止期间已经过去,那么按照该调度它已经逾期,因此一经启动就会立即刷新,而 SYSTEM WAIT VIEW 会在该刷新运行期间一直阻塞。 正在等待 REFRESH ... DEPENDS ON 前置条件的视图尚未开始刷新,因此应先启动被依赖的视图,再启动依赖它们的视图。循环依赖不存在这样的先后顺序,只要其中的视图未经协调,重启就会打断循环:先启动所有成员视图,再运行创建该循环时用来启动它的那条 SYSTEM REFRESH VIEW,并等待该刷新完成。如果某个依赖图当初需要多次此类刷新才能启动,那么现在也需要再次执行同样的一组刷新。若改为触发其他成员视图,循环可能会一直处于空闲状态,因为只有在某个视图的所有前置条件都完成刷新后,该视图才会恢复运行。循环一旦被触发便会自行刷新,因此逐个启动的节奏到触发这一步即可结束。

这对您的自动化意味着什么

在该设置生效期间,一旦发生意外重启,所有可刷新materialized view都会处于停止状态;新创建的视图同样要等到被启动后才会开始刷新。对于刷新未经协调的视图,RESTORE 是个例外:它会启动其中包含的所有此类视图,而这些视图随后可能立即进入逾期状态,并重放其源数据。经过协调的视图不会因恢复操作而启动,因此在您手动启动之前会一直保持停止。请让负责重启服务器和创建视图的自动化流程一并负责启动这些视图。
最后修改于 2026年9月26日