-
Notifications
You must be signed in to change notification settings - Fork 0
Feature Storage zh
English · Tiếng Việt · 中文
Settings ▸ Storage,从 0.1.0 起就藏在 storage 开关后面,直到 1.14.0
才打开。这一页说明这个界面今天实际做了什么——缓存的邮件正文存放在哪里、怎么
搬动它,以及为什么旁边的数据库那部分只是一份操作手册,而不是一个按钮。
同一个界面上放着两个互不相关的决定,因为它们都和 SkimMail 把字节存在哪里有 关:哪个 blob 引擎保存缓存的邮件正文(本地文件系统,或一个兼容 S3 的存 储桶),以及哪个数据库引擎保存其余的一切(默认 SQLite,或者 Postgres/MySQL)。这一页完整覆盖 blob 引擎——它有真实可用的切换、测试和迁移 动作——同时也诚实地讲清数据库那部分,它今天只是一份要复制粘贴的命令,而不是 自动化的迁移。
Settings ▸ Storage,仅所有者。这个界面自己的标题旁边就带着一个 「Advanced」徽章——这不是走个形式,而是一个真实的警告:更改当前使用的引擎, 就是在更改你的数据物理上存放的位置。
storage 开关从 0.1.0 到 1.13.0 一直关闭,原因很具体,如果你见过旧的截图或
旧的发布说明,值得知道:数据库那部分曾经有一个 **「Migrate database…」**按
钮,会打开一个向导,告诉运维人员要先用 -tags postgres 重新构建 SkimMail。
这对任何运行官方构建的人来说从来都不成立——每一个已发布的 tarball、.deb
和容器镜像自 1.4.3 起就已经把 postgres、mysql 和 s3 一并编译进去
了——所以那条指示不只是多余,它描述了一个没有 Go 工具链的自托管者根本无法执
行的步骤。1.14.0 并不是加上了一个缺失的功能;它只是让一个真实存在的界面不
再冒充另一个界面,并在界面自己的文字变得真实之后才把开关打开。
两个引擎,用一个开关切换:Filesystem(默认——缓存的正文存放在
DATA_DIR/blobs 下,备份它就是「复制 DATA_DIR」,见运维)
或者兼容 S3(任何说 S3 协议的端点——MinIO、Cloudflare R2、Backblaze B2、
Wasabi,或者 AWS S3 本身),需要配置 endpoint、bucket、region、access key 和
secret key,以及一个给需要它的端点用的可选 path-style 开关。
对象永远通过 SkimMail 流式传输,绝不会直接从一个公开的 bucket URL 提供 ——即使在 S3 上,邮件内容也保持和文件系统存储一样的净化、拦截 tracker 和按请 求鉴权,而且不论当前是哪个引擎,经常被读取的 blob 都会在本地缓存以提升速 度。选择 S3 并不会让你的存储桶变成邮件客户端或浏览器可以直接交谈的东西。
Test connection 会构建候选配置,并用一次廉价的 Stat 调用去探测一个哨
兵 key——「not found」的响应也算成功,因为它证明了存储桶和凭证是可达的,而
不需要那里已经存在任何东西。在保存之前先做这个测试;一个配置错误的 S3 目标
会在保存/切换时被同一个探测拒绝(见下文),但提前发现问题不会有任何代价。
这是在按下任何一个按钮之前,值得多读一遍的区别:
- Save 保存新引擎,并立即把正在运行的 blob 缓存切换过去。如果新位置和 旧位置确实不同(不同的 S3 bucket,或者在文件系统和 S3 之间切换——仅仅轮换 一个 S3 access key 不算一次搬迁),旧引擎缓存的正文会被留在原地、不 再被引用,指向它们的索引也会被丢弃。旧存储里没有任何东西会被删除—— SkimMail 不会擅自伸手进一个可能同时是你备份目标的 S3 bucket 并开始删除对 象——但也没有任何原先缓存过的东西会被继续复制过来。这样做之所以安全,正是 因为正文缓存本身就是一个缓存:以这种方式被遗弃的任何东西,只需要下次打开 时重新从各账户的 IMAP 服务器取一次就行。
- Switch & migrate 做同样的切换,然后在后台遍历旧存储里的每一个 key 并 复制到新存储,跳过已经存在的 key(可以安全地重复运行),并在过程中统计已 复制/已跳过/失败的数量。如果你希望昨天缓存过的正文在新引擎上仍然是一次本 地命中,而不是一次全新的 IMAP 抓取,就用这个。
不管选哪一个,这个界面都从不会删除旧引擎里已存储的对象。 一次切换是可 以反悔的:把配置指回原处,只要你还没有用别的东西覆盖那个 bucket,旧的数据 依然还在。
从 SQLite 迁移到 Postgres 或 MySQL 被呈现为一个为你打印命令、让你自己去执
行的向导,而不是 SkimMail 代你执行的动作:选择目标引擎,粘贴一个连接字符
串(只检查形状——用的是正则表达式,不是一次真实的连接尝试),然后你会得到
一小段脚本,用 skimmail config set(或者等效的环境变
量,它们的优先级高于 config-set 设置的值)把服务器指向新数据库,外加一句之
后需要重新登录的提醒。
不会复制任何一行数据。 SkimMail 的邮件存储是一个从各账户 IMAP 服务器重
建出来的缓存,所以「迁移」数据库的意思是:搭一个空的 Postgres 或 MySQL 实
例,把 SkimMail 指向它,再重新添加你的账户——随后的同步会把一切重新填满。你
现有的、位于 DATA_DIR 下的 SQLite 文件会被完全保留不动,这正是整件事可以
撤销的原因:把配置指回 DB_DRIVER=sqlite,你就恰好回到了出发点。
| 起始版本 | 1.14.0(开关打开);blob 引擎本身的机制是 1.11.0 |
| 角色 | 所有者 |
| Blob 引擎 | filesystem、兼容 S3 |
| 数据库「迁移」 | 一份操作手册(要复制的命令),不是自动化动作 |
| 并发 | 同一时刻只有一次 blob 回填;在一次运行中再启动第二次是空操作 |
| S3 可用性 | 自 1.4.3 起编译进每一个官方构建 |
- 不会替你迁移数据库。 这个界面上的向导只检查连接字符串的形状,然后把 命令交给你;它不发起网络请求,也不复制任何一行数据。见上文。
- 仅用 Save 切换 blob 引擎不会把旧 blob 带过去。 只有 Switch & migrate 才会这样做;单独的 Save 会把它们遗弃在旧存储里(绝不删除)并忘 记索引。
- 绝不会删除你正在离开的那个存储里的对象。 那个存储桶或目录也可能同时 是一个备份目标(见备份与恢复);这个界 面不会自作主张地认为清空它是安全的。
- 轮换 S3 secret key 不被当作位置变更。 只有 endpoint/bucket/region/path-style 才用来判断「同一个地方」——仅仅更新凭证 既不会触发遗弃,也不会触发迁移。
-
运维 —— 文件系统备份,以及
blobs/在DATA_DIR下的位 置 - 邮件正文缓存 —— 一个 blob 里实际存的是什 么、大小/时长限制,以及静态加密
-
配置 —— 三平面模型、
skimmail config,以及仅限启动 时的DB_DRIVER/DATABASE_URL/BLOB_STORE/S3_*变量
SkimMail · skimmail@base101.app · 2026-09-15 · commit dffbb18