INTRODUCTION
Out of nowhere my SharePoint 2013 site (and has happened on my other 2010 farm, too) is timing out on a particular sub-site. The whole site still loads but when I go to this particular sub-site, I just got timeout.
After an intensive research I found out that when you publish a page in SharePoint, there is this bug that may corrupt the navigation items and end up creating duplicates. If you check in the database (simply go to the content database of your SP site in SQL Management Studio then run SELECT * FROM NavNodes), you will see thousands of duplicates for a particular page. Mine created about ~1000 duplicates.
This what causes the timeout. If you look in the log file you will see something like below:
==
07/16/2014 12:09:19.85 w3wp.exe (0x4B4C) 0x4A50 SharePoint Foundation Database d0d6 High System.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 106) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows) at System.Data.SqlClient.SqlData… 6dd9b59d-4588-918f-63ef-39784f1643db
07/16/2014 12:09:19.85* w3wp.exe (0x4B4C) 0x4A50 SharePoint Foundation Database d0d6 High …Reader.TryReadInternal(Boolean setTimeout, Boolean& more) at System.Data.SqlClient.SqlDataReader.Read() at Microsoft.SharePoint.SPSqlClient.ExecuteQueryInternal(Boolean retryfordeadlock) at Microsoft.SharePoint.SPSqlClient.ExecuteQuery(Boolean retryfordeadlock) ClientConnectionId:6dd9b59d-4588-918f-63ef-39784f1643db 6dd9b59d-4588-918f-63ef-39784f1643db
07/16/2014 12:09:19.85 w3wp.exe (0x4B4C) 0x4A50 Web Content Management Publishing 8vzf High PortalSiteMapProvider was unable to fetch children for node at URL: /About-Us, message: Value cannot be null. Parameter name: node.Parent, stack trace: at Microsoft.SharePoint.Publishing.CommonUtilities.ConfirmNotNull(Object value, String parameterName) at Microsoft.SharePoint.Publishing.Navigation.SPNavigationSiteMapNode.UpdateSPNavigationNode(SPNavigationNode node, SPNavigationNode previous, String name, String url, String description, String target, String audience, Boolean forceCreate) at Microsoft.SharePoint.Publishing.Navigation.SPNavigationSiteMapNode.UpgradeDraftSPNavigationNode(SPNavigationNode draftNode, SPNavigationNode previous) at Microsoft.SharePoint.Publishing.Navigation.PortalWebSiteMapNode.<>c__Displa… 6dd9b59d-4588-918f-63ef-39784f1643db
07/16/2014 12:09:19.85* w3wp.exe (0x4B4C) 0x4A50 Web Content Management Publishing 8vzf High …yClass3.<UpdateNavigationNodes>b__1() at Microsoft.Office.Server.Utilities.Security.SecurityUtilities.RunWithAllowUnsafeUpdates(SPWeb web, Action secureCode) at Microsoft.SharePoint.Publishing.Navigation.PortalWebSiteMapNode.PopulateNavigationChildrenInner(NodeTypes includedTypes) at Microsoft.SharePoint.Publishing.Navigation.PortalWebSiteMapNode.PopulateNavigationChildren(NodeTypes includedTypes) at Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapNode.GetNavigationChildren(NodeTypes includedTypes, NodeTypes includedHiddenTypes, Boolean trimmingEnabled, OrderingMethod ordering, AutomaticSortingMethod method, Boolean ascending, Int32 lcid) at Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapNode.GetNavigationChildren(NodeTypes includedTypes, NodeTypes incl… 6dd9b59d-4588-918f-63ef-39784f1643db
07/16/2014 12:09:19.85* w3wp.exe (0x4B4C) 0x4A50 Web Content Management Publishing 8vzf High …udedHiddenTypes, OrderingMethod ordering, AutomaticSortingMethod method, Boolean ascending, Int32 lcid) at Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapNode.GetNavigationChildren(NodeTypes includedHiddenTypes) at Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider.GetChildNodes(PortalSiteMapNode node, NodeTypes includedHiddenTypes) 6dd9b59d-4588-918f-63ef-39784f1643db
==
RESOLUTION
The resolution to this issue is actually to remove the duplicates but you can only do this from Powershell. From researching online I happened to find this Technet forum post:
http://blogs.technet.com/b/saantil/archive/2013/03/31/sps-2013-error-connecting-to-subsite-an-unexpected-error-has-occurred.aspx
There is a Powershell script that you can use but for easier use I paste it below. Put this in a .ps1 file then simply run it using the SP 2013 Powershell. It will ask you for your root site collection URL.
To make it easier, you can also download the script here. Rename to .ps1.
param
(
$url = $(Read-Host -Prompt “SiteCollection Url”)
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$Logfile = “duplicates_log.txt”
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
function tryDeleteNode
{
param($node,$dictionary,$nodeCollection)
$title = $node.Title
if(!$dictionary.ContainsKey($title))
{
$dictionary.Add($node.Title,$node.Url)
}
else
{
if($dictionary[$title] -eq $node.Url)
{
if($node.Children.Count -eq 0)
{
echo ” -> Deleting Duplicate Node: $title”
$nodeCollection.Delete($node)
$global:didDelete= $true
$temp = (get-date).ToString() +”;”+ ($site.Url) +”;”+ ($title)
echo “$temp”
LogWrite $($temp)
}
else
{
echo ” -> Dupe Node $title has children, Skipping…”
}
}
else
{
echo ” -> Duplicate title $title found, but mismatched link, Skipping…”
}
}
}
function deleteNodesRecurse
{
$nodes = @{}
foreach($node in $quickLaunch)
{
$childNodes = @{}
foreach($child in $node.Children)
{
tryDeleteNode -node $child -dictionary $childNodes -nodeCollection $node.Children
}
tryDeleteNode -node $node -dictionary $nodes -nodeCollection $quickLaunch
}
}
function deleteGlobalNodesRecurse
{
$nodes = @{}
foreach($node in $gnavNodes)
{
$childNodes = @{}
foreach($child in $node.Children)
{
tryDeleteNode -node $child -dictionary $childNodes -nodeCollection $node.Children
}
tryDeleteNode -node $node -dictionary $nodes -nodeCollection $gnavNodes
}
}
$sitecoll = Get-SPSite $url
write-host “SiteCollection: ” $sitecoll.URL
foreach ($site in $sitecoll.AllWebs)
{
write-host ” -> Site: ” $site.URL
do
{
$quickLaunch = $site.Navigation.QuickLaunch
$global:didDelete = $false
deleteNodesRecurse
$pub= [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($site)
$gnavNodes = $pub.Navigation.GlobalNavigationNodes;
deleteGlobalNodesRecurse
}
while($global:didDelete)
$site.Dispose()
}
$sitecoll.Dispose()
Hope this helps,
Tommy