Network Management

Database Maintenance encounters an "CREATE/ALTER partition function failed as only a maximum of 15000 partitions can be created" error.

This article addresses an error encountered during Database Maintenance related to Volume maintenance, where the system fails to create or alter partition functions due to exceeding the maximum allowed number of partitions.

First published date

11/14/2019 1:29 PM

Last published date

12/17/2025 4:21 PM

Overview

SolarWinds encounters an error when carrying out the Database Maintenance:

ERROR SolarWinds.Data.DatabaseMaintenance.MaintenanceEngine - Error in thread: System.Data.SqlClient.SqlException (0x80131904): dbm_ExecuteMaintenance: dbm_CreateEmptyPartitions: dbm_AddPartition: CREATE/ALTER partition function failed as only a maximum of 15000 partitions can be created.
 

Product section

Network Performance Monitor

Cause

The root cause is that some devices are reporting very old timestamps, which causes the system to create partitions far beyond the retention period. This results in exceeding the maximum number of allowed partitions in SQL Server.

Resolution

Step 1: Identify Old Timestamp Records

  • Query the VolumeUsage_CS table for records with very old timestamps (several years back).
  • Cross-reference these timestamps with the corresponding volumes.
  • If certain volumes consistently report old timestamps, consider stopping polling those volumes to prevent recurrence.

Step 2: Remove Old Data

  • Delete records with outdated timestamps from the database to reduce unnecessary partitions.

Step 3: Check Current Partition Count

Run the following SQL query to check the number of partitions on the VolumeUsage_CS_Detail_hist table:
    • select count(*)
      from sys.partitions
      where object_id = object_id('VolumeUsage_CS_Detail_hist')

You will likely see a partition count much higher than your configured retention period.

Step 4: Remove Redundant Partitions

Execute the following SQL script to merge and remove empty, redundant partitions. Please note that this operation may take a considerable amount of time to complete.
​​​​
-- Scripts are not supported under any SolarWinds support program or service.
-- Scripts are provided AS IS without warranty of any kind. SolarWinds further
-- disclaims all warranties including, without limitation, any implied warranties
-- of merchantability or of fitness for a particular purpose. The risk arising
-- out of the use or performance of the scripts and documentation stays with you.
-- In no event shall SolarWinds or anyone else involved in the creation,
-- production, or delivery of the scripts be liable for any damages whatsoever
-- (including, without limitation, damages for loss of business profits, business
-- interruption, loss of business information, or other pecuniary loss) arising
-- out of the use of or inability to use the scripts or documentation.

DECLARE @min_range DATE;
DECLARE @max_range DATE;
DECLARE @days INT;
DECLARE @part_function NVARCHAR(128);
DECLARE @sql NVARCHAR(1024);
DECLARE @table_name NVARCHAR(128) = 'VolumeUsage_CS_Detail_hist';
 
WITH parts
AS
(
SELECT OBJECT_NAME(p.object_id) AS table_name,
CAST(prv.value AS DATE) AS range_value,
pf.name,
p.rows
FROM sys.indexes ind WITH(NOLOCK)
LEFT HASH JOIN sys.partitions p WITH(NOLOCK)
ON ind.object_id = p.object_id
AND ind.index_id = p.index_id
LEFT HASH JOIN sys.allocation_units au WITH(NOLOCK)
ON au.container_id = p.hobt_id
LEFT HASH JOIN sys.filegroups fg WITH(NOLOCK)
ON fg.data_space_id = au.data_space_id
LEFT HASH JOIN sys.data_spaces ds WITH(NOLOCK)
ON ind.data_space_id = ds.data_space_id
LEFT HASH JOIN sys.partition_schemes sch WITH(NOLOCK)
ON sch.data_space_id = ds.data_space_id
LEFT HASH JOIN sys.partition_range_values prv WITH(NOLOCK)
ON prv.function_id = sch.function_id
AND prv.boundary_id = p.partition_number
LEFT HASH JOIN sys.partition_functions pf WITH(NOLOCK)
ON prv.function_id = pf.function_id
WHERE au.type = 1
AND p.object_id = OBJECT_ID(@table_name)
AND CAST(prv.value AS DATE) IS NOT NULL
AND p.rows = 0
)
SELECT @part_function = p.name,
@min_range = MIN(p.range_value),
@max_range = MAX(p.range_value)
FROM parts p
GROUP BY p.name
;
 
PRINT @min_range;
PRINT @max_range;
 
WHILE @max_range > @min_range
BEGIN
SET @sql = 'ALTER PARTITION FUNCTION ' + @part_function + '()' + ' MERGE RANGE (''' + (CAST(@min_range AS NVARCHAR(32))) + ''');';
--PRINT @sql;
EXEC sp_executesql @sql;
SET @min_range = DATEADD(DAY, 1, @min_range);
END;

Step 5: Verify Partition Count and Maintenance

    • Re-run the partition count query from Step 3; the count should now approximate your retention period.
    • Run Database Maintenance again to confirm the error is resolved.