Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
51 changes: 39 additions & 12 deletions Dashboard/Controls/MemoryContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,45 @@
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Memory Usage Over Time" FontWeight="Bold" FontSize="14" Margin="10,5" Foreground="{DynamicResource ForegroundBrush}"/>
<ScottPlot:WpfPlot Grid.Row="1" x:Name="MemoryStatsOverviewChart"/>
<!-- Summary Panel for percentages and pressure status -->
<Border Grid.Row="2" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Padding="10,8">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="Buffer Pool:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsBPPercentText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center" Margin="0,0,20,0"/>
<TextBlock Text="Plan Cache:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsPCPercentText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center" Margin="0,0,20,0"/>
<TextBlock Text="Utilization:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsUtilPercentText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center" Margin="0,0,20,0"/>
<TextBlock Text="Pressure:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsPressureText" Text="None" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<!-- Summary Panel with absolute GB values and pressure status -->
<Border Grid.Row="2" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Padding="10,6">
<WrapPanel HorizontalAlignment="Center">
<!-- Physical Memory -->
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="Physical Memory:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsPhysicalText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<!-- SQL Server Memory (committed) -->
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="SQL Server Memory:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsSqlServerText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<!-- Target Memory -->
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="Target Memory:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsTargetText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<!-- Buffer Pool -->
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="Buffer Pool:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsBPPercentText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<!-- Plan Cache -->
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="Plan Cache:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsPCPercentText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<!-- Utilization -->
<StackPanel Orientation="Horizontal" Margin="0,0,24,0">
<TextBlock Text="Utilization:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsUtilPercentText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<!-- Pressure -->
<StackPanel Orientation="Horizontal">
<TextBlock Text="Pressure:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryStatsPressureText" Text="None" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
</WrapPanel>
</Border>
</Grid>
</Border>
Expand Down
23 changes: 19 additions & 4 deletions Dashboard/Controls/MemoryContent.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ private void UpdateMemoryStatsSummaryPanel(List<MemoryStatsItem> dataList)
{
if (dataList == null || dataList.Count == 0)
{
MemoryStatsPhysicalText.Text = "N/A";
MemoryStatsSqlServerText.Text = "N/A";
MemoryStatsTargetText.Text = "N/A";
MemoryStatsBPPercentText.Text = "N/A";
MemoryStatsPCPercentText.Text = "N/A";
MemoryStatsUtilPercentText.Text = "N/A";
Expand All @@ -344,14 +347,26 @@ private void UpdateMemoryStatsSummaryPanel(List<MemoryStatsItem> dataList)
// Use the most recent data point
var latest = dataList.OrderByDescending(d => d.CollectionTime).First();

MemoryStatsBPPercentText.Text = latest.BufferPoolPercentage.HasValue
? $"{latest.BufferPoolPercentage:F1}%"
// Absolute GB values
MemoryStatsPhysicalText.Text = latest.TotalPhysicalMemoryMb.HasValue
? $"{latest.TotalPhysicalMemoryMb.Value / 1024.0m:F1} GB"
: "N/A";

MemoryStatsPCPercentText.Text = latest.PlanCachePercentage.HasValue
? $"{latest.PlanCachePercentage:F1}%"
MemoryStatsSqlServerText.Text = $"{latest.PhysicalMemoryInUseMb / 1024.0m:F1} GB";

MemoryStatsTargetText.Text = latest.CommittedTargetMemoryMb.HasValue
? $"{latest.CommittedTargetMemoryMb.Value / 1024.0m:F1} GB"
: "N/A";

// Buffer Pool and Plan Cache with GB and percentage
MemoryStatsBPPercentText.Text = latest.BufferPoolPercentage.HasValue
? $"{latest.BufferPoolMb / 1024.0m:F1} GB ({latest.BufferPoolPercentage:F1}%)"
: $"{latest.BufferPoolMb / 1024.0m:F1} GB";

MemoryStatsPCPercentText.Text = latest.PlanCachePercentage.HasValue
? $"{latest.PlanCacheMb / 1024.0m:F1} GB ({latest.PlanCachePercentage:F1}%)"
: $"{latest.PlanCacheMb / 1024.0m:F1} GB";

MemoryStatsUtilPercentText.Text = $"{latest.MemoryUtilizationPercentage}%";

// Build pressure status text
Expand Down
4 changes: 4 additions & 0 deletions Dashboard/Models/MemoryStatsItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public class MemoryStatsItem
public decimal AvailablePhysicalMemoryMb { get; set; }
public int MemoryUtilizationPercentage { get; set; }

// Server and target memory
public decimal? TotalPhysicalMemoryMb { get; set; }
public decimal? CommittedTargetMemoryMb { get; set; }

// Pressure warnings
public bool BufferPoolPressureWarning { get; set; }
public bool PlanCachePressureWarning { get; set; }
Expand Down
8 changes: 6 additions & 2 deletions Dashboard/Services/DatabaseService.Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ public async Task<List<MemoryStatsItem>> GetMemoryStatsAsync(int hoursBack = 24,
ms.available_physical_memory_mb,
ms.memory_utilization_percentage,
ms.buffer_pool_pressure_warning,
ms.plan_cache_pressure_warning
ms.plan_cache_pressure_warning,
ms.total_physical_memory_mb,
ms.committed_target_memory_mb
FROM collect.memory_stats AS ms
{dateFilter}
ORDER BY
Expand Down Expand Up @@ -80,7 +82,9 @@ ORDER BY
AvailablePhysicalMemoryMb = reader.GetDecimal(7),
MemoryUtilizationPercentage = reader.GetInt32(8),
BufferPoolPressureWarning = reader.GetBoolean(9),
PlanCachePressureWarning = reader.GetBoolean(10)
PlanCachePressureWarning = reader.GetBoolean(10),
TotalPhysicalMemoryMb = reader.IsDBNull(11) ? null : reader.GetDecimal(11),
CommittedTargetMemoryMb = reader.IsDBNull(12) ? null : reader.GetDecimal(12)
});
}

