Pergunta

Nossa instalação do SharePoint 2007 possui uma Lixeira de primeiro estágio particularmente imensa.Escrevi um script do PowerShell há algum tempo que exclui itens antigos.Apenas por diversão, isso está postado abaixo.

ATUALIZAÇÃO2: Temos mais de 42.500.000 registros na tabela Lixeira no banco de dados de conteúdo!!
Descobri que nosso trabalho BDLC que foi agendado antes de eu entrar na equipe estava bombeando tantos dados na tabela RecycleBin que nem mesmo o SharePoint consegue gerenciá-los adequadamente sem atingir o tempo limite.Mesmo nosso script agendado só pode remover 1.000 registros a cada 30 minutos.Faça as contas e sinta pena de mim.Há tantos registros que agora você não consegue nem impor cotas sem que o SharePoint expire.Parece que teremos que congelar a exclusão de registros no BDLC

ATUALIZAÇÃO1: Executei meu script do PowerShell para excluir cada item e executei o SQL Profiler para descobrir proc_DeleteRecycleBinItem está sendo executado, o que afeta várias tabelas, então vamos manter um script do PowerShell agendado para executar/relatar a cada N minutos.

Temos mais de 38.500.000 registros na tabela Lixeira no banco de dados de conteúdo!!

Acredito que a razão pela qual isso é tão imenso é porque temos o BDLC da Layer2 sincronizando dados de outros sistemas e está reciclando registros excluídos.Além disso, é tão grande que mesmo o trabalho de timer nativo do SharePoint não consegue controlá-lo e atinge o tempo limite...

Eu sei que levaria um tiro da Máfia do SharePoint perguntando isso, mas...alguém já excluiu linhas do real RecycleBin tabela em um banco de dados de conteúdo do SharePoint?O nosso é 15430792 KB (14,7 GB).

Estou ciente de que a Microsoft abandonará o suporte se você modificar um banco de dados de conteúdo.Por favor, não poste isso como resposta.É claro que essa não é a melhor prática.Esta questão é claramente:alguém já tentou isso?...

Estou simplesmente procurando uma maneira mais rápida de limpar a Lixeira.Você pode ver meus scripts abaixo, então obviamente estou tentando estabelecer alguma manutenção com ele.A lixeira fica tão grande que leva uma eternidade para que os scripts sejam executados porque há muitos dados.

Nossos dados de usuário têm, na verdade, 203790168 KB (194,3 GB) e escrevi um script PS para obter arquivos grandes para poder gerenciar esse tamanho também.Isso, também abaixo, para contribuir de volta ao éter.

Além disso, temos um BDLC (com ferramenta de terceiros da Layer2) que sincroniza os dados entre SQL.Acredito que esse trabalho exclui muitos dados regularmente, o que torna a tabela RecycleBin enorme.

Acho que a resposta à minha própria pergunta pode ser ...algo como...agende uma tarefa para executar o script de manutenção que já escrevi...hmmm...

function RemoveOldItems-SPFirstStageRecycleBin([string]$url, [int]$rowlimit, [int]$days) 
{
    $siteCollection = New-Object Microsoft.SharePoint.SPSite($url);  
    $recycleQuery = New-Object Microsoft.SharePoint.SPRecycleBinQuery;
    $recycleQuery.ItemState = [Microsoft.SharePoint.SPRecycleBinItemState]::FirstStageRecycleBin
    $recycleQuery.OrderBy = [Microsoft.SharePoint.SPRecycleBinOrderBy]::DeletedDate
    $recycleQuery.RowLimit = $rowlimit

    $recycledItems = $siteCollection.GetRecycleBinItems($recycleQuery);

    $count = $recycledItems.Count;

    for($i = 0; $i -lt $count; $i++){
        $age = ((Get-Date) - $recycledItems[$i].DeletedDate).Days;
        if($age -gt $days){
            $g = New-Object System.Guid($recycledItems[$i].ID);
            $recycledItems.Delete($g);
        }
    }

    $siteCollection.Dispose()
}



