同一段视频 9 种压法:设得越「清楚」,文件反而越大
同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。

我的站上所有数据都放在一个文件里。备份的做法一直很简单:把这个文件复制一份,改个名字。
这次我花半小时给它做体检,结论是——这种备份随时可能少数据,而且它不会报错。
复制出来的文件能打开、能查询、能通过数据库自带的体检(integrity_check,一个逐页检查有没有写坏的命令),看起来完全正常。但它可能少了最近几千条记录。
我在这台机器上造了个 7000 条记录的小库,正文用的是本机技能文档里的真实中文,约 36 万字符。
先说清楚数据库为什么会“偷偷变”。为了让写入变快,新数据先记在旁边一张便签上(-wal 文件),过一会儿才誊写到正文文件里。我把自动誊写关掉,模拟“刚写完、还没誊写”的那一刻——这正是备份脚本最容易撞上的时刻。
此刻:正文文件 610,304 字节,便签文件 1,545,032 字节,便签比正文还大。库里一共 7000 条。
四种写法各跑一遍:
| 备份写法 | 备份里的条数 | 体检结果 | 耗时 | 备份大小 |
|---|---|---|---|---|
只复制那个 .db 文件 |
2000 | 正常 | 0.8 毫秒 | 610,304 字节 |
.db 和旁边的便签文件一起复制 |
7000 | 正常 | 2.3 毫秒 | 2,155,336 字节 |
用数据库自带的备份命令(Python 的 backup) |
7000 | 正常 | 17.3 毫秒 | 2,134,016 字节 |
用 VACUUM INTO 导出 |
7000 | 正常 | 21.1 毫秒 | 2,134,016 字节 |
第一行就是坑:备份里只有 2000 条,少了 5000 条,而它的体检结果是“正常”。
真实场景里丢的不是全部新数据,而是“上一次誊写之后”的那一段,可能是几条,也可能是几万条,看那个库多久誊写一次。
第二种写法能把数据捞回来,但有个前提:复制的那一两秒里没人在写。有人在写就是下面这样。
我让一个线程每 300 条提交一次,然后在写入过程中连续复制 20 次,复制完立刻体检:
database disk image is malformed(文件已经被写坏)边写边复制,四分之三的概率拿到一个坏文件。默认模式下没有那张便签兜底,正文写到一半就被复印走了。
区别在体检这一关:坏文件一查就露馅,第一行那种少数据的备份却是“健康”的。
备份只留一种写法,让数据库自己来。我这台机器上连 sqlite3 命令行都没装(实测 command not found),所以用的是 Python 自带的:
import sqlite3
src = sqlite3.connect('file:数据文件?mode=ro', uri=True) # 只读打开,不打扰正在写的程序
dst = sqlite3.connect('备份文件')
src.backup(dst)
dst.close()
src.close()
它会把便签上的内容一起算进去,写完顺手整理一遍,不留下没誊写的东西。7000 条用 17.3 毫秒,快到感觉不到。
拿我站的真实库(844KB)试,整库备份 13.6 毫秒,备份文件 864,256 字节。
integrity_check。两个数字对不上,就重做。VACUUM INTO 需要 3.27 以上。同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。
同一张壁纸 674.9 KB 能压到 122.9 KB,站上 15 张配图省到四分之一
三个老推送接口都死了,我用 IndexNow 把新文章推给搜索引擎