Cache中global被Kill后通过journal日志文件恢复

Cache中global被Kill后通过journal日志文件恢复

原文链接

如何通过日志恢复被删除的数据

修改后代码

Class WYJ.ToolsMethod Extends %RegisteredObject
{
/// Description: 通过journal日志文件恢复删除的global
/// Creator:      YX
/// Modify:       WYJ
/// Input:        filepath-journal文件全名,为空则打开最后一个journal(windos:d:\journal\journal\20230221.001
/// 			  globalName-要恢复的global名
/// 			  offset-开始偏移量
/// 			  end-结束偏移量
/// w ##class(WYJ.ToolsMethod).RestoreGlobal("d:\journal\journal\20230221.001", "^DHCINPO",22253844, 22255216)
ClassMethod RestoreGlobal(filepath As %String = "", globalName As %String, offset As %Integer = 0, end As %Integer = 100000) As %Status [ ProcedureBlock = 0 ]
{
	i filepath = "" {
		s filepath = ##class(%SYS.Journal.System).GetCurrentFileName()
	}
	s obj = ##class(%SYS.Journal.File).%OpenId(filepath)
	q:('$IsObject(obj)) "打开journal文件 "_filepath_"  失败,请检查日志文件名是否正确"
	q:(globalName = "") "目标global为空不允许恢复"
	
	# dim mSetKillRecordObj as %SYS.Journal.SetKillRecord
	#; 为空则从头开始找
	s:(offset = 0) mSetKillRecordObj = obj.FirstRecord
	s:(offset > 0) mSetKillRecordObj = obj.GetRecordAt(offset)
	
	#; 如果输入的Offset不存在,则寻找下一条记录
	s:(mSetKillRecordObj = "") mSetKillRecordObj = obj.GetRecordAfter(offset) 
	
	s currentAddress = offset
	while($isobject(mSetKillRecordObj) = 1)
	{	
		#; 说明已经是最后一条,退出循环
		q:($g(mSetKillRecordObj) = "") 
		#;说明已经是最后一个偏移量,退出循环
		if ((end '= "")&&(mSetKillRecordObj.Address > end)) {
			q
		}
		#; 过滤Begintrans\EndTrans\SET,只留下KILL
		if ((mSetKillRecordObj.TypeName '= "KILL"))  
		{
			#;跳到下一条记录
			s mSetKillRecordObj = obj.GetRecordAfter(mSetKillRecordObj.Address)
			continue
		}
		#; 取GlobalNode节点	
		s globalNode = mSetKillRecordObj.GlobalNode	
		#; 取global的名字
		s masterGlobal = $p(globalNode,"(",1) 
		#; 过滤非目标Global   如果主数据和索引global不一样这里可以改为判断包含关系
		if (masterGlobal '= globalName)  
		{
			#; 跳到下一条记录
			s mSetKillRecordObj = obj.GetRecordAfter(mSetKillRecordObj.Address)
			continue
		}
		
		#; 取新值,删除的话为空
		s newValue = mSetKillRecordObj.NewValue
		
		#; 取旧值,需要回复的数据
		s oldValue = mSetKillRecordObj.OldValue
		
		#; 取Global下标节点,也就是ID
		//s id = $qsubscript(globalNode, 1)
		
		#; 给ID赋值,否则ID顺序自增
		//s @masterGlobal = (id - 1)
		
		s str = "s "_globalNode _"="""_oldValue_""""
		//重新set global x 前建议先把 str write出来看下对着没
		w str,!
		x str    //确定没问题了再放开
		s mSetKillRecordObj = obj.GetRecordAfter(mSetKillRecordObj.Address)	
		
	}
	q $$$OK
}
}

希望以后不要再用到了…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值