
简介一份聚焦 TSM 6.3 与 Mhvtl 虚拟带库联调的备份恢复测试文档面向企业备份运维、数据库容灾实施人员及需要搭建实验环境的学习者重点解决 Linux 下虚拟带库接入、TSM 存储配置以及 Oracle、DB2 备份恢复验证问题。文档按模块展开Mhvtl 编译安装与带库可用性测试、基于 tgt 的 iSCSI 映射、TSM 主服务器安装及机械手、驱动器、卷和备份策略配置并给出 Oracle 的 NUB 客户端配置、RMAN 备份发起以及异机恢复中 spfile、控制文件、数据文件和归档日志的恢复流程目录层级清晰便于按阶段查阅和复现。资源包共 1 个 docx 文件约 1.83MB已有 243 人学习适合作为虚拟带库到 TSM 再到数据库恢复链路的实操参考与排错对照。1. 物理带库排期太长Mhvtl 顶上去能验到什么程度一套备份系统上线前最怕的不是配置难而是没设备可测。采购一台 LTO 机械手要立项、要机房空间、要走到货周期等项目窗口过去一半方案还在 PPT 上。我一般直接拿 Mhvtl 顶上去它在 Linux 上用内核模块模拟出 STK L700 机械手和 LTO5 驱动器通过 iSCSI 映射给备份服务器TSM 6.3 认到的 medium changer 和 tape drive 跟真机没有区别checkin、mount、迁移、回收这些流程全都能跑通。配上 Oracle 11g 和 DB2 9.7 两个客户端备份到带库、备份到本地磁盘、异机恢复三条线可以一次性走完。它验的是配置和流程是否正确不是吞吐性能适合手上有恢复演练指标、又暂时拿不到物理带库的 DBA 和备份运维。2. Mhvtl 落地从内核模块编译到 iSCSI 映射的四步2.1 为什么用 L700 仿真而不是直接把备份写本地磁盘TSM 的设备类分成 DISK 和 LTO 两套很多人在测试阶段图省事全部 define 成 file 类型的 devclass备份能成功报告也好看但带库那一段的逻辑等于没测。真实环境里最容易翻车的恰恰是带库侧卷不在槽位里、机械手抓不到带、mount 超时、卷被占住导致下一个作业排队。这些问题在磁盘设备类下永远不会出现等到生产环境换成物理带库才暴露。Mhvtl 的价值就在这里。它模拟的是一个完整的 SCSI 目标一个 medium changer 加若干 tape drive走的是标准 SCSI 命令集TSM 服务端通过 sg 设备下发 READ ELEMENT STATUS、MOVE MEDIUM、READ/WRITE 这些命令跟操作一台 STK L700 完全一样。默认配置会生成两套带库.10是 4 驱动器 43 槽位的 L700.30是 4 驱动器 44 槽位的 L80条目定义在/etc/mhvtl/library_contents.*里条码前缀、槽位数量、驱动器类型都可以改。需要说清楚边界这套环境测不了 LAN-free。原文档里也明确写了“以下条件限制无法模拟主要是使用 LAN Free 方式的备份”因为 Mhvtl 和 TSM 服务端如果跑在同一台机器上数据流根本不经过 SAN就算拆成两台虚拟机走 iSCSI带宽也是虚拟网卡的量级测出来的速率没有任何参考价值。它验证的是“这条链路能不能走通、配置对不对、恢复顺序对不对”性能评估要另找物理设备。2.2 依赖包、vtl 账号与两个目录装之前先想清楚两个路径放哪。Mhvtl 把虚拟磁带的介质文件落在MHVTL_CONFIG_PATH指定的 home 目录下一盘容量 2G 的卷就在那下面实打实占 2G 空间同时/etc/mhvtl放 library_contents 和 mhvtl.conf。这两个目录建议分开挂载将来清理测试数据时不会把带库定义一起删掉。# 带库工具链 编译依赖 # mtx 操作机械手mt-st 操作驱动器sg3_utils 用来发原始 SCSI 命令排查问题 yum install -y lsscsi mt-st mtx sg3_utils zlib zlib-devel gcc make kernel-devel kernel-headers # 固定用 vtl 账号跑服务避免后面权限混乱 useradd vtl mkdir -p /opt/mhvtl /etc/mhvtl chown -R vtl:vtl /opt/mhvtl /etc/mhvtl参数上要注意kernel-devel和当前运行内核版本必须严格一致uname -r和rpm -q kernel-devel对不上后面make一定报找不到头文件。这是编译类操作最常见的翻车点尤其在做过 yum update 但没重启的机器上。2.3 编译内核模块与首次启动# 先装用户态工具包它提供 mhvtl 的启动脚本和介质管理命令 rpm -ivh mhvtl-utils-1.5-2.x86_64.rpm unzip mhvtl-1.5-2.zip cd markh794-mhvtl-d9f6115/kernel make make install # 编译并安装 vtllibrary / vtltape 两个内核模块 service mhvtl start chkconfig mhvtl on首次启动时日志里会打出两行看起来像报错的信息Could not locate library config file: /etc/mhvtl/library_contents.10 Creating a default one Could not locate library config file: /etc/mhvtl/library_contents.30 Creating a default one这不是失败是服务在生成默认带库定义。看到后面跟着vtllibrary process PID is ...就说明机械手进程起来了。如果要改驱动器数量或者槽位数现在就是时候停服务、编辑这两个文件、再启动改动才会生效。生产测试里我一般只保留一套带库把.30那套的驱动器数改成 0省得后面 TSM 扫描设备时把两套带库的设备混在一起。2.4 lsscsi 认设备sg 号和 st 号的对应关系服务起来后第一件事是把设备编号固定下来。lsscsi -g会把每个 SCSI 设备的块设备节点和通用设备节点都列出来lsscsi -g输出大致长这样我按类型整理成表更直观SCSI 地址类型型号块/字符设备通用设备作用3:0:0:0mediumxSTK L700/dev/sch0/dev/sg10带库 1 机械手3:0:1:0tapeIBM ULT3580-TD5/dev/st0/dev/sg2带库 1 驱动器 03:0:2:0tapeIBM ULT3580-TD5/dev/st1/dev/sg3带库 1 驱动器 13:0:3:0tapeIBM ULT3580-TD4/dev/st2/dev/sg4带库 1 驱动器 23:0:8:0mediumxSTK L80/dev/sch1/dev/sg11带库 2 机械手3:0:9:0tapeSTK T10000B/dev/st4/dev/sg6带库 2 驱动器 0规律很清晰mediumx是机械手tape是驱动器/dev/schN和/dev/stN是给应用程序用的常规节点/dev/sgN是通用节点iSCSI 映射和底层排查都要用 sg 号。这张表要抄下来贴在旁边后面 tgt 配置文件里写的就是这几个 sg 编号。提示/dev/st0这类编号在重启、增删设备、重新登录 iSCSI 会话之后会漂移。凡是准备写进配置文件的路径一律用/dev/tape/by-id/下的稳定链接不要图省事直接写/dev/st0。2.5 mtx 与 tar验证带库真的能动设备认出来不等于能用。先用 mtx 验证机械手能抓带再用 tar 验证驱动器能读写这两步都过了才轮到 TSM 上场。# 看机械手状态几个驱动器、几个槽位、哪些槽位有带 mtx -f /dev/sg10 status # 把 1 号槽位的磁带装进 0 号驱动器 mtx -f /dev/sg10 load 1 0 # 再看一次确认 Data Transfer Element 0 变成 Full并且带 VolumeTag mtx -f /dev/sg10 status | head -5 # 用最小工具验证写入绕开所有备份软件 tar -cvf /dev/st0 /boot mt -f /dev/st0 rewind tar -tvf /dev/st0 # 用完必须卸回槽位 mtx -f /dev/sg10 unload 1 0mtx的参数顺序是-f 机械手通用设备 load 源槽位 目标驱动器unload 反过来。tar 直接写/dev/st0这一步很关键它把 TSM、Oracle、DB2 全部排除在外如果这里写不进去说明问题在 SCSI 链路或内核模块层面往后排查都是浪费时间。容量在/etc/mhvtl/mhvtl.conf里改cat /etc/mhvtl/mhvtl.conf # Default media capacity (500 M) CAPACITY2046CAPACITY2046单位是 MB也就是每盘卷 2G 左右。测试环境里这个值可以调小比如 512好处是备份几十 G 数据就能触发卷切换能快速验证多卷挂载和卷回收逻辑调大反而看不出问题。2.6 tgt 把带库映射出去Mhvtl 装在本机TSM 服务端在另一台机器上中间用 iSCSI 连。服务端装 scsi-target-utils把机械手和驱动器分别映射成 target。yum install -y scsi-target-utils编辑/etc/tgt/targets.conftarget iqn.2015-04.lab.backup:vtl-l700 backing-store /dev/sg10 bs-type sg initiator-address 192.168.81.7 write-cache off /target target iqn.2015-04.lab.backup:vtl-drive0 backing-store /dev/sg2 bs-type sg initiator-address 192.168.81.7 write-cache off /target这里最关键的是bs-type sg。/dev/sg10是字符设备不是块设备tgt 默认的 rdwr 后端打不开它改成 sg 后端之后target 会把 SCSI 命令原样透传给下面的设备机械手的 MOVE MEDIUM 和驱动器的 READ/WRITE 才能正确落到 Mhvtl 上。initiator-address是发起端 IP 白名单测试环境嫌麻烦可以去掉但生产演练时建议保留免得别的机器扫到就挂载。启动后检查一下service tgtd start chkconfig tgtd on tgt-admin --dump | grep -E target|backing客户端这边yum install -y iscsi-initiator-utils # 发起端名称如果服务端配了 ACL这里必须对得上 cat /etc/iscsi/initiatorname.iscsi # 发现目标 iscsiadm -m discovery -t sendtargets -p 192.168.81.6 # 登录 iscsiadm -m node -T iqn.2015-04.lab.backup:vtl-l700 -p 192.168.81.6 -l iscsiadm -m node -T iqn.2015-04.lab.backup:vtl-drive0 -p 192.168.81.6 -l # 设置开机自动登录否则重启后设备全丢 iscsiadm -m node -T iqn.2015-04.lab.backup:vtl-l700 --op update -n node.startup -v automatic登录完再跑一次lsscsi -g客户端上应该能看到一个 STK L700 的 mediumx 和对应的 tape 设备。然后看稳定路径ls -l /dev/tape/by-id/会看到scsi-3600...这样的长串链接这个路径就是后面 TSMdefine path要用的设备名。它由设备的 WWID 生成重启、重新登录都不会变比/dev/st0可靠得多。3. TSM 6.3 服务端设备、存储池与策略的三层落地3.1 实例目录规划为什么 dbdir 不能和日志放一起TSM 服务端跑起来之后有五个路径必须提前定dbdir 是数据库目录actlog 是活动日志volhist 是卷历史devcnfg 是设备配置dsmserv.opt 是主配置文件。前三个最容易出事。dbdir 里面是 TSM 自己的元数据一旦损坏所有卷上的数据都变成“知道有这么盘带但不知道里面是什么”。所以它必须独立目录、独立磁盘并且纳入单独的备份。actlog 会持续增长放在系统盘上很容易把根分区撑满导致服务莫名停摆。volhist 记录的是每一盘卷从 checkin 到 checkout 的完整轨迹丢了的话 TSM 就不知道磁带现在在哪个槽位只能一盘一盘audit volume重新扫43 个槽位扫下来是几个小时。我一般这么建useradd tsminst1 mkdir -p /tsminst1/{dbdir,actlog,volhist,devcnfg,backup} chown -R tsminst1:tsminst1 /tsminst13.2 dsmserv format 与第一次登录su - tsminst1 cd /opt/tivoli/tsm/server/bin # 格式化实例这一步只在首次安装时执行一次 ./dsmserv format dbdir/tsminst1/dbdir \ actlog/tsminst1/actlog \ volhist/tsminst1/volhist \ devcnfg/tsminst1/devcnfg \ dsmserv.opt/tsminst1/dsmserv.opt参数说明dbdir后面不能带文件名只能给目录其余四项给的是文件路径文件不存在会自动创建。dsmserv.opt可以提前写好再传进来也可以后面再拷贝。格式化完成后前台启动./dsmserv看到ANR7800I系列提示和Server ready就说明起来了。测试阶段这样前台跑方便看日志正式演练建议用nohup ./dsmserv /tsminst1/dsmserv.out 21 或者写个 systemd unit避免终端断开服务就没了。管理界面用 dsmadmc 登录6.3 初始账号是 admin/admindsmadmc -idadmin -paadmin进去第一件事是改密码第二件事是确认通信参数。dsmserv.opt里至少要这两行COMMMETHOD TCPIP TCPPORT 1500改完要重启服务端才生效客户端连不上十有八九是这里没配或者被防火墙挡了。3.3 定义 library、drive 和 path这是整个 TSM 配置里最容易定义错的一层。三个对象的关系是library 是机械手drive 是驱动器path 是“哪台服务器通过哪个设备节点访问哪个驱动器”。/* 定义机械手libtypescsi 表示直连 SCSI 带库 */ define library vtl1 libtypescsi /* 定义驱动器elementautodetect 让 TSM 自己去机械手读元素地址 */ define drive vtl1 drive01 elementautodetect /* 定义路径device 必须写服务端本机可见的持久路径 */ define path tsm61 drive01 srctypeserver desttypedrive libraryvtl1 device/dev/tape/by-id/scsi-3600xxxxelementautodetect省掉了手工数元素地址的麻烦但前提是机械手能被 TSM 正常打开。如果这里报ANR8420E说明 path 里的 device 写错了或者权限不对先退回上一步用mtx status确认设备还在。定义完检查q path q drive q libraryq path里的 Online 状态是结果不是过程。它显示 Online 只代表 TSM 打开过这个设备节点不代表驱动器真的能读写。真正的验证在第一次 mount 卷的时候。3.4 DEVCLASS、STGPOOL 与卷的 checkin设备层通了之后才轮到存储层。TSM 的逻辑是devclass 描述“哪一类设备、什么格式”stgpool 描述“数据放哪、放几份”volume 是实际的介质。/* 带库设备类mountlimit 必须和实际驱动器数一致 */ define devclass vtl_lto libraryvtl1 devtypelto formatdrive \ mountlimit4 mountwait60 mountretention5 prefixvtl /* 带库存储池maxscratch 控制最多占用多少盘临时卷 */ define stgpool vtlpool vtl_lto maxscratch20 /* 磁盘设备类用来放数据库备份和 stgpool 的下一级 */ define devclass diskpool devtypefile directory/tsminst1/backup /* 把带库里的卷扫进来注册成 scratch 状态 */ checkin libvolume vtl1 searchbulk statusscratch checklabelyes参数逐个说mountlimit4表示这个设备类最多同时挂 4 个驱动器写多了 TSM 会以为有更多驱动器可用排队逻辑就乱了mountwait60是等带超时超过 60 秒就判失败测试环境可以调大到 120mountretention5是卸载后保留挂载上下文的时间调大能减少反复 mount 的开销prefixvtl决定 TSM 给卷起名时的前缀。checklabelyes会实际去读每盘带的条码标签Mhvtl 在 library_contents 里定义的 VolumeTag 就是在这里被识别出来的。checkin 完用q libvol确认应该看到 40 多盘卷全是 Scratch 状态。3.5 策略域、管理类和拷贝组备份保留多久、留几个版本、满了往哪迁全靠这一层。三层嵌套的关系是domain 包含 policysetpolicyset 包含 mgmtclassmgmtclass 里挂 copygroup。define domain oradb define policyset oradb standard define mgmtclass oradb standard daily /* 备份拷贝组目标存储池 vtlpool保留 30 个版本保留 60 天 */ define copygroup oradb standard daily standard typebackup \ destvtlpool verexists30 retextra60 verdelete2 retonly30 /* 归档拷贝组 */ define copygroup oradb standard daily standard typearchive \ destvtlpool retver365 assign defmgmtclass oradb standard dailyverexists是保留多少个“存在过”的版本retextra是额外保留天数verdelete是删除后还留几个版本。这些值定得太小测试时还没恢复到目标时间点备份就被 expire 掉了恢复演练直接卡死。测试环境我一般把retextra设成 90给恢复留足窗口。然后把 Oracle 和 DB2 的客户端节点注册进来register node oradb oradb domoradb maxnummp4 register node db2db db2db domdb2dom maxnummp4maxnummp是这个节点最多能开几个并发会话要跟后面的 RMAN 通道数对齐通道开 4 个这里写 2第三个通道就会排队等。3.6 用 backup db 收尾服务端自己的元数据也要落地。先确认磁盘设备类能写backup db typefull devclassdiskpool q vol如果报ANR2017I或者卷不够先define volume diskpool /tsminst1/backup/dbbak1.dsm f10g手工给磁盘池加卷。备份数据库成功之后q vol里会多出一盘DBBACKUP类型的卷这个动作是后面所有恢复的前提——磁带上的数据能不能读回来取决于 TSM 自己记不记得它在哪。4. Oracle 与 DB2 接入TDPO 参数表与 SBT 通道脚本4.1 客户端装包顺序API 在前BA 在后Oracle 接 TSM 走的是 TDPOTivoli Data Protection for Oracle它依赖底层的 TSM API。装包顺序错了会报找不到libApiTSM64.so。rpm -ivh gskcrypt64-8.0.x.x86_64.rpm gskssl64-8.0.x.x86_64.rpm rpm -ivh TIVsm-API64.x86_64.rpm rpm -ivh TIVsm-BA.x86_64.rpm装完确认目录ls /opt/tivoli/tsm/client/api/bin64/ ls /opt/tivoli/tsm/client/oracle/bin64/Oracle 客户端相关的配置全在bin64下不要混用bin目录下的 32 位版本混用之后 tdpoconf 会报找不到库。4.2 dsm.opt 与 tdpo.opt两个文件各管一段dsm.opt管的是 TSM 客户端怎么连服务端tdpo.opt管的是 TDPO 怎么调 TSM API两者职责不能混。/opt/tivoli/tsm/client/oracle/bin64/dsm.optSERVERNAME tsm61 TCPSERVERADDRESS 192.168.81.7 NODENAME ORADB PASSWORDACCESS GENERATE ERRORLOGNAME /home/oracle/tsm/dsmerror.log SCHEDLOGNAME /home/oracle/tsm/dsmsched.log/opt/tivoli/tsm/client/oracle/bin64/tdpo.optDSMI_ORC_CONFIG /opt/tivoli/tsm/client/oracle/bin64/dsm.opt DSMI_LOG /home/oracle/tsm TDPO_NODE ORADB TDPO_OWNER oracle TDPO_PSWDPATH /home/oracle/tsm两边的对应关系整理成表参数所在文件作用SERVERNAMEdsm.opt服务端名称必须和服务端set servername一致NODENAMEdsm.opt客户端节点名必须已经 register nodePASSWORDACCESS GENERATEdsm.opt密码由 TSM 托管不用明文写DSMI_ORC_CONFIGtdpo.opt指向 dsm.opt 的绝对路径TDPO_NODEtdpo.opt与 NODENAME 保持一致不一致会认证失败TDPO_PSWDPATHtdpo.opt密码文件存放目录oracle 用户必须有写权限TDPO_PSWDPATH指向的目录权限是血泪经验如果这个目录属主是 roottdpoconf password在 oracle 用户下执行时会报ACO5009E报错信息还看不出是权限问题。装完包第一件事就是chown -R oracle:oinstall /home/oracle/tsm。4.3 密码握手与节点确认su - oracle export TDPO_OPTFILE/opt/tivoli/tsm/client/oracle/bin64/tdpo.opt # 生成节点密码文件会提示输入密码这里要输服务端 register node 时设的密码 tdpoconf password # 确认配置被正确读到 tdpoconf showenvshowenv输出里重点看三行TDPO Node Name、TSM Server Name、Server Port任何一个不对后面 RMAN 一定报认证失败。服务端这边确认节点在线q node ORADB如果Platform显示成Linux86并且Locked是 No就没问题。4.4 RMAN 脚本SBT 通道怎么写run { allocate channel c1 type sbt_tape parms ENV(TDPO_OPTFILE/opt/tivoli/tsm/client/oracle/bin64/tdpo.opt); allocate channel c2 type sbt_tape parms ENV(TDPO_OPTFILE/opt/tivoli/tsm/client/oracle/bin64/tdpo.opt); sql alter system archive log current; backup database plus archivelog delete input format ORADB_%d_%T_%U; release channel c1; release channel c2; }关键点TDPO_OPTFILE的路径必须和tdpoconf用的完全一致两个通道的 parms 都必须带少写一个那个通道就会退化成磁盘备份。format里的%U保证唯一性不要去掉否则同一秒发起的两个通道会撞名。备份发起后到服务端看q session q actlog searchANR q content oradbq content能看到每个备份对象落在哪盘卷上、占多少空间。actlog 里出现ANR0406I Session ... started和ANR0512I系列说明走的是 SBT 通道如果只有ANR0407I没有写入记录八成是退化成文件系统备份了去客户端看dsmerror.log。4.5 DB2 侧TSM_MGMTCLASS 与 backup use tsmDB2 的接入比 Oracle 简单装完 TIVsm-API64 之后直接改数据库配置su - db2inst1 # 指定备份走哪个管理类这个值必须和服务端 ORADB 域下的 mgmtclass 名字对上 db2 update db cfg for SAMPLE using TSM_MGMTCLASS VTL_MC # 全备直接打到带库 db2 backup db SAMPLE use tsm # 查一下备份历史 db2adutl queryTSM_MGMTCLASS这一项最容易踩坑它的值不是策略域名而是管理类名。写错了 DB2 不会报配置错误只会在备份时报找不到管理类然后 fallback 到默认类数据照样备成功但保留策略完全不对等到几个月后要恢复才发现备份早就被回收了。恢复命令db2 restore db SAMPLE use tsm taken at 20250418103000 replace existing时间戳来自db2adutl query的输出精确到秒少一位就报找不到镜像。5. 避坑与排查五条从日志里抠出来的现象5.1 mtx load 成功但 tar 报设备忙现象mtx -f /dev/sg10 load 1 0返回成功本文还有配套的精品资源点击获取