数据库备份看似简单:选择一个目录,执行备份命令,等待返回成功。但在实际技术服务中,真正需要回答的问题远不止“命令能不能执行”。
例如:启用压缩后,备份一定会变慢吗?压缩等级越高,备份集一定越小吗?并行度从1提高到4,备份速度会不会按比例提升?启用BCT后,增量备份究竟能快多少?最重要的是,已经生成的备份集能否真正还原出一个可以正常打开、对象完整、数据可查询的数据库?
围绕这些问题,我在一台Ubuntu虚拟机中搭建了DM8实验实例,完成了18次完整备份、6次增量备份和3条数据库还原路径测试,。
| 项目 | 配置 |
|---|---|
| 操作系统 | Ubuntu Linux虚拟机 |
| 数据库版本 | DM8 V8.10.18.2 |
| 实验实例 | DM8EXP |
| 监听端口 | 5235 |
| CPU | 4 vCPU |
| 内存 | 4GB |
| 磁盘 | 动态扩展VMDK |
| 数据库状态 | OPEN、NORMAL |
| 归档模式 | 已开启 |
| 测试数据 | PERF_DATA表段约31GB |
实验使用单独创建的DM8EXP实例,没有修改原有数据库实例。实验相关文件统一放在/home/dmdba/dm8exp目录下:
/home/dmdba/dm8exp/
├── data/ # 数据库文件
├── backup/ # 完整和增量备份集
├── logs/ # 备份、还原和资源监控日志
├── results/ # CSV、SHOW、CHECK和SQL校验结果
└── scripts/ # 实验执行脚本
测试表空间TS_BAKTEST包含4个自动扩展数据文件。每个文件初始大小为128MB,每次扩展256MB,最大约9GB。
create tablespace TS_BAKTEST datafile
'/home/dmdba/dm8exp/data/DM8EXP/TS_BAKTEST01.DBF'
size 128 autoextend on next 256 maxsize 9216,
'/home/dmdba/dm8exp/data/DM8EXP/TS_BAKTEST02.DBF'
size 128 autoextend on next 256 maxsize 9216,
'/home/dmdba/dm8exp/data/DM8EXP/TS_BAKTEST03.DBF'
size 128 autoextend on next 256 maxsize 9216,
'/home/dmdba/dm8exp/data/DM8EXP/TS_BAKTEST04.DBF'
size 128 autoextend on next 256 maxsize 9216;
create table SYSDBA.PERF_DATA (
ID bigint not null,
PAYLOAD varchar(6400),
CREATED_AT timestamp default current_timestamp
) tablespace TS_BAKTEST;
数据生成脚本以10万行为一个批次插入数据。PAYLOAD由MD5结果拼接后重复填充,使数据真正进入数据库段和数据文件,而不是只增加逻辑行数。
insert /*+ append */ into SYSDBA.PERF_DATA(ID, PAYLOAD)
select id,
repeat(
rawtohex(md5(to_char(id) || '-A')) ||
rawtohex(md5(to_char(id) || '-B')),
100
)
from (
select :START_ID + level as id
from dual connect by level <= 100000
);
commit;
实验前通过DBA_SEGMENTS、DBA_DATA_FILES、V$INSTANCE和V$DATABASE进行检查。
select owner, segment_name, segment_type,
bytes/1024/1024/1024 as segment_gb
from dba_segments
where owner='SYSDBA'
and segment_name='PERF_DATA';
select tablespace_name, file_id, file_name,
bytes/1024/1024/1024 as file_gb,
autoextensible,
maxbytes/1024/1024/1024 as max_gb
from dba_data_files
where tablespace_name='TS_BAKTEST'
order by file_id;
select instance_name, status$, mode$
from v$instance;
select arch_mode
from v$database;
检查结果显示:
PERF_DATA表段约31GB;DM8EXP;OPEN;NORMAL;Y。完整备份实验选择压缩等级和并行度作为变量。
压缩设置包括:
COMPRESSED LEVEL 1;COMPRESSED LEVEL 3。并行度包括:
PARALLEL 1;PARALLEL 4。由此形成6个组合:
P1 + 不压缩
P4 + 不压缩
P1 + LEVEL 1
P4 + LEVEL 1
P1 + LEVEL 3
P4 + LEVEL 3
每组重复3次,共18次有效运行。为了降低单次虚拟机调度、缓存状态和宿主机后台任务造成的波动,结果使用每组三次运行的中位数进行比较。
实验执行顺序采用交叉排列,而不是把同一组连续执行完。例如先执行P1不压缩,再执行P4 LEVEL 3,然后执行P4不压缩。这样可以减少缓存、磁盘状态或CPU温度随时间变化造成的系统性偏差。
完整备份命令的基本形式如下:
backup database full
backupset '/home/dmdba/dm8exp/backup/full_p4_c1_r1'
compressed level 1
parallel 4;
不压缩实验只需要去掉compressed level子句:
backup database full
backupset '/home/dmdba/dm8exp/backup/full_p1_none_r1'
parallel 1;
SHOW BACKUPSET结果;vmstat每秒采样;dmserver和dmap进程的CPU、内存数据。备份开始时执行:
vmstat 1
并按秒采集数据库相关进程:
ps -C dmserver,dmap -o pid,comm,%cpu,%mem,rss,vsz
备份结束后使用以下方式统计备份目录大小:
du -sb /home/dmdba/dm8exp/backup/备份名称
如果备份目录不存在或大小为0,即使进程退出码看似正常,也不会被计入有效样本。
不压缩组分别使用P1和P4,每组执行3次。
| 实验组 | 第1次 | 第2次 | 第3次 | 中位耗时 | 中位体积 |
|---|---|---|---|---|---|
| P1不压缩 | 80.345s | 75.530s | 88.231s | 80.345s | 31.861GiB |
| P4不压缩 | 67.357s | 73.716s | 85.113s | 73.716s | 31.862GiB |
P4相对于P1的中位耗时下降约8.3%:
(80.345 - 73.716) / 80.345 ≈ 8.3%
不压缩时,提高并行度确实带来了一定收益,但P4并没有达到P1的4倍速度。并行度增加的是备份处理通道,虚拟磁盘吞吐量、内存带宽和宿主机存储能力并不会同步扩大。
不压缩备份集约31.86GiB,与数据库有效数据规模接近。它没有压缩计算开销,但会消耗更多本地磁盘空间,也会增加远程传输和异地保存成本。
| 实验组 | 第1次 | 第2次 | 第3次 | 中位耗时 | 中位体积 |
|---|---|---|---|---|---|
| P1 LEVEL 1 | 45.288s | 46.992s | 53.809s | 46.992s | 0.646GiB |
| P4 LEVEL 1 | 49.385s | 47.560s | 51.180s | 49.385s | 0.647GiB |
与P1不压缩相比,P1 LEVEL 1出现了两个明显变化:
空间降幅约为:
1 - 0.646 / 31.861 ≈ 97.97%
本次实验中,压缩备份没有变慢,反而明显更快。原因在于测试数据具有较高压缩率:压缩会增加CPU计算,但备份写入量从31.86GiB降低到约0.65GiB,减少磁盘写入所节省的时间超过了CPU压缩开销。
同样值得注意的是,P4 LEVEL 1中位耗时为49.385秒,比P1的46.992秒慢约5.1%。压缩后磁盘写入量大幅降低,CPU逐渐成为主要限制;继续提高并行度会增加线程调度和CPU竞争。
| 实验组 | 第1次 | 第2次 | 第3次 | 中位耗时 | 中位体积 |
|---|---|---|---|---|---|
| P1 LEVEL 3 | 49.406s | 45.905s | 52.148s | 49.406s | 0.644GiB |
| P4 LEVEL 3 | 50.223s | 48.389s | 52.555s | 50.223s | 0.645GiB |
LEVEL 3相对于LEVEL 1只减少了约2MiB,额外空间收益不足0.3%,但耗时略有增加:
测试数据在LEVEL 1下已经获得了绝大部分压缩收益。继续提高到LEVEL 3,增加了计算量,却没有显著降低备份集体积。
在本次环境中,LEVEL 1的综合表现优于LEVEL 3。
六组中位数汇总如下:
| 压缩方式 | P1中位耗时 | P4中位耗时 | 备份集大小 |
|---|---|---|---|
| 不压缩 | 80.345s | 73.716s | 约31.86GiB |
| LEVEL 1 | 46.992s | 49.385s | 约0.65GiB |
| LEVEL 3 | 49.406s | 50.223s | 约0.64GiB |
从这组结果可以看到,压缩是否变慢不能脱离数据特征和资源瓶颈来判断。
备份的总成本可以简单理解为:
数据读取成本
+ 压缩计算成本
+ 备份写入成本
+ 并行调度成本
不压缩时,需要写出约31.86GiB数据,存储路径承担较大压力;压缩后只写出约0.65GiB,写入成本大幅下降,但CPU计算成本上升。如果数据容易压缩、磁盘写入较慢,压缩可能让总耗时下降;如果数据难以压缩或CPU已经繁忙,压缩也可能延长备份窗口。
并行度同样不能单独判断。P4在不压缩场景中比P1快约8.3%,但在两个压缩场景中均发生回退。
从vmstat采样得到以下资源汇总:
| 实验组 | CPU busy | I/O wait |
|---|---|---|
| P1不压缩 | 52.4% | 6.1% |
| P4不压缩 | 73.8% | 18.3% |
| P1 LEVEL 1 | 86.2% | 0.8% |
| P4 LEVEL 1 | 90.2% | 0.0% |
| P1 LEVEL 3 | 87.2% | 0.7% |
| P4 LEVEL 3 | 90.3% | 0.0% |
不压缩P1的CPU busy约52.4%,仍有一定CPU余量;提高到P4后,CPU busy上升到73.8%,备份时间有所缩短。
压缩组的CPU busy已经达到86%至90%,而I/O wait接近0。此时主要限制已经由备份写入逐渐转向CPU计算。提高并行度无法获得更多CPU资源,反而可能增加调度竞争,因此P4没有快于P1
在实际环境中,更合理的并行度选择方式是从较低值开始,逐步增加,同时观察:
当并行度继续增加但备份耗时不再下降,或者业务负载受到明显影响时,就不应继续提高。
完整备份实验结束后,继续比较传统增量与BCT增量。
首先在未启用BCT的基线完整备份上修改一批数据:
update SYSDBA.PERF_DATA
set payload = repeat(
rawtohex(md5(to_char(id) || '-CHANGED')),
200
),
created_at = current_timestamp
where id between 1 and 100000;
commit;
随后使用LEVEL 1、PARALLEL 4执行3次传统增量备份:
backup database increment
base on backupset '/home/dmdba/dm8exp/backup/smoke3_p4_c1'
backupset '/home/dmdba/dm8exp/backup/legacy_inc_r1'
compressed level 1
parallel 4;
结果如下:
| 运行 | 耗时 | 备份集大小 |
|---|---|---|
| 传统增量1 | 35.548s | 29.31MiB |
| 传统增量2 | 34.267s | 29.41MiB |
| 传统增量3 | 34.987s | 29.42MiB |
| 中位数 | 34.987s | 约29.41MiB |
SHOW BACKUPSET显示传统增量备份中的use_bct为FALSE。
备份集虽然只有约29MiB,但执行时间仍接近35秒。这说明增量备份的耗时不只取决于最终写出多少数据,还包括识别变化块所需要的扫描成本。
BCT即Block Change Tracking,用于跟踪发生变化的数据块。增量备份可以根据变化跟踪信息缩小扫描范围。
启用前先检查参数:
select para_name, para_value
from v$dm_ini
where para_name='ENABLE_BCT';
初始值为0。随后执行:
sp_set_para_value(1, 'ENABLE_BCT', 1);
再次查询确认ENABLE_BCT=1,并检查BCT位图:
select count(*) as bitmap_rows
from v$bct_bitmap;
操作系统中也可以检查数据库目录下的.bct文件,确认变化跟踪文件已经生成。
启用BCT后重新建立一份完整基线备份:
/home/dmdba/dm8exp/backup/bct_base_p4_c1
该基线采用LEVEL 1、PARALLEL 4。SHOW BACKUPSET中的关键字段为:
database name: DM8EXP
compressed level: 1
parallel num: 4
backup type: full
use_bct: TRUE
BCT增量测试不能只修改参数后直接执行。需要确认参数、位图文件和基线备份均已正确建立。
建立BCT基线后,修改另一批数据:
update SYSDBA.PERF_DATA
set payload = repeat(
rawtohex(md5(to_char(id) || '-BCT-CHANGED')),
200
),
created_at = current_timestamp
where id between 100001 and 200000;
commit;
随后同样使用LEVEL 1、PARALLEL 4执行3次BCT增量备份。
| 运行 | 耗时 | 备份集大小 |
|---|---|---|
| BCT增量1 | 8.171s | 34.37MiB |
| BCT增量2 | 6.986s | 34.38MiB |
| BCT增量3 | 6.884s | 34.39MiB |
| 中位数 | 6.986s | 约34.38MiB |
传统增量中位耗时为34.987秒,BCT增量中位耗时为6.986秒:
34.987 / 6.986 ≈ 5.0
耗时降幅约为:
(34.987 - 6.986) / 34.987 ≈ 80%
值得注意的是,BCT备份集约34.38MiB,比传统增量的29.41MiB略大,但BCT仍然明显更快。这说明性能提升并不是因为BCT备份集更小,而是因为变化跟踪信息减少了识别变化块时的扫描工作。
BCT更适合数据库规模较大、增量备份频繁、每轮变化比例相对较低、增量窗口较紧张的场景。
每个有效备份完成后,都需要通过DMRMAN检查其元数据。
show backupset '/home/dmdba/dm8exp/backup/备份集名称';
重点关注:
use_bct状态;例如,不压缩P4完整备份显示:
database name: DM8EXP
compressed level: 0
parallel num: 4
backup type: full
use_bct: FALSE
通过SHOW可以确认实际生成的备份集与实验标签和命令参数一致。
对后续用于恢复的备份集继续执行:
check backupset '/home/dmdba/dm8exp/backup/full_p4_none_r3';
check backupset '/home/dmdba/dm8exp/backup/bct_base_p4_c1';
两个备份集均返回:
check backupset successfully.
因此,备份完成后的基本验证至少应该包含三步:
命令返回码正常
→ SHOW确认备份参数
→ CHECK确认备份集可检查
还原实验设置三条路径:
不压缩完整备份:
/home/dmdba/dm8exp/backup/full_p4_none_r3
LEVEL 1压缩完整备份:
/home/dmdba/dm8exp/backup/bct_base_p4_c1
完整恢复链路如下:
关闭DM8EXP实例
→ CHECK BACKUPSET
→ RESTORE DATABASE
→ RECOVER DATABASE
→ UPDATE DB_MAGIC
→ 启动实例
→ SQL验收
RESTORE命令为:
restore database
'/home/dmdba/dm8exp/data/DM8EXP/dm.ini'
from backupset '/home/dmdba/dm8exp/backup/备份集名称';
脚本同时检查DMRMAN退出码以及日志中是否存在:
restore successfully
三条路径的RESTORE阶段耗时如下:
| 还原路径 | RESTORE耗时 | 结果 |
|---|---|---|
| 不压缩+预分配 | 74.036s | 成功 |
| 压缩+预分配 | 62.317s | 成功 |
| 压缩+边还原边扩展 | 60.251s | 成功 |
这里记录的是RESTORE DATABASE阶段的墙钟时间,不包含后续RECOVER、UPDATE DB_MAGIC、实例启动和SQL校验。三条路径均完成RESTORE。压缩备份的两次恢复没有比不压缩更慢,主要与压缩备份读取量较小、解压CPU开销、目标文件状态以及动态VMDK的读写特征有关。
第三条路径专门验证数据文件没有预先保留完整空间的情况。
实例关闭后,将4个测试数据文件处理为0字节:
| 数据文件 | 处理前大小 | 处理后大小 |
|---|---|---|
| TS_BAKTEST01.DBF | 8,724,152,320B | 0B |
| TS_BAKTEST02.DBF | 8,724,152,320B | 0B |
| TS_BAKTEST03.DBF | 8,455,716,864B | 0B |
| TS_BAKTEST04.DBF | 8,455,716,864B | 0B |
然后使用LEVEL 1压缩完整备份执行RESTORE。还原结束后再次检查,4个数据文件均恢复到处理前的字节数。这说明在本次动态VMDK和文件系统环境中,DMRMAN可以在恢复过程中重新扩展数据文件并写回数据。
RESTORE完成后继续执行:
recover database
'/home/dmdba/dm8exp/data/DM8EXP/dm.ini'
from backupset '/home/dmdba/dm8exp/backup/bct_base_p4_c1';
recover database
'/home/dmdba/dm8exp/data/DM8EXP/dm.ini'
update db_magic;
在压缩边扩展场景中:
RECOVER DATABASE约7.315秒;UPDATE DB_MAGIC约1.255秒;RESTORE负责把备份内容恢复到目标数据文件,RECOVER负责使数据库达到一致状态,UPDATE DB_MAGIC则处理恢复后的数据库标识。只看到restore successfully并不代表整个恢复过程已经结束。
数据库恢复并启动后,再次执行与实验前一致的检查:
select owner, segment_name, segment_type,
bytes/1024/1024/1024 as segment_gb
from dba_segments
where owner='SYSDBA'
and segment_name='PERF_DATA';
select tablespace_name, file_id, file_name,
bytes/1024/1024/1024 as file_gb,
autoextensible,
maxbytes/1024/1024/1024 as max_gb
from dba_data_files
where tablespace_name='TS_BAKTEST'
order by file_id;
select instance_name, status$, mode$
from v$instance;
select arch_mode
from v$database;
恢复后的检查结果为:
DM8EXP实例达到OPEN状态;NORMAL;Y;PERF_DATA对象存在;PERF_DATA表段仍约31GB;TS_BAKTEST及4个数据文件存在;数据库恢复成功不能只判断进程是否存在。完整的成功标准应该是:
命令返回码为0
→ RESTORE成功
→ RECOVER成功
→ UPDATE DB_MAGIC成功
→ 实例OPEN
→ 对象存在
→ 数据规模正常
→ 关键SQL可执行
可以优先从LEVEL 1开始测试。本次实验中,LEVEL 1已经把备份集由31.86GiB降低到约0.65GiB,而LEVEL 3没有带来明显的额外空间收益。
不要直接把并行度设为最大值。应从较低并行度开始,逐步增加,并同时观察备份耗时、CPU、I/O等待以及业务响应时间。
数据库规模较大、增量频繁时,可以评估BCT。启用后应检查:
ENABLE_BCT参数;.bct文件;use_bct状态。每次关键备份至少保留以下证据:
SHOW BACKUPSET结果;CHECK BACKUPSET结果。文章
阅读量
获赞
