标签: sql-server-2017

SQL Server 遇到 I/O 请求耗时超过 15 秒的情况

在生产 SQL Server 上,我们有以下配置:

3 台 Dell PowerEdge R630 服务器,合并到可用性组中
所有 3 台都连接到作为 RAID 阵列的单个戴尔 SAN 存储单元

有时,在 PRIMARY 上,我们会看到类似于以下内容的消息:

SQL Server 在数据库 ID 8 中
的文件 [F:\Data\MyDatabase.mdf] 上遇到了 11 次 I/O 请求需要超过 15 秒才能完成。操作系统文件句柄为 0x0000000000001FBC。
最近一次 long I/O 的偏移量为:0x000004295d0000。
长 I/O 的持续时间为:37397 毫秒。

我们是性能故障排除的新手

解决此与存储相关的特定问题的最常见方法或最佳实践是什么?

必须使用哪些性能计数器、工具、监视器、应用程序等来缩小此类消息的根本原因?

可能有一个扩展事件可以提供帮助,或者某种审计/日志记录?

更新:添加了我自己的答案(见下文),解释了我们为解决问题所做的工作

performance storage sql-server-2017 performance-tuning

20
推荐指数
4
解决办法
2万
查看次数

对于圣经希伯来语,我应该使用哪种排序规则?

对于圣经希伯来语,我应该使用哪种 SQL Server 排序规则?所考虑的数据库需要适应变音符号(即元音、重音、比喻等)。

database-design sql-server collation configuration sql-server-2017

19
推荐指数
2
解决办法
1929
查看次数

启动 SQL Server 2017 服务时出错。错误代码 3417

我的计算机上安装了 SQL Server 2017。这是SELECT @@VERSION返回的内容:

Microsoft SQL Server 2017 (RTM-GDR) (KB4293803) - 14.0.2002.14 (X64) 2018 年 7 月 21 日 07:47:45 版权所有 (C) 2017 Microsoft Corporation Enterprise Edition(64 位),Windows 10 Enterprise 10.0(Build 171) )`

直到昨天它都运行良好。突然SQL SERVER Service没跑了。当我想手动运行该服务时,它显示3417 error. 当我检查事件日志时,我看到了这个错误:

数据库 'master' 的脚本级升级失败,因为升级步骤 'msdb110_upgrade.sql' 遇到错误 200,状态 7,严重性 25。这是一个严重的错误情况,可能会干扰正常操作,数据库将脱机。如果在升级“master”数据库期间发生错误,它将阻止整个 SQL Server 实例启动。检查以前的错误日志条目是否有错误,采取适当的纠正措施并重新启动数据库,以便脚本升级步骤运行完成。`

经过一番谷歌搜索后,我发现我可以运行它/T902 switch并尝试解决问题。但没有任何解决方案对我有用。所以我安装了相同SQL SERVER 2017和恢复数据库的另一个实例。现在新安装的实例也有同样的问题。

可能是什么问题呢?

更新 这是 SQL Server 的完整错误日志。

2018-09-17 13:06:47.29 spid6s 配置选项“显示高级选项”从 1 更改为 1。运行 RECONFIGURE 语句进行安装。

2018-09-17 …

sql-server character-set encoding sql-server-2017

16
推荐指数
1
解决办法
7282
查看次数

具有 500 个数据库的 SQL Server 2017 - 自 CU9 以来频繁的 AG 断开连接

大家好,提前感谢您的帮助。我们在 SQL Server 2017 可用性组方面遇到了挑战。

背景

公司是一家零售B2B后端软件。约500个单租户数据库,5个共享数据库供所有租户使用。工作负载特征主要是读取,并且大多数数据库的活动非常低。

托管在同一地点的物理生产服务器最近从共享 SAN/FCI 配置的 Windows Server 2012 上的 SQL Server 2014 Enterprise 升级到 Windows Server 2016 上的 SQL Server 2017 Enterprise,在 2 插槽/32 核/768 GB RAM 和本地使用 AlwaysOn AG 的 SSD 驱动器。AG 流量使用具有交叉电缆连接的专用 10G NIC 端口。

他们的要求是所有数据库一起进行故障转移,因此他们必须将它们全部放在一个 AG 中。它是同一服务器上的单个不可读取的同步副本。

新服务器已于2018年6月投入生产,安装了最新的CU(当时的CU7)和windows更新,系统运行良好。大约一个月后,在将服务器从 CU7 更新到 CU9 后,他们开始注意到以下挑战,按优先级顺序列出。

我们一直在使用 SQL Sentry 监控服务器,并没有观察到物理瓶颈。所有关键指标似乎都不错。CPU 平均为 20%,IO 时间通常小于 1ms,RAM 未充分利用,网络 <1%。

挑战

