-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
max_server_memory.sql
205 lines (165 loc) · 6.04 KB
/
max_server_memory.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
Max Server Memory Calculator
https://bornsql.ca/memory/
Copyright (c) BornSQL.ca
Written by Randolph West, released under the MIT License
Last updated: 8 January 2022
Based on an original algorithm by Jonathan Kehayias:
https://www.sqlskills.com/blogs/jonathan/how-much-memory-does-my-sql-server-actually-need/
Max Worker Thread Stack calculation based on Tiger Toolbox Maintenance Solution.
Copyright (c) Microsoft Corporation. All rights reserved.
https://github.com/Microsoft/tigertoolbox/tree/master/MaintenanceSolution
SQL Server, on a standalone instance, requires the following reserved RAM for a server:
- 1 GB of RAM for the OS
- plus 1 GB for each 4 GB of RAM installed from 4 - 16 GB
- plus 1 GB for every 8 GB RAM installed above 16 GB RAM
Memory for the Thread Stack can also be taken into account:
- 32-bit, reserve 512KB per thread * Max Worker Threads
- 64-bit, reserve 2MB per thread * Max Worker Threads
- 128-bit, reserve 4MB per thread * Max Worker Threads
Thanks to @sqlEmt and @sqlstudent144 for testing.
Thanks to the Tiger Team for version number and thread stack calculations.
v1.0 - 2016-08-19 - Initial release.
v1.1 - 2016-11-22 - Thread stack reservation; NUMA affinity; new version check.
v1.2 - 2018-09-07 - Removed reference to errant DMV.
v1.3 - 2020-03-17 - Happy St. Patrick's Day.
v1.4 - 2020-06-19 - Fixes to comments and formatting.
v1.5 - 2022-01-08 - Add debug mode.
*/
-- Set this to 1 if you want to configure NUMA Node Affinity
DECLARE @configureNumaNodeAffinity BIT = 0;
-- Set this to 1 if you want to specify a RAM amount
DECLARE @debug BIT = 0;
-- If @debug is set to 1, specify physical memory in MB here
-- For example, if you have 1.82 TB of RAM, use 1908408
DECLARE @physicalMemoryInMb DECIMAL(20, 4) = 1908408;
DECLARE @physicalMemorySource DECIMAL(20, 4);
DECLARE @physicalMemory DECIMAL(20, 4);
DECLARE @recommendedMemory DECIMAL(20, 4);
DECLARE @overheadMemory DECIMAL(20, 4);
DECLARE @cpuArchitecture DECIMAL(20, 4);
DECLARE @numaNodes INT;
DECLARE @numaNodesAfinned TINYINT;
DECLARE @maxWorkerThreadCount INT;
DECLARE @threadStack DECIMAL(20, 4);
SELECT @cpuArchitecture = CASE
WHEN @@VERSION LIKE '%<X64>%' THEN
2
WHEN @@VERSION LIKE '%<IA64>%' THEN
4
ELSE
0.5
END;
SELECT @numaNodes = COUNT(DISTINCT [parent_node_id])
FROM [sys].[dm_os_schedulers]
WHERE [scheduler_id] < 255
AND [parent_node_id] < 64;
SELECT @numaNodesAfinned = COUNT(DISTINCT [parent_node_id])
FROM [sys].[dm_os_schedulers]
WHERE [scheduler_id] < 255
AND [parent_node_id] < 64
AND [is_online] = 1;
SELECT @maxWorkerThreadCount = [max_workers_count]
FROM [sys].[dm_os_sys_info];
SELECT @threadStack = @maxWorkerThreadCount * @cpuArchitecture / 1024.0;
-- Get physical RAM on server, or if @debug is set to 1
-- use the value from @physicalMemoryInMb
IF @debug = 1
BEGIN
SELECT @physicalMemorySource = @physicalMemoryInMb;
END;
ELSE
BEGIN
-- Get physical RAM on server
SELECT @physicalMemorySource
= CAST([total_physical_memory_kb] AS DECIMAL(20, 4)) / CAST((1024.0) AS DECIMAL(20, 4))
FROM [sys].[dm_os_sys_memory];
END;
-- Convert to nearest GB
SELECT @physicalMemory = CEILING(@physicalMemorySource / CAST(1024.0 AS DECIMAL(20, 4)));
IF (@physicalMemory <= 2.0)
BEGIN
SELECT @overheadMemory = 0.5;
END;
IF (@physicalMemory > 2.0 AND @physicalMemory < 4.0)
BEGIN
SELECT @overheadMemory = 2.0;
END;
IF (@physicalMemory >= 4.0 AND @physicalMemory <= 16.0)
BEGIN
SELECT @overheadMemory = 1.0 /* Operating System minimum */
+ (@physicalMemory / 4.0);
END;
IF (@physicalMemory > 16.0)
BEGIN
SELECT @overheadMemory = 1.0 /* Operating System minimum */ + 4.0 /* add in reserved for <= 16GB */
+ ((@physicalMemory - 16.0) / 8.0);
END;
-- Add in the Max Worker Threads Overhead
SELECT @overheadMemory = @overheadMemory + @threadStack;
DECLARE @editionId BIGINT = CAST(SERVERPROPERTY('EditionID') AS BIGINT);
DECLARE @enterprise BIT = 0;
DECLARE @developer BIT = 0;
DECLARE @override BIT = 0;
IF (@editionId IN ( 1804890536, 1872460670, 610778273 ))
BEGIN
SELECT @enterprise = 1;
END;
IF (@editionId = -2117995310)
BEGIN
SELECT @developer = 1;
END;
-- Check for Standard Edition Limitations
IF (@enterprise = 0 AND @developer = 0)
BEGIN
DECLARE @ProductVersion INT = CONVERT(INT, (@@MICROSOFTVERSION / 0x1000000) & 0xff);
IF (@ProductVersion >= 11)
AND (@physicalMemory > 128)
BEGIN
SELECT @overheadMemory = 1.0 + 4.0 + ((128 - 16.0) / 8.0);
-- Set the memory value to the max allowed, if there is enough headroom
IF (@physicalMemory - @overheadMemory >= 128)
SELECT @recommendedMemory = 128,
@overheadMemory = 0,
@override = 1;
END;
IF (@ProductVersion < 11)
AND (@physicalMemory > 64)
BEGIN
SELECT @overheadMemory = 1.0 + 4.0 + ((64 - 16.0) / 8.0);
-- Set the memory value to the max allowed, if there is enough headroom
IF (@physicalMemory - @overheadMemory >= 64)
SELECT @recommendedMemory = 64,
@overheadMemory = 0,
@override = 1;
END;
END;
IF (@override = 0)
BEGIN
SELECT @recommendedMemory = @physicalMemory - @overheadMemory;
END;
-- Configure NUMA Affinity
IF (@configureNumaNodeAffinity = 1)
BEGIN
SELECT @recommendedMemory = (@recommendedMemory / @numaNodes) * @numaNodesAfinned;
END;
SELECT @@VERSION AS [Version],
CASE
WHEN (@enterprise = 1) THEN
'Enterprise Edition'
WHEN (@developer = 1) THEN
'Developer Edition'
ELSE
'Non-Enterprise Edition'
END AS [Edition],
CAST(@physicalMemorySource AS INT) AS [Physical RAM (MB)],
[c].[value] AS [Configured Value (MB)],
[c].[value_in_use] AS [Running Value (MB)],
CAST(@recommendedMemory * 1024 AS INT) AS [Recommended Value (MB)],
N'EXEC sp_configure ''show advanced options'', 1; RECONFIGURE WITH OVERRIDE; EXEC sp_configure ''max server memory (MB)'', '
+ CAST(CAST(@recommendedMemory * 1024 AS INT) AS NVARCHAR(20))
+ '; EXEC sp_configure ''show advanced options'', 0; RECONFIGURE WITH OVERRIDE;' AS [Script]
FROM [sys].[configurations] AS [c]
WHERE [c].[name] = N'max server memory (MB)'
OPTION (RECOMPILE);
GO