Categories
SQL

SQL : AUTO STATS Troubleshooting

SQL : AUTO STATS Troubleshooting

Statistics for Query Optimization are objects that contain statistical information about the distribution of values in one or more columns of a table or indexed view. The query optimizer uses these statistics to estimate the cardinality, or number of rows, in the query result. These cardinality estimates enable the query optimizer to create a high-quality query plan.

To view the indexes and their last update time use the following command:

 SELECT
        o.name AS Table_Name
       ,i.name AS Index_Name
       ,STATS_DATE(o.id,i.indid) AS Date_Updated

FROM
        sysobjects o JOIN
        sysindexes i ON i.id = o.id

WHERE
        xtype = ‘U’ AND
        i.name IS NOT NULL

ORDER BY
        o.name ASC
       ,i.name ASC

To update statistic:

  •     On a single index: UPDATE STATISTICS [Table_Name][INDEX_NAME]
  •     On a single table: UPDATE STATISTICS[TABLE_NAME]
  •     On the entire Database: EXEC sp_updatestats

 

 

Categories
SQL

SQL : Common Wait Types

SQL : Common SQL Wait Types

Using the command DBCC SQLPERF(WAITSTATS) you can get real time totals of all wait types within an SQL instance. The table below outlines some common wait types and what to look for when troubleshooting them. 

NETWORKIO

Waiting on network I/O completion. Waiting to read or write to a client on the network. Check NIC saturation.

LCK_x

Check for memory pressure, which causes more physical I/O, thus prolonging the duration of transactions and locks. View the following counter: Lock Wait Time (ms)

CXPACKET

On OLTP (On-line Transaction Processing) systems, if CXPACKET wait-types account for more than 5% of total locks SQL CPU parallelism can cause performance degradation. On Data WH systems if CXPACKET waits are 10% or greater then it is likely that parallelism is the cause of the performance issues.

 

Look to reduce parallelism or even disable it on OLTP systems. OLTP systems best practice is to disable it completely.

I/O_COMPLETION

Indicates an I/O bottleneck. Identify disk bottlenecks, using IoStallMS values and Perfmon counters:

  • PhysicalDisk: Disk Sec/read, Disk Sec/write, Disk Queues
  • SQL Server Buffer Manager: Page Life Expectancy, Checkpoint Pages/sec, Lazy Writes/sec

·         SQL Server Access Methods for correct indexing: Full Scans/sec, Index Searches/sec

  • See the Memory: Page Faults/sec

 

Identify IoStallMS values using the following query:

/* Find DB ID */

SELECT DB_ID(‘SQLTraceDB’) as [Database ID]

/* Display IoStallMS */

SELECT * FROM ::fn_virtualfilestats(7,-1)

EXCHANGE

Check for parallelism using sp_configure ‘max degree of parallelism’. Disable parallelism by setting 1 or change to # of CPU’s /2.

ASYNC_I/O_COMPLETION

Waiting for asynchronous I/O requests to complete. Identify disk bottlenecks, using IoStallMS values and Perfmon Counetrs:

  • PhysicalDisk: Disk Sec/read, Disk Sec/write, Disk Queues
  • SQL Server Buffer Manager: Page Life Expectancy, Checkpoint Pages/sec, Lazy Writes/sec

·         SQL Server Access Methods for correct indexing: Full Scans/sec, Index Searches/sec

  • See the Memory: Page Faults/sec

 

Identify IoStallMS values using the following query:

/* Find DB ID */

SELECT DB_ID(‘SQLTraceDB’) as [Database ID]

/* Display IoStallMS */

SELECT * FROM ::fn_virtualfilestats(7,-1)

 

Full Scans/Sec
This counter should always be captured. It shows how often a table index is not being used and results in sequential I/O. This is defined as the number of unrestricted full scans. These can be either base table or full index scans. Missing or incorrect indexes can result in reduced performance because of too high disk access.

 

Page Life Expectancy

According to Microsoft, 300 seconds is the minimum target for page life expectancy. If the buffer pool flushes your pages in less than 300 seconds, you probably have a memory problem.

 

WAITFOR

Check common SQL Stored Procedures for WAIT FOR DELAY statements. This is a fixed delay within a stored procedure.

PAGELATCH_x

Usually indicates cache contention issues

PAGEIOLATCH_x

