TimescaleDB 2.28.3 发布:修复列存查询、排序转换与触发器问题

2026-07-17 41 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

TimescaleDB 2.28.3 是一次以正确性和稳定性为重点的维护版本。与 2.28.2 相比,新版本包含性能改进,并修复了列式查询执行、排序键转换以及列存超表触发器管理等问题。由于部分缺陷可能直接影响查询结果,生产环境不应只把它当成普通的小版本更新。

为什么这次修复值得关注

本次发布摘要列出的修复集中在列存储相关路径。对时序数据库来说,这类问题尤其敏感:历史数据通常会被压缩或转入列存,而实时数据仍保留在行存中,同一条查询可能跨越两种存储形态。

其中,#10082 修复了在列式查询执行管道中计算返回 NULL 的函数时可能产生错误结果的问题。这里的风险不只是查询报错,而是查询能够完成,却返回不正确的数据。监控、计费、容量分析等系统如果依赖这类结果,错误可能继续流入报表或下游任务。

10178 修复了排序键表达式包含负常量时,排序转换被错误应用的问题。例如,业务查询可能使用 ORDER BY -temperature 或带负常量的表达式实现逆序语义;优化器或执行层如果错误转换排序条件,就可能改变结果顺序,甚至影响依赖顺序的窗口计算。

10179 则允许在启用列存储的超表上启用和禁用触发器。这对数据审计、同步和运维切换很实用:管理员不必因为超表启用了列存储,就失去通过标准 PostgreSQL 命令控制触发器的能力。

发布摘要还提到对列存储排序问题的进一步修复,但现有摘要没有给出完整细节。升级后应重点回归包含列存数据、复杂排序表达式和 NULL 计算的查询。

升级前先确认扩展与节点状态

TimescaleDB 是 PostgreSQL 扩展。升级软件包后,还需要在每个使用该扩展的数据库中更新扩展版本。执行前请先完成数据库备份,并根据操作系统、PostgreSQL 主版本以及部署方式选择对应的 2.28.3 软件包或容器镜像。

可以这样检查当前实例。把 postgresql://postgres@localhost:5432/metrics 替换为实际连接串:

export DATABASE_URL='postgresql://postgres@localhost:5432/metrics'

psql "$DATABASE_URL" -v ON_ERROR_STOP=1 <<'SQL'
SELECT version() AS postgresql_version;
SELECT extname, extversion
FROM pg_extension
WHERE extname = 'timescaledb';

SELECT default_version, installed_version
FROM pg_available_extensions
WHERE name = 'timescaledb';
SQL

installed_version 表示数据库当前启用的扩展版本,default_version 表示服务器上已安装软件包提供的默认版本。如果服务器软件已更新,但数据库仍显示 2.28.2,可在维护窗口内执行:

psql "$DATABASE_URL" -v ON_ERROR_STOP=1 \
  -c "ALTER EXTENSION timescaledb UPDATE TO '2.28.3';"

不要在尚未安装 2.28.3 扩展文件的服务器上直接运行该命令。对于流复制、容器编排或多节点部署,还要先确认所有相关节点都具备匹配的扩展二进制文件,并遵循当前部署方式规定的滚动升级顺序。

建立一组针对性回归查询

下面是一份可改造的最小 SQL 检查脚本。它不会复现所有已修复缺陷,但覆盖了此次版本最值得验证的三个方向:返回 NULL 的函数、包含负常量的排序表达式,以及列存超表上的触发器控制。

脚本假设数据库已经安装 TimescaleDB 2.28.3。列存策略和相关参数可能受许可证、部署形态及现有表配置影响,因此示例只创建超表与触发器;请使用业务环境已有的列存超表执行最终验证。

CREATE EXTENSION IF NOT EXISTS timescaledb;

DROP TABLE IF EXISTS sensor_readings CASCADE;
CREATE TABLE sensor_readings (
    recorded_at timestamptz NOT NULL,
    device_id   integer NOT NULL,
    temperature double precision
);

SELECT create_hypertable('sensor_readings', by_range('recorded_at'));

INSERT INTO sensor_readings (recorded_at, device_id, temperature) VALUES
    ('2025-01-01 00:00:00+00', 1, 21.5),
    ('2025-01-01 00:01:00+00', 1, NULL),
    ('2025-01-01 00:02:00+00', 1, 19.0);

CREATE OR REPLACE FUNCTION normalize_temperature(value double precision)
RETURNS double precision
LANGUAGE sql
IMMUTABLE
AS $$
    SELECT CASE WHEN value IS NULL THEN NULL ELSE round(value::numeric, 1)::double precision END
$$;

-- 检查返回 NULL 的函数在查询管道中的行为。
SELECT recorded_at, normalize_temperature(temperature) AS normalized
FROM sensor_readings
ORDER BY recorded_at;

-- 检查包含负常量的排序表达式。
SELECT recorded_at, temperature
FROM sensor_readings
ORDER BY temperature * -1 NULLS LAST;

CREATE TABLE trigger_audit (
    operation text NOT NULL,
    device_id integer NOT NULL,
    created_at timestamptz NOT NULL DEFAULT now()
);

CREATE OR REPLACE FUNCTION audit_sensor_insert()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO trigger_audit (operation, device_id)
    VALUES (TG_OP, NEW.device_id);
    RETURN NEW;
END
$$;

CREATE TRIGGER sensor_insert_audit
AFTER INSERT ON sensor_readings
FOR EACH ROW EXECUTE FUNCTION audit_sensor_insert();

ALTER TABLE sensor_readings DISABLE TRIGGER sensor_insert_audit;
ALTER TABLE sensor_readings ENABLE TRIGGER sensor_insert_audit;

INSERT INTO sensor_readings (recorded_at, device_id, temperature)
VALUES ('2025-01-01 00:03:00+00', 2, 18.5);

SELECT * FROM trigger_audit ORDER BY created_at;

在预生产环境中,还应选取真实列存超表执行 EXPLAIN (ANALYZE, BUFFERS),对比升级前后的结果集、排序顺序、执行时间和缓冲区使用情况。性能数字应在相同数据快照和相同 PostgreSQL 配置下采集,否则对比没有意义。

生产升级的检查清单

这次升级的优先级应由查询风险决定。大量使用列存储、复杂排序、用户自定义函数或触发器的系统,应优先安排维护窗口。

  • 备份数据库,并验证恢复流程,而不只是确认备份任务成功。
  • 记录升级前的 PostgreSQL 与 TimescaleDB 版本。
  • 在所有相关节点安装匹配的 2.28.3 扩展软件。
  • 在每个业务数据库中执行 ALTER EXTENSION,不要只升级默认数据库。
  • 回归返回 NULL 的函数、负常量排序表达式和列存数据查询。
  • 验证列存超表上的触发器可以禁用、启用并按预期执行。
  • 比较关键报表的结果集,而不只观察查询是否报错。
  • 监控升级后的错误日志、慢查询、CPU、I/O 和压缩或列存相关后台任务。

2.28.3 没有强调大型新功能,它解决的是更基础的问题:查询结果是否可信,排序语义是否稳定,以及管理员能否正常控制触发器。对于时序数据平台,这些正确性修复通常比新增语法更值得尽快进入生产环境。


相关推荐