SQL Server事务日志分析
refs:
1.) https://blog.51cto.com/ultrasql/1953572
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';
SQL Server事务日志分析相关推荐
- SQL Server 事务日志
https://docs.microsoft.com/en-us/sql/relational-databases/logs/the-transaction-log-sql-server?view=s ...
- Sql Server事务日志
本文导读:SQL Server中的数据库都是由一或多个数据文件以及一或多个事务日志文件组成的.SQL Server事务日志主要是用来记录所有事务对数据库所做的修改,SQL SERVER利用事务日志来确 ...
- 了解SQL Server事务日志备份和完整备份的日志序列号
This article explores the SQL Server Transaction log backups and log sequence number (LSN) in combin ...
- 如何使用损坏或删除SQL Server事务日志文件重建数据库
This is the last article, but not the least one, in the SQL Server Transaction Log series. In this s ...
- 读取SQL Server事务日志
介绍 (Introduction) There has always been some debate as to whether or not there are real benefits to ...
- SQL Server事务日志体系结构
This article will cover SQL Server transaction log architecture including file topography, basic ove ...
- 10个最重要SQL Server事务日志神话
Myth: SQL transaction log truncation will make it smaller 误解: SQL事务日志截断将使其变小 The truncation process ...
- 什么是SQL Server事务日志中的虚拟日志文件?
什么是SQL Server事务日志文件? (What is a SQL Server transaction log file?) SQL Server事务日志文件是每个SQL Server数据库的组 ...
- 删除不需要的(辅助)SQL Server事务日志文件
This article explores the use of multiple SQL Server Transaction Log Files and the process of removi ...
最新文章
- 使用ansible安装docker以及docker-compose
- JFFS2文件系统挂载过程优化的分析报告
- php爬取flash的交互数据库,基于PHP的Flash与MySQL数据库通讯的实现
- Oracle rowid和rownum的区别
- python 自动发邮件 Errno61 Connection refused
- pytorch将Tensor转为list
- SpringBoot2.0使用Spring WebFlux之HelloWord篇
- 计算机网络学习笔记(15. OSI参考模型③、TCP/IP参考模型)
- mongodb 集群shard_MongoDB 分片集群环境搭建
- c语言中指,C语言程序设计中指教学要点分析.doc
- 【TSP】基于matlab GUI遗传算法求解旅行商问题【含Matlab源码 1333期】
- 华三H3C交换机如何配置和使用telnet远程登录设备
- 如何摆脱CRUD等打杂状态,从事更高价值工作
- java毕业设计选题基于SSM毕业设计管理系统|毕设管理文档成绩Shiro
- 全球行业品牌“中国制冷展”将亮相汉渝 寻觅发展新空间
- A Self-paced Multiple-instance Learning Framework for Co-saliency Detection文章阅读
- 重置计算机网络配置后上不了网,win10系统网络重置后不能连接网络如何解决
- 环保数采仪助力绿水青山建设
- 启发式查询树优化实例
- 计算机考研公共课考英语几,新文道教育:2022考研必须要了解的30个知识点
热门文章
- 【计算1970年到任意一个年月距离有多久】
- asp实现注册登录界面_asp.net 实现用户登录和注册——基于webform模式
- 【CTF】记录一次CTF比赛的Writeup(附题目下载地址)
- win系统cpu温度获取
- Photoshop学习(十四):使用快速蒙版
- java 像素矩阵_JAVA eclipse 中,已知灰度图像的像素矩阵怎么输出这个图像
- VMware虚拟机安装黑群晖系统
- 光量子计算机的信息载体,如何使“孤傲”的光子改变彼此的量子态?
- 陀螺仪的简单介绍讲解
- 基于stm32的两轮自平衡小车4(软件调试篇)