凑也要把数据凑出来 -- 数据库损坏恢复
客户的数据库又损坏了
操作系统损坏, 重装后数据库文件无法附加, 报803错误, I/O error. 对着两个二进制的文件当然没辙, 除非专业修复Sql Server的公司可以直接分析文件结构搞定它, 首先就是先复制这两个文件到别的地方备份先, 万一呆会的修复工作弄错了, 想要原来的数据都没办法了.
接下来先让Sql Server能够把它装载起来再说吧. 只好使用瞒天过海的杀手锏了, 建一个新的相同名称, 相同物理文件的数据库, 然后停掉SQL服务, 用损坏的数据库文件覆盖上去, 重启服务, SQL SERVER挣扎了半天, 终于还是认为这个数据库是错误的, 在管理器里显示不出此数据库, 于是只能再来:UPDATE sysdatabases SET status = status ^ 32768 WHERE name = ...
数据库可以出来了, 当然是紧急置疑模式, 用DBCC(之前可能要设置为单用户)检查, 发现有4处不一致错误, 索引上的就不用管了, 大不了重装索引, 关键是找到哪些表损坏了, 然后才能知道如何去凑这些数据, 通过循环一遍, 用select全部数据测试, 发现有一个单据表数据损坏, 无法全部select, 那么我现在要的就是它同步之后增加的数据, 用创建日期倒排序找后几条, 幸好这些数据不在坏的页面, 可以取出, 先不管, 用select into扔到pubs数据库里先存着. 其它未损坏的数据我要挪过去的话, 继续用刚才的循环执行数据来一遍select, 不过这次要into到新数据库去了, 尽管表的索引主键这些都不会在新数据库是创建, 但数据先过去再说, 然后sqldelta出山, 同步数据库结构, 这样sqldelta也不会发生使用临时表同步数据的方式, 保证了我的rowguid列里的值不被修改
到此为止, rowguid列的属性仍然没有修改过来, sqldelta无法处理这种情况, 损坏数据的表仍然未在新库中创建. 先修改rowguid属性吧, 照样来个大循环, 使用alter table alter column add rowguid就行了, 再从数据中心把这个分公司的单据表全部select into过来, 再从刚才的pubs临时表中它未同步的数据也select into where id not in ()过来, 然后用把这个表结构用刚才的方法搞定, 重建数据同步, 然后用我原来的修改数据但不影响数据的SQL以便让它再次收集所有行为数据更新, 再次向数据中心同步一次.
评论Feed: /feed.asp?q=comment&id=1423

