评估合理缓冲池大小的确定性方法是什么?

Han*_*non 29 sql-server sql-server-2008-r2 sql-server-2012

我试图想出一种理智的方法来了解max server memory (mb)设置是否合适(应该更低,或更高,或保持原状)。我知道max server memory (mb)应该总是足够低,以便为操作系统本身等留出空间。

我正在查看的环境有数百台服务器;我需要一个可靠的公式来确定缓冲池的当前大小是否合适,因为 RAM 是按分配给每个服务器的 GB 计算的。整个环境都是虚拟化的,分配给 VM 的“物理”RAM 可以轻松地向上或向下更改。

我有一个特定的 SQL Server 实例,我现在查看的 PLE 为 1,100,052 秒,相当于 12.7 天(服务器启动的时间)。服务器的最大服务器内存设置为 2560MB (2.5GB),其中实际仅提交 1380MB (1.3GB)。

我已经阅读了几篇文章,包括 Jonathan Keheyias(帖子)和 Paul Randal(帖子)的另一篇文章,以及其他几篇文章。Jonathan 主张监控每 4GB缓冲池低于 300 的 PLE太低了。对于上面的 SQL Server 实例,300 * (2.5 / 4) = 187导致目标 PLE 非常低,低于 300。此实例具有 290GB 的 SQL Server 数据(不包括日志文件),仅用于集成测试。假设在过去的12天代表该服务器的典型用法的,我想说的max server memory (mb)设置可能会降低。

在规模的另一端,我有另一个 PLE 为 294 的集成测试服务器,它的max server memory (mb)设置仅为 1GB。该服务器只有 224MB 的 SQL Server 数据(不包括日志),并且正在运行一些 BizFlow 数据库。此服务器可能会受益于更高的max server memory (mb)设置。

对于可能分配了过多内存的目标,我认为一个好的起点可能包括查看:

SELECT 
    RamMB = physical_memory_in_bytes / 1048576
    , BufferPoolCommittedMB = bpool_committed * 8192E0 / 1048576
    , BufferPoolCommitTargetMB = bpool_commit_target * 8192E0 / 1048576
    , PercentOfDesiredSizeMB = CONVERT(INT,(CONVERT(DECIMAL(18,2),bpool_committed) 
                            / bpool_commit_target) * 100)
FROM sys.dm_os_sys_info;
Run Code Online (Sandbox Code Playgroud)

如果BufferPoolCommitTargetMB / BufferPoolCommittedMB大于 1,则服务器未使用整个缓冲池。如果有问题的机器的 PLE 也大于“x”,那么它可能是减少max server memory (mb).

由于Buffer Manager:Lazy writes/sec性能计数器跟踪 SQLOS 由于内存压力而在检查点之间将页面写出到磁盘的次数,这可能是另一个值得关注的好事情。

DECLARE @WaitTime DATETIME;
SET @WaitTime = '00:00:15';
DECLARE @NumSeconds INT;
SET @NumSeconds = DATEDIFF(SECOND, 0, @WaitTime);
DECLARE @LazyWrites1 BIGINT;
DECLARE @LazyWrites2 BIGINT;

SELECT @LazyWrites1 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE 'Lazy writes/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = 'MSSQL$' + CONVERT(VARCHAR(255),
               SERVERPROPERTY('InstanceName')) + ':Buffer Manager';

WAITFOR DELAY @WaitTime;

SELECT @LazyWrites2 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE 'Lazy writes/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = 'MSSQL$' + CONVERT(VARCHAR(255),
               SERVERPROPERTY('InstanceName')) + ':Buffer Manager';

SELECT LazyWritesPerSecond = (@LazyWrites2 - @LazyWrites1) / @NumSeconds;
Run Code Online (Sandbox Code Playgroud)

上面的代码假设服务器在运行的 15 秒内处于负载状态,否则会报告 0;这可能是一个误导性的假阴性。

我还应该查看PAGELATCHIO_*等待统计数据或其他一些等待类型作为内存压力的指标,还是缺乏内存压力?

我的问题是,我如何可靠地确定 PLE 和 的“好”目标值max server memory (mb)

Sha*_*nky 12

正如您已经知道的,没有计算最大服务器内存的通用公式,您可以进行一些快速数学运算并得出一个值,但您最终仍然需要 Perfmon 计数器的帮助来监控内存使用情况并相应地进行更改。我知道下面的通用公式,我也使用它。我从这个链接学到了这个公式

对于 SQL Server 2005 到 2008 R2

请注意,从 SQL Server 2005 到 2008 R2,最大服务器内存仅控制缓冲池。所以最大服务器内存配置在这里有点乏味并且涉及很少的计算

  1. 立即为 Windows 操作系统留出 2 G 内存。

  2. 当然,系统会运行防病毒软件。请为防病毒留出 1.5G。请注意,Mcafee 和 SQL Server 不会齐头并进,因此请确保为它留出足够的空间。您还可以检查 perfmon 计数器Perfmon Process-> Private bytes and Working Set以监视 AV 和 SQL Server 上运行的其他小型应用程序的内存使用情况

