SQL Server事务日志分析

SQL Server事务日志分析

fn_dblog()和fn_dump_dblog()函数介绍

SQL Server有两个未公开的函数fn_dblog()fn_dump_dblog()非常有用并且提供的信息量很大。你可以使用这些函数来获取100多列大量的有用信息。

fn_dblog()用于分析数据库当前的事务日志文件,它需要两个参数,分别为事务开始LSN和结束LSN,默认为NULL,表示返回事务日志文件的所有日志记录。

例如:

SELECT * FROM fn_dblog(null,null);

fn_dump_dblog()用于分析数据库的事务日志备份文件,该函数需要的参数很多,但我们只需要传入备份文件的完整路径名称,其他参数使用默认值DEFAULT。

例如:

SELECT *
FROM fn_dump_dblog (
NULL, NULL, ‘DISK‘, 1, ‘D:\Pay\Pay_201707280400_LOG.trn‘,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT);

再来看看下图多个事务操作写入到事务日志文件的表现:

重要数据输出列值

我们再来分析下100多列输出中的几个重要列:

[Transaction Name]

该列描述该事务操作的类型,主要值有:

INSERT、UPDATE、DELETE、DROPOBJ

次要值有:

AllocPages、SplitPage、AllocHeapPageSysXactDML、UpdateQPStats、Backup:CommitLogArchivePoint、BTree Split/Shrink等。

典型的应用是通过DROPOBJ值来查找对象删除操作。

[Operation]

该列描述日志里记录的操作的具体类型,主要值有:

LOP_BEGIN_XACT、LOP_COMMIT_XACT、LOP_INSERT_ROWS、LOP_DELETE_ROWS、LOP_MODIFY_ROW、LOP_MODIFY_COLUMNS

次要值有:

LOP_BEGIN_CKPT、LOP_END_CKPT、LOP_XACT_CKPT、LOP_LOCK_XACT、

LOP_DELETE_SPLIT、LOP_EXPUNGE_ROWS、LOP_MODIFY_HEADER、LOP_FORMAT_PAGE、LOP_COUNT_DELTA、LOP_HOBT_DELTA、LOP_INSYSXACT、LOP_INVALIDATE_CACHE、LOP_MIGRATE_LOCKS、LOP_SET_BITS、LOP_SET_FREE_SPACE、LOP_SHRINK_NOOP、LOP_TEXT_INFO_BEGIN、LOP_TEXT_INFO_END

[Begin Time]

事务操作的开始时间。

[PartitionID]

具体操作的哪个分区,可以关联查询到具体影响的哪个表或索引。

[TRANSACTION SID]

该事务操作的用户SID,可以通过SUSER_SNAME()函数转换为用户名。

具体示例分析

再来看一个具体事务操作:

SELECT [Current LSN], [Transaction ID], [Transaction Name], [Operation], [Begin Time], [PartitionID], [TRANSACTION SID]
FROM fn_dump_dblog (
NULL, NULL, ‘DISK‘, 1, ‘D:\Pay\Pay_201707280400_LOG.trn‘,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
WHERE [Transaction ID]=‘0000:5c9b41e2‘;

根据[Transaction Name]为INSERT知道这是一个插入操作,具体哪条是插入的数据行,哪条是索引行,可以根据后面的PartitionID再去关联查询到。

根据[TRANSACTION SID]可以查询到操作的用户:

SELECT SUSER_SNAME(0x017017A631B52141B2338990DCFFADCC);

根据[PartitionID]查询到操作的对象:

SELECT so.name
FROM sys.objects so
INNER JOIN sys.partitions sp on so.object_id = sp.object_id
WHERE partition_id in(
72057594041204736,
72057594070630400);

根据partition_id还可以更详细的查看是数据行还是索引行:

--查看某个表的具体数据分布
SELECT DISTINCT so.name AS ‘table_name‘, so.object_id,sp.partition_id,si.name AS ‘index_name‘,internals.type_desc,internals.total_pages, internals.used_pages, internals.data_pages,first_iam_page, first_page, root_page
FROM sys.objects so
INNER JOIN sys.partitions sp ON so.object_id = sp.object_id
INNER JOIN sys.indexes si ON sp.object_id = si.OBJECT_ID AND sp.index_id = si.index_id
INNER JOIN sys.allocation_units sa ON sa.container_id = sp.hobt_id
INNER JOIN sys.system_internals_allocation_units internals ON internals.container_id = sa.container_id
WHERE so.object_id = object_id(‘NotificationRecord‘);

--查看某个表的索引详细信息
SELECT
TableId=O.[object_id],
TableName=O.Name,
IndexId=ISNULL(KC.[object_id],IDX.index_id),
IndexName=IDX.Name,
IndexType=ISNULL(KC.type_desc,‘Index‘),
Index_Column_id=IDXC.index_column_id,
ColumnID=C.Column_id,
ColumnName=C.Name,
Sort=CASE INDEXKEY_PROPERTY(IDXC.[object_id],IDXC.index_id,IDXC.index_column_id,‘IsDescending‘)
WHEN 1 THEN ‘DESC‘ WHEN 0 THEN ‘ASC‘ ELSE ‘‘ END,
PrimaryKey=CASE WHEN IDX.is_primary_key=1 THEN N‘√‘ELSE N‘‘ END,
[UQIQUE]=CASE WHEN IDX.is_unique=1 THEN N‘√‘ELSE N‘‘ END,
Ignore_dup_key=CASE WHEN IDX.ignore_dup_key=1 THEN N‘√‘ELSE N‘‘ END,
Disabled=CASE WHEN IDX.is_disabled=1 THEN N‘√‘ELSE N‘‘ END,
Fill_factor=IDX.fill_factor,
Padded=CASE WHEN IDX.is_padded=1 THEN N‘√‘ELSE N‘‘ END
FROM sys.indexes IDX
INNER JOIN sys.index_columns IDXC
ON IDX.[object_id]=IDXC.[object_id]
AND IDX.index_id=IDXC.index_id
LEFT JOIN sys.key_constraints KC
ON IDX.[object_id]=KC.[parent_object_id]
AND IDX.index_id=KC.unique_index_id
INNER JOIN sys.objects O
ON O.[object_id]=IDX.[object_id]
INNER JOIN sys.columns C
ON O.[object_id]=C.[object_id]
AND O.type=‘U‘
AND O.is_ms_shipped=0
AND IDXC.Column_id=C.Column_id where O.name=‘NotificationRecord‘;

时间: 2024-10-11 01:25:56

SQL Server事务日志分析的相关文章

Sql Server 事务日志

Sql Server事务日志文件是数据库文件的重要组成部分,事务日志主要用来存放数据库的修改记录.数据库为了得到更高的写入效率和性能,同时保证ACID特性,数据在写入时,会将更新先写入事务日志,因为事务日志是连写的,所以写事务会比较快.简单来说,顺序写入时,磁盘的磁头会保持在一定的区域内连续写入,而数据写入数据文件时,有随机性,磁盘的磁头移动消耗的时间要比数据写入日志文件时多. Sql Server对于事务日志文件的管理,是将日志文件在逻辑上分成若干个文件(VLFS),方便管理. 创建一个1M的

Sql Server 事务日志(三)

SQL server的日志文件会随着数据修改的增加而变大,在处理日志文件时,我们常用的方式是将日志截断,并收缩. Backup log databasename to disk='' dbcc shrinkfile(databasename_log) 当然,如果磁盘空间紧张,可以将恢复模式改成‘simple’的方式使日志截断,然后再收缩日志 alter database test set recovery simple; DBCC shrinkfile(test_log) alter datab

人人都是 DBA(VI)SQL Server 事务日志

SQL Server 的数据库引擎通过事务服务(Transaction Services)提供事务的 ACID 属性支持.ACID 属性包括: 原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability) 事务日志(Transaction Log) 事务日志(Transaction Log)存储的是对数据库所做的更改信息,让 SQL Server 有机会恢复数据库.而恢复(Recovery)的过程就是使数据文件与日志保持一致的过程.