故障转移后症状似乎好转,但几天后又会出现,无论哪个服务器是主要服务器 - 两台服务器上的症状都相同。

  1. 偶发的客户端超时和连接故障,例如

    ...建立连接时发生错误...

    或者

    执行超时过期

    有时这些会持续长达 40 秒,然后消退。

  2. 事务日志备份作业的完成时间是以前的 10 倍。以前备份所有500个数据库的日志需要2-3分钟,现在需要15-25分钟。我们已经验证备份本身运行良好,吞吐量良好。但是,在完成一个日志的备份之后和开始下一个之前,会有一个小的延迟。它开始时非常低,但在一两天内达到 2-3 秒。乘以500个数据库,还是有区别的。

  3. 有时,一些看似随机的数据库会在手动故障转移后陷入“未同步”状态。解决此问题的唯一方法是重新启动辅助副本上的 SQL Server 服务,或者删除这些数据库并将其重新加入 …

sql-server availability-groups sql-server-2017

15
推荐指数
1
解决办法
1668
查看次数

尝试回收未使用的空间会导致 SQL Server 中的已用空间显着增加

我在生产数据库中有一个表,其大小为 525 GB,其中 383 GB 未使用:

未使用的空间

我想回收其中的一些空间,但是,在弄乱生产数据库之前,我正在测试数据库中数据较少的相同表上测试一些策略。这个表有一个类似的问题:

未使用的空间

关于表的一些信息:

  • 填充因子设置为 0
  • 大约有 30 列
  • 其中一列是图像类型的 LOB,它存储的文件大小从几 KB 到几百 MB
  • 该表没有任何与之关联的假设索引

服务器正在运行 SQL Server 2017 (RTM-GDR) (KB4505224) - 14.0.2027.2 (X64)。数据库正在使用SIMPLE恢复模型。

我尝试过的一些事情:

  • 重建索引:ALTER INDEX ALL ON dbo.MyTable REBUILD. 这产生了微不足道的影响。
  • 重新组织索引:ALTER INDEX ALL ON dbo.MyTable REORGANIZE WITH(LOB_COMPACTION = ON). 这产生了微不足道的影响。
  • 将 LOB 列复制到另一个表,删除该列,重新创建该列,并将数据复制回来(如这篇文章所述:释放未使用的空间 SQL Server 表)。这减少了未使用的空间,但似乎只是将其转换为已用空间:

    未使用的空间

  • 使用 bcp 实用程序导出表、截断它并重新加载它(如这篇文章所述:如何为表释放未使用的空间)。这也减少了未使用的空间并增加了与上图类似的程度。

  • 即使不推荐,我也尝试了 DBCC SHRINKFILE 和 DBCC SHRINKDATABASE 命令,但它们对未使用的空间没有任何影响。
  • 跑步DBCC CLEANTABLE('myDB', 'dbo.myTable')没什么区别
  • 在保持图像和文本数据类型以及将数据类型更改为 varbinary(max) 和 …

index sql-server storage sql-server-2017

15
推荐指数
1
解决办法
1288
查看次数

直方图外的基数估计

设置

我在理解基数估计时遇到了一些麻烦。这是我的测试设置:

  • Stack Overflow 数据库 2010 版
  • SQL Server 2017 CU15+GDR (KB4505225) - 14.0.3192.2
  • 新 CE(兼容级别 140)

我有这个过程:

USE StackOverflow2010;
GO

CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount
    @CommentCount int
AS
BEGIN
    SELECT * 
    FROM dbo.Posts p
    WHERE 
        p.CommentCount = @CommentCount
    OPTION (RECOMPILE); 
END;
GO
Run Code Online (Sandbox Code Playgroud)

dbo.Posts表上没有非聚集索引或统计信息(在 上有聚集索引Id)。

当为此要求估计计划时,“估计行数”dbo.Posts是 1,934.99:

EXEC #sp_PostsByCommentCount @CommentCount = 51;
Run Code Online (Sandbox Code Playgroud)

当我询问估计计划时,自动创建了以下统计对象:

DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]);
Run Code Online (Sandbox Code Playgroud)

SSMS 中统计输出的屏幕截图

其中的亮点是:

  • 统计数据的采样率非常低,为 1.81% (67,796 / 3,744,192)
  • 仅使用了 31 个直方图步骤
  • “所有密度”值为0.03030303(采样了 33 个不同的值)
  • RANGE_HI_KEY直方图中的最后一个是 50,其中EQ_ROWS1 …

sql-server statistics database-internals cardinality-estimates sql-server-2017

15
推荐指数
1
解决办法
471
查看次数

如何在 Ubuntu 上完全删除 SQL Server 2017?

文档包含有关如何删除 SQL Server 的说明。但是,这会留下某些包。如何删除所有痕迹并卸载 SQL Server 2017?

sql-server linux ubuntu installation sql-server-2017

14
推荐指数
1
解决办法
2万
查看次数

为什么临时表比急切线轴更有效地解决万圣节问题?

考虑以下查询,该查询仅在源表中不存在时才插入源表中的行:

INSERT INTO dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR WITH (TABLOCK)
SELECT maybe_new_rows.ID
FROM dbo.A_HEAP_OF_MOSTLY_NEW_ROWS maybe_new_rows
WHERE NOT EXISTS (
    SELECT 1
    FROM dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR halloween
    WHERE maybe_new_rows.ID = halloween.ID
)
OPTION (MAXDOP 1, QUERYTRACEON 7470);
Run Code Online (Sandbox Code Playgroud)

