SQL Server Database Capacity Planning

 SQL Server database capacity planning involves estimating the resources and storage requirements necessary to support the expected growth of your database over time. Here are some key considerations and steps to help you with SQL Server database capacity planning:

Data Analysis and Profiling:

Analyze the existing data and understand its characteristics, including the size, growth rate, and usage patterns.

Identify the tables, indexes, and other database objects that contribute to the overall database size.

Profile the workload by capturing and analyzing relevant queries and transactions to determine resource usage patterns.
 
Storage Requirements:

Estimate the size of the database files (data files, transaction log files) based on the current data size and expected growth rate.

Consider factors such as data compression, partitioning, and archiving strategies to optimize storage utilization.

Choose appropriate storage technology (e.g., direct-attached storage, SAN, or cloud storage) based on performance, scalability, and cost considerations.
 
Memory Considerations:

Determine the memory requirements for SQL Server based on the database size, workload, and query complexity.

Allocate sufficient memory for SQL Server's buffer cache, query execution plans, and other caching mechanisms to optimize performance.

Configure the appropriate maximum memory setting to ensure SQL Server does not consume excessive resources on the server.
 
CPU and Processing Power:
Analyze the workload and identify the CPU-intensive queries or processes.
Determine the CPU requirements based on the workload's complexity, concurrency, and expected growth.
Consider factors such as parallelism settings, query optimization, and server hardware capabilities to ensure adequate CPU resources.
 
Network Considerations:

Assess the network bandwidth requirements based on data transfer rates between clients and the SQL Server.

Consider factors such as client connections, data replication, and backup/restore operations that may utilize network resources.
 
Optimize the network configuration and infrastructure to minimize latency and maximize performance.

Scalability and Growth:

Consider the expected growth rate of the database and plan for future scalability.
Implement strategies such as database partitioning, table partitioning, or sharding to distribute data across multiple servers if required.

Regularly monitor database growth and performance to ensure that the capacity planning remains aligned with the actual usage.
 
Monitoring and Maintenance:

Implement a robust monitoring and alerting system to track resource utilization, performance metrics, and storage growth.

Regularly review and analyze monitoring data to identify trends, bottlenecks, and areas for optimization.
Perform routine database maintenance tasks such as index maintenance, statistics updates, and backup integrity checks to optimize performance and storage utilization.

Interview Questions on AOAG in SQL server

1.What are the prerequisites for setting up AlwaysOn?

2.How do you set up replication in AlwaysOn environment?

3.How do you manage replication during Windows patching or failover if replication has been set up in AlwaysOn?

4.How do you sync logins in AlwaysOn?

5.How do you sync users in AlwaysOn secondary?

6.How do you add database files in AlwaysOn?

7.How do you perform an in-place upgrade of SQL Server in a AlwaysOn environment?

8.What is the procedure for SQL Server patching in AlwaysOn?

9.How do you failover a mirror server if replication has been set up?

10.What is the SPN concept in AlwaysOn?

11.What is file share in AlwaysOn?

12.How do you create multiple AlwaysOn listeners?

13.How do you check latency in AlwaysOn?

14.What is the command used to check latency in replication without using GUI?

15.What are DNS issues in AlwaysOn?

16.If a user is connecting to the primary and not able to connect to the secondary, and the secondary is in read-only mode, how do you fix the issue in AlwaysOn?

17.How do you fix if secondary is not in sync?

18.How do you apply TDE in AlwaysOn?

19.How do you add the databases to availability group when encryption is enabled?

20.How to check the health of AlwaysOn?

21.How to resolve if blockings occur in secondary replica due to reporting server?

22.What are the DMVs used to troubleshoot AlwaysOn?

23.How do you set backup priority in AlwaysOn?

24.How do you restore the database which is part of AG ?


How to Send an Email Notification When SQL Server Service Restarts

Monitoring SQL Server service restarts is essential for maintaining database availability and troubleshooting unexpected issues. In this post, I’ll show you how to automate email notifications whenever SQL Server services start.

Why Monitor Service Restarts?

Unexpected SQL Server service restarts could indicate issues like:

  • Server reboots
  • Maintenance activities
  • Resource constraints
  • Crashes or failures

Getting an instant email notification helps database administrators (DBAs) quickly investigate the reason for the restart.

SQL Script to Send Email on Service Restart

Below is a simple T-SQL script that sends an email when SQL Server services restart.

USE msdb

GO

-- Declare variables for email content

DECLARE @ServerName VARCHAR(128),

        @ComputerNamePhysicalNetBIOS VARCHAR(128),

        @Datetime DATETIME,

        @EmailRecipients VARCHAR(512),

        @EmailSubject VARCHAR(128),

        @MessageBody VARCHAR(512)