翻译:SQL Server事务日志管理的阶段,1级:事务日志概述

原文链接:http://www.sqlservercentral.com/articles/Stairway+Series/73775/ 原文作者: Tony Davis, 2013/10/30 (第一次出版: 2011/06/17) 该系列 本文是SQL Server中"Stairway系列:事务日志管理的阶梯"的一部分 当事情进展顺利的时候,没有必要特别意识到事务日志的作用或工作原理. 你只需要确信每个数据库都有正确的备份机制. 当事情出错时,对事务日志的理解对于采取纠正措施是非常

如何通过trn日志文件恢复SQL Server 事务日志 还原 备份

首先恢复时一个完整的备份,但在完整的备份里一定要选择with nonerecovery(企业管理器里选项中是第2项) sql 语句是: restore database mydata from disk = 'c:\temp\movedb.bak'  with norecovery 这时数据库就会变成恢复模式,这样你就可以一条一条的把trn文件添加进行恢复了. 语句是: restore log Mydata from disk =    "D:\Program Files\Microsoft S

SQL Server 2014 日志传送部署(2):日志传送系统要求和实验架构

13.2 部署日志传送 13.2.1 部署日志传送的系统要求 SQL Server 2014日志传送的部署对硬件基础设施有一定的要求,下面将概述这些系统要求. 网络 日志传送不一定需要Windows域环境,但是Windows域环境方便了日志传送的配置和管理:相对非域环境,其安全性提升不少. 参与日志传送的SQL Server服务器必须在网络中相互连通,主服务器能够将事务日志备份到共享文件夹,辅助服务器可以将事务日志备份复制到本地文件夹:监视服务器能够连接到主服务器和辅助服务器. 服务器和存储 主

如何截断SQL Server2008+事务日志空间

SQL数据库事务日志记录数据库的任何更改,用户可回滚事务日志来恢复数据,但随着数据库使用时间变长,日志文件也会变得很大. 若要避免数据库的事务日志被填满,例行备份至关重要.做了日志备份后,会释放不活跃的VLF,增加日志的可用空间.但默认情况下备份日志,其日志文件的大小并未变化,如下图 备份前,总大小24.13MB 备份后,总大小仍然为24.13MB,但已用空间占比从93.1%降至11.0% 也就是,已使用日志空间是减小了,但未使用日志空间并未释放.其实,如果磁盘空间足够的话,可以不用收缩空间 那

如何处理SQL Server事务复制中的大事务操作

如何处理SQL Server事务复制中的大事务操作 事务复制的工作机制 事务复制是由 SQL Server 快照代理.日志读取器代理和分发代理实现的.快照代理准备快照文件(其中包含了已发布表和数据库对象的架构和数据),然后将这些文件存储在快照文件夹中,并在分发服务器中的分发数据库中记录同步作业. 日志读取器代理监视为事务复制配置的每个数据库的事务日志,并将标记为要复制的事务从事务日志复制到分发数据库中,分发数据库的作用相当于一个可靠的存储-转发队列. 分发代理将快照文件夹中的初始快照文件和分发数

SQL Server 2005 日志文件过大处理

由于安装的时候没有计划好空间,默认装在系统盘,而且又没有做自动备份.截断事务日志等,很快LDF文件就达到十几G,或者几十G ,此时就不得不处理了. 备份和计划就不说了,现在就说下怎么把它先删除吧: 1:先分离数据库 2:为了保险,先不要删除,把LDF文件重命名下 3:附件数据库. 4:OK. 以上可能遇到的问题: 1:有用户连接,无法分离(勾选“断开所有连接”) 2:附件数数据库的时候提示找不到LDF文件,不要慌,在附件的时候,把LDF的路径一项删除,然后点击"确定",这样就附件成功了