Quantcast
Channel: udayarumilli.com
Viewing all 145 articles
Browse latest View live

SQL Script to Monitor CPU Utilization

$
0
0

SQL Script to Monitor CPU Utilization

This post helps you in understanding and using SQL Script to Monitor CPU utilization. There are certain scenarios where we can quickly use this script to get SQL Server CPU utilization.

  • When there is a performance issue, and you need to quickly check the CPU usage
  • When doing Root Cause Analysis
  • When we only have access to SQL Server not to Windows

SQL Server CPU Utilization history report for last N minutes:

Below is the SQL Script to Monitor CPU utilization. This script captures the CPU usage history report from last 10 min. This can be customized by changing the variable “@lastNmin” value.

/*****	Script: SQL Server CPU Utilization report from last N minutes *****/
/*****	Support: SQL Server 2008 and Above *****/
/*****	Tested On: SQL Server 2008 R2 and 2014 *****/
/*****	Output: 
	SQLServer_CPU_Utilization: % CPU utilized from SQL Server Process
	System_Idle_Process: % CPU Idle - Not serving to any process 
	Other_Process_CPU_Utilization: % CPU utilized by processes otherthan SQL Server
	Event_Time: Time when these values captured
*****/

DECLARE @ts BIGINT;
DECLARE @lastNmin TINYINT;
SET @lastNmin = 10;
SELECT @ts =(SELECT cpu_ticks/(cpu_ticks/ms_ticks) FROM sys.dm_os_sys_info); 
SELECT TOP(@lastNmin)
		SQLProcessUtilization AS [SQLServer_CPU_Utilization], 
		SystemIdle AS [System_Idle_Process], 
		100 - SystemIdle - SQLProcessUtilization AS [Other_Process_CPU_Utilization], 
		DATEADD(ms,-1 *(@ts - [timestamp]),GETDATE())AS [Event_Time] 
FROM (SELECT record.value('(./Record/@id)[1]','int')AS record_id, 
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]','int')AS [SystemIdle], 
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]','int')AS [SQLProcessUtilization], 
[timestamp]      
FROM (SELECT[timestamp], convert(xml, record) AS [record]             
FROM sys.dm_os_ring_buffers             
WHERE ring_buffer_type =N'RING_BUFFER_SCHEDULER_MONITOR'AND record LIKE'%%')AS x )AS y 
ORDER BY record_id DESC;

 

SQL Server Database wise CPU Utilization

From above script we come to know that SQL Server is utilizing high CPU, now the next step is to find out which database from the SQL instance is causing the high CPU utilization. Below is the SQL Script to Monitor CPU Utilization database wise.

/*****	Script: Database Wise CPU Utilization report *****/
/*****	Support: SQL Server 2008 and Above *****/
/*****	TestedOn: SQL Server 2008 R2 and 2014 *****/
/*****	Output: 
SNO: Serial Number
DBName: Databse Name 
CPU_Time(Ms): CPU Time in Milliseconds
CPUPercent: Let’s say this instance is using 50% CPU and one of the database is      using 80%. It means the actual CPU usage from the database is calculated as: (80 / 100) * 50 = 40 %
*****/
WITH DB_CPU AS
(SELECT	DatabaseID, 
		DB_Name(DatabaseID)AS [DatabaseName], 
		SUM(total_worker_time)AS [CPU_Time(Ms)] 
FROM	sys.dm_exec_query_stats AS qs 
CROSS APPLY(SELECT	CONVERT(int, value)AS [DatabaseID]  
			FROM	sys.dm_exec_plan_attributes(qs.plan_handle)  
			WHERE	attribute =N'dbid')AS epa GROUP BY DatabaseID) 
SELECT	ROW_NUMBER()OVER(ORDER BY [CPU_Time(Ms)] DESC)AS [SNO], 
	DatabaseName AS [DBName], [CPU_Time(Ms)], 
	CAST([CPU_Time(Ms)] * 1.0 /SUM([CPU_Time(Ms)]) OVER()* 100.0 AS DECIMAL(5, 2))AS [CPUPercent] 
FROM	DB_CPU 
WHERE	DatabaseID > 4 -- system databases 
	AND DatabaseID <> 32767 -- ResourceDB 
ORDER BY SNO OPTION(RECOMPILE);

SQL Server Query Wise CPU Utilization

From the above scripts you confirmed that there is a huge CPU utilization from one of the SQL Instance and you identified the database which is causing high CPU. Now the next step is to identify top 10 queries which are causing high CPU utilization. Here is the SQL Script to Monitor CPU Utilization query level. This is a wonderful script provided by SQLBlog and SQLKnowlwdge.

Note: Remember that it returns the list of costly queries which causes high CPU utilization when only the CPU usage is >=80% from last 10 Min, otherwise it returns nothing. You can modify the script as per your needs.

/*****	Script: Top 10 queries that causes high CPU Utilization *****/
/*****	Support: SQL Server 2008 and Above *****/
/*****	TestedOn: SQL Server 2008,R2 and 2014 *****/
/*****	Output: All query related details *****/
/*****	Note: This script returns list of costly queries when CPU utilization is >=80% from last 10 min ****/

SET NOCOUNT ON
DECLARE @ts_now bigint 
DECLARE @AvgCPUUtilization DECIMAL(10,2) 

SELECT @ts_now = cpu_ticks/(cpu_ticks/ms_ticks) FROM sys.dm_os_sys_info

-- load the CPU utilization in the past 10 minutes into the temp table, you can load them into a permanent table
SELECT TOP(10) SQLProcessUtilization AS [SQLServerProcessCPUUtilization]
,SystemIdle AS [SystemIdleProcess]
,100 - SystemIdle - SQLProcessUtilization AS [OtherProcessCPU Utilization]
,DATEADD(ms, -1 * (@ts_now - [timestamp]), GETDATE()) AS [EventTime] 
INTO #CPUUtilization
FROM ( 
      SELECT record.value('(./Record/@id)[1]', 'int') AS record_id, 
            record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') 
            AS [SystemIdle], 
            record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 
            'int') 
            AS [SQLProcessUtilization], [timestamp] 
      FROM ( 
            SELECT [timestamp], CONVERT(xml, record) AS [record] 
            FROM sys.dm_os_ring_buffers 
            WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' 
            AND record LIKE '%<SystemHealth>%') AS x 
      ) AS y 
ORDER BY record_id DESC


-- check if the average CPU utilization was over 80% in the past 10 minutes
SELECT @AvgCPUUtilization = AVG([SQLServerProcessCPUUtilization] + [OtherProcessCPU Utilization])
FROM #CPUUtilization
WHERE EventTime > DATEADD(MM, -10, GETDATE())

IF @AvgCPUUtilization >= 80
BEGIN
	SELECT TOP(10)
		CONVERT(VARCHAR(25),@AvgCPUUtilization) +'%' AS [AvgCPUUtilization]
		, GETDATE() [Date and Time]
		, r.cpu_time
		, r.total_elapsed_time
		, s.session_id
		, s.login_name
		, s.host_name
		, DB_NAME(r.database_id) AS DatabaseName
		, SUBSTRING (t.text,(r.statement_start_offset/2) + 1,
		((CASE WHEN r.statement_end_offset = -1
			THEN LEN(CONVERT(NVARCHAR(MAX), t.text)) * 2
			ELSE r.statement_end_offset
		END - r.statement_start_offset)/2) + 1) AS [IndividualQuery]
		, SUBSTRING(text, 1, 200) AS [ParentQuery]
		, r.status
		, r.start_time
		, r.wait_type
		, s.program_name
	INTO #PossibleCPUUtilizationQueries		
	FROM sys.dm_exec_sessions s
	INNER JOIN sys.dm_exec_connections c ON s.session_id = c.session_id
	INNER JOIN sys.dm_exec_requests r ON c.connection_id = r.connection_id
	CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
	WHERE s.session_id > 50
		AND r.session_id != @@spid
	order by r.cpu_time desc
	
	-- query the temp table, you can also send an email report to yourself or your development team
	SELECT *
	FROM #PossibleCPUUtilizationQueries		
END

-- drop the temp tables
IF OBJECT_ID('TEMPDB..#CPUUtilization') IS NOT NULL
drop table #CPUUtilization

IF OBJECT_ID('TEMPDB..#PossibleCPUUtilizationQueries') IS NOT NULL
drop table #PossibleCPUUtilizationQueries

Script to find Top 20 Costliest Stored Procedures – High CPU:

 This script sourced from here. It results a list of stored procedures which are utilizing high CPU. This script goes through the buffer cache and find out these results based on Total and Average worker thread times. Below is the SQL Script to Monitor CPU Utilization from the stored procedure point of view.

/*****	Script: Top 20 Stored Procedures using High CPU *****/
/*****	Support: SQL Server 2008 and Above *****/
/*****	Tested On: SQL Server 2008 R2 and 2014 *****/
/*****	Output: 
		SP Name: Stored Procedure Name
		TotalWorkerTime: Total Worker Time since the last compile time
		AvgWorkerTime: Average Worker Time since last compile time
		execution_count: Total number of execution since last compile time
		Calls/Second: Number of calls / executions per second
		total_elapsed_time: total elapsed time
		avg_elapsed_time: Average elapsed time
		cached_time: Procedure Cached time
*****/
SELECT TOP (20) 
  p.name AS [SP Name], 
  qs.total_worker_time AS [TotalWorkerTime], 
  qs.total_worker_time/qs.execution_count AS [AvgWorkerTime], 
  qs.execution_count, 
  ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) AS [Calls/Second],
  qs.total_elapsed_time, 
  qs.total_elapsed_time/qs.execution_count AS [avg_elapsed_time], 
  qs.cached_time
FROM	sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK) ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

Script to find Top 20 Costliest Queries – High CPU

 This script sourced from here. It results a list of queries which are utilizing high CPU. Below is the SQL Script to Monitor CPU Utilization from Ad-hoc queries.

/*****	Script: Top 20 Stored Procedures using High CPU *****/
/*****	Support: SQL Server 2008 and Above *****/
/*****	Tested On: SQL Server 2008 R2 and 2014 *****/
/*****	Output: Queries, CPU, Elapsed Times, Ms and S ****/
SELECT TOP (20)
    st.text AS Query,
    qs.execution_count,
    qs.total_worker_time AS Total_CPU,
    total_CPU_inSeconds = --Converted from microseconds
    qs.total_worker_time/1000000,
    average_CPU_inSeconds = --Converted from microseconds
    (qs.total_worker_time/1000000) / qs.execution_count,
    qs.total_elapsed_time,
    total_elapsed_time_inSeconds = --Converted from microseconds
    qs.total_elapsed_time/1000000,
    qp.query_plan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS apply sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

Summary:

I believe these scripts will be helpful to quickly get the Instance, Database and Query level CPU utilization reports.

References:

http://sqlblog.com/blogs/ben_nevarez/archive/2009/07/26/getting-cpu-utilization-data-from-sql-server.aspx

http://sqlknowledge.com/2010/12/how-to-monitor-sql-server-cpu-usage-and-get-auto-alerts/

https://sqlserverperformance.wordpress.com/2013/05/06/sql-server-2012-diagnostic-information-queries-may-2013/

http://www.johnsansom.com/how-to-identify-the-most-costly-sql-server-queries-using-dmvs/

 

 

The post SQL Script to Monitor CPU Utilization appeared first on udayarumilli.com.


Microsoft SQL Server Developer Edition is Free Now

$
0
0

Microsoft SQL Server Developer Edition is Free Now

Microsoft announced SQL Server Developer Edition is free. It’s April 1st but still we can believe as it is officially announced on Microsoft Information Platform. Microsoft SQL Server Developer Edition is free now and we should know few things:

  • Developer Edition is free download for Visual Studio Dev Essentials members.
  • SQL Server 2014 Developer Edition is free (Not like 180 Days Trail).
  • SQL Server 2016 Developer Edition will also be free.
  • This Free Developer Edition can be used in Development and Test Environments.
  • SQL Server 2014 Developer Edition offers the full feature set of SQL Server 2014 Enterprise Edition.

Here is the official announcement on “Microsoft SQL Server Developer Edition is Free Now”.

Reference:

 

https://blogs.technet.microsoft.com/dataplatforminsider/2016/03/31/microsoft-sql-server-developer-edition-is-now-free/?utm_content=%23MSDN+%23Data

 

The post Microsoft SQL Server Developer Edition is Free Now appeared first on udayarumilli.com.

Having Database and Web Server on single EC2 Instance

$
0
0

Advantages and Disadvantages of Having Database and Web Server on single EC2 Instance:

Recently when I was working with one of the client, they were planning for migrating their systems to AWS EC2 and they asked me a simple question “Can we have Database and Web server on single EC2 instance? What are all the advantages and disadvantages of having Database and Web Server on single EC2 instance?”   There are several things needs to be considered to answer this question. We thought of document it which can be helpful for the future reference.

Disadvantages of having Database and Web Server on single EC2 Instance:

Category Advantages
Security No Advantages
Performance

Communication easier between App server and DB Server as both are in same host

If the application makes a large amount of database queries, a considerable amount of network load can be removed by keeping it all on the same system, keeping the response times low.

On AWS if we have App and DB on same machine we need not worry about the region, otherwise we should make sure both DB and App servers are in same availability zone and region.

Load Balancing

On AWS we can get the benefit from Auto Scaling

Maintenance

It makes easier to maintain all App and DB from one place

HA & DR

No Advantages

Cost

Since App and DB sharing the same host it reduces almost half of the price

Scalability

We start using the application and database and we’ll add more resources when required in future using Auto Scaling

 

Disadvantages of having Database and Web Server on single EC2 Instance:

 

Category Disadvantages
Security

Webserver may need to be available for Public internet access and taking untrusted input from anonymous users.

If web server gets compromised then there might be high chances that attacker can get root access on database server too

Performance

Both the web server/app and SQL Server would cache requested data in memory and it strains the cache performance by running them in the same memory space.

May impact CPU cycles as sharing it between App and database

Huge I/O impact when we need to share the Disk between App and Database files

Usually Application and Database servers are having the different hardware requirements.
Database servers fare better with a lot of memory and a really fast disk array while web servers only require enough memory to cache files and frequent DB requests.

Load Balancing

It shouldn’t be a problem as long as we are having a proper estimations on App and DB server resource utility, but an unbalanced resource utility might causes a App / DB hang or interruption

Maintenance No Disadvantages
HA & DR

More recovery time required in-case of any disaster

Cost

Due to performance concern we can only have the databases related to the application sharing the instance, if we have a dedicated DB instance it can serve multiple applications effectively.

Scalability

It is easy and relatively cheap to add web servers and put them into cluster to handle
increased traffic It is not so easy and cheap to add data servers and cluster them.

 

Note: Please help us if we are missing anything. Please drop your suggestions in comments.

Summary:

Choose Database and Web Server on single EC2 Instance:

  • For a cost effective and low traffic / light weighted applications
  • Make sure using the least privilege accounts as there are high security risks
  • We can get a benefit from Auto Scaling

Choose Database on Web Servers on Different EC2 Instances:

  • For a good Scalability, High Availability, Performance and Security
  • Make sure instances are in Same availability Zone in Same Region
  • We can get benefit from ElasticCache

 

The post Having Database and Web Server on single EC2 Instance appeared first on udayarumilli.com.

SQL Server Security Audit Report

$
0
0

SQL Server Security Audit Report

SQL_Server_Security_Audit_Report

The purpose of sql server security audit report is to identify the potential vulnerabilities in the database system. This is a security audit assessment for Microsoft SQL Server and this report represents how much the database server is at risk to an attack. The vulnerabilities tested in sql server security audit report included:

  • Access control
  • Privilege Control
  • SQL injection
  • Configuration Management

Parameters have been classified into 5 categories based on the security impact. These are

  • Critical: Very critical vulnerability and it has to be fixed right away
  • High: High impact on security need to check based on your business requirement and environment.
  • Medium: Medium level of impact
  • Low: Impact is very low but still needs to be considered as a security issue.
  • Info: Just an information and no impact from security prospective

The target of this sql server security audit report is to identify as much as security vulnerabilities and report it in an organized manner. This is not an evolution of how “good” or “bad” databases are constructed as we are considering only the security prospect.

This report showcases the current security status by severity, vulnerability, compliance based on the given input rules. Any final decisions on how to handle these security issues should be verified and approved by the security leader or application owner. We strongly recommend fixing the Critical Vulnerabilities as a priority.

Audit Result:

Passed: The security parameter is passed as the configured value is safe

Exception: The parameter is vulnerable but this has to be an exception as per your business policy.

Failed: Parameter is failed in audit and focus required on this. Critical failures has to be fixed on priority

SQL Server Security Audit Report:

FAQ

Q1. What is the requirement for running this report?

Ans:

This is a native T-SQL script or a Powershell script to capture all these parameters. Any DBA with admin permission and also make sure that the DBA should be able to login to the SQL Server with sysadmin rights and also be able to RDS the host machine. For scripts details please have a look at references section.

Q2. What is the process for running this Audit?

Ans:

  • Get ready with an Admin login and RDS rights to the target machine
  • Logon to the server and run the prepared script
  • Complete the manual verification for the required parameters
  • Fill the attached excel sheet with the corresponding values and that’s it reports are ready

When we need to do the same for enterprise environment we can use a SQL Server table to store this data and then use a reporting tool preferably Excel, SSRS or PowerBI to get these reports server wise.

Q3. On which basis we have got these parameters?

Ans:

If you are an experienced in building new database systems using Microsoft SQL Server you should already have a checklist to check the current server security. These parameters have been prepared based on security best practices and Microsoft suggested practices, Security centre checklists and categorized based on our business requirement.

Note: We can change the severity, parameters, and their expected values and more things can be automated based on your business requirements and policies.

Q4. Does this report impact the performance or any other aspect? Any caution required?

Ans:

No! It just showcases the database server security levels and doesn’t impact the business in anyway. We used T-SQL scripts and some of the parameters has been captured manually. Below are the statistics per server.

Scripts Run time <= 2 sec.

Data Retrieval <= 100 kb

 

Q10. Do we have any third party tools available for this audit?

Ans:

Yes! Usually for sql server security audit report we use third party tools where we can see more options to customize the level of Audit and the richness on reporting. But the business should be ready to invest on license. This is a native T-SQL script with MS Excel Pivots and the same audit can be implemented in more effective way using Powershell scripts and PowerBI.

References:

Excel Sheet – sql server security audit report

T-SQL Scripts – Script-1, Script-2

Thanks to Rudy Panigas and Mayur-DEW for providing wonderful T-SQL scripts.

The post SQL Server Security Audit Report appeared first on udayarumilli.com.

SQL Server Memory Usage

$
0
0

SQL Server Memory Usage

SQL Server Memory Usage

SQL Server Memory Usage Related Interview Questions and Answers

Introduction:

This post takes you through “how to monitor SQL Server Memory usage”. Most of the clients I worked with had a common question “What is my SQL Server Memory Usage?” yah there are lot of ways to monitor SQL Server Memory Usage. Also if you are a senior database professional whether you might be an administrator, developer or architect you might be asked the question “How do you know SQL Server Memory usage?” One can design the best scalable and an optimized database system when he/she understands the RDBMS architecture. Here we’ll be discussing memory related parameters and how sql server uses memory. Before going through “Monitoring SQL Server Memory Usage” we should understand below things.

  • Memory Types
  • Top Performance Counters
  • Memory Allocation to SQL Server
  • Virtual Address Space
  • Buffer Pool and Memory-To-Leave (MTL)
  • Lock Pages in Memory
  • Instant File Initialization
  • Logical Reads & Physical Reads

Memory Types:

Physical Memory: The actual memory installed on mother board.

Virtual Memory: Total Physical Memory + Page File

Page File: When available memory can’t serve the coming requests it starts swapping pages to disk to the page file. The current page file size we can get from “sysdm.cpl” à Advanced à Performance Settings –> Advanced

Cached memory: It holds data or program code that has been fetched into memory during the current session but is no longer in use now.

Free memory: It represents RAM that does not contain any data or program code and is free for use immediately.

Working Set: Amount of memory currently in use for a process. Peak Working Set is the highest value recorded for the current instance of this process. Consistently Working Set < Min Server Memory and Max Server Memory means SQL Server is configured to use too much of memory.

Private Working Set: Amount of memory that is dedicated to that process and will not be given up for other programs to use.

Sharable Working Set: Shareable Working Set can be surrendered if physical RAM begins to run scarce

Commit Size: The total amount of virtual memory that a program has touched (committed) in the current session. Limit is Maximum Virtual Memory that means Physical RAM + Page File + Kernal Cache.

Hard faults / Page Faults: Pages fetching from the page file on the hard disk instead of from physical memory. Consistently high number of hard faults per second represents Memory pressure.

Memory Related Top Performance Counters:

Memory: Available Bytes:

High: Good Health

Low: Low Value Indicates Shortage of Memory)

Available Bytes counter indicates how many bytes of memory are currently available for use by processes.

Memory: Pages/sec:

High: Indicates excessive paging

Low: Good Health

Pages/sec counter indicates the number of pages that either were retrieved from disk due to hard page faults or written to disk to free space in the working set due to page faults.

SQL Server: Buffer Manager: Buffer Cache Hit Ratio:

High > 90%: Good Health

Low < 90%: More requests are getting data from physical disk instead of data cache

Minimum Server Memory: Minimum amount of memory which is initially allocated to SQL Server. Default value is 0.

Maximum Server Memory: Maximum Server Memory that sql server can use up to. Make sure you are having a proper statistics and future plan before making any changes. Default value is set to 2 Peta Bytes. To determine this value first we need to know the memory required for OS and memory required for any other applications / services. Maximum Server Memory = Total Physical Memory – (Memory Required for OS + Memory Required for Other Applications);

Memory Manager: Total Server Memory (KB):

Shows how much memory SQL Server is using. The primary use of SQL Server’s memory is for the buffer pool, but some memory is also used for storing query plans and keeping track of user process information.

