使用即时文件初始化提高SQL Server性能

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
日志服务 SLS,月写入数据量 50GB 1个月
简介:

今天我想谈下SQL Server里的一个特别话题——即时文件初始化(Instant File Initialization)。对于你的SQL Server实例,如果你启用了即时文件初始化,在特定情况下,你会获得巨大的性能提升。即时文件初始化定义了当在数据文件里分配新的空间时,SQL Server引擎如何和Windows操作系统打交道。

问题缘由

在SQL Server默认配置里,当你在数据文件里分配新空间时,SQL Server会调用内部WIN32 API函数,填0初始化新分配的NTFS簇。这就是说新分配的空间的每个字节会用0值(0x0)重写。这个举动会阻止访问到原始数据问题,即在同个NTF簇里物理存储的数据。在下列SQL Server操作中,会发生填0初始化:

  • 创建新的数据库
  • 数据库自动增长
  • 数据库备份还原

当你创建10GB的数据库文件,SQL Server第1步需要把10GB的数据块写上0值。这个会花费很长时间。我们来看下面CREATE DATABASE语句:

复制代码
 1 -- Create a new 10 GB database
 2 CREATE DATABASE TestDatabase ON PRIMARY
 3 ( 
 4     NAME = N'TestDatabase',
 5     FILENAME = N'D:\SQL\DATA\TestDatabase.mdf' , 
 6     SIZE = 10240000KB , 
 7     FILEGROWTH = 1024KB
 8 )
 9 LOG ON 
10 (
11     NAME = N'TestDatabase_log', 
12     FILENAME = N'D:\SQL\Log\TestDatabase_log.ldf' ,
13     SIZE = 1024KB , 
14     FILEGROWTH = 10%
15 )
16 GO
复制代码

从代码可以看到,这里我创建10GB的数据库文件。在我SQL Server默认配置里,这个语句花费了近49秒,因为SQL Server通过WIN32 API函数写入10GB的0到存储。假设你有损坏的数据库(例如也是10GB),你想还原备份,会发生什么?在第1步通常人们会怎么做?是会删除损坏的数据库。这意味这你的数据库文件没了,在还原文件操作期间,SQL Server第1步需要重建文件。

  1. SQL Server第1步创建10GB“空”的数据库,在NTF文件系统里数据文件会被填0初始化。
  2. 最后1步备份被还原时,SQL Server再次写入10GB的数据到数据文件。

你会发现,你写了近20GB的数据到你的存储!如果你在现存的文件上还原你的备份,SQL Server会跳过第1步,直接写入10GB的数据到你的存储——你就获得了100%的性能提升!

即时文件初始化

如果你不想SQL Server进行你数据文件的填0初始化,你可以重新配置SQL Server。如果你授权SERVICE帐号,在对应运行的SQL Server下——执行卷维护任务(Performance Volume Maintenance Task)特权,在你重启SQL Server后,SQL Server会跳过数据文件的填0初始化。我曾说过这只对数据文件有效——在SQL Server里日志文件还是总要填0初始化的!这是米有办法滴!!!如果日志文件没有填0初始化,当日志文件被包裹时,故障还原进程就不知道从哪里结束。故障还原停在它找到下条日志记录需要处理头部0值地方。

你可以通过secpol.msc对SQL Server的SERVICE帐号授予执行卷维护任务(Performance Volume Maintenance Task)特权。

在重启后,SQL Server现在可以跳过数据文件的填0初始化。当我再次执行CREATE DATABASE,它只花费了近210ms——那是巨大的区别!副作用呢?你可以通过DBCC PAGE命令获得在分配的NTFS簇里存储的原始内容: 

复制代码
1 -- Enable DBCC trace flag 3604
2 DBCC TRACEON(3604)
3 GO
4 
5 -- Dump out a page somewhere in the data file
6 -- A hex dump is working here
7 DBCC PAGE (TestDatabase, 1, 1000, 2)
8 GO
复制代码

你看到我在我的数据文件里随便倾倒出了一个页。在那个情况下,SQL Server现在就会返回你一些垃圾数据——在新分配的NTFS簇里先前存储的数据——对SQL Server毫无关联的数据。

通过对SQL Server授予这个权限,基本上你打开了一个安全漏洞:用户(有正确权限的)可以获得老数据,在文件系统里先前存储的。因此对此你必须要仔细考虑下,对SQL Server是否要授予这个特权。

如果你想知道,你的SQL Server是否带这个权限在运行,你可以启用30043605跟踪标记。用这些启用的跟踪标记,SQL Server在错误日志会报告那个文件被填0初始化。接下来当你创建新的数据库时,对于SQL Server没有授予这个特权,从错误日志你可以看到,数据日志文件都被填0初始化了:

如果SQL Server有执行卷维护任务(Performance Volume Maintenance Task)特权,从错误日志你可以看到,只有日志文件被填0初始化:

 

Windows内核

