图片 3

事务日志概述,日志文件结构及误操作数据找回

  1.1  日志文件与数据文件一致性

一. 概述

方法1:
第一步:
backup log database_name with no_log
或者 backup log database_name with truncate_only
–no_log和truncate_only是在这里是同义的,随便执行哪一句都可以
第二步:
1.收缩特定数据库的所有数据和日志文件,执行 dbcc shrinkdatabase
(database_name,[,target_percent])–database_name是要收缩的数据库名称;target_percent是数据库收缩后的数据库文件中所要的剩余可用空间百分比
2.收缩一次一个特定数据库中的数据或日志文件,执行 dbcc
shrinkfile(file_id,[,target_size]) –file_id是要收缩的文件的标识
(ID) 号,若要获得文件 ID,请使用 FILE_ID 函数或在当前数据库中搜索
sysfiles;target_size是用兆字节表示的所要的文件大小(用整数表示)。如果没有指定,dbcc
shrinkfile 将文件大小减少到默认文件大小
两个dbcc都可以带上参数notruncate或truncateonly,具体意思看帮助。
方法2(这个方法在sqlserver2000的环境下做一般能成功,在sqlserver7及以下版本就不一定了):
第一步:
先备份整个数据库以备不测
第二步:
备份结束后,在Query Analyzer中执行如下的语句:
exec sp_detach_db yourDBName,true –卸除这个DB在MSSQL中的注册信息
第三步:
到日志的物理文件所在的目录中去删除该日志文件或者将该日志文件移出该目录
第四步:
在Query Analyzer中执行如下的语句:
exec sp_attach_single_file_db
yourDBName,’d:mssql7datayourDBName_data.mdf’
–以单文件的方式注册该DB,如果成功则MSSQL将自动为这个DB生成一个500K的日志文件。
以上方法在清除log日志中均有效。
但,能否让sql server 不产生log日志呢?以上方法好像均无效。
 
我这儿正好有个case:
我客户的sql
server每天都会产生4,500M的log日志,每天都清除一下,非常不便。有没有办法实现不产生log日志呢?
我分析了一下客户产生log日志的原因,并且做了相应测试。
客户是每天将数据库清空,从总系统中将数据导入到sql
server里。我感决sqlserver在插入时产生log不大,在delete整个库时产生log极大。
比如:
SELECT * into test_2 from b_bgxx
共45000条记录,产生十几M log,如果
delete from test_2
产生80多M log ,这明显存在问题。
虽然可以换成:
truncate table test_2
但我还是希望能找到不产生log的方法。就如oracle不产生归档一样。

 在上一章备份与恢复里了解到事务日志的重要性,这篇重点来了解事务日志。
事务日志记录了数据库所有的改变,能恢复该数据库到改变之前的任意状态。在sql
server实例每次启动时都会去检查数据文件与日志文件的一致性。
包括日志记录的任何已提交的数据必须体现在数据文件上,未被标记为已提交的将禁止写入数据文件,日志还存储了收到客户端回滚事务请求,sqlserver出错如死锁等,日志产生一个rollback命令。

  在sql server
里有数据文件.mdf和日志文件.ldf,日志文件是sqlserver数据库的另一个重要组成部分,日志文件记录了所有事务以及每个事务对数据库所做的修改。为了提高数据库的性能,
sqlserver
数据是缓存在内存里,并没有实时写入到磁盘,直到数据库出现检查点(checkpoint)或者内存不足必须(Lazy
Write)将数据的修改写入到磁盘。 sql
server在开启了事务并对内存中的数据进行修改时,会生成日志记录。 sqlserver
对数据页的插入修改删除都是在内存中完成后提交事务,但并不会同步到硬盘的数据页上。
为了保证数据库事务的一致性 如(服务器崩溃,断电)等
内存中的修改没有来得及写入硬盘,下次重启时候要能够恢复到一个事务一致的时间点,就必须依赖于事务日志。

   事务日志是在数据库创建或改变时与数据库关联起来的一个或多个文件。
任务改变数据库的操作都会在事务日志中写入描述这些改变的记录,包括要改变的页码,增加或删除的数据值,事务信息,起止的日期和时间信息等。通过dbcc
log可以看到如下信息

     1.1 存储结构

图片 1

  与数据文件不同
日志文件不是按页/区来进行组织的。每个物理日志文件是分成多个虚拟日志单元,虚拟日志单元没有固定大小,且数量不固定,
管理员也不能配置大小和数量。
例如:日志文件每自动增长一次(默认是按10%的空间扩展),会至少增加一个虚拟单元。

  sql server里每个日志记录都有一个唯一的日志序列号标识LSN,
同一个事务里的所有日志记录是一个连接起来的整体,这样能够容易的定位一个事务的各个部分,从而实现撤销undo或重做redo操作。

  事务日志是一种回绕的文件。例如一个数据库里的日志文件包括5个虚拟日志单元,在创建数据库时,逻辑日志文件从物理文件的始端开始,新的日志记录被添加到逻辑日志未端,然后向物理日志未端扩张。

  1.2 优先写日志

  当逻辑日志的末端到达物理日志的末端时,新的日志记录将回绕到物理日志文件的始端继续向后写(这是因为日志备份会截断使日志空间重用)。

  在日志里有个名词叫“优先写日志”。是指:缓存管理器能够保证日志写入磁盘优先于相应的数据改变写入磁盘,这叫优先写日志。一旦某个数据页发生改变,相应的日志项的LSN将会被写入该数据页的页头,缓存管理器能够保证日志页以特定的顺序写入磁盘,使得无论故障在何时发生,sqlserver
能清楚知道在系统故障之后应该处理哪些日志块。如下图所示

  下图是日志文件的流程图,当日志备份后虚拟日志1和虚拟日志2会被截断,虚拟日志3成为了逻辑日志的开头,当虚拟日志3和虚拟日志4在使用后,再次备份时,由于日志文件是一个回绕的文件,此时又从虚拟日志1开始。
   图1  日志文件的外观

图片 2

  图片 3

发表评论

电子邮件地址不会被公开。 必填项已用*标注