Memory Manager: Target Server Memory (KB):

This value shows how much memory SQL Server attempts to acquire. If you haven’t configured a max server memory value for SQL Server, the target amount of memory will be about 5MB less than the total available system memory.

Total Server Memory is almost same as Target Server Memory – Good Health

Total Server Memory is much smaller than Target Server Memory – There is a Memory Pressure or Max Server Memory is set to too low.

Page Life Expectancy:

High: Good Health

Low: Memory Pressure or Max Server Memory is not allocated properly

Number of seconds a page is staying on buffer cache. Usually we do calculate based on the Memory allocated to SQL server Instance. For 4 GB ram the PLE is supposed to be 300 sec / 5 Min.

4 GB – (4/4) * 300 = 300 Sec = 5 Min

16 GB – (16 / 4) * 300 = 1200 Sec = 20 Min

32 GB – (32 / 4) * 300 = 2400 Sec = 40 Min

This is to set an estimated health benchmark for PLE, one can follow their own formula based on their environment and experience.

Interview Questions and Answers – SQL Server Memory Usage

Q. How SQL Server acquires and releases Memory to / from OS?

Ans:

When SQL Server is using memory dynamically, it queries the system periodically to determine the amount of free memory. Maintaining this free memory prevents the operating system (OS) from paging. If less memory is free, SQL Server releases memory to the OS. If more memory is free, SQL Server may allocate more memory. SQL Server adds memory only when its workload requires more memory; a server at rest does not increase the size of its virtual address space.

Q. What is Virtual Address Space (VAS)?

Ans:

  • A virtual address is a binary number in virtual memory that enables a process to use a location in primary storage (main memory) independently of other processes.
  • This provides a layer of abstraction between an application and physical memory so that the operating system can choose the most efficient way to use physical memory across all the processes.
  • For example, two different processes can both use the memory address 0xFFF because it’s a virtual address and each process has its own VAS with the same address range.
  • The size of the virtual address space is determined largely by the CPU architecture.
  • 32 bit can have Max 2^32 = 4 GB VAS and 64 bit will have 2^64 = Almost 16 Trillion GB VAS – 8TB is CAP

Q. I have restarted my windows server. Can you be able to explain how memory allocation happens for SQL Server?

Ans:

Memory allocation is always depends on CPU architecture.

32 Bit:

  • Initially allocates memory for Memory To Leave (MTL) also known as VAS Reservation (384 MB). This MTL value can be modified using the start parameter “–g”
  • Then Allocates memory for Buffer Pool = User VAS – MTL (Reserved VAS) = Available VAS
  • Maximum BPool Size = 2048 MB – 384 MB = 1664 MB.

64 Bit:

  • Allocates Memory for Buffer Pool based on Maximum Server Memory configuration
  • Non-Buffer Pool Memory region (MTL / VAS Reservation) = Total Physical Memory – (Max Server Memory + Physical Memory Used by OS and Other Apps)
  • Ex: Windows Server is having 64 GB physical memory; SQL Server Max Server Memory = 54 GB and OS and other apps are using 6 GB then the memory available for
  • Non-BPool (MTL / VAS Reservation) = 64 – (54+6) = 4 GB
  • Max Buffer Pool Size = Max Server Memory = 54 GB

Q. What are all the objects that use MTL / Non-BPool memory allocated for SQL Server?

Ans:

  • Connections with Network Packet Size higher than 8KB (8192 bytes)
  • Memory allocated by Linked Server OLEDB Providers and third party DLL’s loaded in SQL Server process
  • Extended Stored Procedures or sp_OAcreate calls
  • XML Documents
  • Query Plans with the size > 8 KB
  • SQL Server CLR
  • Backups using larger MAXTRANSFERSIZE parameter
  • Memory consumed by memory managers when memory requested for more than 8 KB contiguous allocation
  • Memory for threads (stack size is 2 MB in 64-BIT SQL)

Q. What is “Lock Pages in Memory”?

Ans:

  • As you may know how memory allocation on windows operating system SQL Server occupies memory as much as it can based on the configurations and available memory.
  • When windows operating system encounter a memory pressure it starts asking SQL Server to release memory and that released memory will be paged to page file.
  • When Lock Pages In Memory is enabled for SQL Server Service Account then SQL Server can lock the pages and need not release memory when windows forcing to release.

Q. Can you technically explain how memory allocated and lock pages works?

Ans:

Windows OS runs all processes on its own Virtual Memory known as Virtual Address Space and this VAS is divided into Kernal (System) and User (Application) mode.

Default: No Lock Pages in Memory is enabled

  • SQL Server memory allocations made under User Mode VAS using VirtualAlloc() WPI function.
  • Any memory that allocates via VirtualAlloc() can be paged to disk.
  • SQLOS resource monitor checks QueryMemoryResourceNotification windows API and when windows sets Memory Low notification, SQLOS responds to that request by releasing the memory back to windows.

Lock Pages in Memory is Enabled for SQL Server:

  • SQL Server memory allocations are made using calls to the function AllocateUserPhysicalPages() in AWE API.
  • Memory that allocates using AllocateUserPhysicalPages() is considered to be locked. That means these pages should be on Physical Memory and need not be released when a Memory Low Notification on Windows.

Q. Does Lock pages in Memory (LPIM) is enabled to by default for SQL Server 2008 R2 / 2012 /2014?

Ans:

No! As per Microsoft documentation it’s not. We need to enable it.

Q. When to choose Lock Pages in Memory option for SQL Server?

Ans:

  • When using Old windows servers – SQL Server 2005 on Windows Server 2003
  • When working with 32 Bit servers and AWE is enabled
  • When using Windows 2008 R2 / 2012 / 2014 and above still seeing Hard Trims happening SQL Server process memory.

Note: If you are using the latest windows systems and configured SQL Server memory settings as per the business requirement we need not worry about Lock Pages in Memory.

Q. How to enable Lock Pages in Memory for SQL Server?

Ans:

We can enable by adding SQL Server service account to “Lock Pages in Memory” in group policy editor.

  • Open Group Policy Editor using the shortcut “GPEDIT.MSC”
  • Computer Configuration
  • Windows Settings
  • Security Settings
  • Local Policies
  • User Rights Assignment
  • Right Side “Lock Pages In Memory”
  • Right Click Properties
  • Add SQL Server DBEngine service account
  • Restart SQL Server

Q. On which basis you would determine the Max Server Memory Setting for SQL Server?

Ans:

Max Server Memory is the maximum amount of memory reserved for SQL Server. There are few things needs to be considered:

  • Applications sharing the host with SQL Server and required average memory for those Apps
  • Total Physical memory is less than 16 GB leave 1 GB for OS for each 4 GB
  • Total Physical memory is greater than 16 GB leave 1 GB for OS for each 8 GB
  • Monitor Memory\Available Mbytes counter and check the status
  • Ex: If no user application is sharing with SQL Server
  • Total Physical Memory = 8 GB – 2 GB for OS and Apps + (6 GB – Max Server Memory)
  • Total Physical Memory = 16 GB – 4 GB for OS and Apps + (12 GB – Max Server Memory)
  • Total Physical Memory = 96 GB – 12 GB for OS and Apps+ (84 GB – Max Server Memory)

Remember in 64 bit machine we need to consider Non-Buffer Pool object memory region while leaving memory for OS. This is just a baseline that we followed while setting up new environments. We are strictly supposed to monitor the memory usage in peak hours and adjust the settings.

Q. Here is a scenario: When we are monitoring memory usage by one of the SQL Server instance, surprisingly sql server is using more memory than Max Server Memory configuration. Any idea why it’s happening?

Ans:

  • Yes! It is expected as Memory is allocated for SQL server: BPool + Non-Bpool.
  • BPool can be controlled by the Max Server Memory Setting but not the Non-BPool memory.
  • Also Lock Pages in Memory can control BPool memory but still Non-BPool pages are paged to disk

Q. What is Instant File Initialization and how it works?

Ans:

On Windows systems when SQL Server needs to write something on disk, first it verify that the hard disk space is trustworthy means the space is readable. The verification process is:

  • SQL Server writes zeros to the file
  • This process is known as zeroing process
  • SQL Server uses single thread for zeroing process
  • The actual operation that triggers this verification should wait until this verification process completed.

If Instant File Initialization is enabled for SQL Server, it skips the zeroing process for data files and reduces the wait time.

Q. What are the database activities that get benefit from Instant File Initialization?

Ans:

  • Creating a new Database
  • Restoring a database from backup file
  • Increasing database data file size manually
  • Increasing database data file size due to Auto Growth option
  • Tempdb creation at the time of SQL Server restart

Note: Remember growing log file still uses the zeroing process

Q. How to check if Instant File Initialization is enabled for a SQL Server

Ans:

Enabling trace flags (3004,3605) enable writing zeroing process information into SQL Server error log. If Instant File Initialization is enabled for sql server we can’t see zeroing process messages for data file where we can still can see zeroing process messages related to log files something like “Zeroing Completed On …….._log.ldf”.

Q. How to enable Instant File Initialization?

Ans:

In order for SQL Server to be able to perform instant file initialization the SQL Server service account must be granted the Perform Volume Maintenance Task security permission. This can be done by using the Local Security Policy Editor.

  • Run lusrmgr.msc on the server to find the appropriate group name for each instance of SQL Server.
  • Run secpol.msc on the server.
  • Under Security Settings on the left, go to Local Policies and under that to User Rights Assignment.
  • Under Policy on the right side, go to “Perform volume maintenance tasks” and double click on it
  • Add SQL Server group created by SQL setup (standalone) or cluster domain group (for clusters)
  • Restart SQL Server

Note: If your sql server service account is already in part of Windows Local Administrators Group then we need not add it to the Volume Maintenance Task. Also IFI doesn’t works if Transparent Data Encryption (TDE) is enabled.

Q. Have you ever implemented Instant file Initialization in any environment? If yes did you observe any performance gain?

Ans:

Yes! I have enabled this option in most of the environments I worked and I strongly suggest enabling it.

I have clearly seen the performance gain by enabling Instant File Initialization. An example:

Restoring a database from the backup (160 GB) – 3Hr 47Min

After Enabling Instant File Initialization the same operation took – 2Hr 8 Min

Q. Does Instant File Initialization is enabled for SQL Server by default?

Ans:

No! By default IFI is not enabled for SQL Server as there is a slight security risk.

As you may know, when data is deleted from disk by the operating system, it really is not physically deleted; the space holding the data is just marked as being available. At some point, the older data will be overwritten with new data.

  • When Instant File Initialization is not enabled: Data is zeroed out before writing anything on that page.
  • When Instant File Initialization is enabled: There is a slight security risk here. When a new database is created those new pages are not zeroed out and there is a chance that newly allocated pages might contain previously deleted data and one can read that data using a recovery tool.

Q. Can you tell me the difference between Logical Reads and Physical Reads?

Ans:

Logical Reads:

  • Logical read indicates total number of data pages needed to be accessed from data cache to process query.
  • It is very possible that logical read will access same data pages many times, so count of logical read value may be higher than actual number of pages in a table.
  • Usually the best way to reduce logical read is to apply correct index or to rewrite the query.

Physical Reads:

  • Physical read indicates total number of data pages that are read from disk.
  • For a query when required pages are not found on cache memory it picks the required pages from Hard Disk and keep those pages on cache memory for further usage. This is known as physical read.

Q. When I have been checking for buffer usage one of the stored procedure is using large number of Logical Reads. Does this impact performance? What are the most possible reasons for a large number of logical reads?

Ans:

Yes! Large number of logical reads leads to memory pressure. There are few common reasons that cause more logical reads:

  • Unused Indexes: Indexes should be built on the basis of data retrieval process. If indexes defined on columns and those columns are not being used in queries that leads to huge number of logical reads.
  • Wide Indexes: Indexing on the large number of columns will leads to high logical reads.
  • Poor Fill Factor/Page Density: When a less fill factor is specified large number of page needed to qualify a simple query which leads to High Logical Reads.
  • Poor Query Design: If query leads to index scan, Hash Join when Merge Join is possible, not using indexes etc. causes the more number of logical reads.

References:

The above List of Questions was asked in worlds top organizations for the positions Senior Database Architect and SQL Server SME and Database Advisory Team Lead. These questions were shared by Lalit Sharma and Niveedita. We would like to thank both of you for your valuable time and contribution. Would like to thank famous MVPs / bloggers (Glenn Berry, Brent Ozar, Jonathan Kehayias, John Sansom) for the tremendous explanation on sql server internals. Their articles are very helpful in understanding internals and answering these questions.

Also Check:

Script to Monitor SQL Server Memory Usage

SQL Server CPU Utilization

The post SQL Server Memory Usage appeared first on udayarumilli.com.

Script to Monitor SQL Server Memory Usage

$
0
0

Script to Monitor SQL Server Memory Usage

Script to Monitor SQL Server Memory Usage

Introduction:

This post will takes you through the T-SQL Script to monitor SQL Server Memory Usage. In previous blog post we have explained the parameters involved in understanding sql server memory usage. There are total 7 scripts to monitor SQL Server Memory Usage.

  • Buffer Pool Usage
  • System Memory Information
  • SQL Server Process Memory Usage Information
  • Buffer Usage by Database
  • Object Wise Buffer Usage
  • Top 25 Costliest Stored Procedures – Logical Reads
  • Top Performance Counters

Script to Monitor SQL Server Memory Usage: Buffer Pool Usage

Results:

BPool_Committed_MB: Actual memory committed/used by the process (SQL Server).

BPool_Commit_Tgt_MB: Actual memory SQL Server tried to consume.

BPool_Visible_MB: Number of 8-KB buffers in the buffer pool that are directly accessible in the process virtual address space (SQL Server VAS).

Analysis:

BPool_Commit_Tgt_MB > BPool_Committed_MB: SQL Server Memory Manager tries to obtain additional memory

BPool_Commit_Tgt_MB < BPool_Committed_MB: SQL Server Memory Manager tries to shrink the amount of memory committed

If the value of BPool_Visible_MB is too low: We might receive out of memory errors or memory dump will be created.

 

/*********************************************/
--Script: Captures Buffer Pool Usage
--Works On: 2008, 2008 R2, 2012, 2014, 2016
/*********************************************/

-- SQL server 2008 / 2008 R2

SELECT
     (bpool_committed*8)/1024.0 as BPool_Committed_MB,
     (bpool_commit_target*8)/1024.0 as BPool_Commit_Tgt_MB,
     (bpool_visible*8)/1024.0 as BPool_Visible_MB
FROM sys.dm_os_sys_info;

-- SQL server 2012 / 2014 / 2016
SELECT
      (committed_kb)/1024.0 as BPool_Committed_MB,
      (committed_target_kb)/1024.0 as BPool_Commit_Tgt_MB,
      (visible_target_kb)/1024.0 as BPool_Visible_MB
FROM  sys.dm_os_sys_info;

Script to Monitor SQL Server Memory Usage: System Memory Information

Results:

total_physical_memory_mb: Actual Physical Memory installed in OS

available_physical_memory_mb: Available Physical Memory

total_page_file_mb: Pagefile size on OS

available_page_file_mb: Available page file size

Percentage_Used: Physical Memory Percentage used

system_memory_state_desc: Memory current Health status

Analysis:

available_physical_memory_mb: Should be some positive sign based on total physical memory

available_page_file_mb: Should be some positive sign based on your total page file

Percentage_Used: 100% for a long time indicates a memory pressure

system_memory_state_desc: should be Available physical memory is high / steady

/*********************************************************************/
--Script: Captures System Memory Usage
--Works On: 2008, 2008 R2, 2012, 2014, 2016
/*********************************************************************/

select
      total_physical_memory_kb/1024 AS total_physical_memory_mb,
      available_physical_memory_kb/1024 AS available_physical_memory_mb,
      total_page_file_kb/1024 AS total_page_file_mb,
      available_page_file_kb/1024 AS available_page_file_mb,
      100 - (100 * CAST(available_physical_memory_kb AS DECIMAL(18,3))/CAST(total_physical_memory_kb AS DECIMAL(18,3))) 
      AS 'Percentage_Used',
      system_memory_state_desc
from  sys.dm_os_sys_memory;

 

Script to Monitor SQL Server Memory Usage: SQL Server Process Memory Usage

Results:

physical_memory_in_use: Indicates the process working set in KB, as reported by operating system, as well as tracked allocations by using large page APIs

locked_page_allocations: Specifies memory pages locked in memory

virtual_address_space_committed: Indicates the amount of reserved virtual address space that has been committed or mapped to physical pages.

available_commit_limit: Indicates the amount of memory that is available to be committed by the process (SQL server)

page_fault_count: Indicates the number of page faults that are incurred by the SQL Server process

Analysis:

physical_memory_in_use: We can’t figure out the exact amount of physical memory using by sqlservr.exe using task manager but this column showcase the actual amount of physical memory using by SQL Server.

locked_page_allocations: If this is > 0 means Locked Pages is enabled for SQL Server which is one of the best practice

available_commit_limit: This indciates the available amount of memory that can be committed by the process sqlservr.exe

page_fault_count: Pages fetching from the page file on the hard disk instead of from physical memory. Consistently high number of hard faults per second represents Memory pressure.

/**************************************************************/
-- Script: SQL Server Process Memory Usage
-- Works On: 2008, 2008 R2, 2012, 2014, 2016
/**************************************************************/
select
      physical_memory_in_use_kb/1048576.0 AS 'physical_memory_in_use (GB)',
      locked_page_allocations_kb/1048576.0 AS 'locked_page_allocations (GB)',
      virtual_address_space_committed_kb/1048576.0 AS 'virtual_address_space_committed (GB)',
      available_commit_limit_kb/1048576.0 AS 'available_commit_limit (GB)',
      page_fault_count as 'page_fault_count'
from  sys.dm_os_process_memory;

 

Script to Monitor SQL Server Memory Usage: Database Wise Buffer Usage

Results:

db_name: Name of the database in the given SQL server Instance

db_buffer_pages: Total number of corresponding database pages that are in buffer pool

db_buffer_Used_MB: Database wise Buffer size used in MB

db_buffer_Free_MB: Database wise Buffer Size Free (sum of free space on all pages) in MB.

db_buffer_percent: Database wise percentage of Buffer Pool usage

Analysis:

We can quickly find out the top databases which are consuming more Memory / Buffer Pool from the given SQL server Instance

/**************************************************************/
--Script: Database Wise Buffer Usage
--Works On: 2008, 2008 R2, 2012, 2014, 2016
/**************************************************************/

DECLARE @total_buffer INT;
SELECT  @total_buffer = cntr_value 
FROM   sys.dm_os_performance_counters
WHERE  RTRIM([object_name]) LIKE '%Buffer Manager' 
       AND counter_name = 'Database Pages';

;WITH DBBuffer AS
(
SELECT  database_id,
        COUNT_BIG(*) AS db_buffer_pages,
        SUM (CAST ([free_space_in_bytes] AS BIGINT)) / (1024 * 1024) AS [MBEmpty]
FROM    sys.dm_os_buffer_descriptors
GROUP BY database_id
)
SELECT
       CASE [database_id] WHEN 32767 THEN 'Resource DB' ELSE DB_NAME([database_id]) END AS 'db_name',
       db_buffer_pages AS 'db_buffer_pages',
       db_buffer_pages / 128 AS 'db_buffer_Used_MB',
       [mbempty] AS 'db_buffer_Free_MB',
       CONVERT(DECIMAL(6,3), db_buffer_pages * 100.0 / @total_buffer) AS 'db_buffer_percent'
FROM   DBBuffer
ORDER BY db_buffer_Used_MB DESC;

 

Script to Monitor SQL Server Memory Usage: Object Wise Buffer Usage

Results:

Object: Name of the Object

Type: Type of the object Ex: USER_TABLE

Index: Name of the Index

Index_Type: Type of the Index “Clustered / Non Clustered / HEAP” etc

buffer_pages: Object wise number of pages is in buffer pool

buffer_mb: Object wise buffer usage in MB

Analysis:

From the previous script we can get the top databases using memory. This script helps you out in finding the top objects that are using the buffer pool. Top objects will tell you the objects which are using the major portion of the buffer pool.If you find anything suspicious then you can dig into it.

/**************************************************************/
--Script: Object Wise Buffer Usage
--Works On: 2008, 2008 R2, 2012, 2014, 2016
/**************************************************************/

;WITH obj_buffer AS
(
SELECT
       [Object] = o.name,
       [Type] = o.type_desc,
       [Index] = COALESCE(i.name, ''),
       [Index_Type] = i.type_desc,
       p.[object_id],
       p.index_id,
       au.allocation_unit_id
FROM
       sys.partitions AS p
       INNER JOIN sys.allocation_units AS au ON p.hobt_id = au.container_id
       INNER JOIN sys.objects AS o ON p.[object_id] = o.[object_id]
       INNER JOIN sys.indexes AS i ON o.[object_id] = i.[object_id] AND p.index_id = i.index_id
WHERE
       au.[type] IN (1,2,3) AND o.is_ms_shipped = 0
)
SELECT
       obj.[Object],
       obj.[Type],
       obj.[Index],
       obj.Index_Type,
       COUNT_BIG(b.page_id) AS 'buffer_pages',
       COUNT_BIG(b.page_id) / 128 AS 'buffer_mb'
FROM
       obj_buffer obj 
       INNER JOIN sys.dm_os_buffer_descriptors AS b ON obj.allocation_unit_id = b.allocation_unit_id
WHERE
       b.database_id = DB_ID()
GROUP BY
       obj.[Object],
       obj.[Type],
       obj.[Index],
       obj.Index_Type
ORDER BY
       buffer_pages DESC;

Script to Monitor SQL Server Memory Usage: Top 25 Costliest Stored Procedures by Logical Reads

Results:

SP Name: Stored Procedure Name

TotalLogicalReads: Total Number of Logical Reads since this stored procedure was last compiled