Usually indicates I/O issues. Check disk subsystem.

OLEDB

See Disk secs/Read and Disk secs/Write. If Disk secs/Read is high, add additional I/O bandwidth, balance I/O across other drives.

 

To get the Transact-SQL statement involved in OLEDB waits:

DECLARE @Handle binary(20)

SELECT @Handle = sql_handle FROM sysprocesses

WHERE waittype = 0x0042

SELECT * FROM ::fn_get_sql(@Handle)

 

Categories
SQL

SQL : Troubleshooting Waits

SQL Troubleshooting Wait Time

The following SQL script will export the output of ‘DBCC SQLPERF(WAITSTATS)’ into a temporary table named #waitstats.

CREATE TABLE #waitstats
(
    [Wait Type]        nvarchar(32) not null,
    [Requests]         float not null,
    [Wait Time]        float not null,
    [Signal Wait Time] float not null
)

INSERT INTO #waitstats EXEC(‘dbcc sqlperf(waitstats)’)

SELECT * FROM #waitstats
ORDER BY ‘Wait Time’ DESC

To delete the temporary table use the command:

DROP TABLE #waitstats 

Categories
SQL

SQL : Troubleshooting Index Fragmentation

The following SQL script will identify fragmented indexes and automaticallyrebuild them. Note that this should not be run duringbusy periods/production hours and should only be run against databases which are not partitioned:

{code lang:sql showtitle:false lines:false hidden:false}declare @tablename varchar (128)
declare @id int
declare @Cnt smallint
declare @nrc_mask int
declare tables cursor for
select TABLE_SCHEMA + ‘.’ + TABLE_NAME
from INFORMATION_SCHEMA.TABLES
where TABLE_TYPE = ‘BASE TABLE’

create table #spt_space
( aidi int,
[rows] int null,
reserved dec(15) null,
AUTOSTATS char(2) null,
[Last Updated] datetime
)
open tables
/*
** Set NORECOMPUTE mask
*/
set @nrc_mask = 16777216

fetch next
from tables
into @tablename
while @@fetch_status = 0
begin

select @id = object_id(@tablename)

insert into #spt_space (aidi, reserved)
select @id, sum(reserved)
from sysindexes
where indid in (0, 1, 255)
and id = @id
update #spt_space set [rows] = i.[rows]
from #spt_space inner join sysindexes i
on #spt_space.aidi = i.id
where i.indid =indid and i.id = @id

update #spt_space set [AUTOSTATS] =
case (si.status & @nrc_mask)
when @nrc_mask then ‘OFF’
else ‘ON’
end,
[Last Updated] = stats_date(#spt_space.aidi, si.indid)
from sysindexes si inner join #spt_space
on #spt_space.aidi = si.id
where si.id = @id AND — Table
si.indid BETWEEN 1 AND 254 — Skip HEAP/TEXT index
fetch next
from tables
into @tablename
end

— Close and deallocate the cursor
close tables
deallocate tables

CREATE TABLE #fraglist (
ObjectName CHAR (255),
ObjectId INT,
IndexName CHAR (255),
IndexId INT,
Lvl INT,
CountPages INT,
CountRows INT,
MinRecSize INT,
MaxRecSize INT,
AvgRecSize INT,
ForRecCount INT,
Extents INT,
ExtentSwitches INT,
AvgFreeBytes INT,
AvgPageDensity INT,
ScanDensity DECIMAL,
BestCount INT,
ActualCount INT,
LogicalFrag DECIMAL,
ExtentFrag DECIMAL)

CREATE TABLE #bigtables (i int NOT NULL IDENTITY(1,1), tablename varchar(128))
INSERT #bigtables(tablename)
SELECT object_name(aidi) as tablename
FROM #spt_space
–WHERE rows >= 100000

SELECT * FROM #spt_space
DROP TABLE #spt_space
SELECT @Cnt = count(*) FROM #bigtables

DECLARE @DTime datetime
Set @DTime = GETDATE()

SET @id = 1
WHILE @id <= @Cnt
BEGIN
SELECT @tablename = tablename FROM #bigtables WHERE i = @id
INSERT INTO #fraglist
EXEC (‘DBCC SHOWCONTIG (”’ + @tablename + ”’)
WITH TABLERESULTS, ALL_INDEXES, NO_INFOMSGS, FAST’)
SET @id = @id + 1
END

