Delete items of SharePoint recycle bin efficiently using - SPRecycleBinQuery
Recently I had a strange query from one of my clients. The client had the OOB SharePoint recycle bin. Somehow the number of items in his recycle bin became more than 500,000. So as we know SharePoint has a scheduled cleanup job that can be scheduled to run once a day, that cleans up items that go beyond the retention period. So now when this scheduled job runs, it tries to delete around 10,000 items and hangs the SharePoint server. On digging it further I found that the SharePoint locks the database tables and hence hangs the SharePoint Server. This happens as the batch process is trying to delete 10,000 in one go.
In normal scenarios we would try to either delete items one by one – by iterating through all the items of the list and call the item’s delete method or use the deleteall() method. Both the ways have problems as they are very inefficient and memory consuming. Technique one would load the entire item collection in memory and hence inefficient and technique 2 for deleteall would behave in the same manner as the Scheduled job.
So the only solution would be to query the Recycle Bin to get say 1000 items and then delete the items one by one. But there is one more challenge here. Normally the data in SharePoint (stored in the DB) is displayed/represented as a List and you can use SPQuery API to query the lists. Recycle Bin is of special type as the recycle bin is a page that brings data directly from the Database so SPQuery can’t be used.
On researching in the SDK I found a useful API - SPRecycleBinQuery (With very little documentation on usage). This API queries the Recycle Bin and you can set the maximum row limit hence it is very efficient as well. Following code can be used to delete the items in such a scenario:
<Code>
try
{
Console.WriteLine("Please specify the Site Collection Url: (Please click enter after typing)");
SPSite site = new SPSite(Console.ReadLine());
SPWeb web = site.RootWeb;
SPRecycleBinQuery q = new SPRecycleBinQuery();
Console.WriteLine("Specify the number of records to be deleted (Click enter after typing)");
q.RowLimit = Int32.Parse(Console.ReadLine());
q.OrderBy = SPRecycleBinOrderBy.Default;
SPRecycleBinItemCollection itemColl = web.GetRecycleBinItems(q);
foreach (SPRecycleBinItem item in itemColl)
{
Guid[] id = new Guid[1];
id[0] = item.ID;
itemColl.Delete(id);
}
Console.WriteLine("Deletion was successful (Click enter to exit)");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Exception Message" + ex.Message);
}
</Code>
Comments
Anonymous
November 27, 2008
PingBack from http://blog.a-foton.ru/index.php/2008/11/27/delete-items-of-sharepoint-recycle-bin-efficiently-using-sprecyclebinquery/Anonymous
November 02, 2010
Hi Varun, I am trying something similar in my customer's farm. If I may ask, how long did it take for your script to purge 500,000 items? thanksAnonymous
January 25, 2011
Do you know how to deal with the second stage recycle bin? Cheers/Anonymous
March 18, 2011
For second stage recycle bin set following criteria for SPRecycleBinQuery. q.ItemState = SPRecycleBinItemState.SecondStageRecycleBin;