AvgLogicalReads: Average Number of Logical Reads since this stored procedure was last compiled

execution_count: Number of Times SP got executed since it was compiled

total_elapsed_time: Total elapsed time for this proc since last time compiled

avg_elapsed_time: Average elapsed time

cached_time: Time at which the stored procedure was added to the cache.

Analysis:

  • This helps you find the most expensive cached stored procedures from a memory perspective
  • You should look at this if you see signs of memory pressure
  • More number of logical reads means you need to check execution plan to find the bottleneck

/**************************************************************/
--Script: Top 25 Costliest Stored Procedures by Logical Reads
--Works On: 2008, 2008 R2, 2012, 2014, 2016
/**************************************************************/

SELECT  TOP(25)
        p.name AS [SP Name],
        qs.total_logical_reads AS [TotalLogicalReads],
        qs.total_logical_reads/qs.execution_count AS [AvgLogicalReads],
        qs.execution_count AS 'execution_count',
        qs.total_elapsed_time AS 'total_elapsed_time',
        qs.total_elapsed_time/qs.execution_count AS 'avg_elapsed_time',
        qs.cached_time AS 'cached_time'
FROM    sys.procedures AS p
        INNER JOIN sys.dm_exec_procedure_stats AS qs 
                   ON p.[object_id] = qs.[object_id]
WHERE
        qs.database_id = DB_ID()
ORDER BY
        qs.total_logical_reads DESC;

 

Script to Monitor SQL Server Memory Usage: Top Performance Counters – Memory

Results:

Total Server Memory: Shows how much memory SQL Server is using. The primary use of SQL Server’s memory is for the buffer pool, but some memory is also used for storing query plans and keeping track of user process information.

Target Server Memory: This value shows how much memory SQL Server attempts to acquire. If you haven’t configured a max server memory value for SQL Server, the target amount of memory will be about 5MB less than the total available system memory.

Connection Memory (GB): The Connection Memory specifies the total amount of dynamic memory the server is using for maintaining connections

Lock Memory (GB): Shows the total amount of memory the server is using for locks

SQL Cache Memory: Total memory reserved for dynamic SQL statements.

Optimizer Memory: Memory reserved for query optimization.

Granted Workspace Memory: Total amount of memory currently granted to executing processes such as hash, sort, bulk copy, and index creation operations.

Cursor memory usage: Memory using for cursors

Free pages: Amount of free space in pages which are commited but not currently using by SQL Server

Reserved Pages: Shows the number of buffer pool reserved pages.

Stolen pages (MB): Memory used by SQL Server but not for Database pages.It is used for sorting or hashing operations, or “as a generic memory store for allocations to store internal data structures such as locks, transaction context, and connection information.

Cache Pages: Number of 8KB pages in cache.

Page life expectancy: Average how long each data page is staying in buffer cache before being flushed out to make room for other pages

Free list stalls / sec: Number of times a request for a “free” page had to wait for one to become available.

Checkpoint Pages/sec: Checkpoint Pages/sec shows the number of pages that are moved from buffer to disk per second during a checkpoint process

Lazy writes / sec: How many times per second lazy writer has to flush dirty pages out of the buffer cache instead of waiting on a checkpoint.

Memory Grants Outstanding: Number of processes that have successfully acquired workspace memory grant.

Memory Grants Pending: Number of processes waiting on a workspace memory grant.

process_physical_memory_low: Process is responding to low physical memory notification

process_virtual_memory_low: Indicates that low virtual memory condition has been detected

Min Server Memory: Minimum amount of memory SQL Server should acquire

Max Server Memory: Maximum memory that SQL Server can acquire from OS

Buffer cache hit ratio: Percentage of pages that were found in the buffer pool without having to incur a read from disk.

Analysis:

Total Server Memory is almost same as Target Server Memory: Good Health

Total Server Memory is much smaller than Target Server Memory: There is a Memory Pressure or Max Server Memory is set to too low.

Connection Memory: When high, check the number of user connections and make sure it’s under expected value as per your business

Optimizer Memory: Ideally, the value should remain relatively static. If this isn’t the case you might be using dynamic SQL execution excessively.

Higher the value for Stolen Pages: Find the costly queries / procs and tune them

Higher the value for Checkpoint Pages/sec: Problem with I/O, Do not depend on Automatic Checkpoints and use In-direct checkpoints.

Page life expectancy: Usually 300 to 400 sec for each 4 GB of memory. Lesser the value means memory pressure

Free list stalls / sec: High value indicates that the server could use additional memory.

Memory Grants Outstanding: Higher value indicates peak user activity

Memory Grants Pending: Higher value indicates SQL Server need more memory

process_physical_memory_low & process_virtual_memory_low: Both are equals to 0 means no internal memory pressure

Min Server Memory: If it is 0 means default value didnt get changed, it’ll always be better to have a minimum amount of memory allocated to SQL Server

Max Server Memory: If it is default to 2147483647, change the value with the correct amount of memory that you can allow SQL Server to utilize.

Buffer cache hit ratio: This ratio should be in between 95 and 100. Lesser value indicates memory pressure

/**************************************************************/
--Script: Top Performance Counters - Memory
--Works On: 2008, 2008 R2, 2012, 2014, 2016
/**************************************************************/

-- Get size of SQL Server Page in bytes
DECLARE @pg_size INT, @Instancename varchar(50)
SELECT @pg_size = low from master..spt_values where number = 1 and type = 'E'

-- Extract perfmon counters to a temporary table
IF OBJECT_ID('tempdb..#perfmon_counters') is not null DROP TABLE #perfmon_counters
SELECT * INTO #perfmon_counters FROM sys.dm_os_performance_counters;

-- Get SQL Server instance name as it require for capturing Buffer Cache hit Ratio
SELECT  @Instancename = LEFT([object_name], (CHARINDEX(':',[object_name]))) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Buffer cache hit ratio';


SELECT * FROM (
SELECT  'Total Server Memory (GB)' as Cntr,
        (cntr_value/1048576.0) AS Value 
FROM    #perfmon_counters 
WHERE   counter_name = 'Total Server Memory (KB)'
UNION ALL
SELECT  'Target Server Memory (GB)', 
        (cntr_value/1048576.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Target Server Memory (KB)'
UNION ALL
SELECT  'Connection Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Connection Memory (KB)'
UNION ALL
SELECT  'Lock Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Lock Memory (KB)'
UNION ALL
SELECT  'SQL Cache Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'SQL Cache Memory (KB)'
UNION ALL
SELECT  'Optimizer Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Optimizer Memory (KB) '
UNION ALL
SELECT  'Granted Workspace Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Granted Workspace Memory (KB) '
UNION ALL
SELECT  'Cursor memory usage (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Cursor memory usage' and instance_name = '_Total'
UNION ALL
SELECT  'Total pages Size (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name= @Instancename+'Buffer Manager' 
        and counter_name = 'Total pages'
UNION ALL
SELECT  'Database pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name = @Instancename+'Buffer Manager' and counter_name = 'Database pages'
UNION ALL
SELECT  'Free pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name = @Instancename+'Buffer Manager' 
        and counter_name = 'Free pages'
UNION ALL
SELECT  'Reserved pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Reserved pages'
UNION ALL
SELECT  'Stolen pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Stolen pages'
UNION ALL
SELECT  'Cache Pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Plan Cache' 
        and counter_name = 'Cache Pages' and instance_name = '_Total'
UNION ALL
SELECT  'Page Life Expectency in seconds',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Page life expectancy'
UNION ALL
SELECT  'Free list stalls/sec',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Free list stalls/sec'
UNION ALL
SELECT  'Checkpoint pages/sec',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Checkpoint pages/sec'
UNION ALL
SELECT  'Lazy writes/sec',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Lazy writes/sec'
UNION ALL
SELECT  'Memory Grants Pending',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Memory Manager' 
        and counter_name = 'Memory Grants Pending'
UNION ALL
SELECT  'Memory Grants Outstanding',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Memory Manager' 
        and counter_name = 'Memory Grants Outstanding'
UNION ALL
SELECT  'process_physical_memory_low',
        process_physical_memory_low 
FROM    sys.dm_os_process_memory WITH (NOLOCK)
UNION ALL
SELECT  'process_virtual_memory_low',
        process_virtual_memory_low 
FROM    sys.dm_os_process_memory WITH (NOLOCK)
UNION ALL
SELECT  'Max_Server_Memory (MB)' ,
        [value_in_use] 
FROM    sys.configurations 
WHERE   [name] = 'max server memory (MB)'
UNION ALL
SELECT  'Min_Server_Memory (MB)' ,
        [value_in_use] 
FROM    sys.configurations 
WHERE   [name] = 'min server memory (MB)'
UNION ALL
SELECT  'BufferCacheHitRatio',
        (a.cntr_value * 1.0 / b.cntr_value) * 100.0 
FROM    sys.dm_os_performance_counters a
        JOIN (SELECT cntr_value,OBJECT_NAME FROM sys.dm_os_performance_counters
              WHERE counter_name = 'Buffer cache hit ratio base' AND 
                    OBJECT_NAME = @Instancename+'Buffer Manager') b ON 
                    a.OBJECT_NAME = b.OBJECT_NAME WHERE a.counter_name = 'Buffer cache hit ratio' 
                    AND a.OBJECT_NAME = @Instancename+'Buffer Manager'

) AS D;

Script to Monitor SQL Server Memory Usage: DBCC MEMORYSTATUS

Finally DBCC MemoryStatus:

  • It gives as much as memory usage information based on object wise / component wise.
  • First table gives us the complete details of server and process memory usage details and memory alert indicators.
  • We can also get memory usage by buffer cache, Service Broker, Temp tables, Procedure Cache, Full Text, XML, Memory Pool Manager, Audit Buffer, SQLCLR, Optimizer, SQLUtilities, Connection Pool etc.

Summary:

These Scripts will help you in understanding the current memory usage by SQL Server. To maintain a healthy database management system:

  • Monitor the system for few business days in peak hours and fix the baselines
  • Identify the correct required configurations for your database server and make the required changes
  • Identify top 10 queries / procedures based on Memory and CPU usage
  • Fine tune these top 10 queries / procedures

Note:

These scripts are tested on SQL Server 2008, 2008 R2, 2012 and 2014. As we always suggests please test these scripts on Dev/Test environment before using them on production systems.

References:

Would like to thank famous MVPs / MCM / bloggers (Glenn Berry, Brent Ozar, Jonathan Kehayias, John Sansom) for the tremendous explanation on sql server internals. Their articles are very informative and helpful in understanding SQL Server internals.

Also Check:

SQL Server Memory Usage

SQL Server CPU Utilization

The post Script to Monitor SQL Server Memory Usage appeared first on udayarumilli.com.

Search for an Object in SQL Server

$
0
0

Search for an Object in SQL Server

This article helps you in understanding how to Search for an object in SQL Server using T-SQL script. When we need to search for an object inside a database we can do that using sys.objects but when it comes to cross database search that needs a solution. There are different ways to search for an object in SQL Server:

  • T-SQL Script: A native T-SQL script.
  • Object Explorer Search: User required proper permissions to use this
  • Red Gate SQL Search: It’s not always possible installing freeware on enterprise environments
  • SSMS Tools Pack Add-in: An extra tool has to be added to SSMS

Why Instance level object search is required?

There are few cases where we search for objects across the instance.

  • Cleanup: This is the common task that every DBA / Developer performs. We usually create backups for tables for temporary basis while performing a critical update or working on a change requests. But we forget to cleanup / remove those objects.
  • Critical times: When there is an incident happened and you are working on resolution someone asked you details of an object path.
  • Developer / DBA are new to environment: When you are new to the environment and you wanted to quickly know the object path.

Search for an object in SQL Server using T-SQL:

Now we are going to create a stored procedure that helps us to search for an object name in SQL Server instance level. Remember the same script you can remove procedure and use as a T-SQL batch script.

/***********************************************************************/
--ProcName: usp_ObjectSeek
--Description: To search for an object in SQL Server instance level
--@ObjName: Name of the object to be searched
--@SearchType: Search Criteria; Default to equal
--	            equal: Entire object name should be macthed
--                  start: Object Name should starts with this name
--	            end: Object Name should end with this name
--	            contain: Object name should conatin this name 	 
/***********************************************************************/
CREATE PROCEDURE usp_ObjectSeek (@objName VARCHAR(200),@SearchType VARCHAR(20) = 'equal')
AS
BEGIN
	SET NOCOUNT ON;

	-- Declare sql to hold dynamic query
	DECLARE @SQL VARCHAR(4000);

	--Declare a table variable to hold the resultset
	DECLARE @ObjSeek TABLE (ID TINYINT IDENTITY,
				DBName VARCHAR(100) NOT NULL, 
				Obj_Name VARCHAR(100) NOT NULL,
				Obj_Type VARCHAR(50) NOT NULL);

	-- Change the search predicate based on the input
	SELECT @SearchType = LOWER(@SearchType)
	SELECT @objName =CASE	WHEN @SearchType = 'contain' then '%'+@objName+'%'
				WHEN @SearchType = 'start' then @objName+'%'  
				WHEN @SearchType = 'end' then '%'+@objName  
				WHEN @SearchType = 'equal' then @objName  
			 END;
	-- Create a dynamic query to seek for the given object
	-- "?"  indicates the db name
	SET @SQL = 'SELECT  ''?'' 	as DBName, 
			     Name 	as Obj_Name, 
			     type_desc	as Obj_Type 
		    FROM   [?].sys.objects 
		    WHERE  name like'''+@ObjName+'''';
			
	-- Search all databases in the current instance
	-- Insert details into ObjSeek table Variable
	INSERT INTO @ObjSeek (DBName,Obj_Name,Obj_Type)
	EXEC sp_msforeachdb  @SQL;

	-- Get the actual result set
	SELECT * FROM @ObjSeek;

	SET NOCOUNT OFF;
END

Execution:

Now we will see how to execute this procedure to search for an object for different scenarios:

-- Retrive all objects named as "test" from all databases
EXECUTE usp_ObjectSeek 'test','equal'

-- Retrive all objects where name ends with "_bkp" from all databases
EXECUTE usp_ObjectSeek '_bkp','end'

-- Retrive all objects where name starts with "dump_" from all databases
EXECUTE usp_ObjectSeek 'dump_','start'

-- Retrive all objects where name contains the word "temp" from all databases
EXECUTE usp_ObjectSeek 'temp','contain'

FAQ:

Q. Is this a case sensitive search?

Ans:

No! Object name is not case sensitive.

Q. Does this procedure require any special permission?

Ans:

No! User with read access on database can search the database for the given object.

Ex: A SQL Server Instance is having 12 databases.

User1 is having read access on 7 databases and no access on remaining 5 databases.

When he runs this procedure it searches only 7 databases.

The post Search for an Object in SQL Server appeared first on udayarumilli.com.

Microsoft Acquiring LinkedIn

$
0
0

Microsoft Acquiring LinkedIn

Microsoft Acquiring LinkedIn

I am very excited to see the news “Microsoft Acquiring LinkedIn” on Monday morning. I have been working on Microsoft products from last 10 years and I love LinkedIn. “Satya Nadella” (the man of inspiration who made Indians proud especially “Telugu” people) announced the news on one of the video from Microsoft website.

Satya Nadella” has made a first biggest deal as the Microsoft CEO. I believe this is the fantastic step by Microsoft and this is a big deal as Microsoft will be acquiring the world’s largest and the biggest professional social network LinkedIn for $26.2 billion, $196 per share.

Satya Nadella said

“The LinkedIn team has grown a fantastic business cantered on connecting the world’s professionals, I have always had a great admiration for LinkedIn, I have been talking with Reid and Jeff for a while … I have been thinking about this for a long time.”

By this deal Microsoft targeted Organization Growth by integrating Microsoft Office Business suite users with LinkedIn and Targeted advertising.

Jeff Weiner will continue as a CEO for LinkedIn and reports to Satya Nadella. LinkedIn shares surged 47 percent after the announcement on Monday to near $193, Microsoft’s stock was down 3.2 percent.

The deal has been approved by boards from both the companies and it is expected to be closed by end of 2016.

Microsoft Acquiring LinkedIn

The post Microsoft Acquiring LinkedIn appeared first on udayarumilli.com.


New Features Added in SQL Server

$
0
0

New Features Added in SQL Server

New Features Added in SQL Server

This post helps you in quickly reviewing the “New Features Added in SQL Server” from 2008 to 2016. The most common interview question is “What are the new features added in SQL Server XXXX?” To simplify the answer we are just giving the single line abbreviations. While preparing for an interview just have a quick look and try to remember 4 to 5 features on current working and last released version. Let’s say you are currently working on 2012 then you need to look for 2012 and 2008 R2.   Also people would expect you to know few new features added in the latest version which is SQL Server 2016. Features are categorised for DBA, Developer and Security. That doesn’t mean that SQL Developer need not look into DBA section or vice versa. This is just to make it more readable, when a feature is more related to Developer we added in Developer section when a feature is more relevant administration part it will be in DBA section. Believe this will be helpful for a quick review for version wise feature support.

 

New Features Added in SQL Server 2008

 

SQL DBA:

Activity Monitor: Great tool to showcase resource utilization and performance using GUI.

Policy Based Management: The ability to manage standards on multiple servers

Enhanced Database Mirroring: Automatic data page repair and compressing outgoing log stream

Resource Governor: We can configure it to control SQL Server resource utilization and workload.

External Key Management: Provides a comprehensive solution for encryption and key management.

Hot Add CPU: Adding resources online without downtime.

PowerShell: SQL Server 2008 ships with PowerShell snap-in built on .Net framework 2.0.

Table Compression: Compress data and index pages to save memory and I/O.

Backup Compression: Native backup compression.

Performance data collection: Centralized data repository for storing and reporting performance data

Extended Events: Event collection is easier now compares to running a trace

 

SQL Developer:

File-stream Data: To store binary large objects out on the file system.

Multi-Server Queries: being able to submit a batch of queries against multiple servers simultaneously.

Object Explorer Details: 36 possible columns of information about a database

Object Search: Searches for all objects within the selected scope: server, database, tables

SSMS Debug: the ability to debug any Transact-SQL within SSMS using breakpoints etc.

Intellisense in SQL Server Management Studio: interactive help support similar to Visual Studio.

Plan Freezing: Now we can lock down query plans

Spatial Data Types: Geometry and Geography

DATE / TIME Data Types: DATE, TIME, DATETIMEOFFSET

CLR Enhancements: User-defined aggregates and User-defined types now enhanced up to 2GB.

Table-Valued Parameters: It allows stored procedures to accept and return lists of parameters.

MERGE command: For incremental load using INSERT, UPDATE and DELETE operations.

HierarchyID Datatype: Provides tree like functionality among the data elements in a table

Grouping Sets: An extension to the GROUP BY

Filtered Indexes and Statistics: We can create non clustered index on a subset of a table

Object Dependencies: New DMV’s provided for reliable information on depending objects

Sparse Columns: Columns that are optimized for the storage of NULL values.

 

Security:

TDE – Transparent Database Encryption: Encrypt database without code changes

Change Data Capture: Track data changes.

SQL Auditing: the ability to audit at the server, database and table levels.

  

New Features Added in SQL Server 2008 R2

 

SQL DBA:

SQL Server 2008 R2 Datacenter: Supports 256 logical processors

SQL Server Utility: Central repository control for multiple SQL Servers

Multi Server Dashboards: Dashboards showing combined server data can be created.

 

SQL Developer:

Master Data Services: To manage enterprise central database

Data-Tier Application: To map Database and Visual Studio builds

StreamInsight: Can analyse streaming data on the fly

Unicode Compression: New algorithm for Unicode storage

PowerPivot for SharePoint and Excel: Process datasets and reports.

Report Builder 3.0: Improved visualizations for SSRS

Parallel Data Warehouse: Data warehouses to be scaled over several physical SQL Servers.

SSMS enhancements for SQL Azure: SSMS support for cloud

 New Features Added in SQL Server 2012

 

SQL DBA:

Licensing Model: It’s not based on sockets introduced new core based licensing model

Edition changes: Introduced new BI edition and retired Datacenter, Workgroup and standard for small business.

AlwaysOn availability: Provides both Disaster Recovery and High Availability

Enhanced PowerShell Support: More CMDLETS introduced

Windows Server Core: Core is the GUI less version of Windows that uses DOS and PowerShell for user interaction SQL Server 2012 supports Windows Core

SQL Azure Enhancements: DB size limit increased to 150 GB, Azure data sync allows hybrid model etc.

 

SQL Developer:

Indirect checkpoints: Now we can configure checkpoint intervals database wise

ColumnStore-Index: Stores columns on page instead of rows

SSDT: BIDS is now SSDT SQL Server Data Tools.

FileTable: Builds upon FILESTREAM and SQL Server can access windows files on non-transactional

Sequence objects: an alternative for IDENTITY property

THROW: Improved error handling

New Conversion Functions: PARSE, TRY_PARSE, TRY_CONVERT

New Logical functions: CHOOSE, IIF

New String functions: CONCAT, FORMAT

New Date & Time functions: DATEFROMPARTS, DATETIME2FROMPARTS, DATETIMEFROMPARTS, DATETIMEOFFSETFROMPARTS, SMALLDATETIMEFROMPARTS, TIMEFROMPARTS.

ROWS and RANGE: Support for Window framing on result sets

LAG and LEAD: To get the previous and next rows data

New Rank distribution functions: PERCENT_RANK, PERCENTILE_CONT, PERCENTILE_DISC, CUME_DIST

OFFSET / FETCH: Supports paging for ad hoc queries

FORCESCAN: New table hint

WITH RESULT SETS: More control on stored procedure returned result set metadata

sp_describe_first_result_set: Advanced version for SET FMTONLY option. Also DMV’s added for this

Statistical Semantic Search: Advanced feature builds upon the existing full-text search

Data Quality Services- DQS: A service added to MDS for advanced data profiling and cleansing

Power View: Light weight tool for BI reports

BI Semantic Model: Hybrid model that allows one data model will support all BI experiences

Big Data Support: ODBC driver for SQL Server that will run on a Linux platform etc.

Security:

User-Defined Server Roles: Customization for Server Roles

Database Audit: Like SQL Server Audit and it performs audits database level

Contained Databases: Users can be added on a database without login can easier migration

New Features Added in SQL Server 2014

SQL DBA:

Standard Edition Memory Capacity: Increased to 128 GB whereas 2012 standard editions it is 64 GB.

SQL Server Developer Edition is free: Microsoft made SQL Server 2014 Developer Edition license free.

AlwaysOn AG more secondaries:  2012 supports 4 whereas 2014 supports up to 8 secondaries

AlwaysOn AG readable secondaries: Readable secondaries remain online even though primary replica is down.

Add Azure Replica Wizard: Helps us to create asynchronous secondary replicas in Windows Azure

Buffer Pool Extension: SQL Server 2014 enable users to use Solid State Disk (SSD) to expand the SQL Server 2014 Buffer Pool as non-volatile RAM (NvRAM).

RG I/O control: In 2014 Resource Governor can also be configured to control the physical I/O.

Backup Encryption: SQL Server 2014 introduced native backup encryption. It supports several encryption algorithms AES 128, AES 192, AES 256, and Triple DES.

Managed Backup to Azure: SQL Server 2014 native backup supports Windows Azure with auto scheduling.

SQL Developer:

In-Memory OLTP Engine: We can enable memory optimization for selected tables and stored procedures.

Updateable Column-store Indexes: On SQL Server 2012 to utilize the column-store index, the underlying table had to be read-only. SQL Server 2014 eliminates this restriction. In 2014 Column-Store Index must use all the columns in the table and can’t be combined with other indexes.

Cardinality Estimator Improvements:  Cardinality Estimator redesigned in SQL Server 2014.

Delayed Durability: Introduced delayed durable transactions. A delayed durable transaction returns control to the client before the transaction log record is written to disk. Durability can be controlled at the database level, COMMIT level, or ATOMIC block level.

Partition Switching and Indexing: The individual partitions of partitioned tables can now be rebuilt.

Lock priority for Online Operations:  The ONLINE = ON option now contains a WAIT_AT_LOW_PRIORITY option which permits you to specify how long the rebuild process should wait for the necessary locks. We can also be able to configure terminating the blocking process related to rebuild.

Incremental Statistics: Now we can create partition level statistics by using the option INCREMENTAL

Inline Specification for Indexes: Inline specification of CLUSTERED and NONCLUSTERED indexes is now allowed for disk-based tables. Creating a table with inline indexes is equivalent to issuing a create table followed by corresponding CREATE INDEX statements. Included columns and filter conditions are not supported with inline indexes.

SELECT … INTO Enhancement: This statement now can be operated in parallel

Power View and Power BI: Power View now in 2014 supports OLAP cubes along with the tabular data. Power BI for office 365 is a cloud based BI solution.

 

Security:

SELECT ALL USER SECURABLES: A new server level permission. When granted, a login such as an auditor can view data in all databases that the user can connect to.

CONNECT ANY DATABASE: A new server level permission when granted, a login can connect to any existing / future database in that instance. Combine with SELECT ALL USER SECURABLES or VIEW SERVER STATE to allow an auditing process.

IMPERSONATE ANY LOGIN: A new server level permission when granted, allows a middle-tier process to impersonate the account of clients connecting to it, as it connects to databases.

New Features Added in SQL Server 2016

SQL DBA:

SQL Server Developer Edition is free: Microsoft made SQL Server 2014 Developer Edition license free and same continued with SQL Server 2016 Developer Edition.

AlwaysOn Enhancements: Standard Edition will come with AGs support with one database per group synchronous or asynchronous, not readable (HA/DR only). 3 sync replicas supported whereas it was 2 in SQL 2014. Listener will be able to do round-robin load balancing of read-only requests on multiple secondaries. Now supports Microsoft DTC. SQL Server AlwaysOn to Azure Virtual Machine.

Database Scoped Configurations: The new ALTER DATABASE SCOPED CONFIGURATION allows us to control database level configurations. Ex: Parameter sniffing at database level.

Striped Backups to Microsoft Azure Blob Storage: In SQL Server 2016, SQL Server backup to URL using the Microsoft Azure Blob storage service now supports striped backups sets using block blobs with the maximum backup size of 12.8 TB.

File-Snapshot Backups to Microsoft Azure Blob Storage: In SQL Server 2016, SQL Server backup to URL now supports using Azure snapshots to backup databases in which all database files are stored using the Microsoft Azure Blob storage service.

Managed Backup: In SQL Server 2016 SQL Server Managed Backup to Microsoft Azure uses the new block blob storage for backup files. It supports automatic and custom scheduling, backups for system databases and backups for databases with simple recovery model.

No need to enable Trace flag 4199: Most of the query optimizer behaviours controlled by this trace flag are enabled unconditionally under the latest compatibility level (130)

TempDB enhancements: Trace Flags 1117 and 1118 are not required for tempdb anymore. When tempdb is having database files all files will grow at the same time based on growth settings. All allocations in tempdb will use uniform extents. By default, setup adds as many tempdb files as the CPU count or 8, whichever is lower. We can have the control on tempdb configuration while installing SQL Server 2016.

New Default Database Size and Autogrow Values: For model database these default values are changed in 2016. Default data and log file size is 8 MB and auto-growth is 64 MB.

MAXDOP option for DBCC: Now we can specify MAXDOP option for DBCC CHECKTABLE, DBCC CHECKDB and DBCC CHECKFILEGROUP.

Replication Enhancements:  Replication supports memory-optimized tables and replication support enabled for Azure SQL Database.

SQL Developer:

ColumnStore Index Enhancements: A read-only nonclustered columnstore index is updateable after upgrade without rebuilding the index. Also columnstore indexes can be created for In-Memory tables

Live Query Statistics: Management Studio provides the ability to view the live execution plan of an active query.

Query Store: It can quickly find the performance differences caused by changes in query plans. The feature automatically captures a history of queries, plans, and runtime statistics, and retains these for your review. It separates data by time windows, allowing you to see database usage patterns and understand when query plan changes happened on the server.

Temporal Tables: SQL Server 2016 now supports system-versioned temporal tables. A temporal table is a new type of table that provides correct information about stored facts at any point in time.

Built-in JSON support: Java Script Object Notation (JSON) SQL Server 2016 enables ability to move JSON data to SQL Server tables using various clauses and functions. Ex: FOR JSON, OPENJSON, ISJSON, JSON_VALUE, JSON_QUERY, JSON_MODIFY

PolyBase: PolyBase allows you to use T-SQL statements to access data stored in Hadoop or Azure Blob Storage and query it in an ad-hoc fashion. It also lets you query semi-structured data and join the results with relational data sets stored in SQL Server. PolyBase is optimized for data warehousing workloads and intended for analytical query scenarios.

Stretch Database: SQL Server migrate historical data transparently and securely to the Microsoft Azure cloud. SQL Server handles the data movement in the background based on the policy we can configure. The entire table is always online and queryable.  Stretch Database doesn’t require any changes to existing queries or applications the location of the data is completely transparent to the application.

In-Memory OLTP Enhancements:  To be frank it’s not just enhancements. In-Memory OLTP on 2014 is just a trail version and in 2016 this is the first version where we have seen lot of things has been fixed and supported.

In-Memory – ALTER TABLE is log-optimized, and runs in parallel:  Only the metadata changes are written to the log also now it can run in parallel.

In-Memory Statistics: Now statistics are updated automatically

In-Memory Parallel Scan: Memory-optimized tables, and hash indexes, are now scannable in parallel.

In-Memory – LOBs with large row size:  Now memory optimized tables can have LOB type columns

In-Memory – TDE and MARS: MARS and TDE support enabled for In-Memory optimized tables

In-Memory T-SQL support: SQL Server 2016 overcomes the maximum limitations on 2014 In-Memory OLTP T-SQL Support.  Now In-Memory OLTP supports OUTPUT clause, UNIQUE index, FOREIGN KEY, Alter, Schema changes, Triggers, Check constraint, UNIION, UNION ALL, DISTINCT, OUTER JOIN, Sub queries and lot many native features supports in 2016 In-Memory optimized tables and natively compile stored procedures.

Foreign Key Relationship Limits: SQL Server 2016 increases the limit for the number of other table and columns that can reference columns in a single table from 253 to 10,000.

Support for UTF-8: BULK INSERT, bcp Utility and OPENROWSET now support the UTF-8 code page.

TRUNCATE TABLE – Partition:  The TRUNCATE TABLE statement now permits the truncation of specified partitions.

ALTER TABLE Enhanced: Now allows actions to be performed while the table remains available.

NO_PERFORMANCE_SPOOL: New query hint can prevent a spool operator from being added to query plans.

DROP IF:  Really useful feature. It drops the object if it exists in database.

sp_execute_external_script:  Advanced Analytics Extensions allow users to execute scripts written in a supported language such as R.

COMPRESS – DECOMPRESS:  Functions to convert values into and out of the GZIP algorithm.

New DATETIME:  DATEDIFF_BIG, AT TIME ZONE functions and sys.time_zone_info view are added to support date and time interactions.

STRING_SPLIT and STRING_ESCAPE: New string functions added

Security:

Row-Level Security: This is a predicate based access control.

Always Encrypted: Encrypt entire data (Data file, Log file, Backup, Communication Channel) and only application can see the data.

Dynamic Data Masking: Dynamic data masking limits sensitive data exposure by masking it to non-privileged users.

Transparent Data Encryption Enhanced: TDE supports Intel AES-NI hardware acceleration of encryption. This will reduce the CPU overhead of turning on Transparent Data.

AES Encryption for Endpoints: The default encryption for endpoints is changed from RC4 to AES.

New Credential Type: A credential can now be created at the database level in addition to the server level credential that was previously available.

The post New Features Added in SQL Server appeared first on udayarumilli.com.

Script to get row count for all tables in a SQL Server database

$
0
0

Script to get row count for all tables in a SQL Server database

Script to get row count for all tables in a SQL Server database

This post helps you in writing a Script to get row count for all tables in a SQL Server database. For any database developer or administrator the most common requirement is to identifying the larger tables based on data size, index size and row count. This script can quickly list out all tables in the given database and retrieves the below details:

  • Name: Table Name
  • Rows: Total row count
  • Reserved: Space reserved for the table – MB
  • Data: Total space allocated for data pages – MB
  • Index_size: Total space allocated for Index pages – MB
  • Unused: Unused space – MB

Here is the script to get row count for all tables in a SQL Server database:

SET NOCOUNT ON;
BEGIN TRY
	--Create a temparory table 
	CREATE TABLE #Tab (
			[Name]		 NVARCHAR(128),    
			[Rows]		 CHAR(11),    
			[Reserved]	 VARCHAR(18),  
			[Data]		 VARCHAR(18),     
			[Index_size] VARCHAR(18),    
			[Unused]	 VARCHAR(18)); 

	--Capture all tables data allocation information 
	INSERT #Tab 
	EXEC sp_msForEachTable 'EXEC sp_spaceused ''?''' ;

	--Alter Rows column datatype to BIGINT to get the result in sorted order
	ALTER TABLE #Tab ALTER COLUMN [ROWS] BIGINT  ;

	-- Get the final result: Remove KB and convert it into MB
	SELECT	Name,
		[Rows],
		CAST(LTRIM(RTRIM(REPLACE(Reserved,'KB',''))) AS BIGINT)/1024.0 AS 'Reserved MB',
		CAST(LTRIM(RTRIM(REPLACE(Data,'KB',''))) AS BIGINT)/1024.0 AS 'Data MB',
		CAST(LTRIM(RTRIM(REPLACE(Index_Size,'KB',''))) AS BIGINT)/1024.0 AS 'Index_Size MB',
		CAST(LTRIM(RTRIM(REPLACE(Unused,'KB',''))) AS BIGINT)/1024.0 AS 'Unused MB'
	FROM #Tab 
	ORDER BY [rows] DESC;

