设为首页 收藏本站
查看: 868|回复: 0

[经验分享] SQL SERVER Undelete 可能性探索(一)Clustered Table-SqlWorker

[复制链接]

尚未签到

发表于 2018-10-20 14:25:22 | 显示全部楼层 |阅读模式
  SQLSERVER中,如果数据被误删了,依照官方的说法,SQLSERVER是没有undelete的。要想救回被删除的数据,最典型的方法就是透过将备份档还原成另一DB,将数据从另一DB找回来后,再新增回正式的DB。
  不过,如果对于SQLSERVER的transaction log结构了解的人,只要交易纪录还在,就可以透过解析交易纪录来取得被删除的数据,再将数据Insert回DB。只是transaction log的解析有点复杂。这也是个值得探讨且有趣的主题。如果可以,或许可以找时间来谈谈这个。
  其实还有一种方法….
  SQLSERVER在执行delete的时候,它并不是真正立即将数据从page中抹除。它只是先将它「标记」为删除,这时候从逻辑上来看是已删除了(查不到了),但实际上数据还存在,这时我们称此笔纪录为 Ghost record。
  注:
  SQLSERVER的「标记」删除,在clustered table及heap table标记方法是不一样的。
  真正的将数据清除(purge),是由GhostCleanuptask这支系统线程来做,它大约每5~10秒钟会被唤醒一次,去真正地清除Ghost record。不过,为避免造成系统忙碌,它每次只会检查或清除有限数量的页面(应该是10 pages)。
  所以从delete commit,到数据真正被清除。中间是有一个缓冲期的。
  有了这样的一个缓冲期,就给了我们一个可以Undelete的机会。
  首先,最要紧的是,当发生误删的时候,必需尽速执行下列指令,停用Ghostcleanuptask。以免资料被真的清除。
  dbcc traceon(661,-1)   --暂停Ghostcleanuptask
  以下我们做一个简单的Undelete测试
  Clustered Table undelete Testing
  建立一个测试数据库,一并建立clustered index及non clustered index,并新增10笔数据
  create database testghost
  go
  use testghost
  go

  create table testtbl(c1 int>  go

  create index>  go
  insert into testtbl values
  (1,'aaaa'),(2,'aaaa'),(3,'aaaa'),(4,'aaaa'),(5,'aaaa'),
  (6,'aaaa'),(7,'aaaa'),(8,'aaaa'),(9,'aaaa'),(10,'aaaa')
  检查该table的page情况
  exec master.dbo.[GetPagRowCount] 'testghost','testtbl',-1
  注:GetPagRowCount是我自写的proc,只是方便查阅各page的数据,也可以用dbcc page去查.
DSC0000.png

  接着删除 c1=5 的数据
  delete from testtbl where c1=5
  执行select查询,已经查不到数据了
DSC0001.png

  假设C1=5为误删数据,我们开始做undelete...
  暂停  Ghost cleanup task
  dbcc traceon(661,-1)
  使用procedure去检查testtbl的page信息。可以看到 clustered页面跟index页面有Ghost record产生了。由于这里只有一笔Ghsot record,所以我们几乎可以确定被误删的数据存放的位置为pageid 78,这也是要undelete的目标页面。(这样的定位方式,可能会有不准确的问题,最好的方法是透过fn_dblog()去取得误删的PageID,再用这个procedure,两者结果比对,就不会错了)
DSC0002.png

  PageID确定后,接下来要确定出该笔数据所在的SlotID,
  我们透过dbcc page,看它的实体纪录,从record_type可以看出来。Slot 4是Ghost record
DSC0003.png

  至此我们可以确定 PageID 78,SlotID 4,是我们要Undelete的目标。
  这是一个 Clustered table,它的标记删除的方法,是在那笔Row 的第一个byte中加入识别的bits,以标记是Ghost record(heap table则不一样)。
  ------------------------------------------------------------------------------------------------
  Row的第一个Byte,由0开始从右边数来第1~3的位,换算成十进制,代表的意义如下:
  0(data record)
  1(Forwarded record)
  2(a forwarding stub)
  3(Index record)
  4(blob fragment or row overflow data)
  5(ghost index record)
  6(ghost data record)
  7(ghost version record)
  -------------------------------------------------------------------------------------------------
  最后利用二进制编辑器,去找到DB的PageID 78,SlotID 4,将第一个byte的Ghost record识别位(十进制6),改成正常的数据位(十进制0)。
  改完之后,再次执行select 查询,资料已经可以查询的到了...
DSC0004.png

  我再检查page信息,发现它仍然被标示成Ghost record
DSC0005.png

  重建所有index...
  alter index ALL on testtbl rebuild
  再检查page信息,已经正常了
DSC0006.png

  不过,这样的改法会造成系统基底表的纪录跟data page的纪录不符,因此在执行dbcc checktable时会有错误。
  整个Clustered Table Undelete的过程,最后必需执行
  dbcc checktable(testtbl,repair_allow_data_loss)
  修复数据表,虽然是用repair_allow_data_loss但它不会造成数据漏失。
  最后别忘了将flag 661关闭
  dbcc traceoff(661,-1)
  SQL SERVER Undelete 测试成功~~
  以上的测试,主要在探索Undelete的可能性,这个测试证明了Undelete是可能的。不过要真正运用在OLTP的作业环境上,还有一段路要走。(异动量大、快速定位目标pageid/slotid、Downtime的问题)。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-624163-1-1.html 上篇帖子: 【VMC实验室】在QCloud上创建您的SQL Cluster(5) 下篇帖子: Python3实现PoC——wooyun-2014-070827(SQL注入)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表