SELECT ObjectName, IndexName, CountPages, ExtentSwitches, BestCount, ActualCount, LogicalFrag FROM #fraglist ORDER BY LogicalFrag DESC
DROP Table #bigtables
DROP table #fraglist{/code}

Use the following code to rebuild indexes that are 10% or more fragmented (you can change this threshold by modifying the figure highlighted in RED):

{code lang:sql title:”SQL Query – Fix Fragmentation” lines:false hidden:false}declare @tablename varchar (128) 

declare @id int 
declare @Cnt smallint 
declare @nrc_mask int 
declare tables cursor for 
select TABLE_SCHEMA + ‘.’ + TABLE_NAME 
from INFORMATION_SCHEMA.TABLES 
where TABLE_TYPE = ‘BASE TABLE’ 

create table #spt_space 
( aidi int, 
[rows] int null, 
reserved dec(15) null, 
AUTOSTATS char(2) null, 
[Last Updated] datetime 

open tables 
/* 
** Set NORECOMPUTE mask 
*/ 
set @nrc_mask = 16777216 

fetch next 
from tables 
into @tablename 
while @@fetch_status = 0 
begin 

select @id = object_id(@tablename) 

insert into #spt_space (aidi, reserved) 
select @id, sum(reserved) 
from sysindexes 
where indid in (0, 1, 255) 
and id = @id 
update #spt_space set [rows] = i.[rows] 
from #spt_space inner join sysindexes i 
on #spt_space.aidi = i.id 
where i.indid =indid and i.id = @id 

update #spt_space set [AUTOSTATS] = 
case (si.status & @nrc_mask) 
when @nrc_mask then ‘OFF’ 
else ‘ON’ 
end, 
[Last Updated] = stats_date(#spt_space.aidi, si.indid) 
from sysindexes si inner join #spt_space 
on #spt_space.aidi = si.id 
where si.id = @id AND — Table 
si.indid BETWEEN 1 AND 254 — Skip HEAP/TEXT index 
fetch next 
from tables 
into @tablename 
end 

— Close and deallocate the cursor 
close tables 
deallocate tables 

CREATE TABLE #fraglist ( 
ObjectName CHAR (255), 
ObjectId INT, 
IndexName CHAR (255), 
IndexId INT, 
Lvl INT, 
CountPages INT, 
CountRows INT, 
MinRecSize INT, 
MaxRecSize INT, 
AvgRecSize INT, 
ForRecCount INT, 
Extents INT, 
ExtentSwitches INT, 
AvgFreeBytes INT, 
AvgPageDensity INT, 
ScanDensity DECIMAL, 
BestCount INT, 
ActualCount INT, 
LogicalFrag DECIMAL, 
ExtentFrag DECIMAL) 

CREATE TABLE #bigtables (i int NOT NULL IDENTITY(1,1), tablename varchar(128)) 
INSERT #bigtables(tablename) 
SELECT object_name(aidi) as tablename 
FROM #spt_space 
–WHERE rows >= 100000 

SELECT * FROM #spt_space 
DROP TABLE #spt_space 
SELECT @Cnt = count(*) FROM #bigtables 

DECLARE @DTime datetime 
Set @DTime = GETDATE() 

SET @id = 1 
WHILE @id <= @Cnt 
BEGIN 
SELECT @tablename = tablename FROM #bigtables WHERE i = @id 
INSERT INTO #fraglist 
EXEC (‘DBCC SHOWCONTIG (”’ + @tablename + ”’) 
WITH TABLERESULTS, ALL_INDEXES, NO_INFOMSGS, FAST’) 
SET @id = @id + 1 
END 

SELECT ObjectName, IndexName, CountPages, ExtentSwitches, BestCount, ActualCount, LogicalFrag FROM #fraglist ORDER BY LogicalFrag DESC 

DROP Table #bigtables 

/* ********************************* */
/* Perform the REINDEX – NOTE This will lock the Table in which the index resides */
/* ********************************* */

DECLARE @objectid int, @indexname varchar(200), @frag decimal, @SQL varchar(500)
DECLARE indexes CURSOR FOR
SELECT ObjectName, ObjectId, IndexName, LogicalFrag
FROM #fraglist
WHERE LogicalFrag >= 10
AND INDEXPROPERTY (ObjectId, IndexName, ‘IndexDepth’) > 0;
— Open the cursor.
OPEN indexes;
— Loop through the indexes.
FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexname, @frag;
WHILE @@FETCH_STATUS = 0
BEGIN;
PRINT ‘Executing DBCC DBREINDEX (‘ +RTRIM(@tablename) + ‘,”’ + RTRIM(@indexname)
+ ”’) – LogicalFrag Currently: ‘ + RTRIM(CONVERT(VARCHAR(15),@frag)) + ‘%’;

SELECT @SQL = ‘DBCC DBREINDEX (‘ +RTRIM(@tablename) + ‘,”’ + RTRIM(@indexname) + ”’)’
EXEC (@SQL)

FETCH NEXT
FROM indexes
INTO @tablename, @objectid, @indexname, @frag;
END;
— Close and deallocate the cursor.
CLOSE indexes;
DEALLOCATE indexes;
— Delete the temporary table.
DROP TABLE #fraglist;
GO

EXEC sp_updatestats

{/code} 

 
Categories
Exchange Server 2007

Exchange 2007 : Error: The Exchange server address list service failed to respond

Exchange 2007 :  Error: The Exchange server address list service failed to respond

During a DR simulation I recently came across the following error on an Exchange 2007 CCR cluster:

Error: The Exchange server address list service failed to respond. This could be because of an address list or email address policy configuration error.

The issue was that the System Attendandt Service had lost connection to the domain controller to which it was using. For some reason it did not automatically onnect to another DC. All other Exchange Functions were working, but management of users, groups and system objects was impossible.

To resolve this issue simply restart the Exchange System Attendant Instance service for the cluster using the Cluster Administrator tool.

This will allow the service to re-attch to an available Domain Controller.

Categories
Windows Server 2003

Windows NTFS Compression : Decompress Entire Volume

Windows NTFS Filesystem Compressiopn: Uncompressing An Entire Volume

I recently came across a perofrmance issue on an old x86 WinTel server, The issue, after regular diagnosis showed no obvious cause, appeared to be that the root drive was compressed in order to increase available disk space.

The one problem with NTFS compression is this: 

‘When you open a compressed file, Windows automatically decompresses it for you, and when you close the file, Windows compresses it again. This process may decrease your computer performance'(http://support.microsoft.com/kb/307987)

Using the COMPACT command line tool it is possible to both identify all compressed files within a folder and its subfolders. This can be acheived using the command:

compact /I /S

To uncompress all files (assuming you have enough free disk space to do so) you can use the following command to uncompress all compressed files within the current folder and all subdirectories:

compact /U /I /S

After disabling file system compression on the root drive the server is now performing as-expected.

Categories
Exchange Server 2007

Exchange 2007 OWA Access To Other Users Mailboxes

Granting Mailbox Access to Other Users Mailbox via OWA

OWA will does not work with inherited mailbox database/server permissions for other users mailbox access. Permissions must be specifically granted on each mailbox. The Powershell scripts will enable access to users users mailboxes ia OWA for a chosen user or group.
 

Save the the following powershell script to a bew .ps1 file, modifying the appropriate username/group name as highlighted in red.

# Set-Full Mailbox Permissions on all Mailboxes in Org for EU Mailbox Admins
#
#This is required for OWA mailbox access as OWA does not support inherited permissions on mailboxes
#
Add-PSSnapin Microsoft.Exchange.Management.Powershell.Admin -erroraction silentlyContinue
$userAccounts = get-mailbox -resultsize unlimited
ForEach ($user in $userAccounts)
{
add-MailboxPermission -identity $user -user “Exchange Mailbox Admins” -AccessRights FullAccess
}

Alternately you can grant access to all mailboxes from OWA for a single Mailbopx Database using the following script, change the mailbox database path as applicable for your environment:

# Set-Full Mailbox Permissions on all Mailboxes in Org for EU Mailbox Admins
#
#This is required for OWA mailbox access as OWA does not support inherited permissions on mailboxes
#

Add-PSSnapin Microsoft.Exchange.Management.Powershell.Admin -erroraction silentlyContinue
$userAccounts = get-mailbox -resultsize unlimited -Database “MYSERVER\SG2\Mailbox Database
ForEach ($user in $userAccounts)
{
add-MailboxPermission -identity $user -user “Exchange Mailbox Admins” -AccessRights FullAccess
}

Categories
Windows Server 2003

Resetting iLO Administrator password on HP BL/Proliant Servers

Resetting iLO Administrator password on HP BL/Proliant Servers

The process below will allow you to reset the ILO/ILO2 Administrator account password from a Windows Operating system running on the server.

Obtain the HP Online ILO configuration tool from here: http://cb-net.co.uk/downloads/HPONCFG.rar

Execute the following command:

 HPONCFG.exe /f Administrator_reset_pw.xml


 

 

Categories
Exchange Server 2007

Exchange 2007 Split Permissions

Exchange 2007 Split Permissions

During the migration/centralisation project I’ve been involved in recently, one of our challenges was delegation of Exchange object management on a per-site or per-country level.

Our goal was to allow local IT teams at each site to create and manage user mailboxes and distribution groups, without having the ability to affect users at other sites and also allowing for centralised management of hardware, backups etc. Now Exchange 2007 doesn’t cater for this permission model out-of-the-box. This type of permissions configuration is referred to as a ‘split permissions’ model.

The Exchange Management Shell allows granular control of permissions at both the AD and Mailbox level. Initial investigation led me to the following command for user management:

Remove-ADPermission -Identity “OU=DE,DC=mydom,DC=com” -User “MYDOM\DE Mailbox Admins” -AccessRights ReadProperty, WriteProperty -Properties Exchange-Information, Exchange-Personal-Information, legacyExchangeDN, displayName, adminDisplayName, displayNamePrintable, publicDelegates, garbageCollPeriod, textEncodedORAddress, showInAddressBook, proxyAddresses, mail 

Users of the DE Mailbox Admins group were also granted rights to Create and Delete User Objects on the “OU=DE,DC=mydom,DC=com” container and all sub-containers.

This however did not provide management of Distribution Groups. In order to achieve this the following shell command is necessary:

ADPermission -Identity “OU=DE,DC=mydom,DC=com” -User “MYDOM\DE Mailbox Admins” -AccessRights GenericAll -ChildObjectTypes msExchDynamicDistributionList

The Exchange Management Tools come with a script which integrates the above commands into a single command:

ConfigureSplitPerms.ps1 -user “DE Mailbox Admins” -identity “OU=DE,DC=mydom,DC=com”

Finally, the only remaining permission required in our environment was the delegation of Public Folder administrative rights. Again, the following shell command can be used to delegate these on a public folder and all of its sub-folders:

Get-PublicFolder “\DE\” –recurse  | Add-PublicFolderAdministrativePermission -User “DE Mailbox Admins” -AccessRights AllExtendedRights -Inheritance SelfAndChildren


Update 12/01/2010: In order to delegate the “Manage Full Mailbox Access” and “Manage Send As Permissions” use the following ExchangeShell command:

Add-ADPermission -identity (Get-MailboxDatabase “\\“).distinguishedName -user “” -ExtendedRights ms-Exch-Store-Admin

Categories
Exchange Server 2007

Exchange 2007 550 5.7.1 Unable To Relay

Exchange 2007 550 5.7.1 ‘Unable To Relay’

In order to create an SMTP Receive Connector in Exchange 2007 which will allow anonymous SMTP servers within your network to connect and relay mail you will need to complete the following configuration steps.

First, create you Receive Connector as follows, ensuring the ‘Anonymous users’ option is selected inn the ‘Permissions groups’ tab.

The ‘Network’ configuration of this connector limits access to a partiicular server thus preventing unauthorised relay of email:

Finally, the most important stage of this configuration, execute the following shell command using the Exchange Management Sell (EMS), replacing ‘HT_Server_Name’ with the machine name of the Hub Transport Server you configured the new recieve connetcor on:

Normal 0 false false false EN-GB X-NONE X-NONE MicrosoftInternetExplorer4 /* Style Definitions */ table.MsoNormalTable {mso-style-name:”Table Normal”; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:””; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:”Calibri”,”sans-serif”; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:”Times New Roman”; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:”Times New Roman”; mso-bidi-theme-font:minor-bidi;}

Get-ReceiveConnector “HT_Server_Name\Server Relay Receive Connector” | Add-ADPermission -User “NT AUTHORITY\ANONYMOUS LOGON” -ExtendedRights “ms-Exch-SMTP-Accept-Any-Recipient”