END TRY
BEGIN CATCH
	DROP TABLE #Tab; 
END CATCH
-- Drop the temparory table 
DROP TABLE #Tab;

When you need to get the list of tables along with the row counts, connect to the database instance open a new query window, paste the above script and execute it. It shouldn’t take much time to execute the script as we are using “sp_spaceused”, for us it took maximum 6 sec on a 3.5 TB database.

Remember there are chances where sp_spaced might give the wrong row counts due to several reasons. There are mainly 3 reasons that cause sp_spaceused gives us the wrong counts:

  • When there are huge DDL changes
  • Statistics are not updated
  • Index maintenance is not being taken care

Here you will find more details and resolution.

The post Script to get row count for all tables in a SQL Server database appeared first on udayarumilli.com.

Update Without Where Clause

$
0
0

Update Without Where Clause

Update Without Where Clause

Running Update Without Where Clause might causes a data damage when it is with the critical table that creates a lot of problems and escalations. Recently while working with one of the customer we had a situation where a DBA executed the release script on production and the script contains an update statement without where clause. He immediately realized that he executed an update statement without where clause and he reported us explaining the situation. There were few things we found:

  • The change request implemented on a premium database
  • Update statement provided from Pre-Prod team which is not having any control on that:
    No Where clause
    No Transaction control – Commit / Rollback
    No Validation on update – Validating and Reporting
  • As per the business requirement single record should be updated but in real it updates all records in that table.
  • Usually when a DBA implements a CR on prod server a backup or snapshot has to be taken prior to implementing the change. Since it was a small database (6 GB) he did take a full backup before implementing the CR.

Solution we have provided:

Let’s say db name is: EcomPro & Table Name “Customers”
Update Statement ran: UPDATE Customers SET Last_Name = ‘Role’

 Made database “EcomPro” access to single user mode
 Identified the transaction ID which was wrongly updated the table without where clause
 Identified the transaction begin time (2016-21-07 16:30:15)
 Performed a latest database transaction log backup on “EcomPro”
 Created a test database and named it as “Test”
 Restored “EcomPro” full backup to “Test” WITH NO RECOVERY
 Restored all available transaction log backups except the last WITH NO RECOVERY
 Restored “EcomPro” latest transaction log backup with point in time recovery (We have given the time just a second before the transaction begin time which is identified in step 3 i.e. 2016-21-07 16:30:14) and restore it WITH RECOVERY.
 We could be able to recover the Customer table in “Test” database. Now we could see the correct data for the column name “Last_Name” for all customers.
 We have written a inter database query between “EcomPro” and “Test” to update the customers table on “EcomPro” database.
 UPDATE EC.Last_Name = T.Last_Name
 FROM EcomPro.dbo.Customer EC
 INNER JOIN Test.dbo.Customer T ON EC.ID = T.ID
 Then we have got our data back.
 Made database “EcomPro” into multi user mode.

Note: We can directly restore the database backup onto the same database instead of creating a new database when you identify the issue and you started taking database in single user mode with in or less than 5 sec of incident happened. But in our case we had a 12 min delay in getting onto the solution so we are not really sure what are all the data modifications happened on these 12 min thereof we have created a separate database and only recovered the lost data.

Third Party Tool to read Log File:

There are tools available to read log file and rollback the required transactions. ApexSQL is one of the famous tools which can recover data from accidental update / delete.

Prevention:

Humans do mistakes but we can handle these mistakes if we can respond and take the required action on-time. Train your production team, developers and release team to handle risk factors:
 DML should always be protected with transactions
 Properly validate data after DELETE and UPDATE statements. Ex: Row counts
 Proper error handling should be in place
 They should report the issue as early as possible once it is identified. Time delays increases the risk factor by losing more data.
 Once you identify a data loss on production system make your database in single user mode
 Identify the required information and see if we can rollback the operation
 Perform a Log backup immediately
 For databases design the recovery model based on SLA
 Always plan transaction log backups for critical databases

Common Mistakes:

Below are the various cases for which this solution can be worked out:
 DELETE without where clause
 UPDATE without where clause
 Mistakenly dropped a table
 Etc…..

Data Recovery – Update Without Where Clause:

Here is an example for recovering the data loss from accidental data update without where clause

First let us create a table and insert data.

USE Test;
GO
-- Remember when we suggested this method for one of our client 
-- he asked me if the database is in simple recovery mode and not possible for log backup 
-- then how can I get my data back?
-- I answered him if the data is not so important and data loss is acceptable then no issues
-- If the db is a critical db then your db should have a proper SLA and a recovery plan accordingly 

-- Create Table Customer 
CREATE TABLE Customer (
	ID		INT IDENTITY NOT NULL,
	First_Name	VARCHAR(50) NOT NULL,
	Middle_Name	VARCHAR(50),
	Last_Name	VARCHAR(50),
	Age		TINYINT NOT NULL,
	Location	VARCHAR(50) NOT NULL,
	PhoneNo		VARCHAR(15) NOT NULL,
	Email		VARCHAR(50) NOT NULL,
	CreatedDate	SMALLDATETIME NOT NULL DEFAULT(GETDATE())
);
GO

-- Data Insertion into Customer table
INSERT INTO Customer (First_Name, Middle_Name, Last_Name, Age, Location, PhoneNo, Email)
VALUES 
('Hevan','K','Mayo',38,'NY','6115657','hmayo@gmail.com'),
('Tang','Zoho','Wy',38,'NY','6115654','tang@gmail.com'),
('Chris','D','Lott',42,'WDC','5664431','clott@kbank.com'),
('Haris','K','Mano',27,'AU','767574732','haris@lavo.com'),
('Hedly','M','Doven',49,'NZ','5544672109','hdven@nzs.com'),
('Tim','K','Roll',54,'NY','63356768','tim@appmake.com'),
('Shane','S','Wang',32,'CHI','392798911','shane@chimark.com'),
('Groven','VK','Wen',39,'CHI','392798912','groven@chimark.com'),
('Joel','M','Mark',27,'AU','778656779','joel@walmart.com'),
('Henan','N','L',45,'NZ','392798922','henan@nstic.com'),
('Larven','T','Me',41,'IND','9879876628','LARVEN@adps.com');

GO


---Take the Full backup of Test DB
BACKUP	DATABASE	[Test] 
	TO	DISK = N'C:\temp\SQL_Backup\Test_Full.bak' 
	WITH	NOFORMAT,	INIT,  
	NAME = N'Test-Full Database Backup', 
	SKIP,	NOREWIND,	NOUNLOAD,  STATS = 10
GO

SELECT * FROM Customer;

Here is the customer table looks like:

Update Without Where Clause_1

Now we’ll try to apply UPDATE Without Where Clause:

-- Now we'll try to Update the Customer Table 
-- For the CustomerID 5 last name is feeded wrongly as Roll now we need to update it as Role
-- We didn't give where clause here
GO

UPDATE Customer SET Last_Name = 'Role';

-- SQL DBA executed the above statement without where condition 
-- Very soon he realized that what he did to the customer table 

SELECT * FROM CUSTOMER;

Update Without Where Clause 2

Now we can see the last_name is updated as “Role” for all customers. Now we will look into the solution for how to recover this lost data? 

/************************************************************************/
/****************************** Solution ********************************/
/************************************************************************/

-- As soon as you realized that there is a wrong update immediately close all user connections 
-- to that database to prevent more data loss 
-- First make your database into single user mode
-- Step 1
ALTER DATABASE [Test] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;

-- Try to find the transaction details that updated the table customer
-- Identify the transaction ID
-- Step 2

SELECT
	[Transaction ID] AS 'Transaction_ID',
	[Operation]	 AS 'Operation',
	[AllocUnitName]	 AS 'AllocUnitName'
FROM	sys.fn_dblog(NULL,NULL)
WHERE	[AllocUnitName] LIKE '%customer%'
ORDER BY	[Transaction ID];

From the below picture we can observe there are multiple operations happened on the table customer table. But the transaction ID “0000:00000339” is the latest update transaction on that table and it has 11 entries (total 11 rows in customer table) in log. This is the transaction that the DBA accidentally executed. If you find any confusion between these transactions you can play with the other options in above query.

Update Without Where Clause 4

Now we’ll find out the transaction begin time:

-- Get the transaction begin time and other info
-- Step 3

SELECT
	[Current LSN]		AS 'Current_LSN',
	[Transaction ID]	AS 'Transaction_ID',
	[Operation]		AS 'Operation',
	[Transaction Name]	AS 'Transaction_Name',
	[CONTEXT]		AS 'Context',
	[AllocUnitName]		AS 'AllocUnitName',
	[Page ID]		AS 'Page_ID',
	[Slot ID]		AS 'Slot_ID',
	[Begin Time]		AS 'Begin_Time',
	[End Time]		AS 'End_Time',
	[Number of Locks]	AS 'No_Locks',
	[Lock Information]	AS 'Lock_Info'
FROM	sys.fn_dblog(NULL,NULL)
WHERE	[Transaction ID] = '0000:00000339';

Update Without Where Clause 5

 

From the above picture if you see that the transaction start time is: “2016/07/21 13:50:20:627”

 Now we’ll perform the latest transaction backup on database “Test”
 Then Restore the database with the latest full backup
 Restore the database with the latest log backup we performed just now with point in time recovery. That means we’ll restore the database just to a second before that transaction begin time:
 Transaction Begin Time: “2016/07/21 13:50:20:627”
 We’ll restore the log file to the time: “2016/07/21 13:50:19:999”

-- Immediately perform a log backup, if it is in full recovery mode and full backup and all following log -- backups available. 
-- Step 4

BACKUP	LOG [Test] TO  
DISK = N'C:\temp\SQL_Backup\Test_TranBkp_1.trn' WITH NOFORMAT, INIT,  
NAME = N'Test-Tran Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO

-- Now restore Full backup with no recovery
-- Step 5

