Improve the health and performance monitoring of your Microsoft SQL Servers.
Monitor SQL Server instances, databases, and Always On clusters remotely.
Monitor Microsoft SQL Server health and performance with the Dynatrace extension.
Microsoft SQL Server database monitoring is based on a remote monitoring approach implemented as a Dynatrace ActiveGate extension. The extension queries Microsoft SQL Server databases for key performance and health metrics, extending your visibility, and allowing Dynatrace Intelligence to provide anomaly detection and problem analysis.
Supported on:
Views and tables involved:
Supported on:
Views and tables involved:
Supported on:
Views and tables involved:
Supported on:
Views and tables involved:
Monitor query performance stats
Supported on:
Involved views and tables:
Monitor lock wait time by wait type
Supported on:
Involved views and tables:
Monitor failed distributed transactions
Supported on:
Involved views and tables:
Monitor top longest queries
Supported on:
Involved views and tables:
Supported on:
Involved views and tables:
Supported on:
Involved views and tables:
Supported on:
Involved views and tables:
Monitor the age of the latest backup and individual backups per database
Supported on:
Involved views and tables:
Monitor backup file size per database
Supported on:
Involved views and tables:
Monitoring individual Azure SQL Database backups
Supported on:
Involved views and tables:
Monitor database file stats
Supported on:
Involved views and tables:
Monitoring the largest database files on Azure SQL Database
Supported on:
Involved views and tables:
Monitoring the largest database files on other SQL Server types
Supported on:
Involved views and tables:
Supported on:
Involved views and tables:
Supported on:
Involved views and tables:
Supported on:
SQL Server (all versions)
Not supported on Azure SQL Database, Azure SQL Managed Instance, or Azure Synapse Analytics.
Involved views and tables:
Supported on:
Involved views and tables:
Required permissions:
VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.##MS_ServerStateReader## server role.VIEW DATABASE STATE permission on the database; or##MS_ServerStateReader## server role.VIEW SERVER STATE permission.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.##MS_ServerStateReader## server role.VIEW DATABASE STATE permission on the database; or##MS_ServerStateReader## server role.VIEW SERVER STATE permission.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.##MS_ServerStateReader## server role.VIEW DATABASE STATE permission on the database; or##MS_ServerStateReader## server role.VIEW SERVER STATE permission.master database for all databases to be visible.master database are visible.ONLINE databases:
VIEW ANY DATABASE (default permission for the public role)OFFLINE databases as well:
ALTER ANY DATABASE on server level; orCREATE DATABASE permission in the master database.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission; otherwise only the current session is visible.VIEW SERVER STATE can't be granted; results are always limited to the current connection.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.##MS_ServerStateReader## server role.VIEW DATABASE STATE permission on the database; or##MS_ServerStateReader## server role.VIEW SERVER STATE permission.VIEW DATABASE STATE permission.VIEW DATABASE STATE permission.VIEW DATABASE STATE permission.VIEW DATABASE STATE permission.VIEW DATABASE STATE permission.VIEW DATABASE STATE permission.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.VIEW ANY DEFINITION; orCREATE DATABASE; orALTER ANY DATABASE.VIEW ANY DEFINITION permission.VIEW ANY DEFINITION permission.VIEW ANY DATABASE; orALTER ANY DATABASE; orCREATE DATABASE permission in master is required.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.VIEW SERVER PERFORMANCE STATE permission.VIEW SERVER STATE permission.##MS_ServerStateReader## server role.VIEW DATABASE STATE permission on the database; or##MS_ServerStateReader## server role.VIEW SERVER SECURITY STATE permission.VIEW SERVER STATE permission.The extension is reported to work with other types of SQL Server, such as AWS RDS or SQL Server on Linux, but they're not officially supported.
Other types of replication and HA monitoring, including the publisher/subscriber model, aren't supported yet.
This extension supports any version of SQL Server with active extended support by Microsoft. See the official Microsoft documentation about lifecycle dates for SQL Server.
Follow these steps to configure your device for Microsoft SQL Server database monitoring.
Required permission: Change monitoring settings
Go to
Dynatrace Hub.
Select and install Microsoft SQL Server extension. This enables the extension in your monitoring environment.
Select Add DB Instance in
Databases. This opens the Add DB Instance wizard.
Select Microsoft SQL Server section in the wizard.
Select a hosting type from the options. This choice determines which script generates the necessary database objects later in the process.
Set up the connection to your database instance. Provide the required credentials directly in the wizard or use secure alternatives:
dynatrace monitoring user you have created directly or use secure alternatives.
You can enable log monitoring to activate extension status logs. Log monitoring covers the longest running queries and the largest database files.
v3.1.2:
1.338.0 and a minimum EEC version of 1.337.0.agent_requests and application_requests log event groups were removed in favor of the generic all_requests event group. Use the program_name attribute to filter for agent or application requests.v2.7.0:
v2.0.0:
instance dimension now only contains the name of the actual named instance or MSSQLSERVER by default.hoursSinceBackup metric is removed and replaced by sql-server.databases.backup.age.v1.2.0:
There is no charge to use the extension. You are only charged for the data that the extension ingests.
The Microsoft SQL Server extension ingests custom metrics, which consume Davis data units (DDUs) (Dynatrace Classic license) or Metrics powered by Grail (DPS), according to your license model.
Each enabled feature set increases consumption. The default feature set can't be turned off.
The number of metric data points produced per minute for a given metric is calculated as follows:
number of unique associated entities / minutes between retrievals = metric data points per minute
Example:
sql-server.databases.backup.size2 instances with 20 databases in each.2 (SQL Server Instances) * 20 (SQL Server Databases in each) = 40 unique databases in total.40 / 1 = 40.In the Dynatrace Platform Subscription, metric ingestion consumes Metrics powered by Grail according to the number of ingested metric data points.
To calculate the approximate yearly consumption, apply the following calculation: <metric data points per minute> * 60 minutes * 24 hours * 365 days.
For the example above: 40 * 60 * 24 * 365 = 21,024,000 metric data points per year.
In the classic licensing model, metric ingestion consumes Davis data units (DDUs) at the rate of .001 DDUs per metric data point. Multiply the above formula for annual data points by .001 to estimate annual DDU usage.
For the example above: 40 * 60 * 24 * 365 * 0.001 = 21,024 DDUs per year.
The DDU cost doesn't include any log events or custom events the extension triggers. For more information, see DDU events.
You can enable the collection of individual backup details using the Backups feature set for SQL Server and Azure SQL Managed Instance, or the Backups Azure feature set for Azure SQL Database. Only one of these two feature sets should be enabled at a time for a given SQL Server type.
Individual backups are fetched by the extension every five minutes.
The following query, when executed in Logs and Events, displays individual backups as observed within the most recent 5-minute timeframe using DQL:
fetch logs, from:now()-5m| filter matchesValue(dt.extension.name, "com.dynatrace.extension.sql-server")| filter matchesValue(event.group, "backups_managed")| fields content, database, backup_type, device_type, recovery_model, compatibility_level, backup_size, compressed_backup_size, backup_start_date, backup_finish_date, physical_device_name, server, instance| sort backup_finish_date desc
Description of fields:
content field contains the backup type (same value as backup_type)backup_size and compressed_backup_size are reported in bytesphysical_device_name represents the physical path or name of the backup deviceThe following query, when executed in Logs and Events, displays individual Azure SQL Database backups as observed within the most recent 5-minute timeframe using DQL:
fetch logs, from:now()-5m| filter matchesValue(dt.extension.name, "com.dynatrace.extension.sql-server")| filter matchesValue(event.group, "backups_azure")| fields content, logical_database_name, physical_database_name, logical_server_name, backup_type, in_retention, backup_start_date, backup_finish_date, server, instance| sort backup_finish_date desc
Description of fields:
content field contains the backup type (same value as backup_type)in_retention indicates whether the backup is still within the configured retention periodYou can enable a collection of top queries ordered by total duration using the Queries feature set.
Top queries are fetched by the extension every 60 minutes. Unlike other queries in the Queries feature set, this interval is fixed and isn't affected by the query interval or heavy query interval configuration fields.
The following query, when executed in Logs and Events, displays top queries as observed within the most recent 60-minute timeframe using DQL:
fetch logs, from:now()-60m| filter matchesValue(dt.extension.name, "com.dynatrace.extension.sql-server")| filter matchesValue(event.group, "longest_queries")| fields total_duration, avg_duration, avg_cpu_time, content, server, instance, database, count_executions, last_execution_time, sql_id| sort asDouble(total_duration) desc
Description of fields:
total_duration field represents a sum of all executions of this query over the given 60-minute timeframe in millisecondsavg_duration represents the average execution time of this query over the given 60-minute timeframe in millisecondsavg_cpu_time represents the average CPU time consumed by this query over the given 60-minute timeframe in millisecondscontent field contains the SQL text of the querycount_executions represents the number of times this query was executed over the given 60-minute timeframesql_id represents the query execution plan IDYou can enable collection of the largest database files by size using the Database files feature set.
Top database files by size are fetched by the extension every five minutes.
The following query, when executed in Logs and Events, displays the largest database files as observed within the most recent 5-minute timeframe by size using DQL:
fetch logs, from:now()-5m| filter matchesValue(dt.extension.name, "com.dynatrace.extension.sql-server")| filter matchesValue(event.group, "largest_files")| fields content, file_size, file_type_desc, file_state_desc, database, server, instance, file_used_space, file_empty_space| sort asDouble(file_size) desc
Description of fields:
content field represents the physical name of the file as handled by the host OS.file_size is reported in KBfile_used_space is reported in KB and represents the amount of space occupied by allocated pages within a specific filefile_empty_space is reported in KB and represents the space still empty within a specific fileYou can enable monitoring of current jobs using the Jobs feature set.
Current jobs are fetched by the extension every five minutes.
The following query, when executed in Logs and Events, displays current jobs as observed within the most recent 5-minute timeframe using DQL:
fetch logs, from:now()-5m| filter matchesValue(dt.extension.name, "com.dynatrace.extension.sql-server")| filter matchesValue(event.group, "current_jobs")| fields job_name, job_status, content, enabled, last_run_outcome, duration, instance, server, start_execution_date, stop_execution_date, job_category, category_name| sort asDouble(duration) desc
Description of fields:
content field represents the last execution outcome messagejob_status and last_run_outcome are identical, except for two situations:
job_status equals Idlejob_status equals In Progressduration represents complete job duration in seconds after execution is finishedcategory_id represents the category id of the jobcategory_name represents the Name assigned to the category idYou can enable monitoring of failed jobs using the Jobs feature set.
Failed jobs are fetched by the extension every five minutes.
The following query, when executed in Logs and Events, displays failed jobs as observed within the most recent 5-minute timeframe using DQL:
fetch logs, from:now()-5m| filter matchesValue(dt.extension.name, "com.dynatrace.extension.sql-server")| filter matchesValue(event.group, "failed_jobs")| fields job_name, step_name, outcome, content, duration, instance, server, sql_severity, retries_attempted, start_execution_date, stop_execution_date| sort stop_execution_date desc
Description of fields:
content field represents the message of the last executed step and usually contains the erroroutcome represents the final job status message as composed by SQL Server Agentduration represents the complete job duration in seconds after execution is finishedsql-server.memory.target
number of SQL Server Instances in environment * 60sql-server.memory.physical
number of SQL Server Instances in environment * 60sql-server.databases.state
number of SQL Server Databases in environment * 60sql-server.uptime
number of SQL Server Instances in environment * 12sql-server.databases.transactions.count
number of SQL Server Databases in environment * 60sql-server.memory.total
number of SQL Server Instances in environment * 60sql-server.cpu.kernelTime.count
number of SQL Server Instances in environment * 60sql-server.general.userConnections
number of SQL Server Instances in environment * 60sql-server.general.processesBlocked
number of SQL Server Instances in environment * 60sql-server.general.logins.count
number of SQL Server Instances in environment * 60sql-server.cpu.userTime.count
number of SQL Server Instances in environment * 60sql-server.memory.virtual
number of SQL Server Instances in environment * 60sql-server.host.cpus
number of SQL Server Hosts in environment * 12sql-server.worker.activeWorkers
number of SQL Server Instances in environment * 60sql-server.worker.maxWorkers
number of SQL Server Instances in environment * 60sql-server.worker.threadsPercent
number of SQL Server Instances in environment * 60sql-server.always-on.ag.secondaryRecoveryHealth
number of SQL Server Availability Groups in environment * 60sql-server.always-on.ag.primaryRecoveryHealth
number of SQL Server Availability Groups in environment * 60sql-server.always-on.ar.failoverMode
number of SQL Server Availability Replicas in environment * 60sql-server.always-on.ag.synchronizationHealth
number of SQL Server Availability Groups in environment * 60sql-server.always-on.ar.operationalState
number of SQL Server Availability Replicas in environment * 60sql-server.always-on.ar.connectedState
number of SQL Server Availability Replicas in environment * 60sql-server.always-on.db.filestreamSendRate
number of SQL Server Availability Databases in environment * 60sql-server.always-on.db.state
number of SQL Server Availability Databases in environment * 60sql-server.always-on.db.synchronizationHealth
number of SQL Server Availability Databases in environment * 60sql-server.always-on.db.logSendQueueSize
number of SQL Server Availability Databases in environment * 60sql-server.always-on.ar.role
number of SQL Server Availability Replicas in environment * 60sql-server.always-on.db.synchronizationState
number of SQL Server Availability Databases in environment * 60sql-server.always-on.db.redoRate
number of SQL Server Availability Databases in environment * 60sql-server.always-on.db.redoQueueSize
number of SQL Server Availability Databases in environment * 60sql-server.always-on.ar.synchronizationHealth
number of SQL Server Availability Replicas in environment * 60sql-server.always-on.db.logSendRate
number of SQL Server Availability Databases in environment * 60sql-server.always-on.ar.availabilityMode
number of SQL Server Availability Replicas in environment * 60sql-server.always-on.ag.automatedBackupPreference
number of SQL Server Availability Groups in environment * 60sql-server.always-on.ar.isLocal
number of SQL Server Availability Replicas in environment * 60sql-server.always-on.ar.recoveryHealth
number of SQL Server Availability Replicas in environment * 60sql-server.databases.backup.age
number of SQL Server Databases in environment * 60sql-server.databases.backup.size
number of SQL Server Databases in environment * 60backups_managed
Up to number of individual backups taken in the interval * 12 * avg log sizebackups_azure
Up to number of individual backups taken in the interval * 12 * avg log sizesql-server.databases.file.emptySpace
number of SQL Server Databases in environment * 60sql-server.databases.file.size
number of SQL Server Databases in environment * 60sql-server.databases.file.usedSpace
number of SQL Server Databases in environment * 60largest_files
Up to 100 (num of files) * 12 * avg log sizelargest_files
Up to 100 (num of files) * 12 * avg log sizesql-server.latches.waits.count
number of SQL Server Instances in environment * 60sql-server.latches.averageWaitTime.count
number of SQL Server Instances in environment * 60sql-server.locks.timeouts.count
number of SQL Server Instances in environment * 60sql-server.locks.waits.count
number of SQL Server Instances in environment * 60sql-server.locks.waitTime.count
number of SQL Server Instances in environment * 60sql-server.locks.deadlocks.count
number of SQL Server Instances in environment * 60sql-server.buffers.checkpointPages.count
number of SQL Server Instances in environment * 60sql-server.memory.grantsOutstanding
number of SQL Server Instances in environment * 60sql-server.memory.connection
number of SQL Server Instances in environment * 60sql-server.buffers.pageWrites.count
number of SQL Server Instances in environment * 60sql-server.buffers.pageLifeExpectancy
number of SQL Server Instances in environment * 60sql-server.memory.grantsPending
number of SQL Server Instances in environment * 60sql-server.buffers.cacheHitRatio
number of SQL Server Instances in environment * 60sql-server.buffers.freeListStalls.count
number of SQL Server Instances in environment * 60sql-server.buffers.pageReads.count
number of SQL Server Instances in environment * 60sql-server.sql.recompilations.count
number of SQL Server Instances in environment * 60sql-server.sql.compilations.count
number of SQL Server Instances in environment * 60sql-server.sql.batchRequests.count
number of SQL Server Instances in environment * 60sql-server.locks.elapsedTimeRequestsPercent
number of SQL Server Instances in environment * 60sql-server.databases.failedDistributedTransactions.count
number of SQL Server Databases in environment * 60sql-server.locks.byWaitType
number of SQL Server Instances in environment * 60longest_queries
Up to 100 (num of queries) * 1 * avg log sizesql-server.replica.bytesSentToTransport.count
number of SQL Server Instances in environment * 60sql-server.replica.sends.count
number of SQL Server Instances in environment * 60sql-server.replica.sendsToTransport.count
number of SQL Server Instances in environment * 60sql-server.replica.bytesReceived.count
number of SQL Server Instances in environment * 60sql-server.replica.bytesSent.count
number of SQL Server Instances in environment * 60sql-server.replica.resentMessages.count
number of SQL Server Instances in environment * 60sql-server.replica.receives.count
number of SQL Server Instances in environment * 60sql-server.sessions
number of SQL Server Instances in environment * 60sql-server.databases.log.flushWaits.count
number of SQL Server Databases in environment * 60sql-server.databases.log.filesUsedSize
number of SQL Server Databases in environment * 60sql-server.databases.log.growths.count
number of SQL Server Databases in environment * 60sql-server.databases.log.truncations.count
number of SQL Server Databases in environment * 60sql-server.databases.log.shrinks.count
number of SQL Server Databases in environment * 60sql-server.databases.log.filesSize
number of SQL Server Databases in environment * 60sql-server.databases.log.percentUsed
number of SQL Server Databases in environment * 60sql-server.sql.agent.status
number of SQL Server Agents in environment * 60current_jobs
Number of currently enabled jobs * 12 * avg log sizefailed_jobs
top 100 failed jobs * 12 * avg log sizeall_requests
avg Number of active requests * 60 * avg log sizeNote on current_jobs, failed_jobs, longest_queries, all_requests, and largest_files: These metrics are based on log data. Because every environment is different, estimate the calculation on the client side, and then calculate the data size ingested. Currently, 100 DDUs are consumed per GB ingested. See the DDU consumption model for Log Management and Analytics in the documentation. If you're on Log Monitoring Classic, each log record (line, message, entry) deducts 0.005 DDU from your available quota. See the DDUs for Log Monitoring Classic in the documentation.
The two metrics below
sql-server.databases.file.usedSpacesql-server.databases.file.emptySpaceare only reported for the database the extension is currently connected to. The FILEPROPERTY(..., 'SpaceUsed') function only returns used-space information for the database of the current connection.
master database (limitation of SQL Server itself).Azure backups are monitored by querying the sys.dm_database_backups view, which is currently available for all Azure SQL Database service tiers except Hyperscale.
To obtain information about every replica in a given availability group, connect the extension to the server instance hosting the primary replica. When connected to a server instance hosting a secondary replica of an availability group, the extension returns only local information for the availability group.
When connected to a secondary replica, the extension retrieves the states of every secondary database on the server instance. On the primary replica, the extension returns data for each primary database and for the corresponding secondary database.
Depending on the action and higher-level states, database-state information may be unavailable or out of date. Furthermore, the values have only local relevance. See limitations of sys.dm_hadr_database_replica_states.
When a database is added to an availability group, the primary database is automatically joined to the group. Secondary databases must be manually prepared on each secondary replica before they can be joined to the availability group.
If the local server instance can't communicate with the WSFC failover cluster, only rows for local availability replicas are returned. This happens when the cluster is down or quorum has been lost. These rows contain only the columns cached locally in metadata.
SELECT queries to obtain monitoring data. The database is never modified or locked.sys.* system views and msdb database (when applicable). User databases and objects are never affected.query interval and heavy query interval, control how often queries run. To run the 1-minute queries at a longer interval, for example every 10 minutes, enter 10 in the query interval field.heavy query interval field works the same way, except it changes the frequency of queries that run every five minutes.longest_queries) run on a fixed 60-minute interval and aren't affected by either the query interval or heavy query interval setting.Locks and waits feature set.You'll have a new dashboard to view this data in a single pane of glass.