在SQL Server运行下服务帐号,你对它授予了执行卷维护任务(Performance Volume Maintenance Task)特权,在Windows操作系统内部会发生什么呢?启用这个特权后(它内部是通过WIN32 API调用所谓的SE_MANAGE_VOLUME_NAME函数),SQL Server可以调用SetFileValidData的WIN32 API函数。从在线文档里可以看到,调用那个函数的进程,有SE_MANAGE_VOLUME_NAME权限。当那个函数被SQL Server调用时,函数本身会设置文件所谓的High Watermark——在其NTFS簇里,文件直接扩展而不重写原始内容!正如在线文档所述:

 

“The SetFileValidData function allows you to avoid filling data with zeros when writing nonsequentially to a file. The function makes the data in the file valid without writing to the file. As a result, although some performance gain may be realized, existing data on disk from previously existing files can inadvertently become available to unintended readers.”

 

 

“If SetFileValidData is used on a file, the potential performance gain is obtained by not filling the allocated clusters for the file with zeros. Therefore, reading from the file will return whatever the allocated clusters contain, potentially content from other users. This is not necessarily a security issue at this point, because the caller needs to have SE_MANAGE_VOLUME_NAME privilege for SetFileValidData to succeed, and all data on disk can be read by such users.”

 

我已经说过,对于你的SQL Server实例,你是否启用这个权限主要是关系到安全的。

小结

对于你的SQL Server实例,你是否应该启用即时文件初始化?这个依具体情况而定……当你是SQL Server和系统管理员时,授予这个权限是个好主意,因为作为系统管理员,你总是可以访问文件系统的。但当你有专属的系统管理员和SQL Server管理员时,这就不可能授予了,因为系统管理员并不信任你,对于你的SQL Server实例你不会获得这个权限。那样的话SQL Server总会填0初始化数据和日志文件……


本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4639282.html,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
1月前
|
SQL 数据库
SQL面试50题------(初始化工作、建立表格)
这篇文章提供了SQL面试中可能会遇到的50道题目的建表和初始化数据的SQL脚本,包括学生、教师、课程和成绩表的创建及数据插入示例。
SQL面试50题------(初始化工作、建立表格)
|
9天前
|
SQL 存储 API
Flink实践:通过Flink SQL进行SFTP文件的读写操作
虽然 Apache Flink 与 SFTP 之间的直接交互存在一定的限制,但通过一些创造性的方法和技术,我们仍然可以有效地实现对 SFTP 文件的读写操作。这既展现了 Flink 在处理复杂数据场景中的强大能力,也体现了软件工程中常见的问题解决思路——即通过现有工具和一定的间接方法来克服技术障碍。通过这种方式,Flink SQL 成为了处理各种数据源,包括 SFTP 文件,在内的强大工具。
43 15
|
17天前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
23 1
|
20天前
|
SQL 数据处理 数据库
专坑同事的SQL写法:性能杀手揭秘
【8月更文挑战第29天】在日常的数据库开发与维护工作中,编写高效、清晰的SQL语句是每位数据工程师的必修课。然而,不当的SQL编写习惯不仅能降低查询效率,还可能给同事的工作带来不必要的困扰。今天,我们就来揭秘八种常见的“专坑同事”SQL写法,助你避免成为那个无意间拖慢整个团队步伐的人。
28 1
|
25天前
|
SQL 关系型数据库 MySQL
【MySQL 慢查询秘籍】慢SQL无处遁形!实战指南:一步步教你揪出数据库性能杀手!
【8月更文挑战第24天】本文以教程形式深入探讨了MySQL慢SQL查询的分析与优化方法。首先介绍了如何配置MySQL以记录执行时间过长的SQL语句。接着,利用内置工具`mysqlslowlog`及第三方工具`pt-query-digest`对慢查询日志进行了详细分析。通过一个具体示例展示了可能导致性能瓶颈的查询,并提出了相应的优化策略,包括添加索引、缩小查询范围、使用`EXPLAIN`分析执行计划等。掌握这些技巧对于提升MySQL数据库性能具有重要意义。
52 1
|
17天前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
32 0
|
17天前
|
Java XML Maven
跨越时代的飞跃:Struts 2 升级秘籍——从旧版本无缝迁移到最新版,焕发应用新生!
【8月更文挑战第31天】随着软件技术的发展,Struts 2 框架也在不断更新。本文通过具体案例指导开发者如何从旧版平滑升级到 Struts 2.6.x。首先更新 `pom.xml` 中的依赖版本,并执行 `mvn clean install`。接着检查 `struts.xml` 配置,确保符合新版本要求,调整包扫描器等设置。审查 Action 类及其注解,检查配置文件中的弃用项及插件。更新自定义拦截器实现,并验证日志配置。最后,通过一系列测试确保升级后的系统正常运行。通过这些步骤,可以顺利完成 Struts 2 的版本升级,提升应用的安全性和性能。
47 0
|
2月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
2月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
44 6
|
25天前
|
SQL NoSQL 关系型数据库
性能与扩展性的考量:SQL vs NoSQL
【8月更文第24天】在选择数据库系统时,开发者和架构师面临着一个关键决策:是选择传统的SQL(结构化查询语言)数据库还是现代的NoSQL(非关系型)数据库。这两种类型各有优劣,尤其是在性能和扩展性方面。本文将深入探讨SQL和NoSQL数据库在这两个方面的差异,并通过具体的代码示例来展示它们各自的优势。
29 0