USE [master]
GO
ALTER	DATABASE [Test]	SET	SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE	DATABASE [Test] FROM  
	DISK = N'C:\temp\SQL_Backup\Test_Full.bak' 
	WITH  FILE = 1,  NORECOVERY,  NOUNLOAD,  REPLACE,  STATS = 5
GO

-- Now restore all available log backups with NO RECOVERY - In our example we have only one latest log bkp
-- Now restore Transaction log backup with point intime 
-- Step 6
RESTORE	LOG [Test] FROM  
	DISK = N'C:\temp\SQL_Backup\Test_TranBkp_1.trn' 
	WITH  FILE = 1,  NOUNLOAD,  STATS = 10,  
	STOPAT = N'2016/07/21 13:50:19:999'
GO


--After successful restore now we’ll check the customer data:

-- Now we'll check the customer table
USE Test
GO
SELECT * FROM customer

Update Without Where Clause 6

If you observe the last_column the data is back and the database recovered with the given point of time.

Summary:
It’s not always easy to deal with the accidental mistakes databases. But we should expect these and be ready with the recovery plans. Also prevention is always better than cure thereof It’s always suggested to maintain a certain standards and policies while dealing with the critical database systems. This post will help you in understanding the recovering data when we accidentally executed an update without where clause.

 

The post Update Without Where Clause appeared first on udayarumilli.com.

Preparing for SQL DBA Interview

$
0
0

Preparing for SQL DBA Interview

Preparing for SQL DBA Interview

This article list out few tips on “Preparing for SQL DBA Interview” If you are reading this article which means you must be a Database Administrator/professional or getting ready for entering into DBA world. In today’s corporate world attending or taking a technical interview is mandatory whether it’s for a new role in current organization, new customer/client or for a new organization. Preparing for SQL DBA Interview is always a challenge. We have randomly chosen SQL Server database professionals from three different experience levels and had a deep discussion on “Preparing for SQL DBA Interview”.

  • Fresher/Junior – Should know the basics of process and technology
  • Mid-Level – Should be able to expertise in one or two areas and know the process
  • Senior Level – Should be expertise in technology and able to drive the process

There are few points everyone should follow to get succeed in an interview. Below are the key points which can be helpful in “Preparing for SQL DBA Interview”

  • Profile

  • Preparation

  • Communication

  • Interview Process

  • Preparing a Topic

Profile

This is the first piece of information that tells about you so please be careful in preparing your profile:

  • Don’t add the generic skill-set: Include only the topics that you are experienced or learned.
  • Add your professional experience, key skills, education details, your achievements, certifications, training and projects.
  • Number of pages should be restricted to 3 or 4.
  • Maintain a profile on professional network like LinkedIn and add a link to your profile (I have seen a lot of opportunities are hitting through professional networks)
  • Remember you should know / learn / prepare / experience each and everything you mentioned in your profile as the interview questions are always depends on summary points that you showcase in your profile.

Preparation

When you are not prepared for an interview you will not be going to make a WIN. Preparation makes you to feel more confident and plays the main role in your success.  Prepare a self-reference guide with all your experiences, your tough times, difficult technical issues you faced, complex requirements and resolutions and your own interview experiences. Now we’ll see WHAT should be in our preparation list:

 Top Questions:

Prepare top 10 questions in each category, let’s say you mentioned you are experienced in Performance Tuning, DBA daily activities, Replication and Clustering. You must be ready to answer top 10 questions from these categories. TOP 10 is different from person to person let’s say you are mostly handles SQL Server AlwaysOn Failover Cluster installations, person B might be expert in troubleshooting clustering issues and Person C mostly experienced in RCA and Performance Tuning in clusters. Based on your experience prepare your own list and see this is just a onetime activity and you can use the reference guide throughout your career.

 Environment:

This is the most critical area where 80% failures in answering the questions. This is the primary area to test your experience, so prepare well. Environment includes different things that one can learn only through experience. We’ll see the common questions on environment:

 Versions:

Remember the versions you worked on:

  • Prepare at least few new features added in the latest version you worked in (Ex: 2012 when compared to 2008 R2).
  • Have a look at new features added in latest SQL Server version. Ex: 2016
  • You might be asked SQL Server components, try to remember few major components

Servers / Instances / Databases:

If you are experienced you must be confident in answering the question “How many total windows / SQL servers/Instances and Databases available in your previous work environment?”. Below we are giving an average values that we got from various professionals working in different organizations. It always depends on business Application requirement

 Number of SQL Servers / Instances:

  • Enterprise Big Environment: 100 to 800
  • Mid-Level: 50 to 100
  • Small: 10 to 60

 Number of databases:

We always have an average figure as an answer for this question, because we can’t know the exact count as we maintain databases for different environments. For example an application can require 4 databases, then the same number of databases may require for DEVELOPMENT, TESTING, STAGING and in PRODUCTION. If any DR / HA is configured then those replicas should also be considered. Thereof we usually do not count the number of databases but yes we can see inventories for database details. Here are the average counts:

  • Big Environments: 1000 to 4000
  • Mid-Level Environments: 500 to 1000
  • Small Environments: 100 to 500

 Database Size:

  • Big Enterprise:
    • OLTP: 50 GB – 2 TB
    • OLAP: 600 GB – 12 TB
  • Mid-Level Enterprise:
    • OLTP: 10 GB – 2 TB
    • OLAP: 100 GB – 5 TB
  • Small Environment:
    • OLTP: 1 GB – 200 GB
    • OLAP: 50 GB – 1 TB

 Team Size:

  • Enterprise Environments: 50 to 100
  • Mid-Level: 5 to 20
  • Low Level: 1 to 5

Hardware specs (CPU, Memory, and Storage):

CPU:  Processors: Most of the servers use processor from AMD, DELL or Intel X series

Cores: It’s the most important thing as SQL Server licenses based on the number of cores. It’s starting from 4 and 16, 64 etc.

Memory:

Minimum: 4 GB (We still see in some small instances in DEV and QA)

Medium: 64 to 128 GB

Maximum: 512 GB+ (For a premium prod server)

Storage:  SAN, SMB, NFS, iSCSI, EBS – if it’s AWS, Virtual Volumes – If it’s VMware etc.

 Software & Tools:

  • Make a note on third party tools you used in your environment ex: LITESPEED, REDGATE etc.
  • Also make a note on how licensing happening for SQL Server in your environment
  • Make a note on version number of names for ticketing and monitoring tools Ex: SCOM, TFS, and SVN etc.

Processes:

This is one of the most important key points. Processes related questions can be from:

  • How request handling happening in your environment if you are working on ITIL
  • Timeframe and other details on SPRINT / SCRUM if you are into agile
  • Documenting process
  • Inventory management
  • Onsite Offshore communication
  • How frequently you communicate with your client
  • How an incident is handled
  • What is bridge call?
  • Escalation Matrix: How escalation happens in your environment etc.
  • SLA: What is the Service Level Agreement for acknowledging the critical alerts?
  • Policies: What are the Backup policies for PROD, QA and DEV environments?
  • Experiences: Make a quick notes on strange / bad / good experiences from your daily routine
  • Projects: Know something about your projects / actual business

Responsibilities:

  • Be prepared to answer the question “what are your current job responsibilities?”
  • Prepare the details on Daily / Weekly / Monthly / Quarterly maintenance tasks

Behavioral Questions:

When you are targeting a critical role with a “Big IT Giant”, you should be prepared the answers for these questions as well:

  • Your next 5 years plan?
  • Most difficult situation you handled?
  • The situation you failed in?
  • Why you are leaving the current role?
  • Any innovative idea you initiated?
  • How do you define the success?
  • Best / Worst day in your life?
  • What are your top 3 wishes if god gives you a chance?
  • Most difficult person you faced in your work place?
  • Your manager is submitting a wrong bill to company, how do you react?
  • You got 3 offers: 1. Dream Company, 2. Dream location, 3. Dream Salary. Which one you choose and why?
  • Your strength and weakness
  • Who is your role model and Why?
  • When the last time you made a controversy in working place?
  • You have an emergency in your office and family what’s your priority and why?
  • Why this company?
  • Why we should hire you?

Communication

I have seen people blaming themselves “I am not great in English” yes that’s true you can’t be great in English unless English is your mother tongue. But you can be good in any language with some practice. So practice well let’s practice answering the first question “Tell me about yourself” and also practice answering the top 10 questions. Take some breath time and answer the questions. Remember communication plays 60% role in your success.

Preparing a Topic

Here we’ll see how to prepare a specific topic. Let’s say you have added “Replication, Clustering, Performance Tuning are your strong points”.  Now we’ll see  how to prepare the topic “Replication”:

Replication Components: Replication Agents, Methodology, advantages etc.

Types and Differences: Types of replication typologies and differences between them

Common Issues / Scenarios & Resolutions: Found duplicate records in subscriber, No-records found at subscriber, Log is getting full at Publisher, adding a new article without generating new snapshot etc.

New Features: Try to remember at least one new feature added in replication on the latest version in your experience Example: 2012 / 2014 / 2016.

Monitoring: A very common question “How to monitor replication health?”, Replication Monitor, Tracer Tokens, DMV etc.

Top 5 Questions: You should be prepared the top 5 common questions on topic replication. For example Different types of replications, implementations (Advantages) of Transnational and Merge, Can we issue TRUNCATE command on publisher, How to monitor replication, Replication Agents etc.

Interview Process

If you are in crisis or targeting a role in your dream company then take it seriously and follow the tips:

  • Be on time at interview venue
  • I don’t see people coming in formal dresses in today’s interviews, that’s not an issue but try to be a professional.
  • For the first question “Introduce Yourself”, give your experience details, your achievements and then education if still you have time and they are listening then continue with other details
  • If you guessed the answer you can tell that are guessing “This is just a guess from my analysis”
  • Drive the interview process. If you want to drive the process you should be prepared well which means if you say “I am good in Performance Tuning” please do not expect a question like “What is an index” rather you can expect “Why indexed view when filter index is there?”.
  • Remember that in most of the cases your next question is based on the current question answer isn’t it? Let’s say if you are asked “What are the common issues with TEMPDB?”, if you answer something like, TEMPDB full, Space issue, Version store full, forced to shrink, Latch Contention etc. Then the next question will be on one of these 5 reasons. You might be asked “What is Latch Contention?” and then “How do you troubleshoot it?” etc.
  • Be focused and here the question completely, try to give the straight answer unless you are asked to explain in detail.
  • Ask the right questions for which we need to do some research required on that organization, role.
  • We can ask for the answer if you can’t answer any question.
  • Don’t be dumb when you don’t aware of something. See I have seen people kept silent or try to cover with the false answers. If you are asked a scenario based question in replication, but you don’t know answer then you can accept that by saying “I am really not sure how to handle this but I have seen similar kind of issue when duplicates are inserted in subscribers and that time we did give XXXX resolution”.
  • If something is really strange you are asked about that you can frankly express that you don’t aware of that.
  • Remember no one knows everything, you are asked scenario based questions to check how you are reacting and using your analysis to get the answer.
  • Never ever blame your previous / current work place or colleagues
  • Do not reveal previous clients information Ex: You can say I worked with world’s largest bank instead of XXXXX Bank.
  • Do the proper follow up on post interview

Final note:

Interview process is not just to test your technical knowledge instead throughout the interview process you are tested in analytical skills, stress management, management skills, problem solving skills, way of thinking, attitude, experience and of course your technical knowledge.  Prepare well, be confident and get the success in your next interview.

You might be interested in:

Database Job Openings

SQL Server DBA Responsibilities

Database Career Paths

How to become an Expert in your Career

SQL Server Interview Questions and Answers

 

The post Preparing for SQL DBA Interview appeared first on udayarumilli.com.

SQL Server Health Check

$
0
0

SQL Server Health Check

sql-server-health-check

Hello there, if you are a SQL DBA the most common task that you perform is “SQL Server Health Check”. You may already have an automated report but this is for doing a quick SQL Server Health Check using native T-SQL. This script helps you in generating HTML report using T-SQL. There are situations where we need to quickly perform SQL Server Health Check:

  • You got a request to check the health of a SQL Server instance
  • When there is a complaint raised against the instance performance
  • When SQL Server restarted
  • Etc.

This SQL Server Health Check Reports:

SQL Server Instance Details: SQL Version, Edition, Service Pack, Processor Type etc.

Error Log: Errors logged into SQL Server error log from Last 4 days

Instance Last Recycle Information: Last recycle time and total uptime information

Tempdb usage: File location and space available information.

CPU Usage: CPU usage information

Memory Usage: Memory usage details

Performance Counters Data: Major performance counter values

Missing Backup Report: Database with no full backup from last 48 hours or without any backup

Connection Information: Host wise connection information

Log Space Usage Report: Log files usage information for all databases. It highlights the value with red color when the percentage use > 80.

Job Status Report: Reports current running jobs information

Blocking Report: Reports blocking information if any

Long running Transactions: Retrieves the long running transactions if any

Most important Note:

There is only one place (Memory Usage Capturing Buffer Pool information) where you need to comment / un-comment out based on the SQL Server version on which this script is running.

Executing:

To get the SQL Server Health Check report, once the stored procedure got created, execute it by passing the required parameters:

EXEC usp_SQLhealthcheck_report

@MailProfile = ‘TEST_MAIL’ ,

@MailID = ‘DBA@org.com’,

@Server = ‘PROD_Server001’;

@MailProfile (Required): SQL Server database mail profile

@MailID (Required): Email recipient

@Server (Optional): If not mentioned then it takes @@SERVERNAME

 

SQL Server Health Check Script:

Download the script file: sqlserver_healthcheck

/****
EXEC usp_SQLhealthcheck_report 
					@MailProfile = 'TestProfile' ,
					@MailID = 'SQLDBA@Org.com',
					@Server = 'Test-PROD';
***/

IF EXISTS (SELECT 1 FROM SYS.SYSOBJECTS WHERE NAME = 'usp_SQLhealthcheck_report' AND TYPE = 'P')
BEGIN
	DROP PROCEDURE usp_SQLhealthcheck_report;
END
GO
/****************************************************************************/
/*************** SQL SERVER HEALTH CHECK REPORT - HTML **********************/
-- Tested: SQL Server 2008 R2, 2012, 2014 and 2016
-- Report Type: HTML Report Delivers to Mail Box
-- Parameters: DBMail Profile Name *, Email ID *, Server Name (Optional); 
-- Reports:	SQL Server Instance Details
--			Last 4 days Critical Errors from ErrorLog
--			Instance Last Recycle Information
--			Tempdb File Usage
--			CPU Usage
--			Memory Usage
--			Performance Counters Data
--			Missing Backup Report
--			Connection Information
--			Log Space Usage Report
--			Job Status Report
--			Blocking Report
--			Long running Transactions  
/****************************************************************************/
/****************************************************************************/
CREATE PROCEDURE usp_SQLhealthcheck_report (
		@MailProfile NVARCHAR(200), 
		@MailID NVARCHAR(2000),
		@Server VARCHAR(100) = NULL)
AS
BEGIN
SET NOCOUNT ON;
SET ARITHABORT ON;

DECLARE @ServerName VARCHAR(100);
SET @ServerName = ISNULL(@Server,@@SERVERNAME);

/*************************************************************/
/****************** Server Reboot Details ********************/
/*************************************************************/

CREATE TABLE #RebootDetails                              
(                              
 LastRecycle datetime,                              
 CurrentDate datetime,                              
 UpTimeInDays varchar(100)                        
)                      
Insert into #RebootDetails        
SELECT sqlserver_start_time 'Last Recycle',GetDate() 'Current Date', DATEDIFF(DD, sqlserver_start_time,GETDATE())'Up Time in Days'
FROM sys.dm_os_sys_info;

/*************************************************************/
/****************** Current Blocking Details *****************/
/*************************************************************/
CREATE TABLE #BlkProcesses                              
(                              
 spid  varchar(5),                              
 Blkspid  varchar(5),                              
 PrgName  varchar(100),        
 LoginName varchar(100),                              
 ObjName  varchar(100),                              
 Query  varchar(255)                               
)  
insert into #BlkProcesses
SELECT s.spid, BlockingSPID = s.blocked, substring(s.program_name,1,99), SUBSTRING(s.loginame,1,99),         
   ObjectName = substring( OBJECT_NAME(objectid, s.dbid),1,99), Definition = CAST(text AS VARCHAR(255))        
FROM  sys.sysprocesses s        
CROSS APPLY sys.dm_exec_sql_text (sql_handle)        
WHERE        s.spid > 50  AND s.blocked > 0 


/*************************************************************/
/****************** Errors audit for last 4 Days *************/
/*************************************************************/

CREATE TABLE #ErrorLogInfo                              
(                              
 LogDate  datetime,
 processinfo varchar(200),                              
 LogInfo  varchar(1000)                               
)    

DECLARE @A VARCHAR(10), @B VARCHAR(10);
SELECT @A = CONVERT(VARCHAR(20),GETDATE()-4,112);
SELECT @B = CONVERT(VARCHAR(20),GETDATE()+1,112);
Insert into #ErrorLogInfo
EXEC xp_ReadErrorLog 0, 1,N'Login', N'Failed', @A,@B,'DESC';


/*************************************************************/
/************* SQL Server CPU Usage Details ******************/
/*************************************************************/
Create table #CPU(             
servername varchar(100),                         
EventTime2 datetime,                          
SQLProcessUtilization varchar(50),                         
SystemIdle varchar(50),
OtherProcessUtilization varchar(50),
load_date datetime                          
)    
DECLARE @ts BIGINT;
DECLARE @lastNmin TINYINT;
SET @lastNmin = 240;
SELECT @ts =(SELECT cpu_ticks/(cpu_ticks/ms_ticks) FROM sys.dm_os_sys_info); 
insert into #CPU
SELECT TOP 10 * FROM (
SELECT TOP(@lastNmin)
		@ServerName AS 'ServerName',
		DATEADD(ms,-1 *(@ts - [timestamp]),GETDATE())AS [Event_Time], 
		SQLProcessUtilization AS [SQLServer_CPU_Utilization], 
		SystemIdle AS [System_Idle_Process], 
		100 - SystemIdle - SQLProcessUtilization AS [Other_Process_CPU_Utilization],
		GETDATE() AS 'LoadDate'
FROM (SELECT record.value('(./Record/@id)[1]','int')AS record_id, 
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]','int')AS [SystemIdle], 
record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]','int')AS [SQLProcessUtilization], 
[timestamp]      
FROM (SELECT[timestamp], convert(xml, record) AS [record]             
FROM sys.dm_os_ring_buffers             
WHERE ring_buffer_type =N'RING_BUFFER_SCHEDULER_MONITOR'AND record LIKE'%%')AS x )AS y 
ORDER BY SystemIdle ASC) d

/*************************************************************/
/************* SQL Server Memory Usage Details ***************/
/*************************************************************/

CREATE TABLE #Memory_BPool (
BPool_Committed_MB VARCHAR(50),
BPool_Commit_Tgt_MB VARCHAR(50),
BPool_Visible_MB VARCHAR(50));
--Please comment this when you installed on 2012 and above 
/****
-- SQL server 2008 / 2008 R2
INSERT INTO #Memory_BPool  
SELECT
     (bpool_committed*8)/1024.0 as BPool_Committed_MB,
     (bpool_commit_target*8)/1024.0 as BPool_Commit_Tgt_MB,
     (bpool_visible*8)/1024.0 as BPool_Visible_MB
FROM sys.dm_os_sys_info;
****/ 
--Please comment this when you installed on 2008 R2 and below 
-- SQL server 2012 / 2014 / 2016
INSERT INTO #Memory_BPool 
SELECT
      (committed_kb)/1024.0 as BPool_Committed_MB,
      (committed_target_kb)/1024.0 as BPool_Commit_Tgt_MB,
      (visible_target_kb)/1024.0 as BPool_Visible_MB
FROM  sys.dm_os_sys_info;


CREATE TABLE #Memory_sys (
total_physical_memory_mb VARCHAR(50),
available_physical_memory_mb VARCHAR(50),
total_page_file_mb VARCHAR(50),
available_page_file_mb VARCHAR(50),
Percentage_Used VARCHAR(50),
system_memory_state_desc VARCHAR(50));

INSERT INTO #Memory_sys
select
      total_physical_memory_kb/1024 AS total_physical_memory_mb,
      available_physical_memory_kb/1024 AS available_physical_memory_mb,
      total_page_file_kb/1024 AS total_page_file_mb,
      available_page_file_kb/1024 AS available_page_file_mb,
      100 - (100 * CAST(available_physical_memory_kb AS DECIMAL(18,3))/CAST(total_physical_memory_kb AS DECIMAL(18,3))) 
      AS 'Percentage_Used',
      system_memory_state_desc
from  sys.dm_os_sys_memory;


CREATE TABLE #Memory_process(
physical_memory_in_use_GB VARCHAR(50),
locked_page_allocations_GB VARCHAR(50),
virtual_address_space_committed_GB VARCHAR(50),
available_commit_limit_GB VARCHAR(50),
page_fault_count VARCHAR(50))

INSERT INTO #Memory_process
select
      physical_memory_in_use_kb/1048576.0 AS 'physical_memory_in_use(GB)',
      locked_page_allocations_kb/1048576.0 AS 'locked_page_allocations(GB)',
      virtual_address_space_committed_kb/1048576.0 AS 'virtual_address_space_committed(GB)',
      available_commit_limit_kb/1048576.0 AS 'available_commit_limit(GB)',
      page_fault_count as 'page_fault_count'
from  sys.dm_os_process_memory;


CREATE TABLE #Memory(
Parameter VARCHAR(200),
Value VARCHAR(100));

