真实用同一张MySQL表同时建Dictionary和MySQL引擎表做对照,验证LIFETIME缓存机制真实的滞后窗口和自动刷新时机。
代码CREATE DICTIONARY demo.mysql_dict (id UInt32, name String, amt Decimal(10,2)) PRIMARY KEY id SOURCE(MYSQL(HOST '127.0.0.1' PORT 3306 USER 'root' PASSWORD '' DB 'mysqllab' TABLE 'ch_integration_test')) LAYOUT(HASHED()) LIFETIME(MIN 10 MAX 20); -- 真实在MySQL端立即改一行数据 UPDATE ch_integration_test SET name='ALICE_UPDATED' WHERE id=1; -- 立即分别查字典和上一篇的MySQL引擎表 SELECT dictGet('demo.mysql_dict','name', toUInt64(1)); SELECT name FROM demo.mysql_ext WHERE id=1;
SELECT dictGet('demo.mysql_dict','name', toUInt64(1));
→ alice ← 真实还是旧值(字典还没到刷新时机)
SELECT name FROM demo.mysql_ext WHERE id=1;
→ ALICE_UPDATED ← 真实立即看到了新值(上一篇验证过的live直连)同一次UPDATE,同一份底层数据,字典和MySQL引擎表给出的答案真实不一样——这就是LIFETIME缓存机制真实的样子:Dictionary不是每次查询都去问一次MySQL,而是真实先把整张表(或者按需的部分)加载进内存,之后的dictGet都只是查这份内存里的缓存,跟MySQL端实际发生了什么完全脱钩,直到缓存真实过期。
-- sleep 22秒
SELECT dictGet('demo.mysql_dict','name', toUInt64(1));
→ ALICE_UPDATED ← 真实自动刷新了,跟MySQL端一致了
SELECT last_successful_update_time FROM system.dictionaries WHERE name='mysql_dict';
→ 2026-09-29 18:44:37 ← 真实的最近一次刷新时间每一步都是本文上面用真实Dictionary和MySQL对照跑出来的原始结果。
CREATE DICTIONARY ... SOURCE(MYSQL(...)) LIFETIME(MIN 10 MAX 20)