我有一个生产数据库,它遇到了剧烈波动的页面预期寿命 (PLE) 问题。(它在随机时间崩溃为零。)
我一直在研究 PLE 问题,并发现一些似乎指向 VMWare 问题的内容,但我不确定我是否正确使用了数据。似乎我正在丢失缓冲区/缓存页面。
我正在使用这个查询:
SELECT COUNT(*) AS cached_pages_count,
CASE database_id
WHEN 32767 THEN 'ResourceDb'
ELSE DB_NAME(database_id)
END AS database_name
FROM sys.dm_os_buffer_descriptors
GROUP BY DB_NAME(database_id), database_id
ORDER BY cached_pages_count DESC;
Run Code Online (Sandbox Code Playgroud)
(在这里找到)
我正在计算 PLE 崩溃前后的结果(计数)。一个例子是之前的 1,097,820 和之后的 131,394。所以我似乎“丢失”了 966,426 页。
我的猜测是所有虚拟机的硬件都处于压力之下,因此它会随机从服务器中交换一些内存一段时间。(这只是一个猜测。)当这种情况发生时,所有页面都丢失了,因此 PLE 直线下降。
那么,我sys.dm_os_buffer_descriptors是否正确使用了视图? 从我读到的它总是显示使用过的缓冲区/缓存页面。所以如果它是空的(或显着减少),我要么不再有内存,要么是空的。(我很想用一种方法来证实这个结论。)
或者还有另一种解释为什么计数下降这么多?
我们的系统管理员管理虚拟机。我希望在使用这些数据去找他们之前了解我的查询。从数据库的角度来看,PLE 崩溃的时间似乎是随机的。(在 PLE 崩溃期间不会发生重新索引或其他高性能的事情)
我做了大量的工作,看看它是否与工作负载有关。虽然存在一个性能不佳的查询,但用完所有缓存还不够。[没有] 当缓冲区计数下降时,服务器上没有重建或其他非常规用户活动。即使是这样,我也不会在上面的查询中看到使用它吗?(意味着如果它是 SQL Server 操作,计数不会保持不变,只是内容不同吗?)
我无权访问 VMWare 设置。我希望在涉及那些做的事情之前更好地理解我的发现。这个问题的重点是确保我首先正确使用视图。
在评论链的末尾:
我试图说 PLE 问题导致我丢失了缓冲页面问题。我用来获取 PLE 的查询将显示低 PLE,因为页面正在丢失。所以他们身上的东西消失了。这是一个错误的读数,因为内存量减少了。
这是我的@@Version:
Microsoft SQL Server 2012 …Run Code Online (Sandbox Code Playgroud) 我有一个产品“Microsoft SQL Server 2012 (SP1) - 11.0.3128.0 (X64)”,它显示出奇怪的缓冲区和页面预期寿命 (PLE) 症状。
我每分钟都在我的服务器上运行这个(跟踪这个问题):
SELECT @ple = CAST([cntr_value] AS VARCHAR(20))
FROM sys.dm_os_performance_counters
WHERE [object_name] LIKE '%Manager%'
AND [counter_name] = 'Page life expectancy'
SELECT @usedBufferPages = CAST(COUNT(*) /128 AS VARCHAR(20))
FROM sys.dm_os_buffer_descriptors
DECLARE @StartDate VARCHAR(8) = Convert(VARCHAR(8), GETDATE(), 14)
RAISERROR ('%s. PLE at %s and Used Buffers at %s at %s ', 0,
1,@runCountString ,@ple, @usedBufferPages, @StartDate) WITH NOWAIT
Run Code Online (Sandbox Code Playgroud)
这是一些示例输出:
16. PLE at 858 和 Used Buffers at 7290 at 09:51:42 17. PLE at …
performance sql-server sql-server-2012 page-life-expectancy buffer-pool
假设我有父-> 子表设置。打电话给他们Shipment和Widget。
无论如何要创建一个索引视图,该视图将具有父级 (ShipmentId) 的 PK 和最新子级 (Widget.CreatedWhen) 的创建时间。
这是我正在寻找的查询:
SELECT widg.ShipmentId, MAX(widg.CreatedWhen) NewestWidget
FROM dbo.Widget widg
GROUP BY widg.ShipmentId
Run Code Online (Sandbox Code Playgroud)
显然这个查询不能是一个索引视图,因为它已经MAX在里面了。
但是是否有其他方法通过“索引视图合法”SQL 来获得类似的结果集?
据我了解,当您在表上定义列时,您就定义了其精度。该精度占用 1 个字节并存储在列级别。如果您使用 5 或更高的精度,则 DateTime2 列每行将占用 8 个字节。(精度不存储在行级别。)
但是,当您将相同的 DateTime2 转换为 VarBinary 时,它将占用 9 个字节。这是因为它需要存储在列级别的精度字节。
我很好奇这与 DateTime2 存储在内存中有何关系。假设内存中有 1,000,000 个 DateTime2(每个的精度为 5 或更高)。它会占用 8,000,000 字节内存还是 9,000,000 字节内存?
基本上,我想知道默认精度的 DateTime2 是否会比普通的 DateTime 对页面预期寿命造成更大的压力?
我每周两次使用 Visual Studio DB 项目重新创建我的开发数据库。
今天,我将我的权限固定为基于 Active Directory 组,而不是授予个人权限。
在我重新运行我的构建后,我注意到一个域/Windows 使用仍在那里。我搜索了整个数据库项目,但在任何地方都找不到该用户。
所以为了测试,我创建了一个不同的数据库(即 MyDummyDb)。果然用户也被添加到该数据库中。
该用户甚至没有有效的登录名(我也将登录名更改为基于 AD 组)。
所以我必须假设有一个服务器级别的设置来控制哪些用户被自动添加到新数据库中。
这是正确的吗?有谁知道这个设置在哪里?
所以,我有一些死锁问题。
我看到了两种解决方法。添加read uncommitted到我的数据库或执行快照隔离并添加read committed snapshot.
在对两者进行了一些研究之后,在我看来,它read uncommitted可以允许读取可能永远不会提交到数据库的数据。
另一方面,read committed snapshot只会提供最新的(它是最新的,对吗?)已提交的数据版本(即使数据可能处于更改/事务中间。)
这是正确的吗?
如果是这样,我倾向于快照隔离(我真的不想返回处于更改过程中的数据。)
但是,我的 DBA 告诉我,他最后听说快照隔离存在“问题”。(他没有详细说明问题所在,只是说它不是企业就绪功能。)
所以,这里是我关于快照隔离的问题:
快照隔离功能强大吗?它只是有效吗?
或者是否有我需要注意的“陷阱”?
我一直在尝试让以前工作的复制开始工作。
我尝试了很多设置,但我似乎无法让它工作。
这是场景。我从目标数据库中删除了所有 FK 约束(称之为 DestDB)。
然后我重新初始化我的复制,当我运行时,我收到这个(去标识化)错误:
ALTER TABLE 语句与 FOREIGN KEY 约束“FK_TableOnlyInDestDB_MyReplicatedTable”冲突。冲突发生在数据库“DestDB”、表“SomeSchema.MyReplicatedTable”、“MyReplicatedTableId”列中。(来源:MSSQLServer,错误号:547)
它让我发疯,因为该数据库中不存在指示的 FK。
现在,我确实从另一个数据库复制了这个数据库(备份和恢复)。所以我唯一能想到的是它以某种方式穿越了溪流。
但这似乎不太可能。
任何想法都会很棒!
注意:这是我运行的查询,以确保我没有 FK(它没有返回任何行):
use DestDB
SELECT f.name AS ForeignKey,
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
Run Code Online (Sandbox Code Playgroud)
我还检查以确保有问题的 FK 不在源表上(在我从中复制的数据库中)。
我也试过: EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
也试过 Dropping MyReplicatedTable。删除就好了,复制重新创建了它。(但仍然给了我错误。)
我尝试创建一个空数据库作为订阅者。效果很好,所以是 DestDB 中的某些东西导致了问题,但 ERROR 中的 FK 不存在。
我有几个大表需要复制到事务数据库上的分区副本中。
我担心这会对我的生产应用程序的性能造成影响。
为了缓解这种情况,我正在研究资源调控器。我将设置我的脚本以使用限制为最多 5% CPU 和内存的资源池。
关于这一点,我不确定的唯一部分是对 PLE 的影响。
据我了解,表中的选择会将值读入缓存。这将强制排除缓存中的其他内容。(PLE 的基本概念。)但是“强制退出”的项目会被限制在我指定的 5% 之内吗?
意思是在我使用了 5% 的内存后,它是否只会强制排除相同 5% 中的缓存项目?(其他 95% 不受影响。)
另一种提问方式是:5% 的内存限制是否与 5% 的缓存限制相同?
sql-server sql-server-2012 resource-governor page-life-expectancy
我做了一个例子来让我展示我的问题是什么:
设置:
CREATE TABLE [dbo].[Test](
[TestId] [bigint] IDENTITY(1,1) NOT NULL,
[ParentTestId] [bigint] NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([TestId] ASC)
)
GO
ALTER TABLE [dbo].[Test] WITH CHECK ADD CONSTRAINT [FK_Test_ParentTest]
FOREIGN KEY([ParentTestId])
REFERENCES [dbo].[Test] ([TestId])
GO
ALTER TABLE [dbo].[Test] CHECK CONSTRAINT [FK_Test_ParentTest]
GO
DECLARE @iter INT
SET @iter = 1
WHILE @iter < 1000
BEGIN
INSERT INTO dbo.Test ( ParentTestId )
VALUES ( null ),( null ),( null ),( null ),( null ),( null ),( null ),( null ),
( …Run Code Online (Sandbox Code Playgroud) 我刚刚获得了一个 Sql Server 2016 可用性组设置(一个主节点、一个同步辅助节点和一个异步辅助节点)。我在服务器上有五个数据库。
我设置了一个应用程序来对服务器运行查询(使用带有“故障转移伙伴”连接字符串的实体框架。)
当我尝试通过重新启动主服务器来测试故障转移时,出现以下错误:
服务器 MySecondaryServer,数据库主服务器没有配置数据库镜像。
像这样镜像系统数据库似乎很奇怪,所以我们没有将它设置为“可用性数据库”之一。
所以,这是我的问题:我是否应该将主数据库添加到“可用性数据库”列表中,如果我这样做会导致问题吗?
sql-server ×10
buffer-pool ×2
foreign-key ×2
performance ×2
datetime ×1
deadlock ×1
delete ×1
replication ×1