INSERT INTO #Memory 
SELECT 'BPool_Committed_MB',BPool_Committed_MB FROM #Memory_BPool
UNION
SELECT 'BPool_Commit_Tgt_MB', BPool_Commit_Tgt_MB FROM #Memory_BPool
UNION 
SELECT 'BPool_Visible_MB', BPool_Visible_MB FROM #Memory_BPool
UNION
SELECT 'total_physical_memory_mb',total_physical_memory_mb FROM #Memory_sys
UNION
SELECT 'available_physical_memory_mb',available_physical_memory_mb FROM #Memory_sys
UNION
SELECT 'total_page_file_mb',total_page_file_mb FROM #Memory_sys
UNION
SELECT 'available_page_file_mb',available_page_file_mb FROM #Memory_sys
UNION
SELECT 'Percentage_Used',Percentage_Used FROM #Memory_sys
UNION
SELECT 'system_memory_state_desc',system_memory_state_desc FROM #Memory_sys
UNION
SELECT 'physical_memory_in_use_GB',physical_memory_in_use_GB FROM #Memory_process
UNION
SELECT 'locked_page_allocations_GB',locked_page_allocations_GB FROM #Memory_process
UNION
SELECT 'virtual_address_space_committed_GB',virtual_address_space_committed_GB FROM #Memory_process
UNION
SELECT 'available_commit_limit_GB',available_commit_limit_GB FROM #Memory_process
UNION
SELECT 'page_fault_count',page_fault_count FROM #Memory_process;


/******************************************************************/
/*************** Performance Counter Details **********************/
/******************************************************************/

CREATE TABLE #PerfCntr_Data(
Parameter VARCHAR(300),
Value VARCHAR(100));

-- Get size of SQL Server Page in bytes
DECLARE @pg_size INT, @Instancename varchar(50)
SELECT @pg_size = low from master..spt_values where number = 1 and type = 'E'

-- Extract perfmon counters to a temporary table
IF OBJECT_ID('tempdb..#perfmon_counters') is not null DROP TABLE #perfmon_counters
SELECT * INTO #perfmon_counters FROM sys.dm_os_performance_counters;

-- Get SQL Server instance name as it require for capturing Buffer Cache hit Ratio
SELECT  @Instancename = LEFT([object_name], (CHARINDEX(':',[object_name]))) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Buffer cache hit ratio';

INSERT INTO #PerfCntr_Data
SELECT CONVERT(VARCHAR(300),Cntr) AS Parameter, CONVERT(VARCHAR(100),Value) AS Value
FROM
(
SELECT  'Total Server Memory (GB)' as Cntr,
        (cntr_value/1048576.0) AS Value 
FROM    #perfmon_counters 
WHERE   counter_name = 'Total Server Memory (KB)'
UNION ALL
SELECT  'Target Server Memory (GB)', 
        (cntr_value/1048576.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Target Server Memory (KB)'
UNION ALL
SELECT  'Connection Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Connection Memory (KB)'
UNION ALL
SELECT  'Lock Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Lock Memory (KB)'
UNION ALL
SELECT  'SQL Cache Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'SQL Cache Memory (KB)'
UNION ALL
SELECT  'Optimizer Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Optimizer Memory (KB) '
UNION ALL
SELECT  'Granted Workspace Memory (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Granted Workspace Memory (KB) '
UNION ALL
SELECT  'Cursor memory usage (MB)', 
        (cntr_value/1024.0) 
FROM    #perfmon_counters 
WHERE   counter_name = 'Cursor memory usage' and instance_name = '_Total'
UNION ALL
SELECT  'Total pages Size (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name= @Instancename+'Buffer Manager' 
        and counter_name = 'Total pages'
UNION ALL
SELECT  'Database pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name = @Instancename+'Buffer Manager' and counter_name = 'Database pages'
UNION ALL
SELECT  'Free pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name = @Instancename+'Buffer Manager' 
        and counter_name = 'Free pages'
UNION ALL
SELECT  'Reserved pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Reserved pages'
UNION ALL
SELECT  'Stolen pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Stolen pages'
UNION ALL
SELECT  'Cache Pages (MB)', 
        (cntr_value*@pg_size)/1048576.0 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Plan Cache' 
        and counter_name = 'Cache Pages' and instance_name = '_Total'
UNION ALL
SELECT  'Page Life Expectency in seconds',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Page life expectancy'
UNION ALL
SELECT  'Free list stalls/sec',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Free list stalls/sec'
UNION ALL
SELECT  'Checkpoint pages/sec',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Checkpoint pages/sec'
UNION ALL
SELECT  'Lazy writes/sec',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Buffer Manager' 
        and counter_name = 'Lazy writes/sec'
UNION ALL
SELECT  'Memory Grants Pending',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Memory Manager' 
        and counter_name = 'Memory Grants Pending'
UNION ALL
SELECT  'Memory Grants Outstanding',
        cntr_value 
FROM    #perfmon_counters 
WHERE   object_name=@Instancename+'Memory Manager' 
        and counter_name = 'Memory Grants Outstanding'
UNION ALL
SELECT  'process_physical_memory_low',
        process_physical_memory_low 
FROM    sys.dm_os_process_memory WITH (NOLOCK)
UNION ALL
SELECT  'process_virtual_memory_low',
        process_virtual_memory_low 
FROM    sys.dm_os_process_memory WITH (NOLOCK)
UNION ALL
SELECT  'Max_Server_Memory (MB)' ,
        [value_in_use] 
FROM    sys.configurations 
WHERE   [name] = 'max server memory (MB)'
UNION ALL
SELECT  'Min_Server_Memory (MB)' ,
        [value_in_use] 
FROM    sys.configurations 
WHERE   [name] = 'min server memory (MB)'
UNION ALL
SELECT  'BufferCacheHitRatio',
        (a.cntr_value * 1.0 / b.cntr_value) * 100.0 
FROM    sys.dm_os_performance_counters a
        JOIN (SELECT cntr_value,OBJECT_NAME FROM sys.dm_os_performance_counters
              WHERE counter_name = 'Buffer cache hit ratio base' AND 
                    OBJECT_NAME = @Instancename+'Buffer Manager') b ON 
                    a.OBJECT_NAME = b.OBJECT_NAME WHERE a.counter_name = 'Buffer cache hit ratio' 
                    AND a.OBJECT_NAME = @Instancename+'Buffer Manager') AS P;



/******************************************************************/
/*************** Database Backup Report ***************************/
/******************************************************************/

CREATE TABLE #Backup_Report(
Database_Name VARCHAR(300),
Last_Backup_Date VARCHAR(50));

INSERT INTO #Backup_Report
--Databases with data backup over 48 hours old 
SELECT Database_Name, last_db_backup_date AS Last_Backup_Date FROM (
SELECT	CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS Server, 
		msdb.dbo.backupset.database_name, 
		MAX(msdb.dbo.backupset.backup_finish_date) AS last_db_backup_date, 
		DATEDIFF(hh, MAX(msdb.dbo.backupset.backup_finish_date), GETDATE()) AS [Backup Age (Hours)] 
FROM	msdb.dbo.backupset 
WHERE   msdb.dbo.backupset.type = 'D'  
GROUP BY msdb.dbo.backupset.database_name 
HAVING	(MAX(msdb.dbo.backupset.backup_finish_date) < DATEADD(HH, - 48, GETDATE()))  
UNION  
--Databases without any backup history 
SELECT	CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS Server,  
		sd.NAME AS database_name,  
		NULL AS [Last Data Backup Date],  
		9999 AS [Backup Age (Hours)]  
FROM	master.dbo.sysdatabases sd 
		LEFT JOIN msdb.dbo.backupset bs
		ON sd.name  = bs.database_name 
WHERE	bs.database_name IS NULL AND sd.name <> 'tempdb' ) AS B 
ORDER BY	Database_Name; 



					
/*************************************************************/
/****************** Connection Details ***********************/
/*************************************************************/

-- Number of connection on the instance grouped by hostnames
Create table #ConnInfo(             
Hostname varchar(100),                         
NumberOfconn varchar(10)                        
)  
insert into #ConnInfo
SELECT  Case when len(hostname)=0 Then 'Internal Process' Else hostname END,count(*)NumberOfconnections 
FROM sys.sysprocesses
GROUP BY hostname


/*************************************************************/
/************** Currently Running Jobs Info ******************/
/*************************************************************/
Create table #JobInfo(             
spid varchar(10),                         
lastwaittype varchar(100),                         
dbname varchar(100),                         
login_time varchar(100),                         
status varchar(100),                         
opentran varchar(100),                         
hostname varchar(100),                        
JobName varchar(100),                        
command nvarchar(2000),
domain varchar(100), 
loginname varchar(100)   
) 
insert into #JobInfo
SELECT  distinct p.spid,p.lastwaittype,DB_NAME(p.dbid),p.login_time,p.status,p.open_tran,p.hostname,J.name,
p.cmd,p.nt_domain,p.loginame
FROM master..sysprocesses p
INNER JOIN msdb..sysjobs j ON 
substring(left(j.job_id,8),7,2) + substring(left(j.job_id,8),5,2) + substring(left(j.job_id,8),3,2) + substring(left(j.job_id,8),1,2) = substring(p.program_name, 32, 8) 
Inner join msdb..sysjobactivity sj on j.job_id=sj.job_id
WHERE program_name like'SQLAgent - TSQL JobStep (Job %' and sj.stop_execution_date is null

/*************************************************************/
/****************** Tempdb File Info *************************/
/*************************************************************/
-- tempdb file usage
Create table #tempdbfileusage(             
servername varchar(100),                         
databasename varchar(100),                         
filename varchar(100),                         
physicalName varchar(100),                         
filesizeMB varchar(100),                         
availableSpaceMB varchar(100),                         
percentfull varchar(100) 
) 

DECLARE @TEMPDBSQL NVARCHAR(4000);
SET @TEMPDBSQL = ' USE Tempdb;
SELECT  CONVERT(VARCHAR(100), @@SERVERNAME) AS [server_name]
                ,db.name AS [database_name]
                ,mf.[name] AS [file_logical_name]
                ,mf.[filename] AS[file_physical_name]
                ,convert(FLOAT, mf.[size]/128) AS [file_size_mb]             
                ,convert(FLOAT, (mf.[size]/128 - (CAST(FILEPROPERTY(mf.[name], ''SpaceUsed'') AS int)/128))) as [available_space_mb]
                ,convert(DECIMAL(38,2), (CAST(FILEPROPERTY(mf.[name], ''SpaceUsed'') AS int)/128.0)/(mf.[size]/128.0))*100 as [percent_full]    
FROM   tempdb.dbo.sysfiles mf
JOIN      master..sysdatabases db
ON         db.dbid = db_id()';
--PRINT @TEMPDBSQL;
insert into #tempdbfileusage
EXEC SP_EXECUTESQL @TEMPDBSQL;


/*************************************************************/
/****************** Database Log Usage ***********************/
/*************************************************************/
CREATE TABLE #LogSpace(
DBName VARCHAR(100),
LogSize VARCHAR(50),
LogSpaceUsed_Percent VARCHAR(100), 
LStatus CHAR(1));

INSERT INTO #LogSpace
EXEC ('DBCC SQLPERF(LOGSPACE) WITH NO_INFOMSGS;');

/********************************************************************/
/****************** Long Running Transactions ***********************/
/********************************************************************/

CREATE TABLE #OpenTran_Detail(
	[SPID] [varchar](20) NULL,
	[TranID] [varchar](50) NULL,
	[User_Tran] [varchar](5) NOT NULL,
	[DBName] [nvarchar](250) NULL,
	[Login_Time] [varchar](60) NULL,
	[Duration] [varchar](20) NULL,
	[Last_Batch] [varchar](200) NULL,
	[Status] [nvarchar](50) NULL,
	[LoginName] [nvarchar](250) NULL,
	[HostName] [nvarchar](250) NULL,
	[ProgramName] [nvarchar](250) NULL,
	[CMD] [nvarchar](50) NULL,
	[SQL] [nvarchar](max) NULL,
	[Blocked] [varchar](6) NULL
);



;WITH OpenTRAN AS
(SELECT session_id,transaction_id,is_user_transaction 
FROM sys.dm_tran_session_transactions) 
INSERT INTO #OpenTran_Detail
SELECT      
	LTRIM(RTRIM(OT.session_id)) AS 'SPID',
	LTRIM(RTRIM(OT.transaction_id)) AS 'TranID',
	CASE WHEN OT.is_user_transaction = '1' THEN 'Yes' ELSE 'No' END AS 'User_Tran',
    db_name(LTRIM(RTRIM(s.dbid)))DBName,
    LTRIM(RTRIM(login_time)) AS 'Login_Time', 
	DATEDIFF(MINUTE,login_time,GETDATE()) AS 'Duration',
	LTRIM(RTRIM(last_batch)) AS 'Last_Batch',
    LTRIM(RTRIM(status)) AS 'Status',
	LTRIM(RTRIM(loginame)) AS 'LoginName', 
    LTRIM(RTRIM(hostname)) AS 'HostName', 
    LTRIM(RTRIM(program_name)) AS 'ProgramName',
    LTRIM(RTRIM(cmd)) AS 'CMD',
	LTRIM(RTRIM(a.text)) AS 'SQL',
    LTRIM(RTRIM(blocked)) AS 'Blocked'
FROM sys.sysprocesses AS s
CROSS APPLY sys.dm_exec_sql_text(s.sql_handle)a
INNER JOIN OpenTRAN AS OT ON OT.session_id = s.spid 
WHERE s.spid <> @@spid AND s.dbid>4;

/*************************************************************/
/****************** HTML Preparation *************************/
/*************************************************************/

DECLARE @TableHTML  VARCHAR(MAX),                                  
  @StrSubject VARCHAR(100),                                  
  @Oriserver VARCHAR(100),                              
  @Version VARCHAR(250),                              
  @Edition VARCHAR(100),                              
  @ISClustered VARCHAR(100),                              
  @SP VARCHAR(100),                              
  @ServerCollation VARCHAR(100),                              
  @SingleUser VARCHAR(5),                              
  @LicenseType VARCHAR(100),                              
  @Cnt int,         
  @URL varchar(1000),                              
  @Str varchar(1000),                              
  @NoofCriErrors varchar(3)     

-- Variable Assignment            

SELECT @Version = @@version                              
SELECT @Edition = CONVERT(VARCHAR(100), serverproperty('Edition'))                              
SET @Cnt = 0                              
IF serverproperty('IsClustered') = 0                               
BEGIN                              
 SELECT @ISClustered = 'No'                              
END                              
ELSE      
BEGIN                              
 SELECT @ISClustered = 'YES'                              
END                              
SELECT @SP = CONVERT(VARCHAR(100), SERVERPROPERTY ('productlevel'))                              
SELECT @ServerCollation = CONVERT(VARCHAR(100), SERVERPROPERTY ('Collation'))                               
SELECT @LicenseType = CONVERT(VARCHAR(100), SERVERPROPERTY ('LicenseType'))                               
SELECT @SingleUser = CASE SERVERPROPERTY ('IsSingleUser')                              
      WHEN 1 THEN 'Yes'                              
      WHEN 0 THEN 'No'                              
      ELSE                              
      'null' END                              
SELECT @OriServer = CONVERT(VARCHAR(50), SERVERPROPERTY('servername'))                                
SELECT @strSubject = 'Database Server Health Check ('+ CONVERT(VARCHAR(100), @SERVERNAME) + ')'                                  
 


SET @TableHTML =                                  
 '<font face="Verdana" size="4">Health Check</font>                                
 <table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="47%" id="AutoNumber1" height="50">                                
 <tr>                                
 <td width="39%" height="22" bgcolor="#000080"><b>                         
 <font face="Verdana" size="2" color="#FFFFFF">Server Name</font></b></td>                                
 </tr>                                
 <tr>                                
 <td width="39%" height="27"><font face="Verdana" size="2">' + @ServerName +'</font></td>                                
 </tr>                                
 </table>                               
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                              
 <tr>                              
 <td align="Center" width="50%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">Version</font></b></td>                              
 <td align="Center" width="17%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">Edition</font></b></td>                              
 <td align="Center" width="35%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">Service Pack</font></b></td>                              
 <td align="Center" width="60%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">Collation</font></b></td>                              
 <td align="Center" width="93%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">LicenseType</font></b></td>                              
 <td align="Center" width="40%" bgColor="#000080" height="15"><b>                              
<font face="Verdana" color="#ffffff" size="1">SingleUser</font></b></td>                              
 <td align="Center" width="93%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">Clustered</font></b></td>                              
 </tr>                              
 <tr>                              
 <td align="Center" width="50%" height="27"><font face="Verdana" size="1">'+@version +'</font></td>                              
 <td align="Center" width="17%" height="27"><font face="Verdana" size="1">'+@edition+'</font></td>                              
 <td align="Center" width="18%" height="27"><font face="Verdana" size="1">'+@SP+'</font></td>                              
 <td align="Center" width="17%" height="27"><font face="Verdana" size="1">'+@ServerCollation+'</font></td>                              
 <td align="Center" width="25%" height="27"><font face="Verdana" size="1">'+@LicenseType+'</font></td>                              
 <td align="Center" width="25%" height="27"><font face="Verdana" size="1">'+@SingleUser+'</font></td>                              
 <td align="Center" width="93%" height="27"><font face="Verdana" size="1">'+@isclustered+'</font></td>                              
 </tr>                              
 </table>                 
   
 <p style="margin-top: 0; margin-bottom: 0">&nbsp;</p>                              
 <font face="Verdana" size="4">SQL ErrorLog Summary in Last 4 Days</font>' +                                  
 '<table style="BORDER-COLLAPSE: collapse" borderColor="#111111" cellPadding="0" width="933" bgColor="#ffffff" borderColorLight="#000000" border="1">                                
 <tr>                              
 <td width="20%" bgColor="#000080" height="15"><b>                      
 <font face="Verdana" color="#ffffff" size="1">Number of Critical Errors</font></b></td>                              
 </tr>                              
 </table>                              
 <table style="BORDER-COLLAPSE: collapse" borderColor="#111111" cellPadding="0" width="933" bgColor="#ffffff" borderColorLight="#000000" border="1">                                
 <tr>                              
 <td width="20%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">Error Log DateTime</font></b></td>                   
 <td width="80%" bgColor="#000080" height="15"><b>                              
 <font face="Verdana" color="#ffffff" size="1">Error Message</font></b></td>                              
 </tr>'                              
              

SELECT                               
 @TableHTML = @TableHTML + '<tr>                              
 <td width="20%" height="27"><font face="Verdana" size="1">'+ ISNULL(CONVERT(VARCHAR(50),LogDate ),'') +'</font></td>                              
 <td width="80%" height="27"><font face="Verdana" size="1">'+ISNULL(CONVERT(VARCHAR(50),LogInfo ),'')+'</font></td>                              
 </tr>'                              
FROM  #ErrorLogInfo   ORDER BY      LogDate DESC 


 SELECT                                 
 @TableHTML = @TableHTML +                                   
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Instance last Recycled</font>                                
 <table style="BORDER-COLLAPSE: collapse" borderColor="#111111" cellPadding="0" width="933" bgColor="#ffffff" borderColorLight="#000000" border="1">                                    
 <tr>                                    
 <th align="Center" width="50" bgColor="#000080">                                    
  <font face="Verdana" size="1" color="#FFFFFF">Last Recycle</font></th>                                    
 <th align="Center" width="50" bgColor="#000080">                                    
  <font face="Verdana" size="1" color="#FFFFFF">Current DateTime</font></th>                                    
 <th align="Center" width="50" bgColor="#000080">                                 
 <font face="Verdana" size="1" color="#FFFFFF">UpTimeInDays</font></th>                                    
  </tr>'                                
                                
SELECT                                 
 @TableHTML =  @TableHTML +                                     
 '<tr>                                  
 <td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), LastRecycle ), '')  +'</font></td>' +                                      
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  CurrentDate ), '')  +'</font></td>' +                                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  UpTimeInDays ), '')  +'</font></td>' +                                      
  '</tr>'                                
FROM                                 
 #RebootDetails 


/**** Tempdb File Usage *****/
SELECT                                 
 @TableHTML =  @TableHTML +                            
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Tempdb File Usage</font>                                
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                                
   <tr>              
 <th align="Center" width="300" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Database Name</font></th>             
 <th align="Center" width="300" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">File Name</font></th>             
 <th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Physical Name</font></th>             
 <th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">FileSize MB</font></th>             
 <th align="Center" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">Available MB</font></th>             
 <th align="Center" width="200" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Percent_full </font></th>             
   </tr>'                                
select                                 
@TableHTML =  @TableHTML +                                   
 '<tr>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(databasename, '') + '</font></td>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(FileName, '') +'</font></td>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(physicalName, '') +'</font></td>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(filesizeMB, '') +'</font></td>' +                                
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(availableSpaceMB, '') +'</font></td>' +
 CASE WHEN CONVERT(DECIMAL(10,3),percentfull) >80.00 THEN  
'<td align="Center"><font face="Verdana" size="1" color="#FF0000"><b>' + ISNULL(percentfull, '') +'</b></font></td></tr>'                                             
 ELSE
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(percentfull, '') +'</font></td></tr>' END                              
from                                 
 #tempdbfileusage     


/**** CPU Usage *****/
SELECT                                 
 @TableHTML =  @TableHTML +                            
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">CPU Usage Currently</font>                                
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                                
   <tr>              
 <th align="Center" width="300" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">System Time</font></th>             
 <th align="Center" width="300" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">SQLProcessUtilization</font></th>             
 <th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">SystemIdle</font></th>             
 <th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">OtherProcessUtilization</font></th>             
 <th align="Center" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">load DateTime</font></th>             
   </tr>'                                
SELECT                                 
 @TableHTML =  @TableHTML +                                   
 '<tr>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), EventTime2 ), '')  +'</font></td>' +  
  '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), SQLProcessUtilization ), '')  +'</font></td>' +  
   '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), SystemIdle ), '')  +'</font></td>' +                            
   '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), OtherProcessUtilization ), '')  +'</font></td>' +                            
  '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), load_date ), '')  +'</font></td> </tr>'                                
FROM                                 
 #CPU 

