【数据库事务日志碎片原理分析与方案】-深入解析篇.pdf

日志增长与 VLF 文件的个数 通过上面的相关内容的介绍,我们已经知道了日志文件自动的增长会到了一些问

题,而事实确实如此,下面,我们就来更加清楚的看看这些问题。

很显然,我们不希望日志文件任意的增长,我们更加希望这个增长是受我们控制 的。我们先看看自动增长的一些问题:

1.导致过多的 VLF。因为自动增长会在需要的时候去增加日志文件所在磁盘空间的大 小,而且每次分配的空间又会被分成多个 VLF,如果每次增长的磁盘空间不大,而数据库 的操作(指的是那些写日志的操作)又非常的频繁,最后就结果就是数据库的日志文件一 点点的增长,从而导致磁盘的文件碎片和数据库内部日志文件碎片,这样就会极大的降低 了读取日志的速度。另外,大家应该还记得之前我们说过:数据库的日志是循环写入的, 如果日志文件内部碎片,那么在重新将日志写入日志文件的时候,就需要去需找文件的位 置,会使得相对应的数据库操作更加的慢。

2.每次日志文件的增长会消耗 CPU 和 I/O:日志自动增长不会使用实例文件初始化, 因此,SQL Server 需要去每次都去经历日志文件进行初始化的全过程,而这个过程是非常 消耗资源的。这一点,大家只要知道有这么回事就行了,不用深究。

另外,如果我们在建立数据库的时候,采用了默认的配置,那么自动增长是被默 认开启的,而且默认的数据文件和日志文件的大小都很小。如果我们就这样使用数据库, 最后会发现:日志文件中包含成百上千个 VLF。

每次在新建一个数据库的时候,默认的大小以及自动增长的设置都是从 model 这个系统数据库中继承而来的。一般而言,日志文件的初始大小 1MB,自动增长为 10%。

这个时候,可能有朋友就要问了:这个 1MB 日志中包含多少个 VLF,或者说日

志文件的大小与 VLF 的个数之间是什么关系? 我们下面的一个表反映了日志文件的大小和 VLF 个数之间的关系。

很显然,在默认的情况下,数据库的日志文件将会包含 4 个 VLF,因为默认的时 候大小是 1MB<64MB 的。

所以,这样有一个建议:除非你需要用很多的小的数据库,否则,就调整 Model 数据库的一些设置,使得以后你新建的数据库从继承你设定的设置数据。

下面,我们就通过例子来看看一些问题。 我们下面的代码,创建了一个新的数据库,采用的默认的设置。同时,也将恢复

模型设置为 Full,如下所示:

在下面的一段代码中,我们使用 DBCC LOGINFO 来查看日志文件的 VLF 的个数, 如下: 

现在,我们再看到下面的代码,在代码中创建了一个新表 AgileSharpTable,并且开启 事务,然后插入 10000 行数据: 

此时,这个测试花了将近 50 秒的时间,此时,我们在查看 VLF 的信息,此时发现已 经有了 251 个。

下面,我们在新建一个数据库,此时我们自己设置日志文件的大小和增长情况, 如下:

此时,我们还是运行 DBCC LOGINFO,此时发现里面包含了 8 个 VLF,因为我们的 日志文件的初始大小>=64MB 并且<1GB。

像第一个例子,我们此时在新的数据库中创建新的表,并且插入 10000 条数据。然 后我们在运行 DBCC LOGINFO,此时发现,它的 VLF 还是 8 个。而且插入的数据也快了 很多,只有 27 秒,这个主要是因为日志文件初始化的过程变少,提高了性能。

到现在为止,我们做了一些简单的演示,也看出一些性能的问题,下面我们就进 一步的看看 VLF,那么在此之前,我们先具体的看看刚刚使用的 DBCC LOGINFO 命令。

深入 DBCC LOGINFO

通过刚刚的使用,我们已经发现这个命令相当的有用了,通过它我们可以找到日 志文件中的 VLF 的个数。另外,它还可以告诉我们更多的信息。为了更加的清楚,我们 删除之前的那个 VLFTest1 数据库,然后重新建立它。

然后运行 DBCC LOGINFO,得到如下的结果:

列名的解释如下:

FileID:在 sysfiles 中对用的 FileID,可以通过它表明日志文件存在的位置。

FileSize:VLF 的大小,单位是字节。

StartOffSet:VLF 文件在日志文件中起始的字节数。

Status:表明 VLF 是否包含活动的日志记录。2 表示这个 VLF 是活动的,不能被覆盖 写入。

Parity:它的之范围是 0,64 或者 128.
CreateLSN:VLF 最先创建的 LSN。如果两个 VLF 文件有相同的这个数字,就表明这

两个 VLF 是同时创建的,并且通过自动增长

简单的介绍之后,我们再来运行下面的一段代码:

运行 DBCC LOGINFO,结果如下: 从中可以看到,此时我们有一个活动的 VLF,而且还新建了 11 个 VLF。

控制 VLF

到这里,已经讲了很多与 VLF 相关的内容了,相信大家都应该心里不再害怕这些 内容了。其实日志文件碎片产生最主要的原因就是日志文件的增长次数过多,特别是如果 每次只是增长一点点的时候。

