मैं सभी डेटाबेस के लिए सभी फ़ाइलों को कैसे जल्दी से सिकोड़ता हूं?


47

SQL सर्वर (2008 में इस मामले में) मैं सभी फ़ाइलों को लॉग इन और डेटा दोनों को कैसे छोटा कर सकता हूं, उदाहरण के लिए सभी डेटाबेस के लिए? मैं एसएसएमएस के माध्यम से जा सकता हूं और प्रत्येक पर राइट क्लिक कर सकता हूं और कार्य चुन सकता हूं -> सिकोड़ें, लेकिन मैं तेजी से कुछ ढूंढ रहा हूं।

मैंने कुछ "डेटाबेस बनाएँ" स्क्रिप्ट्स लिखीं और यह भूल गया कि उनके पास चूक के लिए गुब्बारे के आकार थे, और इस परियोजना पर इन फ़ाइलों के लिए बहुत अधिक स्थान आरक्षित करने की आवश्यकता नहीं है।

जवाबों:


55

जब आप GUI से "कार्य -> ​​हटना" करते हैं तो यह वास्तव DBCC SHRINKDATABASEमें पर्दे के पीछे एक आदेश जारी करता है। कोशिश करो। जब संवाद बॉक्स आता है, तो "ओके" बटन पर क्लिक न करें। इसके बजाय, "स्क्रिप्ट" बटन पर क्लिक करें। आप एक क्वेरी विंडो में कमांड देखेंगे। संयोजन के साथ sys.dat डेटाबेस पर छोड़ें (मास्टर और msdb को छोड़ दें), और आप सभी डेटाबेस को सिकोड़ने के लिए एक स्क्रिप्ट बना सकते हैं।

उदाहरण के लिए (jcolebrand की टिप्पणी से लिया गया):

SELECT 
      'USE [' + d.name + N']' + CHAR(13) + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) 
FROM 
         sys.master_files mf 
    JOIN sys.databases d 
        ON mf.database_id = d.database_id 
WHERE d.database_id > 4;

उस क्वेरी के आउटपुट को कॉपी करें और अपनी सभी फ़ाइलों को सिकोड़ने के लिए इसे चलाएं।


1
ठीक है, मैं मैं मैं क्या चाहते हैं (बदसूरत लेकिन करता है लगता है बस क्या मैं यह करने की जरूरत है) SELECT 'USE [' + d.name + N']' + CHAR(13) + CHAR(10) + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) FROM sys.master_files mf JOIN sys.databases d ON mf.database_id = d.database_id WHERE d.database_id > 4लेकिन यह पता लगाना मुझे एक नई समस्या दे दी है। एक और सवाल पोस्ट करने के लिए बंद।
jcolebrand

गंभीरता से। @ सैंडी का जवाब देखें। sp_MSForEachDB (इसमें "टेबल"
स्पोक

3
और यहाँ उन सभी के लिए अनिवार्य अनुस्मारक है जो इसे पढ़ रहे हैं: अपने डेटाबेस को सिकोड़ना खतरनाक है।
निक चामास

1
ऑफ़लाइन डीबी को फ़िल्टर करने से यह और बेहतर हो जाएगा। :-)
तिलोउंट

1
@TiloBunt के साथ सहमत, पूरी स्थिति बेहतर है जहां d.database_id> 4 और d.state_desc = 'ONLINE';
मौरो

23

Sql स्टेटमेंट की एक सिंगल लाइन के बारे में कैसे?

निचे दिए गए sql statement को निष्पादित करने से पहले कृपया यह बहुत ही रोचक ब्लॉग पोस्ट पढ़ें ।

EXEC sp_MSForEachDB 'DBCC SHRINKDATABASE (''?'' , 0)'

6
कोड की एक भी लाइन जरूरी नहीं है कि वह सही तरीके से काम न करे। कृपया इन पोस्टों को भी पढ़ें, क्योंकि sp_msforeachdb डेटाबेस को छोड़ सकता है और आपको चेतावनी नहीं दे सकता है: sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/… और mssqltips.com/sqbservertip/2201/…
आरोन बर्ट्रेंड

15

DBCC SHRINKDB (और इसके चचेरे भाई SHRINKFILE) बेहद धीमे हैं, क्योंकि उस कोड में बहुत सारी थ्रेडेड निष्पादन चल रहा है।

एक डेटाबेस फ़ाइल को सिकोड़ने का एक बहुत तेज़ तरीका यह है:

  • डेटाबेस में एक नया फ़ाइलग्रुप आवंटित करें
  • इस फाइलग्रुप को उतना बड़ा बनाएं जितना इसे होना है ( sp_spaceusedकेवल यह निर्धारित करने के लिए उपयोग करें कि कितना बड़ा है)
  • इस नए फ़ाइल समूह के सभी अनुक्रमितों को फिर से बनाएँ
  • पुराना फ़ाइलग्रुप छोड़ें

क्योंकि इंडेक्स रीबॉन्ड्स बड़े पैमाने पर समानांतर हैं, इस तकनीक के परिणामस्वरूप अक्सर डेटाबेस में बहुत तेजी से सिकुड़न होती है। बेशक, यह आपको नए फ़ाइल समूह के लिए अतिरिक्त स्थान की आवश्यकता है, जबकि प्रक्रिया चल रही है। हालाँकि, उदाहरण में सबसे बड़ा फ़ाइलग्रुप रखने के लिए आपको नए फ़ाइल समूह में केवल पर्याप्त स्थान चाहिए (जैसा कि आप जाने के साथ ही स्थान पुनः प्राप्त करेंगे)।