/***** Memory Usage ****/
SELECT                                 
 @TableHTML =  @TableHTML +                            
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Memory Usage </font>                                
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                                
   <tr>              
 <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Parameter</font></th>                            
  <th align="left" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">Value</font></th>            
   </tr>'                                
SELECT                                 
 @TableHTML =  @TableHTML +                                     
 '<tr>                                  
 <td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(200),  Parameter ), '')  +'</font></td>' +                                      
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  Value ), '')  +'</font></td>' +                                   
  '</tr>'                                
FROM                                 
 #Memory; 

/***** Performance Counter Values ****/
SELECT                                 
 @TableHTML =  @TableHTML +                            
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Performance Counter Data</font>                                
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                                
   <tr>              
 <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Performance_Counter</font></th>                            
  <th align="left" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">Value</font></th>            
   </tr>'                                
SELECT                                 
 @TableHTML =  @TableHTML +                                     
 '<tr>                                  
 <td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(300),  Parameter ), '')  +'</font></td>' +                                      
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  Value ), '')  +'</font></td>' +                                   
  '</tr>'                                
FROM                                 
 #PerfCntr_Data; 
 
/***** Database Backup Report ****/
SELECT                                 
 @TableHTML =  @TableHTML +                            
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Missing Backup Report</font>                                
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                                
   <tr>              
 <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Database_Name</font></th>                            
  <th align="left" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">Last_Backup_Date</font></th>            
   </tr>'                                
SELECT                                 
 @TableHTML =  @TableHTML +                                     
 '<tr>                                  
 <td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  Database_Name ), '')  +'</font></td>' +                                      
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  Last_Backup_Date), '')  +'</font></td>' +                                   
  '</tr>'                                
FROM           
 #Backup_Report

 /****** Connection Information *****/

 SELECT                                 
 @TableHTML = @TableHTML +                                   
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Total Number of Connection Currently </font>                                
 <table style="BORDER-COLLAPSE: collapse" borderColor="#111111" cellPadding="0" width="933" bgColor="#ffffff" borderColorLight="#000000" border="1">                                    
 <tr>                                    
 <th align="Center" width="50" bgColor="#000080">                                    
  <font face="Verdana" size="1" color="#FFFFFF">Host Names</font></th>                                    
 <th align="Center" width="50" bgColor="#000080">                                    
  <font face="Verdana" size="1" color="#FFFFFF">Number Of Connection</font></th>                                    
  </tr>'                                
                       
SELECT                                 
 @TableHTML =  @TableHTML +                        
 '<tr>         
<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), Hostname ), '')  +'</font></td>' +                             
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), NumberOfconn  ), '')  +'</font></td>' +                                 
  '</tr>'                                
FROM                                 
 #ConnInfo                                
    
/***** Log Space Usage ****/
SELECT                                 
 @TableHTML =  @TableHTML +                            
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Log Space Usage </font>                                
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                                
   <tr>              
 <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">DatabaseName</font></th>                            
  <th align="left" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">Log_Space_Used</font></th>                            
  <th align="left" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">Log_Usage_%</font></th>            
   </tr>'                                
SELECT                                 
 @TableHTML =  @TableHTML +                                     
 '<tr>                                  
 <td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  DBName ), '')  +'</font></td>' +                                      
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  LogSize ), '')  +'</font></td>' + 
 CASE WHEN CONVERT(DECIMAL(10,3),LogSpaceUsed_Percent) >80.00 THEN
  '<td><font face="Verdana" size="1" color="#FF0000"><b>' + ISNULL(CONVERT(VARCHAR(100),  LogSpaceUsed_Percent ), '')  +'</b></font></td>'
 ELSE
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  LogSpaceUsed_Percent ), '')  +'</font></td>' 
 END +                                   
  '</tr>'                                
FROM                                 
 #LogSpace 


/******** Job Info *******/
SELECT                                 
 @TableHTML = @TableHTML +                                 
 '</table>                        
 <p style="margin-top: 0; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Job Status</font>' +                                    
 '<table style="BORDER-COLLAPSE: collapse" borderColor="#111111" cellPadding="0" width="933" bgColor="#ffffff" borderColorLight="#000000" border="1">                                  
 <tr>                                  
 <th align="left" width="430" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">spid</font></th> 
 <th align="left" width="70" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">latwaittype</font></th>                                  
 <th align="left" width="85" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">dbname</font></th>                                  
 <th align="left" width="183" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Process Login time</font></th>                                  
 <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">status</font></th>                                  
 <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">opentran</font></th>    
  <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">hostname</font></th>  
  <th align="left" width="146" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">JobName</font></th>  
  <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">command</font></th>  
  <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">domain</font></th>   
   <th align="left" width="136" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">LoginName</font></th>                               
 </tr>'                                  
                                
SELECT                                 
 @TableHTML = ISNULL(CONVERT(VARCHAR(MAX), @TableHTML), 'No Job Running') + '<tr><td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100), spid), '') +'</font></td>' +                                    
'<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50), lastwaittype),'') + '</font></td>' +                     
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50), dbname),'') + '</font></td>' +                                
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50), login_time),'') +'</font></td>' +   
  '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50), status),'') +'</font></td>' +   
   '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50), opentran),'') +'</font></td>' +   
    '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50), hostname),'') +'</font></td>' +   
     '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(500), JobName),'') +'</font></td>' +   
      '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(200), command),'') +'</font></td>' +   
        '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50), domain),'') +'</font></td>' +   
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(50),loginname ),'') + '</font></td></tr>'                                   
FROM                                 
 #JobInfo

 
 
 /****** Blocking Information ****/

 SELECT                                 
 @TableHTML = @TableHTML +                
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Blocking Process Info (If Any)</font>                          
 <table style="BORDER-COLLAPSE: collapse" borderColor="#111111" cellPadding="0" width="933" bgColor="#ffffff" borderColorLight="#000000" border="1">                                    
 <tr>   
  <th align="Center" width="50" bgColor="#000080">                                    
  <font face="Verdana" size="1" color="#FFFFFF">ServerName</font></th>                                   
 <th align="Center" width="50" bgColor="#000080">                                    
  <font face="Verdana" size="1" color="#FFFFFF">SpID</font></th>                                    
 <th align="Center" width="50" bgColor="#000080">                                    
  <font face="Verdana" size="1" color="#FFFFFF">BlockingSPID</font></th>       <th align="Center" width="50" bgColor="#000080">                                 
 <font face="Verdana" size="1" color="#FFFFFF">ProgramName</font></th>                                    
 <th align="Center" width="50" bgColor="#000080">                                    
 <font face="Verdana" size="1" color="#FFFFFF">LoginName</font></th>                
 <th align="Center" width="40" bgColor="#000080">                                    
 <font face="Verdana" size="1" color="#FFFFFF">ObjName</font></th>                      
 <th align="left" width="150" bgColor="#000080">                                    
 <font face="Verdana" size="1" color="#FFFFFF">Query</font></th>                                    
 </tr>'           
                               
SELECT                                 
 @TableHTML =  @TableHTML +                               
 '<tr>  
 <td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  @SERVERNAME ), '')  +'</font></td>' +                                      
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  spid ), '')  +'</font></td>' +                                      
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  Blkspid ), '')  +'</font></td>' +                                 
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  PrgName ), '')  +'</font></td>' +                                      
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  LoginName ), '')  +'</font></td>' +                                   
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  ObjName ), '')  +'</font></td>' +                                   
 '<td><font face="Verdana" size="1">' + ISNULL(CONVERT(VARCHAR(100),  Query ), '')  +'</font></td>' +                                   
  '</tr>'                     
FROM                                 
 #BlkProcesses               
ORDER BY     spid  


/**** Long running Transactions*****/
SELECT                                 
 @TableHTML =  @TableHTML +                            
 '</table>                                
 <p style="margin-top: 1; margin-bottom: 0">&nbsp;</p>                                
 <font face="Verdana" size="4">Long Running Transactions</font>                                
 <table id="AutoNumber1" style="BORDER-COLLAPSE: collapse" borderColor="#111111" height="40" cellSpacing="0" cellPadding="0" width="933" border="1">                                
   <tr>              
 <th align="Center" width="300" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">SPID</font></th>             
 <th align="Center" width="300" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">TranID</font></th>             
 <th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">User_Tran</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">DB_Name</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Login_Time</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Duration</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Last_Batch</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Status</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">LoginName</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Host_Name</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">PrgName</font></th>             
<th align="Center" width="250" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">CMD</font></th>             
 <th align="Center" width="200" bgColor="#000080">             
 <font face="Verdana" size="1" color="#FFFFFF">SQL</font></th>             
 <th align="Center" width="200" bgColor="#000080">                                  
 <font face="Verdana" size="1" color="#FFFFFF">Blocked </font></th>             
   </tr>'                                