所以,当我们在创建数据库的时候需要设置合适的文件的大小,使得文件的大小 起码可以应付一段时间的增长。同时,也不要一下子就去创建一个很大的日志文件,因为 里面可能只包含很少的 VLF,最后却发挥不了太大作用,反而导致磁盘空间不足的错误发 生。

很多的朋友都问我有没有一些好的数据或者法则来判断导致应该创建多少个 VLF,这里的 回答是没有,如果非得要答案,只有一个:视情况而定。如果我以前说这话,可能要被人 批死,但是如果做过这方面工作的朋友,应该清楚:这才是真理。没有万能的钥匙。这主 要取决于数据库的读写的比例,还有就是日志文件备份的方式。

另外,也不是说:自动增长就是罪恶的,只要用的合适,依然不错,而且它还是 保护措施,特别是当我们把日志的增长速度估算错误的时候,自动增长可以来帮助我们弥 补这个问题。例如,假设我们把日志大小设置为 40GB,并且禁用了自动增长,但是数据 库的读写速度不是我们当初想的那样,我们当初以为 40GB 可以抗住 3 个月的数据库日志 的写入,但是结果却不是,如果我们禁用自动增长,结果可能导致数据库无法写入。

一般是通过一些数据进行分析了,这里我给朋友们一些可以参考的数据吧,但是 不能盲目的套用,但是思路是这样的。我一般会把日志文件的大小设置和所在的磁盘大小 相差 90%,并且开启自动增长。而且这个大小的设置也不是一下子就设置上去的,例如, 磁盘空间是 100GB,我不会一下子就设置 90GB 的日志文件,因为那样,里面包含的 VLF 太少,会导致严重的性能问题。所以要一步步的设置,例如,开始设置日志大小为 1GB, 然后在将其增加到 2GB(也就是每次增加 1GB,也有人推荐 512MB),一次类推,一直 最后到 90GB。当然,每一次增加的大小可以调整,需要自己去测一下。

修复日志碎片

到这里,对日志文件剩下的话题就是整理它的碎片了。

如果我们发现数据库中包含了非常多的 VLF,此时我们就需要去整理。在这, 朋友又要问了:你说的“非常多的碎片”,到底“非常多”是多少?说实在的,我还真 不好说了,但是可以这样思考:如果是你设置日志文件的大小和 VLF,你会根据我们之 前告诉大家的方法来设置 VLF 的个数(例如,每次增加 1GB 的日志文件,增加 8 个 VLF),得到你设置的 VLF 的个数,然后比较现在的 VLF 个数,如果两个数据之间相差 的十几倍以上,那么就可能存在 VLF 问了,就需要整理碎片了。

整理的方法简单,就是运行 DBCC SHRINKFILE 命令,如下: DBCC SHRINKFILE(<transaction log logical file name>,TRUNCATEONLY);

然后再想之前那么,把日志文件的大小设置回去。

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/125877.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外汇交易技巧分享:利用MT4交易平台进行精准的外汇技术分析

在外汇交易市场中&#xff0c;技术分析是一种重要的决策工具&#xff0c;能够帮助交易者预测价格走势和制定交易策略。而MT4交易平台作为一种功能强大、广泛应用的交易软件&#xff0c;为交易者提供了丰富的技术分析工具和功能。本文将与大家分享几个利用MT4交易平台(可在mtw.s…

Revit SDK 介绍:CreateAirHandler 创建户式风管机

前言 这个例子介绍如何通过 API 创建一个户式风管机族的内容&#xff0c;包含几何和接头。 内容 效果 核心逻辑 必须打开机械设备的族模板创建几何实体来表示风管机创建风机的接头 创建几何实体来表示风管机 例子中创建了多个拉伸&#xff0c;下面仅截取一段代码&#xff…

vue2 vuex

一、Vuex 概述 Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 大白话&#xff1a;Vuex 是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。 使用场景 某个状态 在 很多个组件 来使用 (个人信息) 多个组件 共同维护 一份数据 (购物车) …

虚函数、纯虚函数、多态

一.虚函数 在基类的函数前加上virtual关键字&#xff0c;在派生类中重写该函数&#xff0c;运行时将会根据所指对象的实际类型来调用相应的函数&#xff0c;如果对象类型是派生类&#xff0c;就调用派生类的函数&#xff0c;如果对象类型是基类&#xff0c;就调用基类的函数。 …

蓝桥杯打卡Day5

文章目录 日志排序重复者 一、日志排序IO链接 本题思路:本题就是根据就是排序的知识点&#xff0c;在sort内部可以使用仿函数来改变此时排序规则。 #include <bits/stdc.h>const int N10010; int n; std::string logs[N];int main() {std::ios::sync_with_stdio(false)…

java网络编程,套接字socket

目录 一 网络概述 二 网络的类型分类 三 网络体系结构 四 网络通信协议概述 五 网络通信协议种类 六 Socket简介 七 Socket路径 八 java网络编程三要素 九 基于UDP协议的Socket编程 十 基于TCP协议的Socket编程 十一 基于TCP协议和UDP的区别 一 网络概述 多台相互连…

