SQLServer恢复表级数据

原文:SQLServer恢复表级数据

       最近几天,公司的技术维护人员频繁让我恢复数据库,因为他们总是少了where条件,导致update、delete出现了无法恢复的后果,加上那些库都是几十G。恢复起来少说也要十几分钟。为此,找了一些资料和工作总结,给出一下几个方法,用于快速恢复表,而不是库,但是切记,防范总比亡羊补牢好。

       在生产环境或者开发环境,往往都有某些非常重要的表。这些表存放了核心数据。当这些表出现数据损坏时,需要尽快还原。但是,正式环境的数据库往往都是非常大的,统计数据表明,1T的数据库还原时间接近24小时,所以因为一个表而还原一个库,不单空间,甚至时间上都是一个很大的挑战。本文介绍如何恢复单表,而不需要恢复整个库。

       现在假设一个表:TEST_TABLE。我们需要尽快恢复这个表,并且把恢复过程中对其他表和用户的影响降到最低。

       SQLServer(特别是2008以后),具有很多备份及恢复功能:完整、部分、文件、差异和事务备份。而恢复模式的选择严重影响备份策略和备份类型。

       下面是几个可供参考的方案,但是记住,各有好坏,应该按照实际需要选择:

方案1:恢复到一个不同的数据库:

        这对于小数据库来说不失为一种好的办法,用备份还原一个新的库,并把新库中的表数据同步回去。你可以做完整恢复,或者时间点恢复。但是对于大数据库,是非常耗时和耗费磁盘空间的。这个方法仅仅用于还原数据,在还原数据(就是同步数据)的时候,你要考虑触发器、外键等因素。

方案2:使用STOPAT来还原日志:

       你可能想恢复最近的数据库备份,并回滚到某个时间点,即发生意外前的某个时刻。此时可以使用STOPAT子句,但是前提是必须为完整或大容量日志恢复模式。下面是例子:

RESTORE DATABASE 需要恢复的数据库
 FROM 数据库备份
 WITH FILE=3, NORECOVERY ;

RESTORE LOG需要恢复的数据库
 FROM数据库备份
 WITH FILE=4, NORECOVERY, STOPAT = 'Oct 22, 2012 02:00 AM' ;

RESTORE DATABASE 需要恢复的数据库 WITH RECOVERY ;

注意:这种方法的主要缺点是会覆盖掉从stopat指定时间点之后所修改的所有数据。所以要衡量好得失。

方案3:数据库快照:

       创建数据库快照。当发生意外时,可以从快照中直接获取原来的数据。但是必须是在发生意外之前创建的快照。这在核心表不经常更新,特别是有规律更新时很有用。但是当表经常、不定期被更新,或者很多用户在访问时,这种方法就不可取了。当需要使用这种方法时,记得在每次更新前先创建快照。

方案4:使用视图:

       你可以创建一个新的数据库,并把TEST_TABLE移动到这个库里面。当你需要恢复的时候,你只需要恢复这个非常小的数据库即可。访问源数据库的数据时,最简单的方法就是创建一个视图,选择TEST_TABLE表中所有列的所有数据。但是注意这个方法需要在创建视图前,重命名或者删除源数据库的表:

USE 需要恢复的数据库 ;
GO
CREATE VIEW TEST_TABLE
AS
    SELECT  *
    FROM    备份数据库.架构名.TEST_TABLE ;
GO

      使用这种方法,可以对视图使用SELECT /INSERT/UPDATE/DELETE语句,就像直接操作实体表似得。当TEST_TABLE更改时,要使用SP_REFRESHVIEW存储过程来更新元数据。

方案5:创建同义词(Synonym):

      和方案4类似,把表移到另外一个数据库,然后对源数据库的这个表创建一个同义词:

USE 需要恢复的数据库 ;
GO
CREATE SYNONYM TEST_TABLE
FOR 新数据库.架构名.TEST_TABLE ;
GO

       这个方法的有点就是你不需要担心元数据更新所带来的结构变更不及时。但是这个方法的问题就是不能在DDL语句中引用同义词,或者不能在链接服务器中找到。

方案6:使用BCP保存数据:

       你可以创建一个作业,使用BCP定期导出数据。但是这种方法的缺点和方案1类似,需要找到哪天的文件并导进去,同时要考虑触发器和外键问题。

各种方法的对比:

方法 优点 缺点
还原数据库 快且容易 适用于小库,且要注意触发器和外键等
还原日志 能指定时间点 所有时间点后的新数据会被覆盖
数据库快照 当表不是经常更新时很有用 当表并行更新时,快照容易出现问题
视图 把表的数据于库分开,没有数据丢失 元数据需要周期性更新,并要定期维护新数据库
同义词 把表的数据于库分开,没有数据丢失 在链接服务器上不能用,并要定期维护新数据库
BCP 拥有表的专用备份 需要额外的空间、还会出现触发器、外键等问题

总结:

        良好的编程习惯和良好的备份机制才是解决问题的根本,以上的措施都仅仅是一个亡羊补牢的办法。可能有人说SQLServer 新版本不是有部分还原吗?我们来看看联机丛书的说明:

