归档任务每周一凌晨2点自动执行,将30天前会话压缩为csv.gz存至/opt/dify/archives/,校验通过后软删除archived=true且created_at
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

你需要在Dify系统中自动将历史对话数据从热存储迁出、归档为压缩文本并长期保存,避免数据库膨胀又保留审计与回溯能力。
确认归档数据源与范围
进入 Dify 后台管理界面 → 点击「数据管理」→ 选择「会话历史」标签页。确认当前部署使用的是 PostgreSQL 数据库(自托管版),且表 conversation_messages 中已存在超过 30 天的旧记录。
【必须验证】 执行 SQL 查询:SELECT COUNT(*) FROM conversation_messages WHERE created_at 若返回结果为 0,则暂停后续操作——没有可归档数据,强行执行将生成空压缩包。
配置定时归档任务(Cron + Python 脚本)
方法一:基于系统级 Cron 的轻量归档
在服务器上创建归档脚本 /opt/dify/scripts/archive_conversations.py,内容如下:
```python
import psycopg2
import gzip
import csv
from datetime import datetime, timedelta
from pathlib import Path
conn = psycopg2.connect(
host="localhost",
database="dify",
user="dify-user",
password="your-db-pass"
)
cur = conn.cursor()
cutoff = (datetime.utcnow() - timedelta(days=30)).isoformat()
cur.execute("""
SELECT c.id as conv_id, m.role, m.content, m.created_at
FROM conversation_messages m
JOIN conversations c ON m.conversation_id = c.id
WHERE m.created_at ORDER BY m.created_at
""", (cutoff,))
rows = cur.fetchall()
if not rows:
exit(0)
archive_path = f"/opt/dify/archives/conversations_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv.gz"
Path(archive_path).parent.mkdir(exist_ok=True)
with gzip.open(archive_path, "wt", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["conv_id", "role", "content", "created_at"])
for r in rows:
writer.writerow(r)
# 归档后标记为已处理(非删除)
cur.execute("UPDATE conversation_messages SET archived = true WHERE created_at conn.commit()
```
给脚本添加执行权限:chmod +x /opt/dify/scripts/archive_conversations.py
编辑系统定时任务:sudo crontab -e,追加一行:
0 2 * * 1 /usr/bin/python3 /opt/dify/scripts/archive_conversations.py >> /var/log/dify-archive.log 2>&1
这表示每周一凌晨 2 点执行一次归档,输出日志写入 /var/log/dify-archive.log。
执行归档后清理原始记录
第一步:确认归档文件已成功生成且非空
运行 gzip -t /opt/dify/archives/conversations_*.csv.gz,无报错即校验通过;再用 zcat /opt/dify/archives/conversations_*.csv.gz | head -n 5 查看前 5 行是否含有效字段。
第二步:执行软删除(推荐)
在 PostgreSQL 中执行:
DELETE FROM conversation_messages WHERE archived = true AND created_at
该语句只清除已归档且超过 90 天的历史消息,保留最近 30–90 天的热数据供快速检索,避免误删未归档条目。
第三步:重建索引释放空间
VACUUM FULL conversation_messages;
注意:此操作会短暂锁表,请在业务低峰期执行。若无法停服,改用 VACUUM conversation_messages;(不锁表但空间回收不彻底)。
验证归档完整性与可读性
随机选取一个归档文件,解压并检查字段对齐:
zcat /opt/dify/archives/conversations_20261018_020000.csv.gz | tail -n +2 | head -n 1 | wc -c
若输出值明显大于 100,说明内容非空;再执行:
zcat /opt/dify/archives/conversations_20261018_020000.csv.gz | head -n 10
确认首行为表头、第二行起为四列数据(conv_id/role/content/created_at),且 content 字段含中文不乱码。
这一步不能跳过——曾有用户因数据库字符集未设为 UTF8,导致导出 CSV 中文全变成问号,压缩后也无法恢复。











