备份策略不是「多久备一次」这么简单,它是两个问题:能丢多少(RPO)、多久能恢复(RTO)。 前者决定备份频率,后者决定用全备还是增量。 增量备份分三种:0 级等于全备但能接链、1 级差异备「自上次任意级别」、 1 级累积备「自上次 0 级」。 差异备得少、恢复链长;累积备得多、恢复链短。
16.2 讲的是部件和通道。这一篇讲怎么用它们干活:备什么、备多勤、怎么备增量。 读完这一篇要能回答一个问题:给定「最多丢一小时、四小时内必须恢复」的要求, 备份计划该怎么定。
一、备份策略:先定能丢多少,再定多久备一次
两个指标定一切:RPO 是「最多能接受丢多久的数据」,RTO 是「故障后多久必须恢复」。
RPO 决定备份频率——要求最多丢一小时,那至少每小时要有一次能恢复到「一小时前」的东西。
RTO 决定备份形式——要求四小时恢复,就不能用一条要应用二十个增量的链。
这两个数只能由业务给,不能由 DBA 猜。「每天凌晨全备」这句话背后其实是一个假设:
最多丢 24 小时可以接受。这个假设对不对,得业务点头。
保留策略有两种写法,二选一:REDUNDANCY 2 是「留两份」,简单但不看时间;
RECOVERY WINDOW OF 7 DAYS 是「能恢复到七天内任意点」,更贴合「能丢多少」这个说法。
推荐后者,因为它直接对应 RPO。而且它算的是「满足这个窗口最少要留哪些备份」,
会自动帮你算冗余——代价是每天的备份该留几个不固定,看着不如「留两份」直观。
REPORT OBSOLETE 列出「按策略可以删的」,DELETE OBSOLETE 真删。
注意「过期」和「失效」是两个词:OBSOLETE 是策略上不需要了,EXPIRED 是文件已经不在了。
前者可以放心删,后者只是元数据要清理。
二、备份数据库文件与归档日志
最常用的五条命令,级别从大到小:
| 命令 | 备什么 |
|---|---|
BACKUP DATABASE |
全部数据文件加控制文件 |
BACKUP TABLESPACE users |
一个表空间的数据文件 |
BACKUP DATAFILE 4 |
一个数据文件 |
BACKUP ARCHIVELOG ALL |
全部归档日志 |
BACKUP CURRENT CONTROLFILE |
当前控制文件 |
生产上很少单独用 BACKUP DATABASE,更常见的是 BACKUP DATABASE PLUS ARCHIVELOG。
这个写法会自动按固定顺序做五件事,顺序本身就是它的价值。
① 先切一次日志——ALTER SYSTEM ARCHIVE LOG CURRENT。
② 备份所有归档日志。
③ 备份数据文件。
④ 再切一次日志。
⑤ 备份这期间新产生的归档。
为什么两头都要切?第一次切是为了「把备份开始前的日志全部收进来」,
第二次切是为了「把备份过程中产生的日志也收进来」。
少了第二次,备份出来的数据文件就缺了「备份期间那一段」的重做——
恢复时会报「找不到需要的归档日志」。
这条坑很隐蔽:备份成功了,LIST BACKUP 看着也正常,只有真恢复的时候才发现缺日志。
所以「备份成功」和「备份可用」是两件事——这一篇最后一段讲怎么验证。
三、增量备份:三级三义
先纠正一个常见误解:0 级增量不等于「什么都不备」,它就是一次全备。 区别在于它「登记进了增量链」——只有 0 级备份才能当增量链的起点,普通的全备不行。
| 级别 | 备什么 | 命令 |
|---|---|---|
| 0 级 | 全部块,并且成为增量链起点 | INCREMENTAL LEVEL 0 |
| 1 级差异 | 自上次 1 级或 0 级以来变的块 | INCREMENTAL LEVEL 1 |
| 1 级累积 | 自上次 0 级以来变的块 | LEVEL 1 CUMULATIVE |
「差异增量」是默认行为,不加 CUMULATIVE 就是它。
所以写 BACKUP INCREMENTAL LEVEL 1 DATABASE 得到的是差异增量,要累积必须显式写上那个词。
这一点很容易记反:名字里带「累积」的才是备得多的那个。
两者的取舍可以用一句话概括:差异增量省备份空间、费恢复时间;累积增量费备份空间、省恢复时间。
因为差异增量恢复时要「0 级加中间每一个 1 级」按顺序应用,累积增量只要「0 级加最近一个累积」。
还有一个实务细节:增量备份默认会「扫全表比对 SCN」来判断哪些块变过。
这意味着 1 级增量并不像想象中那么快——它省的是「写」,不是「读」。要连读都省,得开块变更跟踪。
四、块变更跟踪:让增量不用扫全表
原理很朴素:用一个位图文件记「哪些块改过」,改块的时候顺手打个标记。增量备份时直接读位图,
不用扫全表比对。
开启命令是 ALTER DATABASE ENABLE BLOCK CHANGE TRACKING,后面跟 USING FILE 加路径。
关掉是 DISABLE BLOCK CHANGE TRACKING,查状态看 V$BLOCK_CHANGE_TRACKING。
它的收益随库变大而变大:小库扫一遍也就几秒,大库扫一遍要几十分钟。
所以「要不要开」的答案取决于库多大、增量多久跑一次。
代价有两个:多一个文件要维护(它也会坏),以及每次改块多一次写位图的开销。
后一个开销很小但真实存在——高频写入的表上能测出来。所以「开了只有好处」是不对的,
只是好处通常大于代价。
五、备份的校验:备份成功不等于备份可用
三种验证,力度递增。
① VALIDATE DATABASE——检查数据文件有没有坏块,不产生备份。
② BACKUP VALIDATE DATABASE——边验证边备份,坏块会记进 V$DATABASE_BLOCK_CORRUPTION。
③ RESTORE DATABASE VALIDATE——真去读备份文件,验证「这份备份能不能恢复」。
第 ③ 种最接近真实:它把备份文件读一遍、解压、校验块,但不写回数据文件。
所以它能在不影响生产的情况下回答「这份备份到底能不能用」。
为什么必须做这一步:备份文件也可能坏。磁盘坏道、传输截断、压缩算法出错,都会产生「看着有、
其实读不出来」的备份。而这种事通常只在真出事那天才发现——那时候已经来不及了。
所以一条实务建议:每周至少跑一次 RESTORE ... VALIDATE,
并且定期做「真恢复到另一台机器」的演练。前者验证文件,
后者验证流程——很多恢复失败不是文件坏了,是步骤漏了。
六、动手 Demo:三种增量策略的账:每轮备多少块、恢复要几个片
这一篇的 Demo 用 8 个「数据文件」、每个 5000 块来算三种策略的账。每轮随机改 200 块,跑五轮, 统计每轮各策略要备多少块。 然后算第二个账:恢复时要按顺序应用几个备份片。这一列最容易被忽略,但它直接决定 RTO。
# 三种增量策略各备多少块:8 个文件 × 5000 块,每轮改 200 块
import random
NF, NB = 8, 5000
rnd = random.Random(7)
stamp = [[0] * NB for _ in range(NF)] # 每块最后被改的「时刻」
level0, clock = 1, 1 # 0 级备份的时刻
tot = [0, 0, 0]
for r in range(1, 6):
clock += 1
ch = set()
while len(ch) < 200:
ch.add((rnd.randrange(NF), rnd.randrange(NB)))
for fi, bi in ch:
stamp[fi][bi] = clock
full = NF * NB
diff = sum(1 for fi in range(NF) for bi in range(NB)
if stamp[fi][bi] > clock - 1) # 上次备份之后
cum = sum(1 for fi in range(NF) for bi in range(NB)
if stamp[fi][bi] > level0) # 上次 0 级之后
print("第 %d 轮:全备 %d 块,差异 %d 块,累积 %d 块"
% (r, full, diff, cum))
tot = [tot[0] + full, tot[1] + diff, tot[2] + cum]
print("五轮合计:全备 %d,差异 %d,累积 %d" % tuple(tot))
实跑输出:
--------------------------------------------------------------------
第七十二课:全备、差异增量、累积增量——三种策略的账
--------------------------------------------------------------------
**增量备份的前提是「知道哪些块变过」。**
**Oracle 靠数据块里的 SCN 比对,或者开块变更跟踪(BCT)记一份位图。**
**这一课用 8 个「数据文件」、每个 5000 块来算三种策略的账。**
**初始状态:8 个文件 × 5000 块 = 40000 块,全部是脏的(都要备)。**
轮次 改动块 全备 差异增量 累积增量
-----------------------------------
1 200 40000 200 200
2 200 40000 200 399
3 200 40000 200 599
4 200 40000 200 798
5 200 40000 200 998
已选择 5 行
**五轮 0 级之后一共备了多少块:**
策略 累计备份块 恢复要几个备份片
--------------------------------------------------------
每轮全备 200000 1 个(最近那次)
0 级 + 差异增量 1000 1 + 本轮数(0 级加每轮 1 级)
0 级 + 累积增量 2994 2 个(0 级 + 最近一个 1 级)
已选择 3 行
**三行数字就是全部取舍:**
**全备每次最贵、恢复最简单;差异增量每次最便宜、恢复最麻烦;累积增量在中间。**
**「恢复要几个备份片」这一列最容易被忽略,但它决定恢复要多久。**
**差异增量恢复时要按顺序应用一串增量,中间任何一个坏了,整条链就断了。**
**所以常见的实际策略是:每周一次 0 级全备,每天一次差异增量,遇到大变更再补一次累积增量。**
**这不是最优解,是把「备份窗口」和「恢复时间」两笔账折中。**
备份链越长,中间断一环的概率越大
--------------------------------------------------------------------
策略 链上备份片 整条链全好
-------------------------------------
每轮全备 1 0.9990
0 级 + 累积增量 2 0.9980
0 级 + 差异增量 6 0.9940
已选择 3 行
**这张表的算法:假设每个备份片完好的概率是 0.999,链上 n 个就乘 n 次。**
**注意 0.999 是个【假设】,不是实测值**——真实磁盘的损坏率比这高得多。
**所以看这张表别看绝对值,看趋势:链越长,全好的概率越低。**
**而一旦中间某一环坏了,只能恢复到它前面那一个备份点**——**这就是差异增量省空间的隐性代价。**
第一张表:全备每轮恒定 4 万块,差异增量每轮恒定 200 块,累积增量从 200 涨到 998。 三行数字把三种策略的性格写清楚了。 注意累积增量那列不是「200 乘轮数」,而是 200、399、599、798、998。 因为每轮改的 200 块是随机的,跟前面几轮有重叠——重叠的块只算一次。这也是真实情况:改得越集中, 累积增量涨得越慢。 第二张表:五轮累计,全备 20 万块、差异 1000 块、累积 2994 块。差异增量只有全备的 0.5%—— 这就是它省空间的程度。 但第三列「恢复要几个备份片」把账翻回来了:差异增量要 1 加 5 等于 6 个,累积只要 2 个。 恢复时每多一个片,就多一次读取、多一次应用,也多一个「坏了就断链」的风险。 最后那张可靠性表要看清前提:0.999 是假设的「单个备份片完好概率」,不是实测值。 真实磁盘的损坏率比这高,而且还有人为误删。 所以那张表别看绝对值,看趋势:链越长,全好的概率越低。 把两张表合起来看,就能明白为什么实际策略通常是「周全备加日差异加补累积」:平时用差异省窗口, 关键时刻用累积把链缩短。这不是理论最优,是把两笔账折中。
30 秒实验
- 把每轮改动的块数从 200 改成 2000,再跑一次。 看累积增量涨得快多少、差异增量是不是还是恒定 2000——改动越密集,两者差距越小。
- 把改动的块固定在同一个文件的前 200 块(每轮都改同一批)。 看累积增量还会不会涨——完全不涨,因为「自上次 0 级以来」的集合没变大。
- 如果有 Oracle 环境,
跑
BACKUP INCREMENTAL LEVEL 1 DATABASE之后查V$BACKUP_DATAFILE的BLOCKS列。 看它比全备少了多少。
常见误区
- 「0 级增量就是不做备份」。 0 级就是全备,只是它登记进了增量链。 没有 0 级,1 级增量无从谈起。
- 「差异增量比累积增量好」。 差异省空间、累积省恢复时间。 选哪个取决于你的 RTO,不是取决于哪个更先进。
- 「
BACKUP DATABASE就够了,归档不用单独备」。没有归档, 这份备份只能恢复到备份点——热备的意义就没了。 - 「备份成功就是备份可用」。 备份文件本身可能坏。
要跑
RESTORE ... VALIDATE,最好再做一次真恢复演练。
自测三问(点开对答案)
1. RPO 和 RTO 分别决定什么? —— **RPO 是「最多能丢多久的数据」,决定备份频率;** **RTO 是「多久必须恢复」,决定用全备还是增量。** 2. `BACKUP DATABASE PLUS ARCHIVELOG` 为什么要切两次日志? —— **第一次切把「备份开始前」的日志全收进来,第二次切把「备份期间」产生的日志收进来。** 少了第二次,恢复时会缺那一段的重做。 3. 1 级差异增量和 1 级累积增量的区别是什么? —— **差异增量备「自上次 1 级或 0 级以来」变的块,累积备「自上次 0 级以来」变的块。**前者小、 恢复链长;后者大、恢复链短。 4. 备份做完之后,用什么命令验证「这份备份能不能恢复」? —— **`RESTORE DATABASE VALIDATE`。** 它真去读备份文件、解压、校验块,但不写回数据文件, 所以不影响生产。下一篇讲完全恢复。
备份做得再好,恢复不起来等于零。下一篇用两个模式各演一遍:
NOARCHIVELOG 丢一半,ARCHIVELOG 一行不丢。
- ☐ (本篇完,下一篇 16.4 使用 RMAN 工具完全恢复)
相关笔记
- RMAN 工具简介
- 备份与恢复概述
- 数据库和 SQL 重演
-
- 🐬 MySQL必知必会/00-索引
- 🏺 Oracle从入门到精通 · 索引