इस तकनीक में प्रक्रिया में अपने अनुक्रमितों को डीफ़्रैग्मेन्ट करने का अतिरिक्त लाभ भी है।


आप एक महत्वपूर्ण हिस्सा भूल गए। अनुक्रमणिका अनुक्रमणिका ऐसी चीज़ों को स्थानांतरित नहीं करेगी जिनमें संग्रहीत कार्यविधियाँ, विचार, कार्य, समानार्थक शब्द, ढेर इत्यादि शामिल हैं
जेफ मोदेन

और उन लोगों के लिए कोई जगह नहीं है जिसकी आपको परवाह करनी चाहिए। उन्हें प्राथमिक फाइलग्रुप में भी निवास करना है, आप वास्तव में उन्हें स्थानांतरित नहीं कर सकते (और न ही आपको चाहिए)
थॉमस केजर

13

मैंने अनुरोध किया है कि केवल लॉग को सिकोड़ने के लिए मैंने थोड़ी क्वेरी की है:

set nocount on  
SELECT 
      'USE [' + d.name + N']' + CHAR(13) + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) 
FROM 
         sys.master_files mf 
    JOIN sys.databases d 
        ON mf.database_id = d.database_id 
WHERE d.database_id > 4 and mf.type_desc = 'LOG'

"जल्दी से सभी फाइलों को सिकोड़ें, लॉग और डेटा दोनों"
dezso

2
मैं इस की तलाश कर रहा था, और जब मैं आपका उत्तर देखूंगा, तो यह डबल पोस्ट करने वाला था। प्रत्यक्ष उत्तर नहीं, लेकिन बहुत प्रासंगिक और मेरे मामले के लिए हाजिर।
गोमुशी 12

2

नीचे दिए गए कोड, गैर-सिस्टम डेटाबेस की एक सूची प्राप्त करें, डेटाबेस को आसानी से सेट करें और फिर फ़ाइल को सिकोड़ें। मैंने इस कोड को SQL एजेंट जॉब का उपयोग करते हुए कुछ SQL सर्वर बॉक्स में रखा है, जहाँ स्पेस हमेशा एक समस्या है। हर हफ्ते शनि / सूर्य की रात को, यह कुछ ही घंटों में (डेटाबेस के आकार के आधार पर) सभी डेटाबेस को चलाने और सिकोड़ने लगता है।

declare @db varchar(255)
declare c cursor for
select name from sys.databases where is_read_only=0 and state=0
  and name not in ('master','model','tempdb','msdb')
open c
fetch c into @db
while @@fetch_status=0
begin
  exec SP_dboption @db,'trunc. log on chkpt.','true' 
  DBCC shrinkdatabase (@db)
  fetch next from c into @db
end
close c
deallocate c

0

मास्टर, मॉडल, msdb को छोड़कर सभी लॉग फ़ाइलों को सिकोड़ें:

EXEC sp_MSforeachdb '
DECLARE @sqlcommand nvarchar (500)
IF ''?'' NOT IN (''master'', ''model'', ''msdb'')
BEGIN
USE [?]
SELECT @sqlcommand = ''DBCC SHRINKFILE (N'''''' + 
name
FROM [sys].[database_files]
WHERE type_desc = ''LOG''
SELECT @sqlcommand = @sqlcommand + '''''' , 0)''
EXEC sp_executesql @sqlcommand
END'

0

यह एक के बाद एक एसक्यूएल बयानों के माध्यम से पुनरावृति करने के लिए एक कर्सर का उपयोग करके, ऊपर दिए गए उत्तर का विस्तार करता है। यह इमराह के जवाब जितना छोटा नहीं है, लेकिन यह कर्सर के भीतर लूप के भीतर अतिरिक्त तर्क के लिए अनुमति देता है।

SELECT 
    'USE [' 
    + databases.name + N']' 
    + CHAR(13) 
    + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' 
    + masterFiles.name 
    + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) 
    + CHAR(10) 
    + CHAR(13) 
    + CHAR(10)                                                                  AS sqlCommand
INTO
    #shrinkCommands
FROM 
    [sys].[master_files] masterFiles 
    INNER JOIN [sys].[databases] databases ON masterFiles.database_id = databases.database_id 
WHERE 
    databases.database_id > 4; -- Exclude system DBs


DECLARE iterationCursor CURSOR

FOR
    SELECT 
        sqlCommand 
    FROM 
        #shrinkCommands

OPEN iterationCursor

DECLARE @sqlStatement varchar(max)

FETCH NEXT FROM iterationCursor INTO @sqlStatement

WHILE (@@FETCH_STATUS = 0)
BEGIN
    EXEC(@sqlStatement)
    FETCH NEXT FROM iterationCursor INTO @sqlStatement
END

-- Clean up
CLOSE iterationCursor
DEALLOCATE iterationCursor
DROP TABLE #shrinkCommands

0

हम दोहरा सकते हैं SHRINKDBऔर SHRINKFILEगतिशील रूप से सभी डेटाबेस के लिए:

while @DBID<=@MaxDBID
begin
  -- Used Dynamic SQL for all databases.
  Set @SQL ='Use '+@DBName+ ' '+Char(10)
  Set @SQL += 'DBCC SHRINKFILE('+@Filename+',5)' +Char(10)
  Set @SQL += 'DBCC SHRINKDATABASE('+@DBName+')'+Char(10)

  --#6 Increment DBid for looping over all databases
  Set @DBID = @DBID+1
  Select @DBName = DBName, @Filename=DBFileName from #DBNames where [dbid] = @DBID and type_Desc = 'LOG'
  Print (@SQL)
  Exec (@SQL)
end

आप इस लेख में विवरण पा सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.