Docker 的常用命令

0 基本命令 概述 [root192 home]# docker --helpUsage: docker [OPTIONS] COMMANDA self-sufficient runtime for containersOptions:--config string Location of client configfiles (default "/root/.docker")-c, --context string Name of the context…

【ES】笔记-Class类剖析

Class Class介绍与初体验ES5 通过构造函数实例化对象ES6 通过Class中的constructor实列化对象 Class 静态成员实例对象与函数对象的属性不相通实例对象与函数对象原型上的属性是相通的Class中对于static 标注的对象和方法不属于实列对象&#xff0c;属于类。 ES5构造函数继承Cl…

【Linux】环境变量

环境变量 一、引子echo $NAME [NAME:环境变量名] 二、基本概念概念常见的环境变量PATH : 指定命令的搜索路径测试HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的家目录)SHELL : 当前Shell,它的值通常是/bin/bash。 和环境变量相关的命令echo -- 显示某个环境变…

[html]当网站搭建、维护的时候,你会放个什么界面?

效果图&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>网站建设中</title><style>/* 基础样式 */body, html {margin: 0;padding: 0;height: 100%;font-family: Arial, sa…

Stable Diffusion stable-diffusion-webui ControlNet Lora

Stable Diffusion Stable Diffusion用来文字生成图片&#xff0c;ControlNet就是用来控制构图的&#xff0c;LoRA就是用来控制风格的 。 stable-diffusion-webui 国内加速官网&#xff1a; mirrors / AUTOMATIC1111 / stable-diffusion-webui GitCode 安装参考&#xff1a…

OpenCV(三十一):形态学操作

​​​​​​1.形态学操作 OpenCV 提供了丰富的函数来进行形态学操作&#xff0c;包括腐蚀、膨胀、开运算、闭运算等。下面介绍一些常用的 OpenCV 形态学操作函数&#xff1a; 腐蚀操作&#xff08;Erosion&#xff09;&#xff1a; erode(src, dst, kernel, anchor, iteration…

Wireshark技巧[监听串口包]

监听串口包 本文摘录于&#xff1a;https://blog.csdn.net/qq_20405005/article/details/79652927只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 这里要保证安装了USBpcap: 打开USBpcap后一半都要输入过滤条件,否则USB太多数据了,比如…

PHP实现微信小程序状态检测(违规、暂停服务、维护中、正在修复)

实现原理 进入那些状态不正常的小程序会被重定向至一个Url&#xff0c;使用抓包软件抓取这个Url&#xff0c;剔除不必要参数&#xff0c;使用cURl函数请求网页获得HTML内容&#xff0c;根据内容解析出当前APPID的小程序的状态。 代码 <?php// 编码header(Content-type:ap…

正弦信号的平均功率和峰值电压计算举例

正弦信号的平均功率和峰值电压计算举例 一、问题 假设加载在纯电阻为R1Ω&#xff0c;频率为50Hz和60Hz的正弦信号的平均功率分别为0.5W和2W,请求解这两个信号的峰值电压 U p 1 U_{p1} Up1​和 U p 2 U_{p2} Up2​。 二、解答&#xff1a; 根据欧姆定律可知&#xff1a;对于…

docker镜像 容器 仓库

docker镜像 Docker 运行容器前需要本地存在对应的镜像&#xff0c;如果本地不存在该镜像&#xff0c;Docker会从镜像仓库下载该镜像。 获取镜像 Docker Hub 上有大量的高质量的镜像可以用&#xff0c;这里我们就说一下怎么获取这些镜像。 从 Docker 镜像仓库获取镜像的命令…

2023-9-8 求组合数(三)

题目链接&#xff1a;求组合数 IV #include <iostream> #include <algorithm>using namespace std;const int N 5010;int primes[N], cnt; bool st[N]; // 每个质数的次数 int sum[N];void get_primes(int n) {for(int i 2; i < n; i){if(!st[i]) primes[cnt]…

为什么vector容器的begin()既可以被iterator 也可以被const_iterator指向?

答&#xff1a;vector容器中的begin&#xff08;&#xff09;是函数接口&#xff0c;它作为函数&#xff0c;被重载了。 typedef T* iterator; typedef const T* const_iterator; iterator begin();//括号中有隐含形参*this&#xff1b; const_iterator begin() const;//形参为…

UDP的可靠性传输2

系列文章目录 第一章 UDP的可靠性传输-理论篇&#xff08;一&#xff09; 第二章 UDP的可靠性传输-理论篇&#xff08;二&#xff09; 文章目录 系列文章目录三、流量控制RTORTT流量控制1.如何控制流量2. 发送方何时在发送数据3.流程图 拥塞控制1.慢启动 总结1.拥塞控制和流量…

React基础

目录 TODO1 React概述 React的使用 React脚手架的使用 全局安装 npx安装 在脚手架中使用React JSX 1. JSX的基本使用 1.1 为什么用JSX 1.2 JSX简介 1.3 使用步骤 1.4 脚手架中能用JSX 1.5 注意点 2. 在JSX中使用JavaScript表达式 2.1 嵌入js表达式 2.2 注意点 3…