Obsidian 更新灭库记:一次由程序目录放仓库引发的永久性数据丢失事故
0. 前言
今天,我因为一次看似平常的 Obsidian 自动更新,永久丢失了存放在 E:\obsidian\my_notebook 下的全部笔记数据。这不是 Obsidian 的 bug,而是我对"本地优先"软件的文件管理机制存在致命误解。
写下这篇博客,是为了用技术细节还原事故全貌,也是为了给自己立一套不可逆的备份铁律。
1. 事故摘要(TL;DR)
- 错误:将 Obsidian Vault 放在程序安装目录
E:\obsidian\my_notebook - 触发:Obsidian 自动更新,安装程序重建
E:\obsidian\目录 - 结果:
my_notebook被当作旧版本残留清理,新二进制数据(.pak/.dll)物理覆盖原扇区 - 损失:全部 Markdown 笔记永久损坏,Hex 编辑器下无任何可读文本残留
- 结论:不可恢复,必须重建并建立工程级备份体系
2. 事故背景与环境
| 项目 | 详情 |
|---|---|
| 软件 | Obsidian v1.x(Electron 框架构建) |
| 操作系统 | Windows 11 |
| 仓库原位置 | E:\obsidian\my_notebook |
| 数据规模 | 数百篇 Markdown 笔记,含科研项目(HRRP 目标识别)、文献阅读、技术笔记与日常事务 |
| 备份情况 | 无任何备份:无 Git、无云同步、无跨设备副本 |
致命错误:我将 Obsidian 的 Vault(仓库)直接放在了 Obsidian 的安装目录 E:\obsidian\ 内部,与 Obsidian.exe、locales、resources 等程序文件处于同一棵树中。
3. 事故时间线(2026-05-07)
| 时间 | 事件 | 状态 |
|---|---|---|
| 上午 | 打开 Obsidian,软件提示有更新,点击确认 | 正常 |
| 更新后 | 界面变成"空白仓库",左侧文件树消失,找不到任何笔记 | 异常出现 |
| 10:18 | resources 目录被创建(程序文件时间戳) |
更新进行中 |
| 11:13 | locales 目录被重建(新的语言包写入) |
覆盖发生 |
| 11:31 | 截图发现 E:\obsidian 目录结构,确认 my_notebook 与程序文件并列 |
定位问题 |
| 排查中 | 查看 %APPDATA%\obsidian\obsidian.json,发现历史路径记录: |
路径混乱 |
"path":"E:\\obsidian\\locales" |
||
"path":"E:\\obsidian\\locales\\.obsidian" |
||
| 说明之前曾误将程序子目录也识别为仓库 | ||
| 14:55 | 最终确认:my_notebook 内的 .md 文件已全部变为二进制残骸 |
数据死亡 |
| 15:03 | 撰写本博客,记录教训,制定重建方案 | 止损重建 |
4. 根因分析:为什么更新会吃掉用户数据?
4.1 Electron 应用的更新机制
Obsidian 基于 Electron 构建,其 Windows 端的安装目录结构如下:
E:\obsidian\
├── Obsidian.exe ← 主程序
├── locales\ ← 语言包目录(en-US.pak, zh-CN.pak...)
├── resources\ ← 资源文件
├── *.dll ← 系统依赖库
└── my_notebook\ ← [我的仓库,致命地放在了这里]
当执行更新时,安装程序的逻辑是:
- 下载新版本安装包
- 删除旧版本核心目录(
locales、resources等会被整体替换) - 解压新文件到原位置
locales 是 Electron 应用的标准语言资源目录,每次更新都会被强制重建。 而我的 my_notebook 位于 E:\obsidian\ 根目录下,与程序文件处于同一棵树中。更新程序在清理旧版本残留时,将 my_notebook 视为可被覆盖的目录,直接写入新的二进制数据。
4.2 本地优先 = 你自己是唯一的备份责任人
Obsidian 的核心哲学是"本地优先、文件自由"。它允许你打开硬盘上任意文件夹作为 Vault,软件本身不对用户说"这个位置危险"。
这意味着:
- 好处:你完全拥有数据,格式开放(Markdown),换软件也能用
- 风险:软件不替你保管文件位置,放错地方就是你的责任
我把仓库放在程序目录,相当于把日记本夹在系统安装光盘盒里,光盘盒被换新时,日记本就被扔了。
4.3 为什么 DiskGenius 无法恢复?
数据恢复的前提是:原扇区未被新数据覆盖。
但本次事故中:
- 更新发生在 20 分钟内
- 新版本的
.pak语言包文件恰好写入了原my_notebook占用的磁盘扇区 - 因此恢复出的不是"被删除的旧文件",而是"披着
.md外壳的新二进制垃圾"
5. 抢救全过程与取证分析
5.1 第一阶段:定位(误以为只是路径丢失)
- 检查 Obsidian 的
obsidian.json,发现记录了错误路径:{ "vaults": { "86748a667bf590e6": {"path": "C:\\Users\\sunshine\\Documents\\Obsidian Vault", "open": true}, "fae25e6efcd4cd67": {"path": "E:\\obsidian\\locales", "ts": 1778123592942}, "4d01587e1f352ca6": {"path": "E:\\obsidian\\locales\\.obsidian", "ts": 1778122996886} } } - 发现
E:\obsidian\my_notebook文件夹仍然存在,初期以为数据完好
5.2 第二阶段:发现异常(文件已非文本)
打开 my_notebook 内的 .md 文件,发现:
- 记事本显示为乱码(``、不可读符号)
- Notepad++ 切换 UTF-8 / GB2312 / ANSI 均无效
- 文件大小异常(部分远大于正常 Markdown)
5.3 第三阶段:Hex 取证(确认物理覆盖)
使用十六进制编辑器(HxD)查看文件头:
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0000: 68 1B 35 D9 1B C5 1C C7 8C 39 7E BA BE D6 C5 23 h.5......9~....#
0010: 8B D5 1E 3E 1A DF 69 CB AA 2E 35 9D 87 35 ED 0D ...>..i...5..5..
0020: 1B 46 68 BC A5 24 3E 04 58 34 C6 00 78 68 7B D9 .Fh..$>.X4..xh{.
分析:
- 正常 Markdown 文件应以文本字符开头(如
#0x23、-0x2D、或 UTF-8 汉字E4 B8 AD) - 该文件以
68 1B 35 D9开头,第 2 字节即为控制字符0x1B(ESC) - 整片扇区呈现高熵随机分布,无任何可识别的文本片段
结论:原始 Markdown 文本已被新版本的 .pak/.dll 二进制数据物理覆盖。这不是编码错误,不是"用 UTF-8 重新打开"就能解决的,而是文件系统层面的数据覆写。
5.4 第四阶段:DiskGenius 深度扫描(徒劳)
尝试用 DiskGenius 对 E 盘进行"完整恢复 + 额外扫描已知文件类型":
- 能扫出
.md文件记录 - 但恢复出的内容依然是上述二进制残骸
- 原因:更新发生在 20 分钟内,新数据已完全占据原扇区
最终判定:数据永久丢失,无商业恢复软件可救。
6. 血的教训:三条不可违背的铁律
铁律一:程序目录 ≠ 用户数据目录
| 高危目录 | 安全目录示例 |
|---|---|
C:\Program Files\ |
D:\ObsidianVault\ |
C:\Users\name\AppData\ |
D:\ResearchNotes\ |
E:\obsidian\(安装目录) |
E:\MyVault\(与安装目录同级) |
任何软件的 locales\、resources\ |
独立的、自建的文件夹 |
铁律二:本地优先 = 你自己是唯一的备份责任人
Obsidian 是纯本地文件管理器,不是 Notion,不是有道云笔记。它不会自动把你的笔记上传到任何云端。如果你不建立备份,单点故障 = 永久丢失。
铁律三:更新/重装前,先确认仓库位置
任何 Electron 应用、任何软件的重装/更新,都可能重建安装目录。更新前必须确认:
- 当前打开的 Vault 路径是否在安全区域?
- 安装目录内是否残留了用户数据?
7. 重建方案:3-2-1-1-0 科研级数据保全体系
基于本次事故,我建立了以下架构,从今往后,任何单点故障都不能再导致数据丢失。
7.1 架构总览
[Windows 笔记本] D:\ObsidianVault (工作主副本)
│
├─ Syncthing ───────► [Ubuntu 服务器] ~/ObsidianVault (实时镜像)
│ │
│ ├─ Git 裸仓库 ~/backup/obsidian.git (版本历史)
│ │
│ └─ 每周推送 ───► [Gitee 私有仓库] (异地容灾)
│
└─ 坚果云/OneDrive 同步目录 (跨设备 + 云端快照)
7.2 各层职责与工具
| 层级 | 工具 | 作用 | 恢复场景 |
|---|---|---|---|
| 工作层 | Obsidian + D:\ObsidianVault |
日常编辑、阅读、写作 | 主工作区 |
| 实时镜像 | Syncthing (P2P 加密直连) | Win ↔ Ubuntu 实时同步 | 电脑硬盘损坏、系统崩溃 |
| 版本历史 | Git 裸仓库 | 记录每次修改,可回溯任意时间点 | 误删、误改、被覆盖 |
| 异地容灾 | Gitee/GitHub 私有仓库 | 服务器机房灾难时的最终兜底 | 火灾、盗窃、雷击 |
| 跨设备/应急 | 坚果云/OneDrive | 手机/平板应急查看、碎片阅读 | 电脑不在身边 |
7.3 目录结构规范
D:\ObsidianVault\
├── .obsidian\ ← 配置、主题、插件(由 Obsidian 管理)
├── 00-Inbox\ ← 临时笔记、待整理
├── 01-Projects\
│ ├── 目标识别\ ← 按科研项目分文件夹
│ │ ├── 论文大纲.md
│ │ ├── 实验记录.md
│ │ └── 参考文献.md
│ └── 小样本\
├── 02-Papers\ ← 文献阅读笔记
│ ├── 2026-05-综述.md
│ └── 2026-05-Domain-Adaptation.md
├── 03-Notes\ ← 技术笔记、方法学
│ ├── Signal-Processing\
│ ├── Deep-Learning\
│ └── Tools\
├── 04-Daily\ ← 日志、会议、待办
│ ├── 2026-05-07.md
│ └── 会议记录.md
└── 05-Archive\ ← 已结题、已发表、不再活跃
8. 可执行配置清单
8.1 Ubuntu 服务器端(Syncthing + Git)
# 安装 Syncthing
sudo apt install syncthing
# 启动并设置开机自启
systemctl enable --now syncthing@$USER.service
# 创建同步目录
mkdir -p ~/ObsidianVault
# 创建 Git 裸仓库(版本历史)
mkdir -p ~/backup
cd ~/backup
git init --bare obsidian.git
# 每日自动归档脚本(保存为 ~/backup/auto-archive.sh)
cat > ~/backup/auto-archive.sh << 'EOF'
#!/bin/bash
cd ~/ObsidianVault
git add .
DATE=$(date +"%Y-%m-%d %H:%M")
git commit -m "auto: $DATE" --quiet
git push ~/backup/obsidian.git main --quiet
EOF
chmod +x ~/backup/auto-archive.sh
# 添加到 crontab(每天 0点、12点、18点 各归档一次)
(crontab -l 2>/dev/null; echo "0 0,12,18 * * * ~/backup/auto-archive.sh") | crontab -
# 每周推送到 Gitee(异地容灾)
(crontab -l 2>/dev/null; echo "0 3 * * 1 cd ~/backup/obsidian.git && git push gitee main") | crontab -
8.2 Windows 端(Obsidian + Git + 定时任务)
在 D:\ObsidianVault 目录下,打开 PowerShell:
# 初始化 Git
git init
git add .
git commit -m "init: 重建 Obsidian 仓库 - 2026-05-07"
# 连接 Ubuntu 裸仓库
git remote add server ssh://你的用户名@服务器IP/~/backup/obsidian.git
git push -u server main
自动提交脚本(保存为 D:\ObsidianVault\auto-commit.ps1):
cd D:\ObsidianVault
git add .
$date = Get-Date -Format "yyyy-MM-dd HH:mm"
git commit -m "win-backup: $date" --quiet
git push server main --quiet
添加到 Windows 任务计划程序:
Win + R→taskschd.msc- 创建基本任务:
- 名称:
Obsidian Auto Backup - 触发器:每天,每 8 小时重复一次
- 操作:启动程序
powershell.exe - 参数:
-ExecutionPolicy Bypass -File "D:\ObsidianVault\auto-commit.ps1"
- 名称:
8.3 Syncthing 关键配置
忽略模式(避免同步缓存垃圾):
.obsidian/workspace.json
.obsidian/graph.json
.obsidian/cache/
.trash/
*.tmp
版本控制:启用"简易版本控制",保留 30 个版本,防止误删。
9. 灾难恢复速查表
| 故障场景 | 恢复步骤 | 预计耗时 |
|---|---|---|
| Windows 硬盘损坏 | 新电脑安装 Syncthing + Obsidian,从 Ubuntu 同步回 D:\ObsidianVault |
10 分钟 |
| 误删单篇笔记 | 在 Ubuntu ~/ObsidianVault 里找回,或用 Git git checkout HEAD -- 文件名 |
2 分钟 |
| 误改内容想回溯 | git log 找到历史版本 → git checkout <commit-id> -- 文件名 |
5 分钟 |
| Ubuntu 服务器宕机 | 从 Gitee 克隆仓库到新服务器,重新配置 Syncthing | 30 分钟 |
| Obsidian 更新又出幺蛾子 | 直接卸载重装,打开 D:\ObsidianVault,数据完全不受影响 |
5 分钟 |
| 全部本地副本丢失 | 从 Ubuntu 实时镜像复制回来,或用 Git 裸仓库还原 | 15 分钟 |
10. 结语
这次事故没有技术奇迹,没有"最后一刻找回数据"的反转。我的笔记已经变成磁盘上一段无意义的二进制噪声,这是我自己造成的。
但这件事给我上了一课:在科研工作中,数据管理是一项与实验设计、论文写作同等重要的基础工程。 我们不能假设软件会保护我们,不能假设"这次不会出问题"。
从今天开始,D:\ObsidianVault 是我的唯一工作目录,Syncthing 是我的实时镜像,Git 是我的时间机器,Gitee 是我的异地保险箱。
希望读到这篇博客的人,不要重蹈我的覆辙。
附录 A:Hex 残骸样本(作为警示)
如果你也遇到了类似的 68 1B 35 D9... 型乱码,请立即停止数据恢复幻想,转向备份重建。这种高熵二进制分布意味着原始文本已被物理覆盖,不可恢复。
68 1B 35 D9 1B C5 1C C7 8C 39 7E BA BE D6 C5 23 h.5......9~....#
8B D5 1E 3E 1A DF 69 CB AA 2E 35 9D 87 35 ED 0D ...>..i...5..5..
1B 46 68 BC A5 24 3E 04 58 34 C6 00 78 68 7B D9 .Fh..$>.X4..xh{.
浙公网安备 33010602011771号