-- Assign values to variables

SELECT @ComputerNamePhysicalNetBIOS = CAST(SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS VARCHAR(128)),

       @ServerName = CAST(SERVERPROPERTY('ServerName') AS VARCHAR(128)),

       @Datetime = GETDATE(),

       @EmailRecipients = 'bajeyudu@sqldbanow.com', -- Add multiple emails using a semicolon (;)

       @EmailSubject = SQL Server Services Have Been Started!!!'

-- Construct the email body

SELECT @MessageBody = 'SQL Server services have been started on a SQL Server Instance named ' + @ServerName + CHAR(13) +

                      'running on Windows server ' + @ComputerNamePhysicalNetBIOS + '.' + CHAR(13) + CHAR(13) +

                      'Investigate the service restart if it has not been communicated.'

-- Send email using Database Mail

EXEC sp_send_dbmail

    @recipients = @EmailRecipients,

    @subject = @EmailSubject,

    @body = @MessageBody,

    @body_format = 'TEXT'

How to Automate This?

  1. Enable Database Mail:
    Ensure Database Mail is configured in SQL Server. 

  1. Create a SQL Server Agent Job:
    • Open SQL Server AgentJobsNew Job.
    • Set the job name (e.g., "Monitor SQL Service Restarts").
    • Add a new step and paste the above script.
    • Schedule it to run at server startup (under Schedules, choose Start automatically when SQL Server Agent starts)

Automating Suspect Pages Monitoring in SQL Server with Email Alerts

Introduction

Database corruption is one of the most critical issues in SQL Server, and detecting suspect pages early can help prevent data loss and downtime. SQL Server logs suspect pages in msdb.dbo.suspect_pages whenever it encounters corruption issues like torn pages, checksum failures, or I/O errors. In this article, I’ll share a simple yet effective SQL script that automates the detection of suspect pages and sends an HTML-formatted email report to database administrators.

SQL Script for Suspect Pages Alert

The following SQL script checks for suspect pages in SQL Server and sends an email alert with the details when any are found. Additionally, it deletes suspect page records older than 90 days to maintain a clean log.

DECLARE @count INTEGER;

DECLARE @tableHTML NVARCHAR(MAX);

DECLARE @subj NVARCHAR(100);

SELECT @count = COUNT(1) FROM msdb.dbo.suspect_pages;

SET @subj = 'Suspect Pages Found in ' + @@SERVERNAME;

SET @tableHTML =

    N'<H1>Suspect Pages Found in ' + @@SERVERNAME + ', details are below.</H1>' +

    N'<table border="1">' +

    N'<tr><th>Database ID</th><th>Database</th>' +

    N'<th>File ID</th><th>File</th><th>Page ID</th>' +

    N'<th>Event Desc</th><th>Error Count</th><th>Last Updated</th></tr>' +

    CAST((SELECT td = sp.database_id, '',

                 td = d.name, '',

                 td = sp.file_id, '',

                 td = mf.physical_name, '',

                 td = sp.page_id, '',

                 td = CASE

                         WHEN sp.event_type = 1 THEN '823 or 824 error other than a bad checksum or a torn page'

                         WHEN sp.event_type = 2 THEN 'Bad checksum'

                         WHEN sp.event_type = 3 THEN 'Torn Page'

                         WHEN sp.event_type = 4 THEN 'Restored (The page was restored after it was marked bad)'

                         WHEN sp.event_type = 5 THEN 'Repaired (DBCC repaired the page)'

                         WHEN sp.event_type = 7 THEN 'Deallocated by DBCC'

                     END, '',

                 td = sp.error_count, '',

                 td = sp.last_update_date

          FROM msdb.dbo.suspect_pages sp

          INNER JOIN sys.databases d ON d.database_id = sp.database_id

          INNER JOIN sys.master_files mf ON mf.database_id = sp.database_id AND mf.file_id = sp.file_id

          FOR XML PATH('tr'), TYPE) AS NVARCHAR(MAX)) +

    N'</table>';

IF @count > 0

BEGIN

    EXEC msdb.dbo.sp_send_dbmail

        @recipients = N'bandaruajeyudu@outlook.com',

        @body = @tableHTML,

        @subject = @subj,

        @body_format = 'HTML',

        @profile_name = 'SQLMail';

END

DELETE FROM msdb.dbo.suspect_pages WHERE last_update_date < GETDATE() - 90;

--Note: To ensure this script works correctly, you need to configure Database Mail in SQL Server.

How to Monitor SQL Server Failed Jobs and Get Alerts via Email

Managing and monitoring SQL Server jobs is crucial for maintaining the health and performance of your SQL Server environment. One of the key aspects is to ensure that failed jobs are promptly reported and addressed. 