Expand Down
16 changes: 16 additions & 0 deletions install/02_create_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ BEGIN
physical_memory_in_use_mb decimal(19,2) NOT NULL,
available_physical_memory_mb decimal(19,2) NOT NULL,
memory_utilization_percentage integer NOT NULL,
/*Server and target memory*/
total_physical_memory_mb decimal(19,2) NULL,
committed_target_memory_mb decimal(19,2) NULL,
/*Pressure warnings*/
buffer_pool_pressure_warning bit NOT NULL DEFAULT 0,
plan_cache_pressure_warning bit NOT NULL DEFAULT 0,
Expand All @@ -219,6 +222,19 @@ BEGIN
PRINT 'Created collect.memory_stats table';
END;

/*Add columns for existing installs*/
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'collect.memory_stats') AND name = N'total_physical_memory_mb')
BEGIN
ALTER TABLE collect.memory_stats ADD total_physical_memory_mb decimal(19,2) NULL;
PRINT 'Added total_physical_memory_mb to collect.memory_stats';
END;

IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'collect.memory_stats') AND name = N'committed_target_memory_mb')
BEGIN
ALTER TABLE collect.memory_stats ADD committed_target_memory_mb decimal(19,2) NULL;
PRINT 'Added committed_target_memory_mb to collect.memory_stats';
END;

/*
4. I/O Performance - handled by sp_PressureDetector
NOTE: I/O metrics are collected by sp_PressureDetector into collect.PressureDetector_FileMetrics
Expand Down
15 changes: 9 additions & 6 deletions install/06_ensure_collection_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ BEGIN
physical_memory_in_use_mb decimal(19,2) NOT NULL,
available_physical_memory_mb decimal(19,2) NOT NULL,
memory_utilization_percentage integer NOT NULL,
/*Server and target memory*/
total_physical_memory_mb decimal(19,2) NULL,
committed_target_memory_mb decimal(19,2) NULL,
/*Pressure warnings*/
buffer_pool_pressure_warning bit NOT NULL DEFAULT 0,
plan_cache_pressure_warning bit NOT NULL DEFAULT 0,
Expand All @@ -307,12 +310,12 @@ BEGIN
(
plan_cache_mb * 100.0 /
NULLIF(total_memory_mb, 0)
),
CONSTRAINT
PK_memory_stats
PRIMARY KEY CLUSTERED
(collection_time, collection_id)
WITH
),
CONSTRAINT
PK_memory_stats
PRIMARY KEY CLUSTERED
(collection_time, collection_id)
WITH
(DATA_COMPRESSION = PAGE)
);
END;
Expand Down
14 changes: 13 additions & 1 deletion install/14_collect_memory_stats.sql
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,15 @@ BEGIN
system_memory AS
(
SELECT
available_physical_memory_mb = sm.available_physical_memory_kb / 1024.0
available_physical_memory_mb = sm.available_physical_memory_kb / 1024.0,
total_physical_memory_mb = sm.total_physical_memory_kb / 1024.0
FROM sys.dm_os_sys_memory AS sm
),
system_info AS
(
SELECT
committed_target_memory_mb = si.committed_target_kb / 1024.0
FROM sys.dm_os_sys_info AS si
)
INSERT INTO
collect.memory_stats
Expand All @@ -182,6 +189,8 @@ BEGIN
physical_memory_in_use_mb,
available_physical_memory_mb,
memory_utilization_percentage,
total_physical_memory_mb,
committed_target_memory_mb,
buffer_pool_pressure_warning,
plan_cache_pressure_warning
)
Expand All @@ -193,6 +202,8 @@ BEGIN
physical_memory_in_use_mb = pm.physical_memory_in_use_mb,
available_physical_memory_mb = sm.available_physical_memory_mb,
memory_utilization_percentage = pm.memory_utilization_percentage,
total_physical_memory_mb = sm.total_physical_memory_mb,
committed_target_memory_mb = si.committed_target_memory_mb,
buffer_pool_pressure_warning =
CASE
WHEN @previous_buffer_pool_mb IS NOT NULL
Expand All @@ -210,6 +221,7 @@ BEGIN
FROM memory_clerks AS mc
CROSS JOIN process_memory AS pm
CROSS JOIN system_memory AS sm
CROSS JOIN system_info AS si
OPTION(RECOMPILE);

SET @rows_collected = ROWCOUNT_BIG();
Expand Down
Loading