一种可能的计划形状包括合并连接和急切线轴。Eager spool 运算符用于解决万圣节问题

第一个计划

在我的机器上,上面的代码在大约 6900 毫秒内执行。用于创建表格的重现代码包含在问题的底部。如果我对性能不满意,我可能会尝试加载要插入到临时表中的行,而不是依赖于 Eager spool。这是一种可能的实现:

DROP TABLE IF EXISTS #CONSULTANT_RECOMMENDED_TEMP_TABLE;
CREATE TABLE #CONSULTANT_RECOMMENDED_TEMP_TABLE (
    ID BIGINT,
    PRIMARY KEY (ID)
);

INSERT INTO #CONSULTANT_RECOMMENDED_TEMP_TABLE WITH (TABLOCK)
SELECT maybe_new_rows.ID
FROM dbo.A_HEAP_OF_MOSTLY_NEW_ROWS maybe_new_rows
WHERE NOT EXISTS (
    SELECT 1
    FROM dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR halloween
    WHERE maybe_new_rows.ID = halloween.ID
)
OPTION …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals sql-server-2017

14
推荐指数
2
解决办法
1593
查看次数

将许多可空整数 1:1 转换为二进制字符串的最快方法是什么?

我的部分工作量使用了一个CLR 函数,该函数实现了诡异的哈希算法来比较行以查看是否有任何列值发生了变化。CLR 函数将二进制字符串作为输入,因此我需要一种快速的方法将行转换为二进制字符串。我希望在整个工作负载期间散列大约 100 亿行,所以我希望这段代码尽可能快。

我有大约 300 个不同架构的表。出于这个问题的目的,请假设一个简单的表结构,包含 32 个可空INT列。我在这个问题的底部提供了示例数据以及一种对结果进行基准测试的方法。

如果所有列值都相同,则行必须转换为相同的二进制字符串。如果任何列值不同,则必须将行转换为不同的二进制字符串。例如,像下面这样简单的代码将不起作用:

CAST(COL1 AS BINARY(4)) + CAST(COL2 AS BINARY(4)) + ..
Run Code Online (Sandbox Code Playgroud)

它不能正确处理 NULL。如果COL1第 1 行为COL2NULL,第 2 行为 NULL,则两行都将转换为 NULL 字符串。我相信正确处理 NULL 是正确转换整行的最难部分。INT 列的所有允许值都是可能的。

先抢答一些问题:

  • 如果重要的话,绝大多数时间 (90%+) 列都不会为 NULL。
  • 我必须使用CLR。
  • 我必须散列这么多行。我无法坚持哈希。
  • 我相信由于 CLR 函数的存在,我无法使用批处理模式进行转换。

将 32 个可INT为空的列转换为 aBINARY(X)VARBINARY(X)string的最快方法是什么?

承诺的示例数据和代码:

-- create sample data
DROP TABLE IF EXISTS dbo.TABLE_OF_32_INTS;

CREATE TABLE dbo.TABLE_OF_32_INTS (
    COL1 INT NULL,
    COL2 INT NULL, …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2017

14
推荐指数
4
解决办法
351
查看次数

不能在非唯一索引上插入重复的键行?

在过去的几天里,我们已经 3 次遇到这个奇怪的错误,在 8 周没有错误之后,我被难住了。

这是错误消息:

Executing the query "EXEC dbo.MergeTransactions" failed with the following error:
"Cannot insert duplicate key row in object 'sales.Transactions' with unique index
'NCI_Transactions_ClientID_TransactionDate'.
The duplicate key value is (1001, 2018-12-14 19:16:29.00, 304050920).".
Run Code Online (Sandbox Code Playgroud)

我们拥有的索引不是唯一的。如果您注意到,错误消息中的重复键值甚至与索引不一致。奇怪的是,如果我重新运行 proc,它会成功。

这是我能找到的最新链接,但我没有看到解决方案。

https://www.sqlservercentral.com/forums/topic/error-cannot-insert-duplicate-key-row-in-a-non-unique-index

关于我的场景的一些事情:

  • proc 正在更新 TransactionID(主键的一部分)-我认为这是导致错误的原因,但不知道为什么?我们将删除该逻辑。
  • 在表上启用更改跟踪
  • 做事务读未提交

每个表有45个字段,我主要列出了索引中用到的字段。我正在更新更新语句中的 TransactionID(集群键)(不必要)。奇怪的是,直到上周我们几个月都没有遇到任何问题。它只是通过 SSIS 偶尔发生。

桌子

USE [DB]
GO

/****** Object:  Table [sales].[Transactions]    Script Date: 5/29/2019 1:37:49 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

IF NOT EXISTS (SELECT * …
Run Code Online (Sandbox Code Playgroud)

sql-server update sql-server-2017

14
推荐指数
1
解决办法
4655
查看次数