select                                 
@TableHTML =  @TableHTML +                                   
 '<tr>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(SPID, '') + '</font></td>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(TranID, '') +'</font></td>' +                                    
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(User_Tran, '') +'</font></td>' +                                    
  '<td align="Center"><font face="Verdana" size="1">' + ISNULL(DBName, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(Login_Time, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(Duration, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(Last_Batch, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL([Status], '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(LoginName, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(HostName, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(ProgramName, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(CMD, '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL([SQL], '') +'</font></td>' +                 
 '<td align="Center"><font face="Verdana" size="1">' + ISNULL(Blocked, '') +'</font></td></tr>'                               
from                                 
 #OpenTran_Detail     

 
 /****** End to HTML Formatting  ***/  
SELECT                                 
 @TableHTML =  @TableHTML +  '</table>' +                                
 '<p style="margin-top: 0; margin-bottom: 0">&nbsp;</p>                                
 <p>&nbsp;</p>'  
      
  
EXEC msdb.dbo.sp_send_dbmail                                  
 @profile_name = @MailProfile,--'MMStuckup',                           
 @recipients=@MailID,  --'uday.arumilli@ge.com',                                
 @subject = @strSubject,                                 
 @body = @TableHTML,                                    
 @body_format = 'HTML' ;                             


DROP TABLE  #RebootDetails
DROP TABLE  #BlkProcesses
DROP TABLE  #ErrorLogInfo
DROP TABLE  #CPU
DROP TABLE  #Memory_BPool;
DROP TABLE  #Memory_sys;
DROP TABLE  #Memory_process;
DROP TABLE  #Memory;
DROP TABLE  #perfmon_counters;
DROP TABLE  #PerfCntr_Data;
DROP TABLE  #Backup_Report;
DROP TABLE  #ConnInfo;
DROP TABLE  #JobInfo;
DROP TABLE  #tempdbfileusage;
DROP TABLE  #LogSpace;
DROP TABLE  #OpenTran_Detail;

SET NOCOUNT OFF;
SET ARITHABORT OFF;
END

 

 

The post SQL Server Health Check appeared first on udayarumilli.com.

SQL Server Space Usage

$
0
0

SQL Server Space Usage

SQL Server Space Usage

Hello there, this post can explain various ways to know the SQL Server Space Usage information. Here are the different ways available:

  • XP_FIXEDDRIVES
  • SP_SPACEUSED
  • SP_HELPDB
  • DBCC SQLPERF (LOGSPACE)
  • sys.dm_os_volume_stats
  • Database and file wise Space usage
  • Used Space and Free Space For a given Database
  • Table wise space usage in a given database
  • Using SSMS Standard Reports
  • XP_CMDSHELL
  • PowerShell Script

XP_FIXEDDRIVES:

This is simple and straight method when we think of SQL Server Space Usage. It gets the drive free space information.

But we can’t know the Total Drive space, let’s say D drive is having 100 GB in which 60 GB is used and 40 GB is free then this command can only get us the free space information 40 GB.

/*********************************/
/**** Diskspace Report ***********/
/**** Tested: 2005, 2008, ********/
/**** 2008 R2, 2012, 2014, 2016 **/
/*********************************/
EXEC XP_FIXEDDRIVES;

SP_SPACEUSED

This can quickly get the Database and table space information. For database it captures total size, un-allocated space, data and index space details. For a given table it captures the total number of rows, reserved space, Data, Index and unused space information.

/*********************************************/
/**** Database & Table Space Usage ***********/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
-- To capture the Database Space information
EXEC SP_SPACEUSED;

-- To capture the given table Space information
SP_SPACEUSED '[SCHEMA].[TABLE]';

 

SP_HELPDB:

It’s one of the best handy commands which can quickly captures all databases space and other information from the given SQL Server instance. It gets the database name, total size, owner, current status and compatibility level etc. Also this system stored procedure can be used for a specific database where it can get more useful information about the given database including the physical file path and file size.

/*********************************************/
/**** Database space and other information ***/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
--Capture All databases information from the SQL instance
EXEC SP_HELPDB;

--Capture the given database information 
EXEC SP_HELPDB 'Master';

 

DBCC SQLPERF (LOGSPACE):

This is the quickest way to check the log usage for all databases in the instance. It captures log size, space used percentage and status.

/**************************************************/
/**** Log Space Usage Report for All databases*****/
/**** Tested: 2008, 2008 R2 ***********************/
/****	      2012, 2014, 2016 ********************/
/**************************************************/
DBCC SQLPERF(LOGSPACE);

 

sys.dm_os_volume_stats:

When we use XP_FIXEDDRIVES we can’t capture only the free space information, to get the total drive space information we can get it using “sys.dm_os_volume_stats”. Disk space details retrieved when only the drives containing any Database files from this instance. Let’s say the OS is attached the drives C, D, E, H and T. And no data or log file are located on C and H drive then the below query couldn’t get the C & H drive information rather it can capture the total and free space information from remaining drives.

/*********************************************/
/**** Drive Total and Free space info ********/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
SELECT	[Total(GB)],
		[FreeSpace(GB)],
		CAST(([FreeSpace(GB)]*100)/[Total(GB)] AS DECIMAL(15,2)) AS [%FreeSpace]
FROM
	(SELECT DISTINCT
			OVS.volume_mount_point [Drive],
			CAST(OVS.total_bytes / 1073741824 AS DECIMAL(15,2)) [Total(GB)],
			CAST(OVS.available_bytes / 1073741824 AS DECIMAL(15,2)) [FreeSpace(GB)]
	FROM	sys.master_files SMF
			CROSS APPLY sys.dm_os_volume_stats(SMF.database_id, SMF.[file_id]) OVS
	) AS Result;

 

Database and File wise Space Usage:

Here is the query to get database and the individual file (Data and Log) wise space usage information.

/*********************************************/
/**** Data and Log file wise Disk Usage ******/
/**** Tested: 2008, 2008 R2 ******************/
/****	      2012, 2014, 2016 ***************/
/*********************************************/
-- Data and Log file wise space usage for all databases
SELECT      D.name AS 'DB_Name',
			CASE WHEN MF.[Type] = 0 THEN 'DATA' ELSE 'LOG' END AS 'File_Type',
			MF.Name as 'File_Name',
            CAST((SUM(size)*8)/1024.00 AS DECIMAL(15,2)) AS [Disk_Space(MB)],
            CAST((SUM(size)*8)/(1024.00 * 1024.00) AS DECIMAL(15,2)) AS [Disk_Space(GB)]
FROM        sys.databases D
JOIN        sys.master_files MF
ON          D.database_id=MF.database_id
GROUP BY    D.name,MF.Name,MF.Type
ORDER BY    D.name,MF.Name,MF.Type;

-- Database wise  total disk usage in a given instance
SELECT      D.name AS 'DB_Name',
            CAST((SUM(size)*8)/1024.00 AS DECIMAL(15,2)) AS [Total_Disk_Space(MB)],
            CAST((SUM(size)*8)/(1024.00 * 1024.00) AS DECIMAL(15,2)) AS [Total_Disk_Space(GB)]
FROM        sys.databases D
JOIN        sys.master_files MF
ON          D.database_id=MF.database_id
GROUP BY    D.name
ORDER BY    D.name;

 

Used Space and Free Space For a given Database:

The most common situation is to identifying the available free space for a given single database. The below query can help you in identifying the percentage free space in a given database.

/**************************************************/
/**** For a given database used and free space ****/
/**** Tested: 2008, 2008 R2 ***********************/
/****		  2012, 2014, 2016 ********************/
/**************************************************/
SELECT 
	[Database], 
	[File_Name], 
	[FileGroup_Name],
	File_Path,
	[Total_Space(MB)],
	[Available_Space(MB)],
	CAST([Total_Space(MB)]/1024 AS DECIMAL(15,2)) AS [Total_Space(GB)],
	CAST([Available_Space(MB)]/1024 AS DECIMAL(15,2)) AS [Available_Space(GB)],
	CAST(([Available_Space(MB)]*100)/[Total_Space(MB)] AS DECIMAL(15,2)) AS '%_Free'
FROM
	(SELECT 
		DB_NAME() AS 'Database',
		df.name AS [File_Name], 
		ds.name AS [FileGroup_Name],
		df.physical_name AS [File_Path], 
		CAST((df.size/128.0) AS DECIMAL(15,2)) AS [Total_Space(MB)],
		CAST(df.size/128.0 - CAST(FILEPROPERTY(df.name, 'SpaceUsed') AS int)/128.0 AS DECIMAL(15,2)) AS [Available_Space(MB)]
	FROM	sys.database_files AS df WITH (NOLOCK) 
			LEFT OUTER JOIN sys.data_spaces AS ds WITH (NOLOCK) ON df.data_space_id = ds.data_space_id) AS Result;

 

Table wise Disk Space Usage:

The below query gets you the “Table Wise disk space information” which can be helpful to identify the critical tables in a given database , here you can find more information.

/**************************************************/
/**** Table wise Disk Space Report ****************/
/**** Tested: 2008, 2008 R2 ***********************/
/****	      2012, 2014, 2016 ********************/
/**************************************************/
SET NOCOUNT ON;
BEGIN TRY
	--Create a temparory table 
	CREATE TABLE #Tab (
			[Name]		 NVARCHAR(128),    
			[Rows]		 CHAR(11),    
			[Reserved]	 VARCHAR(18),  
			[Data]		 VARCHAR(18),     
			[Index_size] VARCHAR(18),    
			[Unused]	 VARCHAR(18)); 

	--Capture all tables data allocation information 
	INSERT #Tab 
	EXEC sp_msForEachTable 'EXEC sp_spaceused ''?''' ;

	--Alter Rows column datatype to BIGINT to get the result in sorted order
	ALTER TABLE #Tab ALTER COLUMN [ROWS] BIGINT  ;

	-- Get the final result: Remove KB and convert it into MB
	SELECT	Name,
		[Rows],
		CAST(LTRIM(RTRIM(REPLACE(Reserved,'KB',''))) AS BIGINT)/1024.0 AS 'Reserved MB',
		CAST(LTRIM(RTRIM(REPLACE(Data,'KB',''))) AS BIGINT)/1024.0 AS 'Data MB',
		CAST(LTRIM(RTRIM(REPLACE(Index_Size,'KB',''))) AS BIGINT)/1024.0 AS 'Index_Size MB',
		CAST(LTRIM(RTRIM(REPLACE(Unused,'KB',''))) AS BIGINT)/1024.0 AS 'Unused MB'
	FROM #Tab 
	ORDER BY [rows] DESC;

END TRY
BEGIN CATCH
	DROP TABLE #Tab; 
END CATCH
-- Drop the temparory table 
DROP TABLE #Tab;

 

Using SSMS Standard Reports:

We can also check the disk space usage report from SSMS. Connect to the SQL Server instance from SSMS Right click on Database Reports Standard Reports Top 4 options are related to disk usage reports that you can see from the below image.

D:\Users\703124718.INDGE\Desktop\SQLServer_Space_Usage.jpg

XP_CMDSHELL:

XP_CMDSHELL gives us more control on hosted windows server and we can execute shell commands to get the drive and space information. In most of the environments we could see that this option is disabled as there is a security risk when this option enabled and no proper control on system administrator accounts. If in case this option is enabled in your environment you can try capturing the DISK Space information. Here is an example for automated disk space report using XP_CMDSHELL.

EXEC xp_cmdshell 'wmic logicaldisk get size,freespace,caption';

PowerShell Scripts:

This is one of the best options to automate the Disk Space monitoring procedure. It provides more flexibility and provides more options in capturing DISK Space details.

Link1

Link2

Link3

Note: SQL Server Space Usage report can be automated in various ways, to quickly check the current status we can choose using the system stored procedures, for the report automation PowerShell script is the best option.

sql-server-space-usage-scripts is the Script file with all scripts.

The post SQL Server Space Usage appeared first on udayarumilli.com.

SQL Server Blocking Report

$
0
0

SQL Server Blocking Report

SQL Server Blocking Report

This post can help a SQL DBA / Developer to quickly find the SQL Server Blocking Report using T-SQL scripts. There are various ways to get the SQL Server Blocking Report but here we are going to discuss only on T-SQL scripts which can be handy for any DBA or Developer to quickly get the details. Usually we need not worry about the process blocking when it occurs occasionally for a short time periods but we can consider it’s as a critical problem when the same issue repeating multiple times or blocking exists for a long time. Below are the different ways to identify and retrieve SQL Server Blocking Report:

  • System Stored Procedures
  • DMV
  • Activity Monitor
  • SSMS Reports
  • SQL Server Profiler

Here is the link for the detailed information.

Script to Get SQL Server Blocking Report:

Execute the below script, capture the details and analyze these details to identify the root cause then we can provide the resolution based on the root cause.

SELECT
	CASE WHEN 
	CAST( LTRIM(RTRIM(s.blocked)) AS SMALLINT) > 0 
	THEN 'Waiting / Blocked' 
	ELSE 'Blocking' End 		AS 'Process_Type',
	LTRIM(RTRIM(s.spid))		AS 'SPID',
	LTRIM(RTRIM(s.blocked))		AS 'Blocked',
	LTRIM(RTRIM(s.cpu))		AS 'CPU', 
	db_name(LTRIM(RTRIM(s.dbid)))	AS 'DBName',
	LTRIM(RTRIM(s.login_time))	AS 'Login_Time', 
	LTRIM(RTRIM(s.last_batch))	AS 'Last_Batch',
	LTRIM(RTRIM(s.status))		AS 'Status',
	LTRIM(RTRIM(s.loginame))	AS 'LoginName', 
	LTRIM(RTRIM(s.hostname))	AS 'HostName', 
	LTRIM(RTRIM(s.program_name))	AS 'ProgramName',
	LTRIM(RTRIM(s.cmd))		AS 'CMD',
	LTRIM(RTRIM(EST.TEXT))		AS 'Full_Query',
	LTRIM(RTRIM(s.waittime))	AS 'Wait_Time',
	LTRIM(RTRIM(s.lastwaittype))	AS 'Wait_Type',
	LTRIM(RTRIM(s.waitresource))	AS 'Wait_Resource',
	LTRIM(RTRIM(s.cpu))		AS 'CPU_Time(MS)',
	LTRIM(RTRIM(s.physical_io))	AS 'Disk R/W',
	LTRIM(RTRIM(s.memusage))	AS 'Mem_Usage(Total_Pages)',
	LTRIM(RTRIM(s.open_tran))	AS 'NoOfOpenTran',
	LTRIM(RTRIM(s.nt_domain))	AS 'Windows_Domain',
	LTRIM(RTRIM(s.nt_username))	AS 'Windows_UserName'
FROM	sys.sysprocesses s
	CROSS APPLY sys.dm_exec_sql_text(s.sql_handle)EST
WHERE	spid in(select spid from sys.sysprocesses where blocked<>0) or
	spid in(select blocked from sys.sysprocesses);

 

Script to Get SQL Server Blocking Report – Detailed:

Above script can get the maximum information. But sometimes we can see that the blocking might occur between two stored procedures. In that case the above script returns the entire stored procedure code instead of the exact query. Below script can help us in identifying the exact SQL Statement that is blocked / blocking from the stored procedure.

SELECT 
	CASE WHEN 
	CAST( LTRIM(RTRIM(s.blocked)) AS SMALLINT) > 0 
	THEN 'Waiting / Blocked' 
	ELSE 'Blocking' End 		AS 'Process_Type',
	LTRIM(RTRIM(s.spid))		AS 'SPID',
	LTRIM(RTRIM(s.blocked))		AS 'Blocked',
	db_name(LTRIM(RTRIM(s.dbid)))	AS 'DBName',
	LTRIM(RTRIM(s.login_time))	AS 'Login_Time', 
	LTRIM(RTRIM(s.last_batch))	AS 'Last_Batch',
	LTRIM(RTRIM(s.status))		AS 'Status',
	LTRIM(RTRIM(s.loginame))	AS 'LoginName', 
	LTRIM(RTRIM(s.hostname))	AS 'HostName', 
	LTRIM(RTRIM(s.program_name))	AS 'ProgramName',
	LTRIM(RTRIM(s.cmd))		AS 'CMD',
	ER.[statement_start_offset]	AS 'Statement_Start',
	ER.[statement_end_offset]	AS 'Statement_End',
	EST.TEXT			AS 'Full_Query',	
	CASE
	 WHEN ER.[statement_start_offset] > 0 THEN
		CASE ER.[statement_end_offset]  
		   WHEN -1 THEN  
			  SUBSTRING(EST.TEXT, (ER.[statement_start_offset]/2) + 1, 2147483647) 
		   ELSE   
			  SUBSTRING(EST.TEXT, (ER.[statement_start_offset]/2) + 1, (ER.[statement_end_offset] - ER.[statement_start_offset])/2)   
		END  
	 ELSE  
		CASE ER.[statement_end_offset]  
		   WHEN -1 THEN  
			  RTRIM(LTRIM(EST.[text]))  
		   ELSE  
			  LEFT(EST.TEXT, (ER.[statement_end_offset]/2) +1)  
		END  
	END				AS 'Exact_Statement',
	LTRIM(RTRIM(s.waittime))	AS 'Wait_Time',
	LTRIM(RTRIM(s.lastwaittype))	AS 'Wait_Type',
	LTRIM(RTRIM(s.waitresource))	AS 'Wait_Resource',
	LTRIM(RTRIM(s.cpu))		AS 'CPU_Time(MS)',
	LTRIM(RTRIM(s.physical_io))	AS 'Disk R/W',
	LTRIM(RTRIM(s.memusage))	AS 'Mem_Usage(Total_Pages)',
	LTRIM(RTRIM(s.open_tran))	AS 'NoOfOpenTran',
	LTRIM(RTRIM(s.nt_domain))	AS 'Windows_Domain',
	LTRIM(RTRIM(s.nt_username))	AS 'Windows_UserName'
FROM	sys.dm_exec_requests ER 
	CROSS APPLY sys.dm_exec_sql_text(ER.[sql_handle]) EST  
	INNER JOIN sys.sysprocesses s ON ER.session_id = s.spid
WHERE	ER.session_id IN
	(SELECT spid FROM sys.sysprocesses WHERE blocked<>0
	UNION
	SELECT blocked FROM sys.sysprocesses) 
ORDER BY	ER.[session_id], ER.[request_id];

Here is the Script File: sql_server_blocking_report

The post SQL Server Blocking Report appeared first on udayarumilli.com.


SQL Server Backup and Restore Reports

$
0
0

SQL Server Backup and Restore Reports

sql server backup and restore reports

This post can help you to quickly find SQL Server Backup and Restore Reports from a given SQL Server instance. For a typical DBA a most common task is to check the latest backup and restore history for a database. We usually required this information while we are working on a RCA (Root Cause Analysis) to resolve a specific issue, to check the backup frequency or to check the last backup status details. Here are the quick T-SQL scripts which can help us in checking SQL Server Backup and Restore Reports.

SQL Server Backup History Report:

It captures the backup history for a given database (or all databases) based on the parameter @DBName. If @DBName is NULL then it get all databases backup history, if @DBName is assigned with a database name then it get the backup history for the given database.

/******************************************************************/
/***** Database Backup History Details ****************************/
/***** No Perameter Supplied - Get all details ********************/
/***** DBName- Retrieve Bkp info for given DB ***********/
/***** Uncomment Bkp_Type - Filter Backup History for given type **/
/******************************************************************/

DECLARE @DBName VARCHAR(200),
	@Bkp_Type VARCHAR(20);

-- Give a DB name then it gets only the given DB backup history.
-- Ex: @DBName = 'Master'
SET @DBName  = NULL

-- 'D' -- Full Backup; 'I' -- Differential Backup; 'L' -- Transaction Log Backup
-- Ex: @Bkp_Type = 'D'
SET @Bkp_Type = NULL;

SELECT	DISTINCT
	bs.database_name	AS 'DB_Name'
	, bs.backup_start_date	AS 'Bkp_Started_At'
	, bs.backup_finish_date	AS 'Bkp_Finished_At'
	, CONVERT(NVARCHAR(10),(bs.backup_finish_date-bs.backup_start_date),108)  AS 'Bkp_duration'
	, CASE 
		WHEN bmf.physical_device_name LIKE 'VN%' THEN 'TAPE DEVICE'
		ELSE UPPER(bmf.physical_device_name)
	  END			AS 'Bkp_location'
	, bs.type		AS 'Backup_Type'
	, CASE 
		WHEN bs.type = 'D' THEN 'FULL'
		WHEN bs.type = 'I' THEN 'Differential'
		ELSE 'Transactional_Log' 
		END		AS 'Backup_Type_Desc'
	, CAST((bs.backup_size/(1024.00*1024.00)) AS DECIMAL(15,2))		AS 'Bkp_Size (MB)'
	, CAST((bs.backup_size/(1024.00*1024.00*1024.00)) AS DECIMAL(15,2))	AS 'Bkp_Size (GB)'
	, bms.software_name	AS 'Backup_Software'
	, CASE 
		WHEN bms.is_compressed = 1  THEN 'Yes'
		WHEN bms.is_compressed = 0 THEN 'No'
	  END			AS 'Is_Compressed'
	 ,CASE 
		WHEN bms.is_password_protected = 1 THEN 'Yes'
		WHEN bms.is_password_protected = 0 THEN 'No'
	  END			AS 'Is_Password_Protected'
FROM	msdb..backupset bs
	JOIN msdb..backupmediafamily bmf ON bs.media_set_id = bmf.media_set_id
	JOIN msdb..backupmediaset bms ON bms.media_set_id = bmf.media_set_id
WHERE	bs.database_name = ISNULL(@DBName,bs.database_name)  AND 
	bs.type = ISNULL(@Bkp_Type,bs.type)
ORDER BY bs.backup_start_date desc, bs.database_name;

 

SQL Server Backup Missing Report:

This is a handy script to quickly identify the missing backup details from a given SQL Server instance. With the default parameter settings the script can list the databases with no full backup from last 24 hours. We can customize this using the given parameters.

/************************************************************/
/*************** Missing Backup Report **********************/
/***** We can change parameters to customize the report *****/ 
/************************************************************/

DECLARE @Backup_Type VARCHAR(20),
	@Days SMALLINT;

-- D - Full; I - Differential; L- Transaction Log
SET @Backup_Type = 'D'; 

-- Number of days 
-- Ex: -1: Reports all DB without backup in last 24 hours
-- Ex: -30 - Reports all DB without any backup from last 30 Days
SET @Days = -1;

--Database with no Backup in the given period
SELECT 
	SERVERPROPERTY('Servername')	AS 'Server_Name', 
	bs.database_name		AS 'Database_Name', 
	MAX(bs.backup_finish_date)	AS 'Last_Backup_Date', 
	DATEDIFF(hh, MAX(bs.backup_finish_date), GETDATE()) AS 'Backup_Age(Hrs)'
FROM	msdb.dbo.backupset bs
WHERE   bs.type = @Backup_Type  
GROUP BY	bs.database_name 
HAVING		(MAX(bs.backup_finish_date) < DATEADD(DD, @Days, GETDATE()))  
UNION
-- Databases with no backup history 
SELECT      
	SERVERPROPERTY('Servername')	AS 'Server_Name', 
	sd.name				AS 'Database_Name', 
	NULL				AS 'Last_Backup_Date',  
	9999				AS 'Backup_Age(Hrs)' 
FROM	master.dbo.sysdatabases sd
	LEFT JOIN msdb.dbo.backupset bs ON sd.name  = bs.database_name 
WHERE	bs.database_name IS NULL AND sd.name <> 'tempdb' 
ORDER BY	bs.database_name;

SQL Server Restore History Report:

This script can quickly get the restore history from the given SQL Server instance. We can customize the script by passing the specific database name to the parameter @DBName. By default it captures restore information for all databases in the given instance.

/*****************************************************/
/*** Database Restore History Report *****************/
/*** By Default it captures all DB Restore Info ******/
/*** Give a DB name for the parameter @DBName ********/
/*****************************************************/
-- Give a database name to get restore info for a specific DB
DECLARE @DBName VARCHAR(200);
SET @DBName = NULL
SELECT
	rh.destination_database_name		AS 'Destination_DB_Name',
	rh.restore_date				AS 'Restore_Date',
	rh.user_name				AS 'DB_Restored_By',
	CASE rh.restore_type 
	WHEN 'D' THEN 'Full DB Restore'
	WHEN 'F' THEN 'File Restore'
	WHEN 'G' THEN 'Filegroup Restore'
	WHEN 'I' THEN 'Differential Restore'
	WHEN 'L' THEN 'Log Restore'
	WHEN 'V' THEN 'Verify Only'
	END					AS 'Type_Of_Restore',
	bs.server_name				AS 'Baclup_Taken_From',
	bs.user_name				AS 'Backup_Taken_By',
	bs.database_name			AS 'Source_DB_Name',
	bs.backup_start_date			AS 'Backup_Date',
	bmf.physical_device_name		AS 'File_Path'	
FROM	msdb.dbo.restorehistory rh
	INNER JOIN	msdb.dbo.backupset bs	ON	rh.backup_set_id = bs.backup_set_id
	INNER JOIN	msdb.dbo.backupmediafamily bmf	ON	bs.media_set_id = bmf.media_set_id 
WHERE	rh.destination_database_name = ISNULL(@DBName,rh.destination_database_name)
ORDER BY	Restore_Date	DESC;

 

SQL Server Backup and Restore Status Report:

This script is useful to get the estimated completion time and percentage completed time for currently running backup or restore operation on a given SQL Server instance.

/******************************************************************/
/****  Database Backup / Restore percentage Completion Report *****/
/******************************************************************/

USE MASTER
GO
SELECT
     Command		AS 'Command',
     ds.Text		AS 'Query',
     start_time		AS 'StartTime',
     percent_complete	AS 'Percentage_Completed',
     CAST(((DATEDIFF(s,start_time,GetDate()))/3600)as varchar(10))+' hour(s), '
       + CAST((DATEDIFF(s,start_time,GetDate())%3600)/60 as varchar(10))+'min, '
       + CAST((DATEDIFF(s,start_time,GetDate())%60)as varchar(10))+' sec' 
			AS 'Running_Time',
     CAST((estimated_completion_time/3600000)as varchar(10))+' hour(s), '
       + CAST((estimated_completion_time %3600000)/60000 as varchar(10))+'min, '
       + CAST((estimated_completion_time %60000)/1000 as varchar(10))+' sec' 
			AS 'Estimated_Time_To_Go',
      DATEADD(second,estimated_completion_time/1000,getdate()) 
			AS 'Estimated_Completion_Time'
FROM  SYS.DM_EXEC_REQUESTS R
      CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) ds
WHERE
      R.Command in ('RESTORE DATABASE', 'BACKUP DATABASE', 'RESTORE LOG', 'BACKUP LOG');

 

T-SQL Script Files:

1_sqlserver_backup_report

2_sqlserver_backup_missing_report

3_sqlserver_database_restore_history

4_sqlserver_backup_restore_status_report

The post SQL Server Backup and Restore Reports appeared first on udayarumilli.com.

SQL The One

$
0
0

SQL The One

A Book for SQL Server Interview Preparation

SQL The One

Hello there, finally we are presenting the book “SQL The One”. This is the one place guide for SQL Server Interview preparation. The core intention is to help the maximum number of SQL DBA’s and SQL Developers to get their dream job and settle in one of the finest database platform Microsoft SQL Server.

Q. Who can be benefited from “SQL The One”?

Ans:

This book can be helpful for any SQL Server professional who is looking for an interview preparation guide. The book is mainly designed for SQL Server DBA and SME but there are categories which can be helpful for all SQL Server Professionals.

Q. How we collected these questions?

Ans:

All questions answered in “SQL The One” are asked in interviews conducted at various Multi-National Companies across the world. MNC’s included the top product and service oriented organizations, majority of the interviews are from India, USA, Canada, Singapore and UAE.

Q. What is the best selling point in “SQL The One”?

Ans:

Performance Tuning, HA & DR and Scenario based questions and answers are the best selling point for this book “SQL The One”.

Q. What are the top 3 points that attracts a typical SQL Server Person?

Ans:

1. This book has been prepared from the interview prospective;

2. It covers wide range of SQL Server versions starting from 2005 to 2016

3. All interview questions have been categorized.

Q. What is the Salient Features of Book “SQL The One”?

Ans:

  • All interview questions are asked in various MNC
  • More than 1000 real time questions with answers
  • More than 250 questions on SQL Server Performance Tuning
  • Covers all SQL Server HA & DR features
  • Lots of scenario based questions
  • Covers SQL Server Versions 2005, 2008, 2008 R2, 2012, 2014 and 2016
  • More than 300 questions on SQL Server HA & DR features
  • Questions are categorized
  • In-depth explanations
  • An Interview Experience with Microsoft
  • Useful as a Quick reference guide for SQL DBA & Developer

Q. How to buy this book?

Ans:

This book will be available on India and international e-Stores. But now the Pre-Sale is on at Amazon.in with the discounted price.

Q. What is the actual release date?

Ans:

From Dec 17th the title will be listed on all e-Stores. But now the Pre-Sale is enabled on Amazon.in for Indian readers.

Summary:

As the reader of this book, for us you are the most important critic and commentator. We value your opinion and want to know what we’re doing right, what we could do better and any other words of wisdom you’re willing to pass our way. You can comment or email me directly to let me know your valuable feedback.

sqltheone@gmail.com

udayarumilli@gmail.com

Book Available on Amazon.in

Book Trailer

The post SQL The One appeared first on udayarumilli.com.

Top 10 SQL Server Backup and Restore Interview Questions

$
0
0

Top 10 SQL Server Backup and Restore Interview Questions

SQL THE ONE

Top 10 SQL Server Backup and Restore Interview Questions

There are total 57 questions are answered under SQL Server Backup and Restore category in the book “SQL THE ONE”. In this chapter we can see questions and answers on Backup and Restore and scenarios. Below are the Top 10 SQL Server Backup and Restore Interview Questions:

1. What are some common reasons why database restores fail?

2. How to rebuild the system databases?

3. What are the new features added for Backup and Restore on SQL Server 2014 / 2016?

4. Is there any performance impact if we enable the backup encryption?

5. Why don’t we just backup SQL Server Database Files (MDF, LDF and NDF) using Windows backup tool instead of SQL Server native backup?

6. You are leading a DBA team and one of your team members came to you and reported that he has executed an UPDATE command without WHERE CLAUSE on production database. Now that entire table has got updated with the wrong data. How do you handle the situation?

7. Let’s say we have a situation. We are restoring a database from a full backup. The restore operation ran for 2 hours and failed with an error 9002 (Insufficient LOGSPACE). And the database went to suspect mode. How do you troubleshoot this issue?

8. Have you ever encounter the issue “media family on device is incorrectly formed”? If yes what is the reason and how you resolved it?

9. One of our database full backup size 300 GB, usually my differential backup size varies between 300 MB and 5 GB, one day we were surprised to see the differential backup size was increased to 250 GB? What might be the reason any idea?

10. How much time it takes to perform a full backup and restore of 500 GB database by using a third party tool LITESPEED and native method using SQL Server Backup / Restore option?

Summary:

These Top 10 SQL Server Backup and Restore Interview Questions are the sample questions randomly collected from the book “SQL THE ONE”.

Please share your feedback and comments on below comments section or reach me on sqltheone@gmail.com. We wish you all the best for the next interview.

Here you can find more Details about the book “SQL THE ONE”.

The post Top 10 SQL Server Backup and Restore Interview Questions appeared first on udayarumilli.com.

Top 10 SQL Server Log Shipping Interview Questions

$
0
0

Top 10 SQL Server Log Shipping Interview Questions

SQL THE ONE

Top 10 SQL Server Log Shipping Interview Questions

There are total 34 questions are answered under SQL Server Log Shipping category in the book “SQL THE ONE”. In this chapter we can see questions and answers on Log Shipping and scenarios. Below are the Top 10 SQL Server Log Shipping Interview Questions:

1. Can you be able to technically explain the log shipping process?

2. Have you ever observed the location of log shipping related SQL Agent jobs?

3. From your experience what are the most common reasons that causes log shipping failures?

4. What is WRK file in log shipping?

5. I have installed SQL Server 2012 Express edition. Is it possible to configure log shipping?

6. I have configured log shipping for my database in standby mode as our business required the secondary should be available for reporting users. Now can you tell me what the major challenge that we need to face?

7. What is TUF file in log shipping?

8. How to perform tail log backup on primary server in case of failover?

9. Can I shrink log shipped database log file?

10. Truncate is a non-logged operation right? If I issues TRUNCATE TABLE on primary server does it effects on secondary database? If yes how?

Summary:

These Top 10 SQL Server Log Shipping Interview Questions are the sample questions randomly collected from the book “SQL THE ONE”.

Please share your feedback and comments on below comments section or reach me on sqltheone@gmail.com. We wish you all the best for the next interview.

Here you can find more Details about the book “SQL THE ONE”.

The post Top 10 SQL Server Log Shipping Interview Questions appeared first on udayarumilli.com.

Top 10 SQL Server Database Mirroring Interview Questions

$
0
0

Top 10 SQL Server Database Mirroring Interview Questions

SQL THE ONE

Top 10 SQL Server Database Mirroring Interview Questions

There are total 43 questions are answered under SQL Server Database Mirroring category in the book “SQL THE ONE”. In this chapter we can see questions and answers on Database Mirroring and scenarios. Below are the Top 10 SQL Server Database Mirroring Interview Questions:

1. What are the added improvements for database mirroring in SQL Server 2016?

2. What is transaction safety in database mirroring?

3. In database mirroring what are the events happens when an automatic failover occurred?

4. In your production environment mirroring is configured for one of the premium database and you are asked to cross check the configuration. Can you elaborate what are all the options you would check for?

5. Can we be able to automate the Database Mirroring monitor process? If yes can you explain in simple steps?

6. We have recently upgraded to SQL Server 2016 and we would like to configure database mirroring for one of our production database. As a lead DBA what is your suggestion on this?

7. Can we configure mirroring when principal and mirror databases are in different domains?

8. When the network connection fails for 3 hours between principal and mirror database, also we have been performing log backups on principal server. When we perform log backups on principal server this truncates the log then how can it be synchronize with the mirror database once the network connect is re-established?

9. What happens if we lose Mirror / Witness or both?

10. We have configured Database Mirroring with automatic fail over mode. When an auto fail over happens from principal to mirror what about the applications which are connecting to the principal server? Does it possible to implement the automation that allows application to connect mirror server if the given principal server doesn’t respond? If yes how it is possible?

Summary:

These Top 10 SQL Server Database Mirroring Interview Questions are the sample questions randomly collected from the book “SQL THE ONE”.

Please share your feedback and comments on below comments section or reach me on sqltheone@gmail.com. We wish you all the best for the next interview.

Here you can find more Details about the book “SQL THE ONE”.

The post Top 10 SQL Server Database Mirroring Interview Questions appeared first on udayarumilli.com.

Viewing all 145 articles
Browse latest View live