0

0

导数中的最小化日志记录:背景和理论_MySQL

php中文网

php中文网

发布时间:2016-05-27 16:57:04

|

1870人浏览过

|

来源于php中文网

原创

什么是最小化日志(Minimal Logging)?

 

Multiavatar
Multiavatar

Multiavatar是一个免费开源的多元文化头像生成器,可以生成高达120亿个虚拟头像

下载

当数据库的恢复模式为SIMPLE或者BULK_LOGGED时,对于最小化日志类型的操作,事务日志不记录单独每个数据行的日志,而是记录对应页和区结构的修改日志。

这样显著减少了操作产生的事务日志数量。例如,向某个数据页上插入200行数据,在最小化日志记录的情况下,只会记录一条此数据页变化的日志,而不是200条Insert日志。

 

最小化日志类型的操作

SELECT INTO 

Bulk导数操作,包括 BULK INSERT和BCP

INSERT INTO . . . SELECT,包括两种情况:

 

a) SELECT中使用OPENROWSET(BULK. . .) 

 

b)目标表不具有非聚集索引,向其插入超过8页的数据量,并且使用了TABLOCK时。如果目标表为空,可以有聚集索引,如果不为空,则不可以。

 

部分更新大值类型的列

 

UPDATE中使用.WRITE插入数据或追加数据时

 

对LOB字段使用WRITETEXT和UPDATETEXT插入或者追加新数据,不包括更新。

 

索引操作,包括在表/视图上CREATE INDEX,ALTER INDEX REBUILD,DBCC DBREINDEX,DROP INDEX(新堆的重新生成将按最小方式记录)

 

数据导入中的最小化日志记录

 

本文关注的是数据导入的最小化日志记录,指BULK INSERT导数操作。很多理论在其它类型的操作上是通用的。

  

1. 普通的INSERT

 

SQL Server中使用锁和日志记录来保证数据库事务的ACID属性。在插入一行数据的整个事务期间,为了避免并发事务访问,这一行会被锁定;

 

同样这一行还会被写入日志记录。插入一行数据的大概的步骤如下:

 

通过行锁锁定行。

 

写入日志记录。日志记录包含被插入行的完整数据。

 

数据行被写入数据页。

 

多行插入时,每一行都会重复以上步骤。这里指大概操作原型,实际处理复杂的多,如锁升级,约束检查等等

 

2. BULK导入

 

当BULK导入提交事务时,事务使用到的所有数据页会被写入磁盘,这样来保证事务原子性。相当于每次提交事务时都做一次CHECKPOINT。如果需要回滚BULK事务,SQL Server会检索日志获取事务涉及的页或者区信息,然后将之重新标记为未使用。备份事务日志时会将BULK涉及的数据页和索引页都备份到日志备份中。还原包含BULK事务的日志备份时,不支持还原到指定时间点。

 

每个数据文件第八个页是BCM页(BULK Chandged Map),之后每隔511230页会有一个BCM页。BCM上的每一位(Bit)代表着一个区,如果此位为1,则表示自上次BACKUP LOG后,这个区被BULK类型操作修改过。再下次日志备份时,会将这些被修改过的区复制到日志备份中。

 

3. 使用最小日志记录导入数据时需要满足的条件

 

并不是任何情况下都可以实现最小日志导数,判断逻辑如下(来自Itzik Ben-Gan)

 

a) SQL Server 2008之前的版本判断逻辑:

non-FULL recovery model

AND NOT replicated

AND TABLOCK

AND (

               Heap

               OR (B-tree AND empty)

       )

 

      b) SQL Server 2008及以后版本的判断逻辑:

Non-FULL recovery model

AND NOT replicated