可以看到,其他这种方法很难还原一个表,但是当库小的时候,倒可以试试。

时间: 2024-07-29 06:18:28

SQLServer恢复表级数据的相关文章

SQLServer恢复表级数据详解

最近几天,公司的技术维护人员频繁让我恢复数据库,因为他们总是少了where条件,导致update.delete出现了无法恢复的后果,加上那些库都是几十G.恢复起来少说也要十几分钟.为此,找了一些资料和工作总结,给出一下几个方法,用于快速恢复表,而不是库,但是切记,防范总比亡羊补牢好. 在生产环境或者开发环境,往往都有某些非常重要的表.这些表存放了核心数据.当这些表出现数据损坏时,需要尽快还原.但是,正式环境的数据库往往都是非 常大的,统计数据表明,1T的数据库还原时间接近24小时,所以因为一个表

通过sqlserver日志恢复误删除的数据

原文:通过sqlserver日志恢复误删除的数据       如果你已经急的焦头烂额,看到这篇文章的时候,请你换个坐姿,深呼吸几次,静下心来将这篇文章读完,也许你的问题迎刃而解.     我遇到的情况是这样的,网站被植入木马,盗取了我的web.config文件,web.config文件里面的数据库连接字符串没有加密,而我的数据库远程连接又没有做IP限制,黑客通过数据库客户端连上我的数据库后,将所有的表都Delete掉了,所以大家一定要有一个好习惯将数据库连接字符串加密或者对远程访问数据库的IP作

select-winfrom中如何把SqlServer数据库表查询出来的数据插入access数据库表中

问题描述 winfrom中如何把SqlServer数据库表查询出来的数据插入access数据库表中 sqlserver里面的数据是根据条件查询出来的,现在是把查询出来的数据,给他导入到access数据库中,但是不知道在C#后台中怎么写 跨数据库去执行insert select,求解啊啊啊啊啊啊 解决方案 大概的代码 DataTable table = new DataTable() SqlConnection sqlconn = new SqlConnection(connectionStr);

sql server-c# sqlserver 查询两个表中数据用datagridview 显示出来 老师出错 求大神指导

问题描述 c# sqlserver 查询两个表中数据用datagridview 显示出来 老师出错 求大神指导 string sql = " select a.2, a.3, b.2, b.3 from a, b, c where a.1= c.1 and b.1 = c.1 "; //查询语句太长 我就直接把意思表达出来 没有粘代码 DataSet ds1 = new DataSet(); DataTable dt = new DataTable (); DataSet ds2 =

验证数据是否重复-sqlserver 检查一张表的数据是否重复,在线等!!!

问题描述 sqlserver 检查一张表的数据是否重复,在线等!!! 我的表结构如上图,其中三个外键,都是由用户自由选择输入的,我想在用户点击保存的时候来验证数据是否已经存在,其中为null值的也需要验证,保证每条数据这三个外键必须唯一不重复,请问SQL 语句怎么写? 解决方案 select * from productPrice t where productID=? AND ChannelID=? AND CustomerTypeId=? 解决方案二: 加一个unique验证就可以保证外键唯

使用热备份进行分时恢复----怎样通过归档逐步恢复以缩短数据迁移时间

备份|恢复|热备份|数据 使用热备份进行分时恢复 ----怎样通过归档逐步恢复以缩短数据迁移时间 Last Updated: Monday, 2004-11-15 10:32 Eygle         很多时候你可能遇到这样的情况:一个大型数据库的迁移,但是只有很少的停机时间,这看起来充满困难.可是我们可以通过各种方法来缩短停机时间. 本例适用于同平台.同版本数据库迁移. 在此情况下,我们可以通过一个热备份,应用归档恢复数据库到一个一致的状态,此时数据库可以被只读(read only)打开.之

如何使用JAVASCRIPT从sqlserver数据库中获得数据

javascript|server|sqlserver|数据|数据库 如何使用JAVASCRIPT从sqlserver数据库中获得数据? --------------------------------------------------------------- var conn = new ActiveXObject("ADODB.Connection"); conn.Open("Data Source=190.190.200.100,1433;Initial Catal

oracle手工完全恢复(三) 恢复表空间

案例2: recover tablespace(恢复表空间(删除了tablespace的所有的datafile)) 在关库状态下删除数据文件时,这样恢复:转储datafile,使丢失的datafile脱机, recover tablespace (1)模拟环境 SQL> conn scott/tiger Connected. SQL> col tname for a30 SQL> select * from tab; TNAME                          TABT

用Flashback功能恢复表中数据

这里只罗列出利用Oracle 9i R2的flashback功能来恢复一下某表中的数据的步骤,其实很简单. 首先如果数据库在归档模式下,我们可以通过查询v$archived_log视图来查看各个归档日志所属的检查点: select name,first_change#,next_change#,first_time from v$archived_log: 通过包dbms_flashback.get_system_change_number来获得数据库的SCN号,当然如果你的数据库是10g的话,