事务复制
事务复制的基本机制,在联机文档上也有介绍。
基本原理
如图,主要依靠2个代理,1.日志读取代理(log reader agent),2.分发代理(distribution agent)。
其中log reader agent,负责从发布数据库上读取日志并且写入到分发数据库(distribution)中。然后distribution agent负责从distribution读取数据并且写入到订阅中。
Log Reader Agent
开profiler,使用tsql模板即可。在已经有复制环境的状态下,对发布项目执行:
BEGIN TRAN
go
INSERT INTO dbo.rename_sc DEFAULT VALUES
GO 10
COMMIT
最主要的部分:
如图,Log Reader Agent使用会话55去发布库的日志上读取事务,如果发现有需要分发的,那么会调用sp_MSadd_replcmds,这个存储过程会把抓到的指令存放到dbo.MSrepl_commands和MSrepl_transactions2个表中。然后就会使用过程sp_repldone标记事务已经被复制。
SELECT spid,program_name FROM sys.sysprocesses WHERE spid IN( 57,55)
在sql server中查询sys.sysprocesses 这2个spid 会发现program_name='Repl-LogReader-0-p1-9
也就是log reader agent在sql server 上有2个会话一个负责读,一个负责写。这样Log Reader Agent的一次读取完成。
Distribution Agent
Log Reader Agent写入完之后就是有Distribution Agent 把事务应用到订阅库。
获取事务
在存储过程sys.sp_MSget_repl_commands对表dbo.MSrepl_commands读取,之后就是在订阅服务器上面运行sp_MSins命令。
仔细观察其实不难发现msrepl_command表中存的是明码,通过和sp_browsereplcmds对比就能发现,那么也就是说其实在插入MSrepl_commands的时候就已经知道了。
但是这里有个问题Agent是怎么知道要调用这个存储过程的。
在这里会注意到有2个不同的会话在处理,一个负责读,一个负责写入,其中65负责从分发库中读取,51负责应用到订阅库
SELECT spid,program_name FROM sys.sysprocesses WHERE spid IN( 65 ,51)
修改订阅
最后会修改订阅服务器中的MSreplication_subscriptions中的一些字段,其中最终要的是timestamp,这个字段表示现在订阅已经应用到了那个事务。奇特的事情又出现,会发现有2个update语句。不知道是不是为了版本兼容。
UPDATE MSreplication_subscriptions
SET transaction_timestamp = CAST(@P1 AS BINARY(15))
+ CAST(SUBSTRING(transaction_timestamp, 16, 1) AS BINARY(1)) ,
"time" = @P2
WHERE UPPER(publisher) = UPPER(@P3)
AND publisher_db = @P4
AND publication = @P5
AND subscription_type = 1
AND( SUBSTRING(transaction_timestamp, 16, 1) = 0
OR DATALENGTH(transaction_timestamp) < 16
)
UPDATE MSreplication_subscriptions
SET transaction_timestamp = CAST(@P1 AS BINARY(15))
+ CAST(CASE DATALENGTH(transaction_timestamp)
WHEN 16
THEN ISNULL(SUBSTRING(transaction_timestamp, 16, 1), 0)
ELSE 0
END AS BINARY(1)) ,
"time" = @P2
WHERE UPPER(publisher) = UPPER(@P3)
AND publisher_db = @P4
AND publication = @P5
AND subscription_type = 1
Distribution Agent完成一次分发。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现