AND (

          (Heap AND TABLOCK)

          OR (B-tree AND empty AND TABLOCK)

          OR (B-tree AND empty AND TF-610)

          OR (B-tree AND nonempty AND TF-610 AND key-range)

 

从SQL 2008开始可以使用跟踪标记610和排它键范围锁,实现空/非空聚集索引表的最小化日志操作。

 

排他键范围锁的作用例子:聚集索引表tb(id INT),目前有4行数据,分别为1,1000,2000,3000。现在需要向表中插入500行数据,这些数据的值区间为[1001,1500]。

 

当插入时,SQL Server不需要获取聚集索引整体的排它锁(像tablock这种),而只是获取原有键值区间的排它键范围锁。这里就是在(1000,2000)区间上获取X KEY-RANGE LOCK。而不在这个区间的数据,仍然可以被其它进程访问。如果要实现非空索引表的最小化日志记录导数,需要预先将导入数据按目标表的索引键值列进行排序,并启用跟踪标记610。

 

从上面的判断逻辑可以看出,实现最小日志记录的大前提是:数据库不是完整恢复模式且表没有标记为复制。对于堆表总是需要使用TABLOCK。对于索引表,则要分为空表和非空表两种情况来处理。这部分内容在后文的例子再展开来说明。

 

观察BULK导入的日志

 

使用未公开的系统函数sys.fn_dblog查找相关的日志内容。fn_dblog接受两个参数用以指定要查询的日志区间,分别表示开始和结束的LSN。输出字段中,此文需要关注的是Operation, Context, Log Record Length和AllocUnitName。因为是未公开的的函数,所以输出内容代表的意义,需要结合个人经验和大家的“共识”来解读。

 

Operation(LOP):表示执行何种日志操作, 例如修改行为LOP_MODIFY_ROW,设置位图页时为LOP_SET_BITS等等。

 

Context(LCX):日志操作的上下文,一般表示受影响的对象类型。例如LCX_GAM,LCX_HEAP,LCX_PFS等。

 

Log Record Length:以byte为单位的日志长度

AllocUnitName:表示受影响的具体对象

使用如下脚本进行分析,脚本来自Jakub K 

 

-- 日志条目录数据和总大小
SELECT COUNT(*)AS numrecords,
  CAST((COALESCE(SUM([Log Record LENGTH]), 0))
    / 1024. / 1024. AS NUMERIC(12, 2)) AS size_mb
FROM sys.fn_dblog(NULL, NULL) AS D
WHERE AllocUnitName = 'dbo.tableName' OR AllocUnitName LIKE 'dbo.tableName.%';

-- 各类型日志的平均长度和数量
SELECT Operation, Context,
  AVG([Log Record LENGTH]) AS AvgLen, COUNT(*) AS Cnt
FROM sys.fn_dblog(NULL, NULL) AS D
WHERE AllocUnitName = 'dbo.tableName' OR AllocUnitName LIKE 'dbo.tableName.%'
GROUP BY Operation, Context, ROUND([Log Record LENGTH], -2)
ORDER BY AvgLen, Operation, Context;

 


热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

33

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

32

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

36

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

7

2026.01.31

漫画防走失登陆入口大全
漫画防走失登陆入口大全

2026最新漫画防走失登录入口合集,汇总多个稳定可用网址,助你畅享高清无广告漫画阅读体验。阅读专题下面的文章了解更多详细内容。

11

2026.01.31

php多线程怎么实现
php多线程怎么实现

PHP本身不支持原生多线程,但可通过扩展如pthreads、Swoole或结合多进程、协程等方式实现并发处理。阅读专题下面的文章了解更多详细内容。

1

2026.01.31

php如何运行环境
php如何运行环境

本合集详细介绍PHP运行环境的搭建与配置方法,涵盖Windows、Linux及Mac系统下的安装步骤、常见问题及解决方案。阅读专题下面的文章了解更多详细内容。

0

2026.01.31

php环境变量如何设置
php环境变量如何设置

本合集详细讲解PHP环境变量的设置方法,涵盖Windows、Linux及常见服务器环境配置技巧,助你快速掌握环境变量的正确配置。阅读专题下面的文章了解更多详细内容。

0

2026.01.31

php图片如何上传
php图片如何上传

本合集涵盖PHP图片上传的核心方法、安全处理及常见问题解决方案,适合初学者与进阶开发者。阅读专题下面的文章了解更多详细内容。

2

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.2万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

Excel 教程
Excel 教程

共162课时 | 14.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号