• AWS MSSQL to PG


    背景介绍:

    公司业务完全在AWS 云上,因为历史原因和业务发展需要, DBA需要维护aws RDS的异构数据长期持续同步,AWS US的RDS(SQL Server 2016)有db1作为数据的源端,

    AWS CN的RDS(PostgreSQL 12)有db2 作为数据的目的端, 仅仅需部分表持续复制,可以将AWS US,AWS CN看做2朵物理分开的不同云。经过大量测试决定使用AWS DMS作为数据持续同步的工具。

    难点介绍:

    难点1:2朵跨地域的云网络受限。 通过拉专线解决。

    难点2:DMS 设计用于一次性迁移使用并不适合长期持续复制。

    难点3:DMS不稳定出错后需要重新完全加载数据。

    难点4:有10几张巨大表。

    难点5:DMS需要SQL Server端开启CDC来实现持续复制,DMS内部实现数据的获取/转换/分发完全是一个黑盒。

    难点6:RDS的CDC capture job 和CDC clean job权限有限制,对用户透明。

    难点7:每天的业务变更数据行不稳定,无法定一个合适的 CDC capture job 参数。

    难点8:通过调查和profile 发现DMS通过  fn_dblog函数获取SQL Server的变更,既要保证SQL server 维持一定量的日志不被截断,又要尽量保证SQL Server的日志文件使用量在一个合理大小范围内保证DMS task 高效。

    解决方案:

    难点1/3:研究发现 DMS与源端的流量远远大于DMS与目的端的流量,并且大部分DMS 问题发生在DMS 实例与源端之间。 经过测试发现把DMS 实例放在源端局域网内,更稳定,延迟更小。

    难点3:在SQL Server端设置JOB 不断的获取日志点,DMS task 2步同步数据的方式,1)FULL load 完全加载数据  2) DMS task 指定日志点的方式,可以选择靠前几小时的日志点进行持续复制变更数据。

                这样如果以后DMS task  发生了无法修复的错误,并不需要大量时间完全加载数据,我们只需要修改 把2)的日志点修改为发生错误前的日志槽点即可。

    难点4:和业务沟通发现巨大表中包含了全球数据但是CN 只需要CN部分的业务的数据. 在SQL Server端通过JOB 间隔性的把CN的数据分离出来到****_CN 表,只需要在DMS task中将****_CN表在目的端做一个rename回原表明即可。

    难点5/6/7/8:  研究发现如下

    CDC 相关的JOB 运行参数可以入下图方式获取,并且默然一天运行一次[CDC capture job] 来释放log这会导致拥有一个巨大log file,是DMS task 获取数据效率下降,可以使用本地实例验证猜想

    use [db1]
    go
    exec sys.sp_cdc_help_jobs

    DMS 内部运行原理如下图

     针对以上难点设计了一个procedure 来根据log file 空间使用量 梯段变更[CDC capture job] 的 maxtrans 和 maxscans的参数值,并运行[CDC capture job] 。 使 log file 始终保持在一个合理大小范围内。

    使用SQL agnet 定时调用改prodedure.  pridedure 的梯段值和 job 运行的评率可以根据情况调整满足各自的需求。

    step1 在对应源端的db创建procedure

    use [db1] 
    go 
    
    /*
    run demo:
    exec [dbo].[updba_Dynamic_cdc_capture_parameter]  
    get running record:
    select  * from dbo.dmsdba_capture_audit
    */
    alter proc [dbo].[updba_Dynamic_cdc_capture_parameter]    
    as     
    begin    
      set nocount on    
    
    	if object_id('dbo.dmsdba_capture_audit') is null
    	begin
    	  create  table dbo.dmsdba_capture_audit(
    		  intime datetime primary key,
    		  log_used_MB int,
    		  after_log_used_MB int,
    		  starttime datetime,
    		  endtime datetime,
    		  pollinginterval  bigint,
    		  maxtrans int,
    		  maxscans int
    	  )
    	 end
    	else
    	begin
    		delete dbo.dmsdba_capture_audit where intime<dateadd(DAY,-90,GETDATE())
    	end
    
      declare @log_used_MB int  ,@after_log_used_MB int
      declare @start datetime, @end datetime 
        
      select   @log_used_MB =FILEPROPERTY ( name , 'SpaceUsed' )/128    
      from sys.database_files with(nolock) where  type_desc='Log'    
    
      declare @pollinginterval_input bigint
    		,@maxtrans_input int
    		,@maxscans_input int
    
       
      if   @log_used_MB>5120 and @log_used_MB<10240
    	begin
    	  /* set parimeter for job  cdc.MyCadent_captur */  
    		select @pollinginterval_input=86399
    			,@maxtrans_input=10000
    			,@maxscans_input=2 		 		     
    	end
    
      if   @log_used_MB>=10240 and @log_used_MB<20480
    	 begin
    	/* set parimeter for job  cdc.MyCadent_captur */  
    		select @pollinginterval_input=86399
    			,@maxtrans_input=20000
    			,@maxscans_input=4 	 					   
    	 end		 
    
      if   @log_used_MB>=20480  
    	  begin
    	  /* set parimeter for job  cdc.MyCadent_captur */  
    		select @pollinginterval_input=86399
    			,@maxtrans_input=40000
    			,@maxscans_input=8   
    	  end    
    
      
    
       if   @log_used_MB>5120 
       begin
    
    
    	 declare @job_status1 nvarchar(200),@job_status2 nvarchar(200)
    
    		--run job capture job to get CDC data into ***CT, and then  release CDC log   
    		EXEC sys.sp_cdc_change_job @job_type = 'capture' ,@pollinginterval = @pollinginterval_input,@maxtrans=@maxtrans_input,@maxscans=@maxscans_input  	 		   
    		begin  try   
    		 exec sp_cdc_stop_job 'capture'    
    		end  try
    		begin catch
    			select 1
    		end catch	
    		 waitfor delay '00:00:05' 
    		 select @start=getdate()
    		 exec sp_cdc_start_job 'capture'  
    
    		 WHILE 1=1
    		 BEGIN
    			SELECT  @job_status1= NULL,@job_status2=null
    			select   @job_status1=scan_phase from  sys.dm_cdc_log_scan_sessions 
    			where start_time>=(select max(start_time) from sys.dm_cdc_log_scan_sessions )
    			waitfor delay '00:00:05'
    			select   @job_status2=scan_phase from  sys.dm_cdc_log_scan_sessions 
    			where start_time>=(select max(start_time) from sys.dm_cdc_log_scan_sessions )
    
    			IF 	@job_status1=N'Done' and @job_status2=N'Done'
    				BREAK
    			WAITFOR DELAY '00:00:05'
    
    		 END
    
    		select   @end=getdate(),@after_log_used_MB =FILEPROPERTY ( name , 'SpaceUsed' )/128    
    		from sys.database_files with(nolock) where  type_desc='Log' 	
    	
    		insert into dbo.dmsdba_capture_audit(intime,log_used_MB,after_log_used_MB,starttime,endtime,pollinginterval,maxtrans,maxscans)
    		select getdate(), @log_used_MB,	@after_log_used_MB,@start,@end,@pollinginterval_input,@maxtrans_input,@maxscans_input
    		 
            --after capture data, run clean job to clean ***CT table
    		begin  try   
    		 exec sp_cdc_stop_job 'cleanup'    
    		end  try
    		begin catch
    			select 1
    		end catch	
    		 waitfor delay '00:00:05' 
    		 exec sp_cdc_start_job 'cleanup' 	
    
    		--finally  change @maxtrans/@maxscans back to a small value to maksure dms do not lost log
    		EXEC sys.sp_cdc_change_job @job_type = 'capture' ,@pollinginterval = 86399,@maxtrans=5,@maxscans=2   
    		begin  try   
    			exec sp_cdc_stop_job 'capture'    
    		end  try
    		begin catch
    			select 1
    		end catch	
    		waitfor delay '00:00:05' 
    		exec sp_cdc_start_job 'capture'  
    	end
    end
    
    
    GO
    

      step2 创建 JOB 根据需要定时运行 procedure  updba_Dynamic_cdc_capture_parameter

     

  • 相关阅读:
    由数字三角形问题理解动态规划
    堆排序
    清理oracle数据库空间
    十个常用破解网络密码的方法
    说说windows下64位程序和32位程序
    sql server使用第二记
    手机通讯录PK
    sql server 初级实践记
    You and your research ( Richard Hamming) P5
    TED
  • 原文地址:https://www.cnblogs.com/llgg/p/14545866.html
Copyright © 2020-2023  润新知