Below is a script that creates a report of failed SQL Server jobs and sends it via email. This script can be particularly useful for DBAs to automate the monitoring process.

CREATE TABLE #Failed_Jobs (

    Status VARCHAR(10) NOT NULL,

    [Job Name] VARCHAR(100) NOT NULL,

    [Step ID] VARCHAR(5) NOT NULL,

    [Step Name] VARCHAR(30) NOT NULL,

    [Start Date Time] VARCHAR(30) NOT NULL,

    Message NVARCHAR(MAX) NOT NULL

);

-- Insert failed job details

INSERT INTO #Failed_Jobs

SELECT 

    'FAILED' AS Status, 

    CAST(sj.name AS VARCHAR(100)) AS "Job Name",

    CAST(sjs.step_id AS VARCHAR(5)) AS "Step ID",

    CAST(sjs.step_name AS VARCHAR(30)) AS "Step Name",

    CAST(

        REPLACE(CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR, sjh.run_date)), 102), '.', '-') + ' ' +

        STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR, sjh.run_time), 6), 3, 0, ':'), 6, 0, ':')

    AS VARCHAR(30)) AS "Start Date Time",

    sjh.message AS "Message"

FROM msdb.dbo.sysjobs sj

JOIN msdb.dbo.sysjobsteps sjs ON sj.job_id = sjs.job_id

JOIN msdb.dbo.sysjobhistory sjh ON sj.job_id = sjh.job_id AND sjs.step_id = sjh.step_id

WHERE sjh.run_status <> 1

  AND CAST(sjh.run_date AS FLOAT) * 1000000 + sjh.run_time > 

      CAST(CONVERT(VARCHAR(8), GETDATE() - 1, 112) AS FLOAT) * 1000000 + 70000  -- yesterday at 7 AM

UNION

SELECT 

    'FAILED', 

    CAST(sj.name AS VARCHAR(100)) AS "Job Name",

    'MAIN' AS "Step ID",

    'MAIN' AS "Step Name",

    CAST(

        REPLACE(CONVERT(VARCHAR, CONVERT(DATETIME, CONVERT(VARCHAR, sjh.run_date)), 102), '.', '-') + ' ' +

        STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR, sjh.run_time), 6), 3, 0, ':'), 6, 0, ':')

    AS VARCHAR(30)) AS "Start Date Time",

    sjh.message AS "Message"

FROM msdb.dbo.sysjobs sj

JOIN msdb.dbo.sysjobhistory sjh ON sj.job_id = sjh.job_id

WHERE sjh.run_status <> 1 AND sjh.step_id = 0

  AND CAST(sjh.run_date AS FLOAT) * 1000000 + sjh.run_time > 

      CAST(CONVERT(VARCHAR(8), GETDATE() - 1, 112) AS FLOAT) * 1000000 + 70000  -- yesterday at 7 AM

-- Check if there are failed jobs

DECLARE @cnt INT;  

SELECT @cnt = COUNT(1) FROM #Failed_Jobs;    

IF (@cnt > 0)

BEGIN

    DECLARE @strsubject VARCHAR(100);

    SELECT @strsubject = 'Check the following failed jobs on ' + @@SERVERNAME;

    DECLARE @tableHTML NVARCHAR(MAX);

    SET @tableHTML = 

        N'<H1>Failed Jobs Listing - ' + @@SERVERNAME + '</H1>' + 

        N'<table border="1" cellspacing="0" cellpadding="4">' +

        N'<tr><th>Status</th><th>Job Name</th><th>Step ID</th>' +

        N'<th>Step Name</th><th>Start Date</th><th>Message</th></tr>' +

        CAST((

            SELECT 

                N'<tr><td>' + Status + 

                N'</td><td>' + [Job Name] + 

                N'</td><td>' + [Step ID] + 

                N'</td><td>' + [Step Name] + 

                N'</td><td>' + [Start Date Time] + 

                N'</td><td>' + Message + N'</td></tr>'

            FROM #Failed_Jobs

            FOR XML PATH(''), TYPE

        ) AS NVARCHAR(MAX)) + 

        N'</table>';

    EXEC msdb.dbo.sp_send_dbmail

        @from_address = 'BANDARUAJEYUDU@OUTLOOK.com',

        @recipients = 'BANDARUAJEYUDU@OUTLOOK.com',

        @subject = @strsubject,

        @body = @tableHTML,

        @body_format = 'HTML',

        @profile_name = 'SQLMail';

END

-- Drop temp table

DROP TABLE #Failed_Jobs;

By automating the reporting of failed jobs, DBAs can quickly address issues and ensure the smooth operation of SQL Server jobs.