十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Oracle ASM磁盘rebalance迁移实战:从原理到踩坑全解析

Oracle ASM磁盘rebalance迁移实战:从原理到踩坑全解析 这块内容我构思了挺久才动笔。上个月刚帮一个客户把两节点RAC的存储阵列整体下架三个ASM磁盘组近8TB数据全部通过rebalance搬到了新存储上全程在线业务零中断。很多DBA对ASM磁盘迁移的理解停留在加盘、删盘、等同步这种粗粒度真到自己动手的时候会发现里面有不少细枝末节能让人折腾到后半夜。这篇就把ASM磁盘通过rebalance迁移这件事从原理到实操彻底拆开讲适合正在准备存储替换、磁盘组扩容或者故障盘更换的DBA和运维同学参考。1. ASM磁盘rebalance迁移的底层逻辑1.1 为什么第一反应应该是rebalanceASM磁盘组里的数据分布由ASM实例自己管理不依赖操作系统层面的LVM或文件系统。所以当你想把数据从一批物理磁盘挪到另一批物理磁盘时不能简单地用dd、cp或者rsync把设备内容拷过去——ASM的元数据、extent分配关系、failure group映射全部写在磁盘头和各磁盘的分配表里硬件层面的拷贝会让ASM认为磁盘内容产生冲突轻则报ora-15032重则导致磁盘组无法mount。rebalance是ASM自带的在线数据重分布机制。它的核心动作是把数据extent从源磁盘读出来按照磁盘组的冗余策略重新写入目标磁盘同时更新ASM元数据中的extent指针最终释放源磁盘上的空间。整个过程对数据库透明业务SQL感知不到数据正在搬家这是它相比停库-备份-还原最大优势。1.2 rebalance到底在平衡什么ASM管理空间的最小单位是AUAllocation Unit默认1MB一个磁盘组的每个磁盘会按AU进行编号extent由AU组成。在normal冗余模式下一份数据会有两个镜像副本分别放在不同的failure group里。当磁盘组中新增磁盘或者删除磁盘时磁盘组的空间分布出现不均衡。ASM后台会启动一个rebalance协调进程ARBn最多同时有几个并行协调器按照每个磁盘的目标空间权重重新计算extent的分布计划把部分extent从数据偏多的磁盘搬向数据偏少的磁盘。目标权重基于磁盘的可用空间和磁盘组的冗余策略算出尽量让每个磁盘最终承载的数据量趋于一致。这里的迁移不是整盘搬移而是按extent粒度、按需重分布。新加入的8块盘并不会简单地把旧盘的每个AU都复制一份而是根据新的分布计划搬移那些应该属于新盘的extent。这会在后台产生大量随机读和随机写但每一笔I/O的粒度都很小且完全可控。1.3 三种典型的rebalance迁移形态从实战角度看ASM磁盘迁移通常是以下三种情形之一替换存储新存储LUN挂载完毕后加入磁盘组然后从磁盘组中删除旧存储对应的磁盘让rebalance自动把数据搬完最后下线旧存储。磁盘组扩缩容容量不够了加盘或者磁盘故障需要移除通过add/drop操作触发rebalance让数据和容量同时调整到位。磁盘组间数据搬迁比如把业务数据从一个ASM磁盘组迁移到另一个新建的ASM磁盘组这种不能靠rebalance直接跨组搬需要借助expdp/impdp、RMAN备份恢复或DBMS_FILE_TRANSFER等方式但如果新磁盘组建立在同一批存储上也可以先建好新组再通过rebalance让新旧磁盘组里的数据重新铺开。无论哪种最终真正执行数据移动的都离不开rebalance本身区别只是触发方式不同。2. 动手之前必须做好的四项功课2.1 冗余模型决定了你最少要准备几块盘很多人在加盘时忽略了一个关键点磁盘组的冗余模型直接影响新盘是否真的能用来承载数据。external冗余外部镜像一般配合存储底层的RAID只需要磁盘组里至少有一块可用磁盘新加一块盘就能直接参与数据分布。normal冗余要求每个数据extent有两个副本且两个副本不能落在同一个failure group里。如果你新增的磁盘属于某个既有failure group那么rebalance时它只能和同failure group之外的磁盘配合存放镜像副本。high冗余类似副本数变成了三份。我在实际迁移中最常遇到的问题是新存储的LUN在操作系统层认出来以后没有正确配置ASM磁盘的failgroup归属。比如normal冗余的磁盘组里目标端所有新盘默认都归到同一个failure grouprebalance会尝试把两个镜像副本放到同一组物理磁盘上ASM虽然不报错但冗余保护等于失效了。一旦那组存储整体故障所有数据都找不回来。所以动手前先问清楚存储架构明确新LUN分布在哪些物理控制器、哪些物理故障域上并在建ASM盘时用FAILGROUP子句手动指定分组。还不够的话参考这个检查清单检查项说明磁盘组冗余类型v$asm_diskgroup.type确认是EXTERN/NORMAL/HIGH目标盘failure group数量v$asm_disk.failgroup确认新盘是否分布在至少2个故障组新盘可用空间是否满足磁盘组总数据量/冗余副本数再加20%~30%余量新盘路径在双节点是否一致RAC所有节点必须看到完全相同的磁盘路径和权限2.2 目标端磁盘的属主、权限与多路径确认ASM不认识普通操作系统设备名它必须能通过ASMLib、udev规则或者直接以AFDASM Filter Driver方式稳定访问磁盘。我在Linux环境下的标准做法用multipath -ll确认新LUN的多路径设备名比如/dev/mapper/3600a098038304a3733244b5351436341。根据多路径设备的wwid在/etc/udev/rules.d/99-oracle-asm.rules里写udev规则固定权限和属主为oracle:dba权限0660并设置ASM_DISK环境变量。在grid用户下执行/etc/init.d/oracleasm scandisks或者直接用asmcmd afd_scan扫描。这里最容易踩的坑是双节点udev规则不一致。我在一次迁移里发现节点1能正确识别所有新盘节点2只识别出一半rebalance执行到一半报ORA-15032: not all alterations performed原因就是节点2的udev规则里少写了一条路径。验证方式很简单# 在grid用户下执行 oracleasm listdisks # 或 asmcmd lsdsk --candidate两边节点输出的磁盘列表必须完全一致否则先别碰任何rebalance操作。2.3 空间核算到底需要多少新盘空间核算不能简单拿当前磁盘组已用空间当依据。因为rebalance搬移的是按冗余策略放大后的数据normal冗余下可用空间约为所有磁盘总容量的一半high冗余下约为三分之一。经验公式新盘可用总容量 ≥ 当前磁盘组已用物理容量 × 冗余放大倍数 × 1.2举例normal冗余的DATA磁盘组当前报告USABLE_FILE_MB是4TB实际物理已用是8TB左右两份镜像。要迁移目标端新盘新盘总物理容量至少需要8TB × 1.2 ≈ 9.6TB建议直接取10TB以上。如果预算有限低于这个水平rebalance会因空间不足停在中间磁盘组变成MOUNTED/UNBALANCED状态后续SQL也会受影响。补充一个查询语句迁移前把基线记录下来SELECT name, type, total_mb, free_mb, usable_file_mb, (total_mb - free_mb) AS used_mb FROM v$asm_diskgroup;2.4 在线迁移与停机窗口的取舍rebalance支持完全在线理论上不需要停业务但在I/O繁忙的生产库上rebalance会抢占一部分存储带宽可能导致业务SQL响应时间上升。如果你是第一次做这种迁移手上又没有什么回退预案建议选业务低谷期启动rebalance比如周末凌晨。如果条件允许我更推荐先在维护窗口做一次演练迁移把一块小磁盘加入一个不重要的磁盘组触发rebalance观察存储延迟和数据库等待事件的变化用实测数据决定生产迁移时ASM_POWER_LIMIT开多大。这是成本最低也最有效的风险评估手段。3. rebalance迁移的标准操作流程与SQL3.1 最常见场景先加新盘再删旧盘这是替换存储时最稳妥的做法顺序很关键先让新盘加入磁盘组、参与数据分布等rebalance完成后再执行旧盘删除。这样任何时刻磁盘组里的数据都至少保留全量冗余副本即使rebalance中途失败旧盘上的数据还在不会出现单一故障点。第一步向磁盘组添加新磁盘ALTER DISKGROUP DATA ADD DISK /dev/mapper/3600a098038304a3733244b5351436341 NAME data_new01, /dev/mapper/3600a098038304a3733244b5351436342 NAME data_new02, /dev/mapper/3600a098038304a3733244b5351436343 NAME data_new03 FAILGROUP fg_new01;如果目标盘分布在多个存储故障域需要分多个FAILGROUP添加ALTER DISKGROUP DATA ADD DISK /dev/mapper/3600a098038304a3733244b5351436344 NAME data_new04 FAILGROUP fg_new01, /dev/mapper/3600a098038304a3733244b5351436345 NAME data_new05 FAILGROUP fg_new02;不加FAILGROUP的时候ASM会为新盘自动分配failgroup通常是每块盘一个独立failgroup这在大多数场景下没问题但会导致故障域碎片化不推荐长期使用。第二步确认添加后rebalance已经完成SELECT group_number, operation, state, power, sofar, est_work, est_minutes FROM v$asm_operation;当查询结果为空说明rebalance结束这时候才执行旧盘删除ALTER DISKGROUP DATA DROP DISK data_old01; ALTER DISKGROUP DATA DROP DISK data_old02;也可以一次指定多块盘一起撤ALTER DISKGROUP DATA DROP DISKS IN FAILGROUP fg_old01;这里说个细节DROP DISK之后ASM会自动触发rebalance不需要额外再写一句REBALANCE语句。但如果你希望把drop和rebalance拆开控制可以加NO REBALANCE子句这个在12.2之后的版本才支持先把磁盘标记为要被删除等手动时机再执行rebance。这个特性在做分阶段迁移时很好用。3.2 磁盘故障场景下的FORCE DROP如果某块磁盘已经物理损坏ASM无法正常读取删除时需要加FORCEALTER DISKGROUP DATA DROP DISK data_bad01 FORCE;FORCE的含义是跳过正常盘上元数据的读取流程直接把这块盘从磁盘组元数据中摘除然后立即触发rebalance把这份盘上的extent从其他冗余副本恢复出来。务必记住FORCE DROP是一把双刃剑。如果磁盘实际还在线但I/O短暂超时你强制删除后ASM会把该盘的所有extent视为缺失从镜像副本恢复数据这个流程会显著加重其他磁盘的I/O负载。更危险的是如果normal冗余下另一份副本所在磁盘也有坏块强制删除后数据恢复会直接失败。所以做FORCE DROP前先确认-- 确认磁盘实际状态 SELECT name, path, state, mode_status, mount_status, total_mb, free_mb FROM v$asm_disk WHERE group_number (SELECT group_number FROM v$asm_diskgroup WHERE name DATA);如果磁盘状态是ONLINE、NORMAL说明它还能被ASM访问优先走正常DROP不要急着FORCE。只有确认状态为OFFLINE、ERROR或MISSING时才考虑FORCE。3.3 手动控制rebalance的POWER和时机某些场景下自动触发的rebalance可能不是你想要的节奏。比如你同时往两个磁盘组加盘我不建议让它们并行自动rebalance因为两个rebalance任务会同时抢占存储I/O数据库响应时间可能明显恶化。更好的方式是禁用自动rebalance改为手动精细控制-- 12c 可以把diskgroup.disk_repair_time调大同时关闭自动rebalance ALTER SYSTEM SET ASM_POWER_LIMIT0;ASM_POWER_LIMIT0意味着新增磁盘时不会自动启动rebalance磁盘组会进入UNBALANCED状态数据分布不均衡但读写完全正常。等到你规划的窗口再手动执行ALTER DISKGROUP DATA REBALANCE POWER 8;POWER的取值范围是0~11数字越大并行度越高、搬迁越快但对系统I/O压力也越大。通常生产环境建议从5~6开始观察存储延迟再逐步上调。另外还有一个实际用途如果rebalance运行过程中你发现压力过大可以实时改小powerALTER DISKGROUP DATA REBALANCE POWER 2;正在运行的rebalance任务会立即按新的POWER调整并行度不需要取消重来。这是rebalance做得很好的一个地方。3.4 跨磁盘组迁移的补充做法前面提过rebalance只能在同一个磁盘组内重新分布数据它飞不到另一个磁盘组去。真的要把数据从一个ASM磁盘组整体迁到另一个正规做法还是通过逻辑或物理导出导入。简单总结两条可靠路径如果源和目标都是同一个数据库实例管理的磁盘组用DBMS_FILE_TRANSFER把数据文件在ASM磁盘组之间复制再把表空间offline切换或者做数据文件的rename。如果数据量不大且时间窗口宽裕用expdp导出再impdp导入到目标表空间更稳妥还能顺便做一次逻辑层面的健康检查。数据文件级迁移使用RMANBACKUP AS COPYSWITCH DATAFILE是另一种非常成熟的方式本质上等于把数据文件复制到目标磁盘组后切换文件指针操作粒度比DBMS_FILE_TRANSFER更粗但更直观。换句话说如果你是想把整个磁盘组换掉最保险的流程是新建目标磁盘组 - 迁移数据文件/表空间 - 校验 - 下线旧磁盘组。单独依赖rebalance做不到跨组的自动搬迁。4. rebalance运行中的实时监控与调速4.1 用v$asm_operation看进度rebalance开始后最直接的观察视角是v$asm_operation。字段不多但每个都有实际意义字段含义我关注什么OPERATIONREBALANCE / RESYNC / COMPACT确认当前动作类型恢复盘时也常看到RESYNCSTATERUNNING / WAITING / DONEWAITING说明可能在等I/O或有锁等待POWER当前实际运行功率是否和设置的power一致SOFAR已完成的AU/extent数量和EST_WORK对比估算进度EST_WORK预估总工作量如果持续增大说明数据还在变化或计划在调整EST_RATE每秒处理速率单位为AU/s乘以AU大小就是吞吐EST_MINUTES预估剩余分钟数数值不更新时不要慌大对象搬移可能长时间显示同值常用实时查询SELECT dg.name AS diskgroup, o.operation, o.state, o.power, o.sofar, o.est_work, ROUND(o.sofar / o.est_work * 100, 2) AS pct_done, o.est_minutes FROM v$asm_operation o JOIN v$asm_diskgroup dg ON dg.group_number o.group_number;注意rebalance的进度百分比不是线性变化的。前半段往往很快因为大量小extent迁移起来轻松后面越到尾巴越慢因为剩下的可能是比较大的数据文件extent单次搬迁粒度大而且I/O路径上还要和业务争抢资源。不要因为进度卡在80%多就以为hung住了先看EST_RATE是否仍在跳动再判断是否正常。4.2 ASM_POWER_LIMIT和实例级参数调整ASM_POWER_LIMIT是ASM实例级参数表示磁盘组在没有显式指定power时自动rebalance使用的默认功率。它也在v$asm_operation.power中反映。调整方式-- ASM实例中执行 ALTER SYSTEM SET ASM_POWER_LIMIT8;这个参数只影响后续自动rebalance的初始power不影响执行中的任务。想改执行中的任务还得用ALTER DISKGROUP ... REBALANCE POWER n。如果迁移量大、时间紧把power直接拉满到11理论上最快但存储控制器可能被打爆。我习惯先开到8观察5~10分钟v$asm_operation.est_rate和存储延迟est_rate持续上升说明存储还能扛保持或再往上调。est_rate不涨甚至下降说明存储侧已经饱和往回调低别硬刚。另外别忘了同一节点上ASM实例后台的ARB进程数量也受ASM_POWER_LIMIT影响这个参数调整不需要重启alter system即可生效。4.3 多任务并发时的调度建议如果你的环境里同时存在多个磁盘组需要迁移我建议一次只跑一个磁盘组的rebalance。原因有两个一是ASM实例的ARB进程数量有限多个磁盘组同时rebalance会平分这些进程单任务的有效吞吐反而下降每个任务的完成时间被拉长整体来看并不省时。二是排查困难。两个rebalance任务同时报错时alert日志里几百行ORA-15155、ORA-15032来回穿插定位问题的时间可能比迁移本身还长。真要并行也尽量把不同任务错开在不同power级别比如DATA组用power 6、FRA组用power 3这样至少能保证核心磁盘组优先完成。-- 推荐顺序先跑DATA等完成后再跑FRA ALTER DISKGROUP DATA REBALANCE POWER 8; ALTER DISKGROUP FRA REBALANCE POWER 4;4.4 等待时间过长的排查思路我见过很多次rebalance任务运行十几个小时没结束排查思路大概是这样的流程先看v$asm_operation.state是RUNNING还是WAITING。WAITING往往说明ARB进程在等待某个I/O完成或者有磁盘被OFFLINE后进入等待恢复状态。看ASM实例的alert_ASM1.log关键字rebalance、ORA-15确认是否出现磁盘离线事件。看v$asm_disk_stat里是否有磁盘状态异常OFFLINE、ERROR、MISSING。用OS层的iostat -x 5检查是否有磁盘util达到100%。如果某个磁盘组同时有磁盘在FORCE DROP后的恢复流程rebalance会等待recovery完成这时磁盘组可能处于MOUNTED 0/1或DEGRADED状态不要直接干预先确认恢复进度。上面几层查完大多数卡住的rebalance都能找到具体原因而不是盲目重启ASM实例。5. 迁移中的踩坑记录与最终验证5.1 坑一新盘没有划分好failure grouprebalance后冗余失效这是我自己踩过最复杂的一次。当时连存储工程师都没注意到新存储LUN虽然来自不同控制器但操作系统层看到的wwid被存储虚拟化产品统一成了同一路径前缀。我在添加磁盘时图省事没有手动指定FAILGROUP结果ASM把8块新盘全部划进了同一个自动failgroup。rebalance完成后v$asm_diskgroup.usable_file_mb比预期的多了一倍不止看起来空间变多了实际是因为normal冗余变成了只有名字上的normal实际所有镜像都堆在同一物理故障域。后来我通过v$asm_disk.failgroup检查才真相大白。修正方法是先把新盘从磁盘组删除再按正确的failure group重新加回ALTER DISKGROUP DATA DROP DISK data_new08; ALTER DISKGROUP DATA ADD DISK /dev/mapper/3600a098038304a3733244b5351436331 NAME data_new08 FAILGROUP fg_ctrlA;再强调一次迁移前先花十分钟确认目标盘的failgroup分布比迁移后花三个小时修数据安全值钱得多。5.2 坑二POWER开太大存储I/O打爆数据库出现latch等待有一次我把ASM_POWER_LIMIT直接设成11结果不到五分钟应用侧开始密集报错AWR里top event全是latch: cache buffers chains和db file sequential read存储的写延迟从1ms飙到40ms。问题不是ASM本身bug而是rebalance在极短的时间内对同一批热数据extent发起了大量读改写操作挤占了业务SQL的I/O带宽。当时我的处理方式是ALTER DISKGROUP DATA REBALANCE POWER 2;等业务恢复平稳再把power慢慢往上调。记住rebalance的POWER不是一个设了就万事大吉的静态值它需要你结合存储负载和数据库等待事件动态调整。5.3 坑三rebalance期间硬盘离线触发磁盘组重新挂载rebalance本身的数据搬移会制造持续的大量I/O如果某块老磁盘本身已经有坏道或者链路不稳定在rebalance的高压之下很容易直接离线。ASM遇到磁盘离线后的默认行为是把盘标记为OFFLINE然后启动disk_repair_time倒计时默认3.6小时在计时结束前如果盘恢复上线会执行RESYNC增量恢复。这里有一个隐藏风险如果你的旧盘是因为rebalance的负载才离线的它很可能在倒计时快结束时又自己回来然后触发一次全盘RESYNC又给系统来一轮I/O高峰。我后来的处理策略是迁移前先对源存储做一轮巡检把有隐患的磁盘提前从磁盘组剔除开始rebalance前把disk_repair_time调短比如30分钟避免坏盘反复横跳如果确实遇到离线盘不要盲目把它加回来先判断是链路抖动还是盘真坏了。ALTER DISKGROUP DATA SET ATTRIBUTE disk_repair_time 1800s;5.4 最终验证确认数据分布与磁盘组状态rebalance跑完后不能只看v$asm_operation没记录就撒手。我有一张固定的验证清单确认磁盘组状态SELECT name, state, type, total_mb, free_mb, usable_file_mb FROM v$asm_diskgroup;期望看到stateMOUNTEDfree_mb和usable_file_mb符合预期。确认每块盘的状态和failgroup分布SELECT group_number, name, path, state, mode_status, failgroup, total_mb, free_mb FROM v$asm_disk ORDER BY group_number, name;确认磁盘组数据分布均匀SELECT dg.name, d.name AS disk_name, d.total_mb, d.free_mb, (d.total_mb - d.free_mb) AS used_mb, ROUND((d.total_mb - d.free_mb) / d.total_mb * 100, 2) AS used_pct FROM v$asm_disk d JOIN v$asm_diskgroup dg ON dg.group_number d.group_number WHERE dg.state MOUNTED;正常状态下同组各盘的used_pct应该相差不大这是rebalance生效最直观的证据。在asmcmd下检查版本和磁盘路径asmcmd lsdg asmcmd lsdsk -k最后确认数据库侧没有file在磁盘组切换后报错检查alert日志中是否出现ORA-00603、ORA-15032、ORA-15040等ASM相关错误码。5.5 老盘下线前别急着拔线rebalance完成后旧盘被drop出磁盘组ASM层面上已经不再使用它们。但我不建议立刻把存储映射从主机上卸载或把线缆拔了。稳妥做法是保留24到48小时让数据库稳定运行至少一天观察有没有慢SQL、报错日志或备份任务异常。毕竟rebalance只保证ASM层面的数据完整应用层有些历史连接、未提交事务可能还有文件句柄指向旧路径尽早拔盘会引发意外。我在一个案例里就见过数据库一切正常但备份脚本里硬编码了旧ASM磁盘路径rebalance后第30个小时才在备份日志里暴露问题。保留旧盘相当于给这种隐性引用留了补救窗口。5.6 迁移后的性能基线对比除了验证数据安全我还会做一次性能对比。rebalance不只是改数据分布还改变了每个磁盘上的热数据区域分布迁移后存储性能往往会有些变化。用AWR对比迁移前后的top wait event、DB Time、物理读平均延迟能快速发现是否有盘成为新的热点。我一般会在rebalance完成后一周内做两次AWR对比一次在业务高峰期一次在批量作业运行时段。如果发现某块新盘延迟明显高于同组其他盘再检查是不是该盘的磁盘数太少、failgroup划分不合理或者正好落在存储控制器的高负载分区上。这一步能避免数据搬完了性能却变差了的尴尬。6. 写在最后rebalance迁移这个操作值得掌握的真正原因动手做一次完整的ASM磁盘rebalance迁移之后你会发现它远不止执行一条SQL那么简单。它要求你对磁盘组内部结构有清晰认知对数据库I/O特征有实时感知对存储架构有基本判断力。很多初接触Oracle的DBA在存储替换时第一反应是RMAN全备加恢复这当然也走得通但代价是长时间停机而rebalance迁移提供了一条更平滑、可监控、可回退的路径。我个人在实际操作中最受益的习惯是每次迁移都先写一份预操作思维导图把磁盘组当前分布、冗余策略、目标盘路径、排查命令、回退方案全部列清楚然后才在维护窗口执行。这个习惯已经帮我避免了至少三次因遗漏failgroup配置导致的严重事故。如果你正准备做ASM磁盘迁移把这篇文章里的检查清单和坑位记下来动手前逐项过一遍。迁移本身不难难的是把每个细节都想到、做到、验证到。祝各位一次迁移成功业务零感知。
返回列表