From 6d78885caf9ec561065bd226f1a49206fd60e758 Mon Sep 17 00:00:00 2001 From: KDB <937925477@qq.com> Date: Tue, 11 Aug 2026 08:12:58 +0800 Subject: [PATCH] docs: add v1.1.0 SQL upgrade guide --- docs/v1.1.0-upgrade-guide.md | 185 +++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 docs/v1.1.0-upgrade-guide.md diff --git a/docs/v1.1.0-upgrade-guide.md b/docs/v1.1.0-upgrade-guide.md new file mode 100644 index 000000000..a865b93fb --- /dev/null +++ b/docs/v1.1.0-upgrade-guide.md @@ -0,0 +1,185 @@ +# v1.1.0 SQL 升级操作指南 + +本文说明如何把数据库 schema 从 v1.0.x(与上游同步前)升级到 v1.1.0。命令示例一律使用占位符,本文不含任何真实凭据。 + +## 1. 适用范围 + +- 代码版本:从 v1.0.x(与上游同步前)升级到包含 v1.1.0 SQL 升级脚本的代码版本 +- 数据库:PostgreSQL(schema 基线见 `resources/database/schema_pg.sql` 与 `init_data_pg.sql`) +- 升级脚本:`resources/database/upgrades/v1.1.0/` 下 9 个文件,按文件名日期序执行 +- 本项目没有 Flyway / Liquibase 版本表,SQL 需手动执行 + +## 2. 前置检查 + +### 2.1 确认数据库是 PostgreSQL 且应用指向它 + +连接数据库执行 `SELECT version();`,应返回 PostgreSQL 版本。 + +再确认 `bootstrap/src/main/resources/application.yaml` 的 `spring.datasource`: + +- `driver-class-name` 为 `org.postgresql.Driver` +- `url` 形如 `jdbc:postgresql://:5432/`(本项目默认库名 `ragent`) + +### 2.2 确认当前 schema 版本 + +任选一种方法,判断是否已执行过部分升级脚本: + +```sql +-- 已执行 260328:t_knowledge_document_chunk_log 应有 embed_duration / persist_duration 列 +SELECT column_name +FROM information_schema.columns +WHERE table_name = 't_knowledge_document_chunk_log' + AND column_name IN ('embed_duration', 'persist_duration'); +``` + +```sql +-- 已执行 260803:t_agent_profile 表应存在 +SELECT to_regclass('public.t_agent_profile'); +``` + +psql 交互式下也可用 `\d t_knowledge_document_chunk_log` 直接查看列清单。查询有结果说明对应脚本已执行过,可从下一个脚本开始或整体核对后跳过。 + +## 3. 备份(必须最先做) + +### 3.1 全量备份 + +使用 pg_dump 自定义格式,文件名带日期时间: + +```bash +pg_dump -h -p 5432 -U -Fc -f ragent_backup_20260811_153000.dump +``` + +`-Fc` 表示自定义格式:压缩存储,且支持 pg_restore 选择性恢复。 + +### 3.2 校验备份 + +- `pg_restore --list ragent_backup_20260811_153000.dump` 能列出对象清单 +- 抽查文件大小与库规模是否相符 +- 备份前记录关键表行数(如 `t_message`、`t_knowledge_chunk`),升级后对比确认数据未丢失 + +### 3.3 恢复命令 + +恢复到新库(推荐演练方式): + +```bash +createdb -h -U _restore +pg_restore -h -U -d _restore ragent_backup_20260811_153000.dump +``` + +覆盖现有库(谨慎,会先删除已存在对象): + +```bash +pg_restore -h -U -d -c --if-exists ragent_backup_20260811_153000.dump +``` + +若备份用的是纯文本格式(pg_dump 不带 `-Fc`),用 psql 恢复: + +```bash +psql -h -U -d -f ragent_backup_20260811_153000.sql +``` + +## 4. 执行升级脚本 + +### 4.1 执行顺序 + +严格按文件名日期序,逐个执行: + +```text +1. 260328_knowledge_chunk_log_duration.sql +2. 260408_message_thinking.sql +3. 260703_knowledge_vector_collection.sql +4. 260709_biz_change_log.sql +5. 260722_01_message_sources.sql +6. 260722_02_message_recommendation_context.sql +7. 260725_intent_multi_collections.sql +8. 260730_ingestion_kernel.sql +9. 260803_agent_profile.sql +``` + +单文件执行命令: + +```bash +psql -h -U -d -v ON_ERROR_STOP=1 \ + -f resources/database/upgrades/v1.1.0/260328_knowledge_chunk_log_duration.sql +``` + +`-v ON_ERROR_STOP=1` 让 psql 遇到第一条错误即停止,便于定位。PowerShell 下逐文件执行时同样加上该参数,不要用裸管道把 9 个文件拼成一条命令,否则无法定位失败点。 + +### 4.2 幂等性与重复执行 + +脚本大量使用 `CREATE TABLE IF NOT EXISTS`、`ADD COLUMN IF NOT EXISTS`、`DROP COLUMN IF EXISTS`、`CREATE INDEX IF NOT EXISTS`、`ON CONFLICT DO NOTHING`,重复执行安全,可放心重跑。 + +少数语句没有 IF 保护,重复执行会报错,但报的是"对象已存在/列不存在",不会破坏数据: + +- 260328 的 `RENAME COLUMN`(第二次执行报列不存在) +- 260408 的 `ADD COLUMN`(第二次执行报列已存在) +- 260703 的 `ADD COLUMN` 与 `CREATE INDEX`(第二次执行报对象已存在) + +遇到这类报错,按第 2.2 节的方法核对对象已存在即可继续,无需处理。 + +### 4.3 失败处理与回滚 + +- 脚本没有包裹显式事务,单条语句原子提交,失败的语句本身不会生效 +- 执行中断后,先对照已创建对象(`\dt`、`\d`、`information_schema`),对已存在的跳过,再重跑失败的脚本 +- 需要整体回滚时从第 3 节备份恢复:恢复到新库后切换连接,或 `-c --if-exists` 覆盖原库 + +## 5. 升级后验证清单 + +按脚本逐一抽查(统一查询示例见文末): + +| 脚本 | 关键对象 | 验证点 | +|:---|:---|:---| +| 260328 | `t_knowledge_document_chunk_log` | 存在 `embed_duration`、`persist_duration` 列 | +| 260408 | `t_message` | 存在 `thinking_content`、`thinking_duration` 列 | +| 260703 | `t_knowledge_vector` | 存在 `collection_name` 列与索引 `idx_kv_collection_name` | +| 260709 | `t_biz_change_log` | 表存在,索引 `idx_biz_change_log_biz` / `_time` / `_operator` 存在 | +| 260722_01 | `t_message` | 存在 `sources`(JSONB)列 | +| 260722_02 | `t_message` | 存在 `recommended_questions`、`retrieved_chunks`、`reply_to_message_id`、`message_status` 列 | +| 260725 | `t_intent_node` | 存在 `collection_names`(JSONB)列,存量 `collection_name` 已迁移为单元素数组 | +| 260730 | `t_knowledge_document` 等 | 存在 `mime_type`、`ingestion_spec`;`chunk_strategy`、`chunk_config` 已删除;`t_knowledge_chunk.embedding_text` 存在;`t_knowledge_document_chunk_log.parse_profile` 存在 | +| 260803 | `t_agent_profile`、`t_agent_prompt` | 两表存在;`SELECT count(*) FROM t_agent_profile WHERE builtin = 1;` 返回 1 | + +批量检查示例: + +```sql +SELECT column_name +FROM information_schema.columns +WHERE table_name = 't_message' + AND column_name IN ('sources', 'thinking_content', 'recommended_questions', 'message_status') +ORDER BY column_name; +``` + +应用侧验证: + +- 启动日志无缺列、缺表报错 +- 控制台「智能体」菜单可用,默认助手(内置智能体)可见 + +## 6. 常见问题 + +权限不足 + +- 升级脚本含 DDL(建表、加列、建索引、加注释),需要相应权限:`CREATE TABLE` 需要目标 schema 的 `CREATE` 权限;`ALTER TABLE`、`CREATE INDEX`、`COMMENT ON` 需要对象 owner 或 SUPERUSER +- 最小权限建议:用数据库 owner 账号执行升级脚本;应用账号只保留 DML 权限。若执行账号不是相关表 owner 且报权限错误,改用 SUPERUSER,或先把相关表 owner 转移给执行账号 + +事务与中断 + +- 单条语句原子,中断不会留下半成品语句;按 4.3 节核对对象后重跑即可 +- 不要跳过任何文件,日期序即依赖序 + +字符集 + +- 确认库为 UTF8 编码(PG 默认) +- 客户端连接带 `client_encoding=UTF8`(连接串参数或环境变量 `PGCLIENTENCODING=UTF8`) +- 260803 内置智能体提示词为中文,连接编码不对会乱码或写入失败 + +## 7. 本地开发库同样需要执行 + +本地开发库不执行这批脚本,新功能会直接不可用或报错: + +- 智能体菜单(`t_agent_profile` / `t_agent_prompt`) +- 回答来源面板(`t_message.sources`) +- 推荐追问与消息状态(`t_message.recommended_questions` 等) +- 意图多 Collection(`t_intent_node.collection_names`) +- 摄取内核化(`t_knowledge_document.ingestion_spec` 等) + +本地执行第 4 节的 psql 命令即可,执行前同样先备份。