尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Sybase Replication Server实战:搭建、调优与高频避坑指南

Sybase Replication Server实战:搭建、调优与高频避坑指南 简介Sybase Replication Server高级使用与故障处理指南面向数据库运维工程师、系统管理员及需要维护分布式数据复制环境的从业者重点解决复制队列阻塞、服务器迁移、权限配置等常见问题。资源为docx格式共1个文件压缩包约68KB内容精炼但覆盖全面已有58人学习下载。文档从配置优化入手说明复制分区大小宜设为数据流量6倍一般2GB、最大线程数应大于连接数的两倍加3、适当增加复制内存等调优建议同时强调专用sa用户创建、RSSD_prim权限、RSM客户端连接等关键注意事项。针对复制服务器迁移梳理断开复制代理、静止队列、删除重建分区、归零第二截断点等完整操作顺序对DSI线程异常导致的队列阻塞给出连续执行resume connection跳过事务、通过admin who/sqt定位并清空问题队列的排错思路。常用命令如admin health、rs_config、resume connection亦一并汇总无论是日常维护还是故障应急均可作为实用操作参考。1. Sybase Replication Server是异步分发的好手先搞清它解决什么刚接触Sybase Replication的同事很容易把它当成一个“把主库整个复制到备库”的黑匣子装完RepServer配好连接就以为万事大吉。实际跑两轮就会发现它不复制整个库只复制你显式标记过的表它不做实时强一致同步而是基于日志的异步分发。这个差别决定了所有后续配置和调优的走向。Sybase Replication Server下文简称RepServer适合报表库分流、跨机房数据汇总、多级分发这类场景不适合拿来做要求读写强一致的横向扩展。它的价值在于主库事务提交后RepAgent异步读取日志并转发给RSRS再把指令重放到订阅端。整个链路不阻塞主库事务代价是目标端数据天然有一段时间延迟。想用好它先接受这个“异步”前提。2. 搭一套最小Sybase复制环境从RepServer初始化到第一条订阅生效2.1 先把链路角色分清楚主库、RepAgent、RepServer、DSI很多人第一次排错时被一堆术语绕晕其实这条链只有四个角色。主库ASE上必须启动一个叫RepAgent的进程它专职读取主库事务日志把被标记表的变更整理成复制消息。这些消息先落入RepServer本地的稳定队列再由RepServer分发给目标端。目标端上真正干活的是DSI进程它把消息转换成SQL语句或命令批量应用到订阅表。为什么要多绕一层队列而不是让RepAgent直接写目标端因为队列给了整个系统解耦能力目标端短暂不可用、表被锁、网络抖动时复制消息不会丢而是积在稳定队列里等DSI恢复后继续消费。这个设计也带来了一个常见坑——队列所在磁盘空间不够。因此选型时RepServer所在服务器的磁盘IO和空间重要性不亚于CPU。我自己见过的最短稳定链路是主库ASE 一个RepAgent 一个RepServer 一台目标ASE。三台机器各司其职不要图省事全放一台机器否则日志磁盘和稳定队列抢IO复制延迟会变得非常难看。2.2 用rs_init初始化RepServer并配置主库连接常见做法是先安装好ASE和RepServer二进制然后用rs_init创建RepServer的系统库和配置文件。rs_init是交互式工具填好RepServer名称、sa口令、主库连接信息这些基础项即可。它做两件事创建RepServer要用的系统库并生成启动脚本。初始化完成后用startserver启动RepServerstartserver -f RUN_REP_SRV然后用isql连上RepServer创建到主库的连接。这里的关键是把主库的库名、服务器名、登录用户名都写对-- 在RepServer上执行 create connection to ASE_SRV.mydb set username sa set password YourPass with log transfer on go这条命令的意思是RepServer要和主库ASE_SRV上的mydb数据库建立复制连接并打开日志传输。没有这一句后面建复制定义和订阅都会报“找不到主库”。口令填错时不会当场报错等到订阅激活后看DSI日志才发现连不上目标库所以连接创建后先执行admin who确认连接状态别急着往下配。2.3 建复制定义和订阅让第一张表开始复制连接通之后在RepServer上创建复制定义。复制定义相当于告诉RS“主库mydb里这张orders表这些列参与复制主键是order_id。”-- 在RepServer上执行 create replication definition rep_orders with primary at ASE_SRV.mydb with all tables named orders primary key (order_id) replicate columns (order_id, user_id, amount, create_time) go这里有两个细节值得注意。第一主键必须存在于参与复制的列里否则RS无法在目标端定位更新和删除第二replicate columns只列四列是一种常见优化减少日志消息体积和DSI执行成本。需要整表复制时省略replicate columns子句即可但通常不建议在宽表上这么做网络和队列压力都会上去。接下来建订阅订阅把复制定义绑定到目标库-- 在RepServer上执行 create subscription sub_orders for rep_orders with replicate at ASE_REP.reportdb go订阅创建成功意味着从这一刻起主库orders表上的新增、修改、删除都会异步落到目标库。最后还要回到主库ASE把这张表标记为可复制-- 在主库ASE上执行 use mydb go sp_setreplicate orders, true go这一步非常容易漏。漏掉的症状是复制定义和订阅都正常但主库上新写入的数据就是不动。原因是RepAgent只读取打上复制标记的表。把sp_setreplicate放在创建复制定义之后执行是为了避免表结构检查时出现“表未标记”的干扰性报错。跑完这几步用目标端查一下数据是否同步最小环境就算搭通了。3. 把复制参数调到长期稳定队列、DSI与日志保留的取舍3.1 复制不退化的前提主库日志要留得住RepAgent读主库日志读到哪里算到哪里主库才能把之前的日志截断。如果RepAgent因为网络问题、自身故障或消息过大一直没读主库日志会越积越满。Sybase ASE在日志满时会让写事务阻塞这在业务侧的表现就是“主库突然慢了但CPU不高”。常见的备份策略是定期dump transaction但配合Replication时要注意不要在主库上执行dump transaction with truncate_only来强行截断日志。这会让日志截断点越过RepAgent尚未读取的位置导致复制消息丢失。RepAgent要重新从头拉日志或重建订阅属于比较重的故障恢复动作。要让日志留得住核心思路不是加大日志空间虽然那也是必要措施之一。更稳妥的做法是监控RepAgent的推进状态一旦发现sp_rep_agent状态异常或者延迟读数超过阈值立刻处理而不是等日志满。把日志空间设成“够用三天高峰增量”是我见过比较稳的基线。3.2 DSI是吞吐瓶颈调指令批量和事务批量链路里最容易成为瓶颈的不是网络而是目标端DSI。DSI干的事是把复制消息翻译成SQL再提交到目标库。逐条提交效率太低所以RS提供了批量参数-- 在RepServer上执行 sp_configure dsi_cmd_batch_size, 500 godsi_cmd_batch_size控制DSI一次读取多少条消息作为一批。调大后吞吐量上升但目标端事务粒度变大锁持有时间也变长。如果是报表库这种低并发写入的环境调到500甚至更高都没问题如果目标端还有别的业务在写入建议从100起步观察锁冲突。相邻参数dsi_sql_batch_size控制的是一个批次内SQL文本的总字节数。两者是“条数和字节数哪个先到都触发提交”的关系。好消息是sp_configure改完对新连接生效不用重启RepServer。坏消息是正在跑的DSI连接不会自动收掉旧参数通常要等当前批次结束或者在一个维护窗口内重启复制更稳。3.3 一张表把关键参数列清楚调参最怕凭感觉乱改。我把日常排障中真正有用的参数整理成了一张表按生效范围分成RepServer侧和ASE侧。不同Sybase版本的默认值不完全一样所以表里不写死默认数字以你自己环境sp_configure的输出为准。参数所在侧作用调整建议dsi_cmd_batch_sizeRepServerDSI单批处理的消息条数目标端并发低可调大有锁冲突就调小dsi_sql_batch_sizeRepServerDSI单批SQL的字节上限事务大时设大避免一条大消息拆成多批dsi_in_orderRepServer是否按主库顺序提交默认保持顺序不要为提速关闭dsi_recovery_delayRepServerDSI恢复后重连目标库的间隔目标库重启后调小能加快恢复max repagent threadsASE主库RepAgent处理日志的线程数大变更量时调大配合CPU核数修改主库侧参数示例如下-- 在主库ASE上执行 sp_configure max repagent threads, 6 go调参后别只看状态不看数据。最有效的验证方式是选一张大表做批量UPDATE观察队列积压曲线和DSI吞吐是否匹配。如果队列积压一直在涨DSI却没满负荷问题多半不是参数太小而是目标端表缺索引导致每一条消息执行都很慢。这种时候调大批次数反而加剧锁竞争先给目标表上的主键和常用查询列建好索引再回头调参。提示dsi_in_order只在极少数目标端场景下值得冒险关闭。一旦关闭目标库的数据可能短暂乱序对外查询会出现瞬时不一致业务不能接受就别碰它。4. Sybase Replication高频坑与排查日志被截断、DDL丢失、重复键4.1 主库日志被截断延迟堆积与大事务回滚的起点现象白天复制延迟从秒级慢慢涨到小时级主库日志段报警最后业务写库开始失败。看RepAgent日志发现它反复尝试读取日志但推进不了。原因最常见的是有人对主库执行了dump transaction with truncate_only。这个命令在很多环境里被当作清理日志的快捷方式但在复制环境下它会破坏RepAgent的日志扫描连续性。另一种原因是RepAgent进程本身异常退出后未重启日志截断保护暂时失效。解决先重启RepAgent让日志扫描恢复然后立即确认日志空间余量-- 在主库ASE上执行 use master go sp_rep_agent mydb, status go如果已经出现日志满优先扩大日志段而不是强行截断日志。恢复后观察sp_rep_agent输出中最近一次扫描的日志页号是否持续向前移动。移动正常后队列里的积压会由DSI慢慢消化。这个坑的教训是复制环境下日志清理策略要交给RepAgent的状态决定不能为了腾空间无差别truncate。4.2 改了表结构不复制DDL的坑现象主库给orders表加了一个新列跑了半天目标端查不到这个列后续复制还报错。原因默认情况下RepServer的复制定义只管DML不管DDL。主库加列、删列、改类型这些操作不会自动传给订阅端。目标端表和复制定义的结构不匹配后DSI执行带新列的INSERT时就会报列无效。解决常见做法是把DDL做成双端执行的脚本。生产环境里更省事的方式是给DBA定一个规矩任何涉及复制表的结构变更先在目标库执行相同DDL再在主库执行。顺序不能反反了会有短暂的时间窗让主库把新结构消息发到还没改表的目标端。-- 先在目标库ASE_REP上执行 alter table reportdb..orders add remark varchar(200) null go -- 再在主库ASE_SRV上执行 alter table mydb..orders add remark varchar(200) null go如果已经翻车目标端必须手工补上缺失列然后让DSI从错误点继续。是否需要重建订阅取决于错误类型结构性报错一般补齐就好如果是数据级错位宁可重建订阅也别凑合。4.3 身份列重复与目标端触发器二次执行现象复制正常但目标端频繁报唯一键冲突或者明明没业务写目标表某些字段的数据被莫名改掉。原因第一类问题多半出在identity列。主库表的identity列值在INSERT时被RepAgent原样带过来如果目标端表也定义成identityASE会自动生成新值和RS带过来的值冲突或者下一次业务插入撞上已存在的值。第二类问题是目标端表的触发器还在生效DSI应用复制消息时触发了触发器触发器里又没有区分来源把数据又改了一遍。解决对于identity列目标端表结构不要用identity属性改成普通列让RS显式插入主库的值即可。对于触发器保留业务触发器没问题但要在触发器逻辑最前面加判断来源的代码create trigger trg_orders_noop on reportdb..orders for insert, update, delete as begin if is_replication_system 1 return end gois_replication_system是ASE提供的系统函数返回1表示当前会话来自复制系统。加上这支判断DSI的写入就不会触发连锁业务逻辑而正常业务写入不受影响。这个坑属于“配置时多写一行排障时少熬一晚”的典型。4.4 初始化不一致先灌数据还是先订阅现象订阅建好增量数据正常同步但目标端的历史数据和主库对不上差了一段。原因执行顺序错了。常见的错误做法是先在目标端用bcp把主库当前数据倒入目标表再创建订阅。这中间存在一个时间窗bcp导出的时刻和订阅生效的时刻不一致主库在这段时间内的增量没有被任何复制消息捕获。这个时间窗的缺口订阅恢复不了。解决标准化顺序是先确认主库日志不会在短时间内被截断然后对目标库做一次数据装载装载完成后立刻创建订阅让订阅接续装载起始时刻之后的日志。更稳妥的方式是利用ASE的dump database和load database做整库初始化这样目标库的物理快照和日志起点是对齐的。如果装载起点和订阅起点之间隔了太久宁可重做一次装载也别让数据带着缺口上线。5. 复制延迟到底卡在哪用admin命令把链路一段段拆开5.1 先确认RepAgent活着并定位读取日志的进度复制延迟是结果不是原因。排查时先看主库侧的RepAgent。用isql连主库ASE执行use master go sp_rep_agent mydb, status go输出里重点看RepAgent的运行状态和最近活动时间。如果状态不是active或者最近活动时间是几分钟之前说明RepAgent要么没起来要么在处理一个超大事务时卡住了。这时重启RepAgent并不能解决卡住的问题得先去主库日志里找有没有未提交的大事务。RepAgent读取日志的进度落后越多主库日志越危险所以这一步判断延迟时要尽量快。5.2 用admin who和admin disk_space看队列与DSIRepAgent活着且推进正常接下来看RepServer侧。用isql连RepServeradmin who, rsi go这个命令列出所有RepAgent连接。看连接状态是否正常以及最后转发消息的时间。紧跟着看DSIadmin who, dsi goDSI这里主要看两点是否处于running状态以及是否卡在一个长时间执行的批次里。如果状态是wait或blocked目标端很可能有锁竞争去目标ASE查一下sp_who确认。再看稳定队列的积压情况admin disk_space go输出会显示RepServer本地稳定队列各段的使用量。队列用量持续高位说明消息生产快于消费瓶颈在DSI一侧队列用量低但主库日志仍然增长很快说明RepAgent读取消息的速率没跟上写入速率方向在主库侧。结合admin disk_space和前面两段admin who基本能把延迟定位到具体环节而不是靠猜。5.3 延迟排查的顺序不要一上来就重灌数据给一套我实际用的排查流程按顺序走基本能锁定问题。第一步看主库日志空间和RepAgent状态第二步看RepServer队列积压第三步看DSI状态和目标端锁第四步看目标端错误日志中的DSI报错。# 主库ASE看日志空间和RepAgent isql -Usa -P密码 -SASE_SRV EOF use master go sp_rep_agent mydb, status go EOF# RepServer看连接与队列 isql -Usa -P密码 -SREP_SRV EOF admin who, rsi go admin who, dsi go admin disk_space go EOF# 目标ASE看锁与阻塞 isql -Usa -P密码 -SASE_REP EOF sp_who go EOF这套命令跑下来还没找到原因的情况极少。真遇到再去目标端库的SQL错误日志里翻DSI相关报错那里会有比admin输出更详细的错误号。整个排查过程十五分钟以内应该能定位不建议直接走重灌数据的路线重灌虽然见效快但可能掩盖真实原因下一轮故障还会来。提示稳定队列即使显示为空也不代表没有积压。DSI正在执行的大批次消息在admin disk_space里可能体现不出来要结合DSI的执行时间判断。6. 别动不动就drop subscriptioncheck subscription才是后悔药当目标表因为结构错位或数据缺口要重新对齐时很多人下意识先drop subscription再create subscription。这个操作的代价是如果目标表数据还在重新创建订阅并不会自动把历史数据补平反而可能让订阅起点变得难以界定。更好的做法是用check subscription来校验订阅一致性让RS重新确认订阅定义和目标表结构是否匹配。-- 在RepServer上执行 check subscription sub_orders for rep_orders with replicate at ASE_REP.reportdb go这个命令不产生数据搬运它只做元数据和状态校验。执行成功后订阅状态会被标记为一致之后增量继续正常复制。适用场景是目标表结构在双端已手工对齐、数据层面确认没问题只想恢复订阅关系的场景。如果数据确实有缺口check subscription不会帮你补必须先修数据再check。我在这上面吃过一次亏一次目标端表被运维误清空了一部分数据我直接drop并重建订阅结果新数据正常同步老数据的缺口让报表结果错了整整一周。后来改成先补数据、再check subscription再也没有因为重建订阅的起点问题返工。养成这个习惯后复制维护变得从容很多能不drop就不drop重建前先把数据修好再用check subscription把订阅拉回正常状态。希望这个技巧帮到你少走一次弯路。本文还有配套的精品资源点击获取
返回列表