在此处输入图片说明

  1. 考虑驱动程序/固件的内存要求。您必须根据系统上安装的驱动程序的内存要求得出它。RAMMAP 工具可以提供帮助

  2. 考虑 SQL Server 的 NonbPool(又名 MTL 或 MTR)内存要求。

    select  sum(multi_pages_kb)/1024 as multi_pages_mb from  sys.dm_os_memory_clerks
    
    Run Code Online (Sandbox Code Playgroud)

    +最大工作线程 * 2MB

    +在大多数情况下,用于直接 Windows 分配的内存约为 0 到 300 MB,但如果 SQL Server 进程中加载​​了许多 3 方组件(包括链接服务器 dll、3rd 方备份 dll 等),则可能需要增加内存

    +如果您广泛使用 CLR,请为 CLR 添加一些额外的内存。

  3. 考虑将在服务器上运行的作业(包括复制代理、日志传送等)和包的内存要求。根据运行的作业数量,它可以从 MB 到 GB。对于中型服务器,您可以将其视为 250 MB

  4. 确保操作系统有足够的可用空间。

    大约(每 GB 100 MB 直到 4G)+(每额外 GB 50 MB,直到 12GB)+(每额外 GB 25 MB,直到您的 RAM 大小)

  5. 其他内存要求。

    如果您有任何其他特定于您的环境的内存要求。

    最大服务器内存= 总物理内存 – (1+2+3+4+5+6+7)

    我没有包括 SSIS.SSRS 的内存配置,SSAS 您还需要从总物理服务器内存中减去这些服务所需的内存。

    完成以上配置后,您需要监控以下计数器

  • SQLServer:缓冲区管理器--页面预期寿命(PLE):

  • SQLServer:Buffer Manager--CheckpointPages/sec:

  • SQLServer:Memory Manager--Memory Grants Pending:

  • SQLServer:memory Manager--目标服务器内存:

  • SQLServer:memory Manager--服务器总内存

对于 SQL Server 2012/2014。

From SQL Server 2012 onwards设置最大服务器内存变得很容易。因为现在最大服务器内存几乎占了所有内存消耗。最大服务器内存控制 SQL Server 内存分配,包括缓冲池、编译内存、所有缓存、qe 内存授予、锁管理器内存和 CLR 内存(基本上是 dm_os_memory_clerks 中的任何“clerk”)。线程堆栈、堆、除 SQL Server 之外的链接服务器提供程序的内存或由“非 SQL Server”DLL 分配的任何内存不受最大服务器内存控制。

您可以将 75-80% 分配给 SQL Server,然后使用 perfmon 计数器来监视内存使用情况。在 SQL Server 2012 中,一些性能计数器已被弃用。不推荐使用缓冲区管理器计数器,您必须使用内存管理器计数器

  • SQL Server:内存管理器——目标服务器内存 (KB)

  • SQL Server:内存管理器--服务器总内存 (KB)

  • SQL Server:内存管理器 - 可用内存 (KB)

  • SQL Server:内存管理器--数据库缓存内存 (KB)

关于 PLE 的价值,我使用了 Joanthan 的公式,幸运的是它对我有用。


Bre*_*zar 6

这里的挑战是数字没有考虑最终用户体验。

很好的例子:我有数据库服务器用来跟踪公司员工访问的每个网站。我不在乎它在峰值负载期间是否跟不上插入,因为前端应用程序会定期批量关闭插入,而缓慢的插入不会给用户带来问题。用户仍然可以在网上冲浪而不会被缓慢的插入所阻碍。

在 SELECT 时间,当被要求提供给定员工的可疑浏览历史记录时,HR 部门只会触发报告,但他们并不关心报告需要多长时间 - 他们只是打开报告并去做其他事情。

性能需要从一个问题开始:用户对性能满意吗?如果是这样,请将系统留在原处。

  • James - 一般来说,我不想做出导致用户抱怨的更改。如果您确实想这样做,您可以逐渐减少每个服务器的内存量,直到用户开始抱怨,但是当我已经过度工作时,我通常没有时间采取这些步骤。我必须专注于让不开心的用户开心的任务——而不是试图让开心的用户不开心。;-) (2认同)
  • 好点,布伦特。我被要求查看是否有一些服务器被过度配置,因为我们每年为每 GB 内存付费。我正在查看的许多实例在“最大服务器内存 (mb)”中都有我认为非常少量的 RAM,因此我非常不愿意缩小它们的大小。但是,其他一些实例有 1,000,000 + PLE,因此很明显是 RAM 下降的潜在候选者。显然,降低 RAM 会导致 IOps 增加,我不确定 * 那 * 的成本是多少。 (2认同)