Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlMemory: Allow setting of dynamic value for min server memory #1397 #1695

Merged
merged 13 commits into from
Apr 17, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- SqlSetup
- The helper function `Connect-SqlAnalysis` was using `LoadWithPartial()`
to load the assembly _Microsoft.AnalysisServices_. On a node where multiple
instances with different versions of SQL Server (regardless of features)
is installed, this will result in the first assembly found in the
GAC will be loaded into the session, not taking versions into account.
This can result in an assembly version being loaded that is not compatible
with the version of SQL Server it was meant to be used with.
A new method of loading the assembly _Microsoft.AnalysisServices_ was
introduced under a feature flag; `'AnalysisServicesConnection'`.
This new functionality depends on the [SqlServer](https://www.powershellgallery.com/packages/SqlServer)
module, and must be present on the node. The [SqlServer](https://www.powershellgallery.com/packages/SqlServer)
module can be installed on the node by leveraging the new DSC resource
`PSModule` in the [PowerShellGet](https://www.powershellgallery.com/packages/PowerShellGet/2.1.2)
module (v2.1.2 and higher). This new method does not work with the
SQLPS module due to the SQLPS module does not load the correct assembly,
while [SqlServer](https://www.powershellgallery.com/packages/SqlServer)
module (v21.1.18080 and above) does. The new functionality is used
when the parameter `FeatureFlag` is set to `'AnalysisServicesConnection'`.
This functionality will be the default in a future breaking release.
- Under a feature flag `'AnalysisServicesConnection'`. The detection of
a successful connection to the SQL Server Analysis Services has also been
changed. Now it actually evaluates the property `Connected` of the returned
`Microsoft.AnalysisServices.Server` object. The new functionality is used
when the parameter `FeatureFlag` is set to `'AnalysisServicesConnection'`.
This functionality will be the default in a future breaking release.

### Added

- SqlMemory
- Added two new optional parameters MinMemoryPercent and MaxMemoryPercent.
Provides the ability to set the minimum and/or maximum buffer pool used by
the SQL Server instance as a percentage of total server memory.
([issue #1397](https://github.com/dsccommunity/SqlServerDsc/issues/1397)).

## [15.1.1] - 2021-02-12

### Fixed
Expand Down
1 change: 1 addition & 0 deletions RequiredModules.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@
PSDscResources = '2.12.0.0'
StorageDsc = '4.9.0.0'
NetworkingDsc = '7.4.0.0'
PowerShellGet = '2.1.2'
}

154 changes: 147 additions & 7 deletions source/DSCResources/DSC_SqlMemory/DSC_SqlMemory.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,18 @@ function Get-TargetResource
This is the minimum amount of memory, in MB, in the buffer pool used by
the instance of SQL Server.

.PARAMETER MinMemoryPercent
This is the minimum amount of memory, as a percentage of total server memory, in the buffer pool used by
the instance of SQL Server.

.PARAMETER MaxMemory
This is the maximum amount of memory, in MB, in the buffer pool used by
the instance of SQL Server.

.PARAMETER MaxMemoryPercent
This is the maximum amount of memory, as a percentage of total server memory, in the buffer pool used by
the instance of SQL Server.

.PARAMETER ProcessOnlyOnActiveNode
Specifies that the resource will only determine if a change is needed if
the target node is the active host of the SQL Server instance.
Expand Down Expand Up @@ -123,10 +131,20 @@ function Set-TargetResource
[System.Int32]
$MinMemory,

[Parameter()]
[ValidateRange(1, 100)]
[System.Int32]
$MinMemoryPercent,

[Parameter()]
[System.Int32]
$MaxMemory,

[Parameter()]
[ValidateRange(1, 100)]
[System.Int32]
$MaxMemoryPercent,

[Parameter()]
[System.Boolean]
$ProcessOnlyOnActiveNode
Expand All @@ -151,6 +169,12 @@ function Set-TargetResource
New-InvalidArgumentException -ArgumentName 'MaxMemory' -Message $errorMessage
}

if ($MaxMemoryPercent)
{
$errorMessage = $script:localizedData.MaxMemoryPercentParamMustBeNull
New-InvalidArgumentException -ArgumentName 'MaxMemoryPercent' -Message $errorMessage
}

$MaxMemory = Get-SqlDscDynamicMaxMemory

Write-Verbose -Message (
Expand All @@ -159,21 +183,56 @@ function Set-TargetResource
}
else
{
if (-not $MaxMemory)
if (-not $MaxMemory -and -not $MaxMemoryPercent)
{
$errorMessage = $script:localizedData.MaxMemoryParamMustNotBeNull
New-InvalidArgumentException -ArgumentName 'MaxMemory' -Message $errorMessage
}
}

Write-Verbose -Message (
$script:localizedData.MaximumMemoryLimited -f $InstanceName, $MaxMemory
)
if ($MaxMemory)
{
if ($MaxMemoryPercent)
{
$errorMessage = $script:localizedData.MaxMemoryPercentParamMustBeNull
New-InvalidArgumentException -ArgumentName 'MaxMemoryPercent' -Message $errorMessage
}

$sqlServerObject.Configuration.MaxServerMemory.ConfigValue = $MaxMemory
$sqlServerObject.Configuration.MaxServerMemory.ConfigValue = $MaxMemory

Write-Verbose -Message (
$script:localizedData.MaximumMemoryLimited -f $InstanceName, $MaxMemory
)
}
elseif ($MaxMemoryPercent)
{
$MaxMemory = Get-SqlDscPercentMemory -PercentMemory $MaxMemoryPercent

$sqlServerObject.Configuration.MaxServerMemory.ConfigValue = $MaxMemory

Write-Verbose -Message (
$script:localizedData.MaximumMemoryLimited -f $InstanceName, $MaxMemory
)
}

if ($MinMemory)
{
if ($MinMemoryPercent)
{
$errorMessage = $script:localizedData.MinMemoryPercentParamMustBeNull
New-InvalidArgumentException -ArgumentName 'MinMemoryPercent' -Message $errorMessage
}

$sqlServerObject.Configuration.MinServerMemory.ConfigValue = $MinMemory

Write-Verbose -Message (
$script:localizedData.MinimumMemoryLimited -f $InstanceName, $MinMemory
)
}
elseif ($MinMemoryPercent)
{
$MinMemory = Get-SqlDscPercentMemory -PercentMemory $MinMemoryPercent

$sqlServerObject.Configuration.MinServerMemory.ConfigValue = $MinMemory

Write-Verbose -Message (
Expand Down Expand Up @@ -238,10 +297,18 @@ function Set-TargetResource
This is the minimum amount of memory, in MB, in the buffer pool used by
the instance of SQL Server.

.PARAMETER MinMemoryPercent
This is the minimum amount of memory, as a percentage of total server memory, in the buffer pool used by
the instance of SQL Server.

.PARAMETER MaxMemory
This is the maximum amount of memory, in MB, in the buffer pool used by
the instance of SQL Server.

.PARAMETER MaxMemoryPercent
This is the maximum amount of memory, as a percentage of total server memory, in the buffer pool used by
the instance of SQL Server.

.PARAMETER ProcessOnlyOnActiveNode
Specifies that the resource will only determine if a change is needed if
the target node is the active host of the SQL Server instance.
Expand Down Expand Up @@ -276,10 +343,20 @@ function Test-TargetResource
[System.Int32]
$MinMemory,

[Parameter()]
[ValidateRange(1, 100)]
[System.Int32]
$MinMemoryPercent,

[Parameter()]
[System.Int32]
$MaxMemory,

[Parameter()]
[ValidateRange(1, 100)]
[System.Int32]
$MaxMemoryPercent,

[Parameter()]
[System.Boolean]
$ProcessOnlyOnActiveNode
Expand Down Expand Up @@ -346,6 +423,12 @@ function Test-TargetResource
New-InvalidArgumentException -ArgumentName 'MaxMemory' -Message $errorMessage
}

if ($MaxMemoryPercent)
{
$errorMessage = $script:localizedData.MaxMemoryPercentParamMustBeNull
New-InvalidArgumentException -ArgumentName 'MaxMemoryPercent' -Message $errorMessage
}

$MaxMemory = Get-SqlDscDynamicMaxMemory

Write-Verbose -Message (
Expand All @@ -354,13 +437,26 @@ function Test-TargetResource
}
else
{
if (-not $MaxMemory)
if (-not $MaxMemory -and -not $MaxMemoryPercent)
{
$errorMessage = $script:localizedData.MaxMemoryParamMustNotBeNull
New-InvalidArgumentException -ArgumentName 'MaxMemory' -Message $errorMessage
}
}

if ($MaxMemory)
{
if ($MaxMemoryPercent)
{
$errorMessage = $script:localizedData.MaxMemoryPercentParamMustBeNull
New-InvalidArgumentException -ArgumentName 'MaxMemoryPercent' -Message $errorMessage
}
}
elseif ($MaxMemoryPercent)
{
$MaxMemory = Get-SqlDscPercentMemory -PercentMemory $MaxMemoryPercent
}

if ($MaxMemory -ne $currentMaxMemory)
{
Write-Verbose -Message (
Expand All @@ -370,8 +466,21 @@ function Test-TargetResource
$isServerMemoryInDesiredState = $false
}

if ($MinMemory)
if ($MinMemory -or $MinMemoryPercent)
{
if ($MinMemory)
{
if ($MinMemoryPercent)
{
$errorMessage = $script:localizedData.MinMemoryPercentParamMustBeNull
New-InvalidArgumentException -ArgumentName 'MinMemoryPercent' -Message $errorMessage
}
}
elseif ($MinMemoryPercent)
{
$MinMemory = Get-SqlDscPercentMemory -PercentMemory $MinMemoryPercent
}

if ($MinMemory -ne $currentMinMemory)
{
Write-Verbose -Message (
Expand Down Expand Up @@ -447,3 +556,34 @@ function Get-SqlDscDynamicMaxMemory
$maxMemory
}

<#
.SYNOPSIS
This function returns the amount of memory in MB, calculated from the input percentage of total server memory.

.PARAMETER MemoryPercent
This is the percentage of total server memory to calculate.
#>
function Get-SqlDscPercentMemory
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[ValidateRange(1, 100)]
[System.Int32]
$PercentMemory
)

try
{
$physicalMemory = (Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory
$memoryInMegaBytes = [Math]::Round(($physicalMemory * ($PercentMemory/100)) / 1MB)
}
catch
{
$errorMessage = $script:localizedData.ErrorGetPercentMemory
New-InvalidOperationException -Message $errorMessage -ErrorRecord $_
}

$memoryInMegaBytes
}
2 changes: 2 additions & 0 deletions source/DSCResources/DSC_SqlMemory/DSC_SqlMemory.schema.mof
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class DSC_SqlMemory : OMI_BaseResource
[Write, Description("If set to `$true` then max memory will be dynamically configured. When this parameter is set to `$true`, the parameter **MaxMemory** must be set to `$null` or not be configured. Default value is `$false`.")] Boolean DynamicAlloc;
[Write, Description("Minimum amount of memory, in MB, in the buffer pool used by the instance of _SQL Server_.")] SInt32 MinMemory;
[Write, Description("Maximum amount of memory, in MB, in the buffer pool used by the instance of _SQL Server_.")] SInt32 MaxMemory;
[Write, Description("Minimum amount of memory, as a percentage of total server memory, in the buffer pool used by the instance of _SQL Server_.")] SInt32 MinMemoryPercent;
[Write, Description("Maximum amount of memory, as a percentage of total server memory, in the buffer pool used by the instance of _SQL Server_.")] SInt32 MaxMemoryPercent;
[Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the _SQL Server_ instance.")] Boolean ProcessOnlyOnActiveNode;
[Read, Description("Returns if the current node is actively hosting the _SQL Server_ instance.")] Boolean IsActiveNode;
};
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
ConvertFrom-StringData @'
GetMemoryValues = Getting the current values for minimum and maximum SQL server memory for instance '{0}'.
SetNewValues = Setting the minimum and maximum memory that will be used by the instance '{0}'.
MaxMemoryParamMustBeNull = The parameter MaxMemory must be null when the parameter DynamicAlloc is set to true.
MaxMemoryParamMustNotBeNull = The parameter MaxMemory must not be null when the parameter DynamicAlloc is set to false.
MaxMemoryParamMustBeNull = The parameter MaxMemory must be null when the parameter DynamicAlloc is set to true or MaxMemoryPercent has a value.
MaxMemoryPercentParamMustBeNull = The parameter MaxMemoryPercent must be null when the parameter DynamicAlloc is set to true or MaxMemory has a value.
MaxMemoryParamMustNotBeNull = One of the parameters MaxMemory or MaxMemoryPercent must not be null when the parameter DynamicAlloc is set to false.
MinMemoryPercentParamMustBeNull = The parameter MinMemoryPercent must be null when the parameter MinMemory has a value.
DynamicMaxMemoryValue = Dynamic maximum memory has been calculated to {0}MB.
MaximumMemoryLimited = Maximum memory used by the instance '{0}' has been limited to {1}MB.
MinimumMemoryLimited = Minimum memory used by the instance '{0}' has been set to {1}MB.
DefaultValues = Resetting to the default values; MinMemory = {0}, MaxMemory = {1}.
ResetDefaultValues = Minimum and maximum server memory values used by the instance {0} has been reset to the default values.
AlterServerMemoryFailed = Failed to alter the server configuration memory for {0}\\{1}.
ErrorGetDynamicMaxMemory = Failed to calculate dynamically the maximum memory.
ErrorGetPercentMemory = Failed to calculate percentage of memory.
EvaluatingMinAndMaxMemory = Determines the values of the minimum and maximum memory server configuration option for the instance '{0}'.
NotActiveNode = The node '{0}' is not actively hosting the instance '{1}'. Will always return success for this resource on this node, until this node is actively hosting the instance.
WrongMaximumMemory = Current maximum server memory used by the instance is {0}MB, but expected {1}MB.
Expand Down
32 changes: 1 addition & 31 deletions source/DSCResources/DSC_SqlSetup/DSC_SqlSetup.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ function Get-TargetResource
$getTargetResourceReturnValue.ASSvcAccountUsername = $serviceAnalysisService.UserName
$getTargetResourceReturnValue.AsSvcStartupType = $serviceAnalysisService.StartupType

$analysisServer = Connect-SQLAnalysis -ServerName $sqlHostName -InstanceName $InstanceName
$analysisServer = Connect-SQLAnalysis -ServerName $sqlHostName -InstanceName $InstanceName -FeatureFlag $FeatureFlag

$getTargetResourceReturnValue.ASCollation = $analysisServer.ServerProperties['CollationName'].Value
$getTargetResourceReturnValue.ASDataDir = $analysisServer.ServerProperties['DataDir'].Value
Expand Down Expand Up @@ -2505,36 +2505,6 @@ function Get-InstalledSharedFeatures
return $sharedFeatures
}

<#
.SYNOPSIS
Test if the specific feature flag should be enabled.

.PARAMETER FeatureFlag
An array of feature flags that should be compared against.

.PARAMETER TestFlag
The feature flag that is being check if it should be enabled.
#>
function Test-FeatureFlag
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[Parameter()]
[System.String[]]
$FeatureFlag,

[Parameter(Mandatory = $true)]
[System.String]
$TestFlag
)

$flagEnabled = $FeatureFlag -and ($FeatureFlag -and $FeatureFlag.Contains($TestFlag))

return $flagEnabled
}

<#
.SYNOPSIS
Get current properties for the feature SQLENGINE.
Expand Down
5 changes: 3 additions & 2 deletions source/DSCResources/DSC_SqlSetup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,10 @@ more feature flags can be added to the parameter `FeatureFlag`, i.e.
>from one release to another, including having breaking changes.

<!-- markdownlint-disable MD013 -->
Flag | Description
Feature flag | Description
--- | ---
\- | -
DetectionSharedFeatures | A new way of detecting if the shared features is installed or not. This was implemented because the previous implementation did not work fully with SQL Server 2017.
AnalysisServicesConnection | A new method of loading the assembly *Microsoft.AnalysisServices*. Using this, no longer is the helper function `Connect-SqlAnalysis` using `LoadWithPartial()` to load the assembly **Microsoft.AnalysisServices**. This requires the [SqlServer module](https://www.powershellgallery.com/packages/SqlServer) to be present on the node.
<!-- markdownlint-enable MD013 -->

## Known issues
Expand Down
Loading