我把补丁状态记在一个小的 SQLite 文件里,用 sqlite3 :memory: < main.sql 来跑。我想查最后一次打补丁早于 2026-10-01、且没有生效中维护暂缓的主机。生效中指 until >= '2026-11-02'。
按我的统计应该是 5 台。单看逾期的有 6 台,而只有 db-la-01 有生效的暂缓。下面这个查询什么都不返回。退出状态 0,没有任何警告。
SELECT hostname, env, last_patched
FROM hosts
WHERE last_patched < '2026-10-01'
AND id NOT IN (
SELECT host_id FROM maint_holds WHERE until >= '2026-11-02'
)
ORDER BY last_patched;
计数版本的输出如下。
candidates
----------
0
我已经检查过的有这些。
- 主机清单和暂缓记录的列表看起来都没问题。
- 子查询单独跑,返回的行和我预期的一致。
until 是 TEXT,但所有值都是 ISO 8601,格式一致。
- 把
>= 换成 > 没有任何变化。
作为参考,生效中暂缓记录的列表如下。
id host_id hostname_hint until
-- ------- ------------- ----------
1 3 db-la-01 2026-11-15
3 db-la-02 2026-12-01
第二条暂缓是给 db-la-02 的,它还不在 hosts 里。我还没把主机名解析出来,所以 host_id 是空的。这是个没做完的功能,我看不出它为什么会影响一个针对已存在主机的查询。
那为什么这个过滤会把所有行都去掉,而不是只去掉 db-la-01?我怀疑过是文本比较的问题,但日期没毛病。我漏掉了什么?
从英语翻译·查看原文I keep patching state in a small SQLite file and run it with sqlite3 :memory: < main.sql. I want hosts last patched before 2026-10-01 that have no active maintenance hold. Active means until >= '2026-11-02'.
By my count that is 5 hosts. The overdue count alone is 6, and only db-la-01 has a live hold. The query below returns nothing at all. Exit status 0, no warning.
SELECT hostname, env, last_patched
FROM hosts
WHERE last_patched < '2026-10-01'
AND id NOT IN (
SELECT host_id FROM maint_holds WHERE until >= '2026-11-02'
)
ORDER BY last_patched;
The count version prints this:
candidates
----------
0
What I checked:
- The inventory and holds listings look right.
- The subquery run by itself returns the rows I expect.
until is TEXT, but every value is ISO 8601 and the format is consistent.
- Swapping
>= for > changed nothing.
The active holds listing, for reference:
id host_id hostname_hint until
-- ------- ------------- ----------
1 3 db-la-01 2026-11-15
3 db-la-02 2026-12-01
The second hold is for db-la-02, which isn't in hosts yet. I haven't resolved the hostname, so host_id is empty. That's a half-finished feature, and I don't see why it would affect a query about hosts that do exist.
So why does the filter remove every row instead of just db-la-01? I suspected the text comparison, but the dates are fine. What am I missing?