function Get-DocInventory() {
    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
    $farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
    foreach ($spService in $farm.Services) {
        if (!($spService -is [Microsoft.SharePoint.Administration.SPWebService])) {
            continue;
        }

        foreach ($webApp in $spService.WebApplications) {
            if ($webApp -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]) { continue }

            foreach ($site in $webApp.Sites) {
                foreach ($web in $site.AllWebs) {
                    foreach ($list in $web.Lists) {
                        if ($list.BaseType -ne "DocumentLibrary") {
                            continue
                        }
                        foreach ($item in $list.Items) {
                            $data = @{
                                "Web Application" = $webApp.ToString()
                                "Site" = $site.Url
                                "Web" = $web.Url
                                "list" = $list.Title
                                "Item ID" = $item.ID
                                "Item URL" = $item.Url
                                "Item Title" = $item.Title
                                "Item Created" = $item["Created"]
                                "Item Modified" = $item["Modified"]
                                "Size (kb)" = $item.File.Length/1KB
                                "Size (gb)" = $item.File.Length/1GB

                            }

                            Write-Host $item.Url -ForegroundColor DarkGray

                            # Only add files larger than 100 MB
                            if($item.File.Length -gt 100MB){
                                Write-Host $site.Url + $item.Url -ForegroundColor Red
                                New-Object PSObject -Property $data
                            }
                        }
                    }
                    $web.Dispose();
                }
                $site.Dispose()
            }
        }
    }
}
#Get-DocInventory | Out-GridView
Get-DocInventory | Export-Csv -NoTypeInformation -Path D:\Logs\inventory.csv


$jobName = "Get Large Lists"

function Get-LargeLists() {
    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

    #create stop watch
    [System.Diagnostics.Stopwatch] $sw;
    $sw = New-Object System.Diagnostics.Stopwatch
    $sw.Start()

    $lists = @()
    $reportSiteUrl = "http://my-site.gov/sites/applications/reporting/"
    $reportListUrl = $reportSiteUrl + "Lists/Large%20Lists/"
    $farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
    foreach ($spService in $farm.Services) {
        if (!($spService -is [Microsoft.SharePoint.Administration.SPWebService])) {continue}

        foreach ($webApp in $spService.WebApplications) {
            if ($webApp -is [Microsoft.SharePoint.Administration.SPAdministrationWebApplication]) {continue}

            foreach ($site in $webApp.Sites) {
                foreach ($web in $site.AllWebs) {
                    foreach ($list in $web.Lists) {
                        # only add items that have 1000 items or more
                        if($list.ItemCount -le 99){continue}

                        # create new object
                        $o = New-Object Object
                        Add-Member -InputObject $o -MemberType NoteProperty -Name SiteCollectionUrl -Value $list.ParentWeb.Site.RootWeb.Url
                        Add-Member -InputObject $o -MemberType NoteProperty -Name ListURL -Value ($list.ParentWeb.Url + "/" + $list.RootFolder.Url)
                        Add-Member -InputObject $o -MemberType NoteProperty -Name Title -Value $list.Title
                        Add-Member -InputObject $o -MemberType NoteProperty -Name Description -Value $list.Description
                        Add-Member -InputObject $o -MemberType NoteProperty -Name ItemCount -Value $list.ItemCount

                        # add object to $list global array
                        $lists += $o
                    }
                    $web.Dispose()
                }
                $site.Dispose()
            }
        }
    }

    #export array to csv
    $lists | Export-Csv D:\Logs\large_lists.csv -NoTypeInformation -Force

    #connect to SharePoint Site and List
    $s = New-Object Microsoft.SharePoint.SPSite($reportSiteUrl)
    $w = $s.openweb()
    $l = $w.GetList($reportListUrl)

    #clear SharePoint List
    $query = New-Object Microsoft.SharePoint.SPQuery
    $query.ViewAttributes = "Scope='Recursive'"
    $query.Query = ""

    $items = $l.GetItems($query)
    $items | % { $l.GetItemById($_.Id).Delete() }

    #export to SharePoint List
    $lists | ForEach{
        $item = $l.Items.Add()
        $item["Title"] = $_.Title
        $item["SiteCollectionUrl"] = $_.SiteCollectionUrl

        $u = New-Object Microsoft.SharePoint.SPFieldUrlValue
        $u.Description = "Link"
        $u.Url = $_.ListURL
        $item["URL"] = $u

        $item["Description"] = $_.Description
        $item["Count"] = $_.ItemCount
        $item.Update()
    }

    $w.Dispose()
    $s.Dispose()

    #stop timer and log event
    $sw.Stop()

    C:\_scripts\sp_log.ps1 -jobName $jobName -message "Reported large lists on SharePoint Farm." -type "Success" -duration $sw.Elapsed.Seconds -linkTitle "Link" -linkUrl "http://my-site.gov/sites/applications/reporting/Lists/Large%20Lists/"
}

#catch exceptions
trap [Exception]{
    C:\_scripts\sp_log.ps1 -jobName $jobName -message  $_.Exception.Message -type "Error" -duration $sw.Elapsed.Seconds -linkTitle "Link" -linkUrl "http://my-site.gov/sites/applications/reporting/Lists/Large%20Lists/"
}

Get-LargeLists
Foi útil?

Solução

Executei meu script do PowerShell para excluir cada item e executei o SQL Profiler para descobrir proc_DeleteRecycleBinItem está sendo executado, o que afeta várias tabelas, então vamos manter um script do PowerShell agendado para executar/relatar a cada N minutos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top