मुझे अपने डेटाबेस को सिकोड़ने की आवश्यकता है - मैंने अभी बहुत सारे स्थान खाली कर दिए हैं


35

यह प्रश्न यहाँ विभिन्न रूपों में पूछा जाता है, लेकिन प्रश्न यह है:

मुझे पता है कि एक डेटाबेस सिकुड़ना जोखिम भरा है। इस मामले में, मैंने इतना डेटा हटा दिया है और मैं इसे फिर कभी उपयोग नहीं करूंगा।

  • मैं अपने डेटाबेस को कैसे छोटा कर सकता हूं? मैं कौन सी फाइलें सिकोड़ता हूं?
  • ऐसा करते समय मेरे विचार क्या होने चाहिए?
  • क्या मुझे कुछ भी करना चाहिए?
  • यदि यह एक बड़ा डेटाबेस है तो क्या होगा? क्या मैं इसे छोटे वेतन वृद्धि में सिकोड़ सकता हूं?

2
मैं कुछ समय पहले इससे जूझ रहा था: dba.stackexchange.com/questions/47310/… मैंने अपने उत्तर में अपने अनुभव को संक्षेप में बताने की कोशिश की
Csaba Toth

जवाबों:


30

कुछ शुरुआती कैविट्स:

  1. यह आम तौर पर एक सबसे खराब व्यवहार करने के लिए कहा जाता है कभी एक उत्पादन डेटाबेस या डेटा फ़ाइल हटना (लॉग फ़ाइलों के रूप में एक और मुद्दा है इस सवाल के बारे में वार्ता)। मैं लोगों को सलाह देता हूं कि वे अपने डेटाबेस को इस तरह ब्लॉग पोस्ट्स में न सिकोड़ें जहां मैं "राइट-साइजिंग" और अच्छी प्लानिंग के बारे में बात करता हूं। मैं वहां अकेला नहीं हूं ( पॉल रैंडल , ब्रेंट ओजर , सिर्फ एक जोड़े को और अधिक लिंक प्रदान करने के लिए)। कोई डेटा फ़ाइल या डेटाबेस टुकड़े अनुक्रमित सिकुड़ते, आपके सिस्टम पर एक नाली हो सकता है धीमी गति से और अपने संसाधनों पर श्रमसाध्य है और सिर्फ एक बुरी बात करने के लिए, है आम तौर पर
  2. इस मामले में, हम सभी जानते हैं कि जोखिम वहाँ है, हम इससे निपटने के लिए तैयार हैं, लेकिन हमने बहुत सी जगह खाली कर दी है जिसे हम जानते हैं कि हमें फिर कभी ज़रूरत नहीं होगी। तो इस विशिष्ट प्रकार के मामले में - सिकुड़ना हमारे विकल्पों में से एक के रूप में बहुत मायने रखता है।

यदि आपने चिंताओं और जोखिमों के बारे में पढ़ा है और आपको अभी भी इस सिकुड़न की आवश्यकता है क्योंकि आपने महत्वपूर्ण मात्रा में स्थान खाली कर दिया है, तो उम्मीद है कि इस उत्तर के बाकी हिस्से आपकी मदद करेंगे। लेकिन जोखिमों पर विचार करें।

दो मुख्य दृष्टिकोण हैं यहां दो पर विचार करें:

1.) सिकोड़ें हां, वास्तविक सिकुड़ते हैं - DBCC SHRINKFILEइसके बजाय का उपयोग करने पर विचार करें DBCC SHRINKDATABASE, आपके पास सिकुड़ गया और कैसे हो जाता है पर अधिक नियंत्रण है। यह सुनिश्चित करने के लिए कुछ प्रदर्शन में गिरावट का कारण होगा - यह एक बड़ा ऑपरेशन है जो बहुत सारे IO कर रहा है। आप संभावित रूप से कर सकते हैं से बार-बार सिकुड़ने वाले लक्ष्य आकार के साथ दूर हो सकते हैं जो उत्तरोत्तर छोटे हो जाते हैं।

यह उपरोक्त DBCC SHRINKFILEलिंक में "ए।" उदाहरण है .. एक डेटाफाइल को इस उदाहरण में 7MB लक्ष्य आकार तक सिकुड़ा जा रहा है। यह प्रारूप आपके डाउनटाइम विंडो को अनुमति देने के लिए बार-बार सिकुड़ने का एक अच्छा तरीका है। मैं विकास पर परीक्षण में यह देखने के लिए करूंगा कि प्रदर्शन कैसा दिखता है और उत्पादन में अपेक्षित समय निर्धारित करने के लिए आप एक वेतन वृद्धि पर जा सकते हैं या कितना कम कर सकते हैं। यह एक ऑनलाइन ऑपरेशन है - आप इसे डेटाबेस सिकुड़ने वाले सिस्टम तक पहुंचने वाले उपयोगकर्ताओं के साथ चला सकते हैं, लेकिन प्रदर्शन में गिरावट होगी, लगभग गारंटी। इसलिए मॉनिटर करें और देखें और देखें कि आप सर्वर पर क्या कर रहे हैं, एक डाउनटाइम विंडो या लाइटर गतिविधि की अवधि, आदर्श रूप से चुनें।

USE YourDatabase;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO

हमेशा याद रखें: - हर बार जब आप अपने अनुक्रमित टुकड़े को छोटा करते हैं और एक अनुक्रमणिका का पुनर्निर्माण करना चाहिए यदि आप लंबे समय तक विखंडू में सिकुड़ते जा रहे हैं। यदि आप इसे एक विंडो में पूरा नहीं कर सकते हैं तो आप अब हर बार लागत लगा रहे हैं।

2.) नया डेटाबेस - आप एक नया डेटाबेस बना सकते हैं और उसमें डेटा स्थानांतरित कर सकते हैं। आपको खाली डेटाबेस को स्क्रिप्ट करना होगा और यह सभी कीज़, इंडेक्स, ऑब्जेक्ट्स, प्रॉक्सेस, फ़ंक्शंस आदि होंगे और फिर इसमें डेटा माइग्रेट करेंगे। आप इसके लिए स्क्रिप्ट लिख सकते हैं या आप Red Gate या अन्य विक्रेताओं से SQL डेटा तुलना जैसे टूल का उपयोग कर सकते हैं। यह आपके पक्ष में अधिक सेटअप कार्य, अधिक विकास और परीक्षण है, और आपके पर्यावरण के आधार पर आपके डाउनटाइम विंडो को भी उड़ा सकता है, लेकिन विचार करने के लिए एक विकल्प।

जब मुझे किसी डेटाबेस को सिकोड़ने के लिए मजबूर किया जाता है यदि यह मेरा वातावरण था, तो मैं डेटा फ़ाइल में उचित / विषम मात्रा में सफेद स्थान छोड़ना चाहूंगा क्योंकि मुझे डिस्क हॉग होना पसंद है और भविष्य / अप्रत्याशित विकास के लिए तैयार रहना पसंद है। इसलिए अगर हम अभी-अभी अंतरिक्ष का अधिकांश हिस्सा हटाते हैं, तो मैं ठीक-ठाक स्थान दे दूंगा, लेकिन मैं उन लोगों पर कभी विश्वास नहीं करूंगा "लेकिन यह फिर कभी नहीं बढ़ेगा" और अभी भी कुछ छोड़ दें व्हाइट स्पेस । जिस मार्ग से मैं जाऊँगा वह शायद ( आह) है) हटना दृष्टिकोण है अगर मेरे पास छोटी डाउनटाइम विंडो थी और खाली डीबी बनाने और डेटा को माइग्रेट करने की जटिलता को उकसाना नहीं चाहता था। इसलिए मैं इसे समय-समय पर कई गुना बढ़ाता हूं (मुझे लगता है कि देव और वांछित आकार में मेरे परीक्षण के आधार पर कितनी बार सोचा था। उत्तरोत्तर एक छोटे फ़ाइल आकार को चुनना) और फिर अनुक्रमणिका का पुनर्निर्माण करना .. और फिर मैंने ' d ने कभी किसी को यह नहीं बताया कि मैं अपना डेटाबेस सिकुड़ गया हूं ;-)


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

क्या कोई व्यक्ति NOTRUNCATE और TRUNCATEONLY के निहितार्थ की व्याख्या कर सकता है, जाहिर है कि बाद वाले पृष्ठों को पुनर्व्यवस्थित नहीं करते हैं और इसलिए सूचकांक विखंडन का कारण नहीं बनता है?
डेविड गार्सिया

4
  1. मैं अपने डेटाबेस को कैसे छोटा कर सकता हूं? मैं कौन सी फाइलें सिकोड़ता हूं? : आप फ़ाइलों को अलग-अलग कर सकते हैंDBCC SHRINKFILE कमांड आप । यह आपके सर्वर पर निर्भर करता है कि आपके डेटाबेस में कितनी फाइलें हैं। एक साधारण डेटाबेस में एक डेटाबेस फ़ाइल और एक लेनदेन लॉग फ़ाइल होती है।
  2. ऐसा करते समय मेरे विचार क्या होने चाहिए?: हटना आपके सूचकांक के विखंडन को प्रभावित करता है, तीसरा बिंदु देखें। यह भी ध्यान दें कि आप डेटाबेस फ़ाइल को एक आकार में सिकोड़ना नहीं चाहते हैं जो कि न्यूनतम संभव है, क्योंकि वास्तविक दुनिया के वातावरण में यह वैसे भी बढ़ेगा। इसलिए मैं आकार (आपके उदाहरण में आपने 7 मेगाबाइट दिया) को इस तरीके से ट्यून करूँगा कि आप डेटाबेस फ़ाइल के भीतर 10% -20% मुक्त स्थान छोड़ देंगे, क्योंकि यह उत्पादन वातावरण में वैसे भी भरा होगा, और आप कर सकते हैं कुछ ऑटो-विकास चक्रों को उस तरह से बचाएं। इसलिए वास्तविक संख्या को सावधानीपूर्वक गणना की आवश्यकता है। यह भी ध्यान दें कि आपके द्वारा किया गया "बड़ा स्पेस फ़्रीअप" लेन-देन लॉग फ़ाइल को डीबी फ़ाइल के भीतर आपके द्वारा प्राप्त स्पेस से भी अधिक बढ़ा देगा। इसके अलावा, वास्तविक अंतरिक्ष लाभ जो आप अनुभव कर सकते हैं, वह उससे कम होगा जो आप गणितीय रूप से उम्मीद करते हैं! तो आइए हम आपको बताते हैं गणितीय रूप से 12 गिग्स मुक्त,
  3. क्या मुझे कुछ भी करना चाहिए? : जैसा कि मैंने पहले उल्लेख किया है, आप उन अनुक्रमणिकाओं को फिर से बनाना चाहते हैं जो SHRINK के परिवर्तनों के परिणामस्वरूप विखंडन हो गए। यदि आपने क्वेरी आंकड़ों के बारे में कुछ विशेष करने की आवश्यकता है, तो मैंने पर्याप्त प्रयोग नहीं किया है।
  4. यदि यह एक बड़ा डेटाबेस है तो क्या होगा? क्या मैं इसे छोटे वेतन वृद्धि में सिकोड़ सकता हूं? SHRINK ऑपरेशन किसी भी समय बाधित हो सकता है, और आप बाद में जारी रख सकते हैं। यदि संभव हो तो मैं इसे ऑफ-लाइन डेटाबेस पर प्रदर्शन करने की सलाह दूंगा। बीच में आने और contuniung द्वारा यह हालांकि एक ही सिकुड़ आकार आगे जाना होगा। सैद्धांतिक रूप से आप 7 मेगाबाइट के बजाय कम तंग लक्ष्य आकार निर्दिष्ट करके छोटे वेतन वृद्धि में सिकुड़ सकते हैं, लेकिन मैं कहूंगा कि यदि आप इसे उत्पादन में प्रदर्शन कर रहे हैं, तो बस इसे एक बार दें। जैसा कि आप देखते हैं कि सूचकांक विखंडन और संभावित लेनदेन लॉग वृद्धि के साथ समस्याएं हैं। तो मैं सिर्फ एक बार इस के माध्यम से जाना होगा।

हम सभी जानते हैं कि नियमित रूप से वैसे भी SHRINK करने की सलाह नहीं दी जाती है। मैं उन सभी चेतावनियों और अस्वीकरणों को छोड़ने की कोशिश करता हूं जो आप शायद वैसे भी जानते हैं। बैकअप, और यदि संभव हो तो घर पर ऐसा मत करो :)

बोनस: प्रतिकृति वातावरण में यदि आप प्रकाशक डेटाबेस पर इसे निष्पादित करते हैं, तो यह ग्राहक डेटाबेस को सिकोड़ने का कारण नहीं होगा (जो कि आकार की समस्या हो सकती है क्योंकि वे एक्सप्रेस संस्करण हैं)।

अंत में, मेरी रींडेक्स स्क्रिप्ट:

USE YourDBName

DECLARE @TbName VARCHAR(255)
DECLARE @FullTbName VARCHAR(255)
DECLARE @IxName VARCHAR(255)
DECLARE myCursor CURSOR FOR
    SELECT OBJECT_NAME(dmi.object_id) AS TableName,i.name AS IndexName
    FROM sys.dm_db_index_physical_stats(14, NULL, NULL, NULL , 'LIMITED') dmi
    JOIN  sys.indexes i on dmi.object_id = i.object_id and dmi.index_id = i.index_id
    WHERE avg_fragmentation_in_percent > 30
    ORDER BY avg_fragmentation_in_percent
OPEN myCursor
FETCH NEXT FROM myCursor INTO @TbName, @ixName
WHILE @@FETCH_STATUS = 0
BEGIN
    IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES  WHERE TABLE_SCHEMA = 'dba' AND TABLE_NAME = @TbName)
BEGIN
        SET @FullTbName = 'dba.' + @TbName
        IF (@ixName IS NULL)
        BEGIN
            PRINT 'Reindexing Table ' + @FullTbName
            DBCC DBREINDEX(@FullTbName, '', 0)
        END
        ELSE
        BEGIN
             PRINT 'Reindexing Table ' + @FullTbName + ', Index ' + @IxName
             DBCC DBREINDEX(@FullTbName, @IxName, 0)
        END
    END
    FETCH NEXT FROM myCursor INTO @TbName, @ixName
END
CLOSE myCursor
DEALLOCATE myCursor

इसमें केवल चर 14 है, जिसे चुनिंदा जारी करके प्राप्त किया जा सकता है DB_ID('YourDBName'), और स्क्रिप्ट मानती है कि आप केवल dba में तालिकाओं में रुचि रखते हैं। * स्कीमा।


2
अनुक्रमणिका पुनर्निर्माण के लिए ध्यान दें कि DBREINDEX को SQL 2005 में पदावनत किया गया था। अभिशापों के साथ विशाल स्क्रिप्ट के बजाय, आप बस उपयोग कर सकते हैं: EXEC sp_MSForeachtable @ Command1 = "ALTER INDEX ALL ON! REBUILD" उम्मीद है कि यह किसी की मदद करता है?
KISS

2

आपने सिकुड़ते डेटाबेस के बारे में चेतावनी के सभी सुना है और वे सभी सच हैं। यह आपके अनुक्रमणिका को विखंडित करेगा और सामान्य रूप से आपके डेटाबेस को गड़बड़ करेगा और उत्पादन प्रणाली पर नहीं होना चाहिए।

लेकिन, मैं आम तौर पर साप्ताहिक आधार पर ऐसा करता हूं जब मैं अपने एसएसडी ड्राइव पर जगह के कारण अपने कार्य केंद्र पर बैकअप बहाल करता हूं। माइंड यू, मैंने यह स्क्रिप्ट नहीं लिखी, लेकिन यह सालों पहले मिली। अन्य डेटाबेस [२५० जीबी] पर, मैंने एक SSIS पैकेज बनाया जो मुझे चाहिए कि तालिकाओं को स्थानांतरित कर देगा और फिर उस ओह इंडेक्स के लिए अनुक्रमणिकाओं को फिर से बनाएगा।

DECLARE @DBFileName SYSNAME

DECLARE @TargetFreeMB INT

DECLARE @ShrinkIncrementMB INT

SET @DBFileName = 'Set Name of Database file to shrink'

-- Set Desired file free space in MB after shrink

SET @TargetFreeMB = 500
-- Set Increment to shrink file by in MB
SET @ShrinkIncrementMB = 100

SELECT [FileSizeMB] = convert(NUMERIC(10, 2),
round(a.size / 128., 2)),

[UsedSpaceMB] = convert(NUMERIC(10, 2),

round(fileproperty(a.NAME, 'SpaceUsed') / 128., 2)),

[UnusedSpaceMB] = convert(NUMERIC(10, 2),

round((a.size - fileproperty(a.NAME, 'SpaceUsed')) / 128., 2)),

[DBFileName] = a.NAME

FROM sysfiles a

DECLARE @sql VARCHAR(8000)
DECLARE @SizeMB INT
DECLARE @UsedMB INT

SELECT @SizeMB = size / 128.
FROM sysfiles
WHERE NAME = @DBFileName

SELECT @UsedMB = fileproperty(@DBFileName, 'SpaceUsed') / 128.

SELECT [StartFileSize] = @SizeMB
    ,[StartUsedSpace] = @UsedMB
    ,[DBFileName] = @DBFileName

WHILE @SizeMB > @UsedMB + @TargetFreeMB + @ShrinkIncrementMB

BEGIN
    SET @sql = 'dbcc shrinkfile ( ' + @DBFileName + ', ' + convert(VARCHAR(20), @SizeMB - @ShrinkIncrementMB) + ' ) '

    PRINT 'Start ' + @sql
    PRINT 'at ' + convert(VARCHAR(30), getdate(), 121)

    EXEC (@sql)

    PRINT 'Done ' + @sql
    PRINT 'at ' + convert(VARCHAR(30), getdate(), 121)

    SELECT @SizeMB = size / 128.
    FROM sysfiles
    WHERE NAME = @DBFileName

    SELECT @UsedMB = fileproperty(@DBFileName, 'SpaceUsed') / 128.

    SELECT [FileSize] = @SizeMB
        ,[UsedSpace] = @UsedMB
        ,[DBFileName] = @DBFileName
END

SELECT [EndFileSize] = @SizeMB
    ,[EndUsedSpace] = @UsedMB
    ,[DBFileName] = @DBFileName

SELECT [FileSizeMB] = convert(NUMERIC(10, 2), round(a.size / 128., 2))

    ,[UsedSpaceMB] = convert(NUMERIC(10, 2), round(fileproperty a.NAME, 'SpaceUsed') / 128., 2))

,[UnusedSpaceMB] = convert(NUMERIC(10, 2), round((a.size - fileproperty(a.NAME, 'SpaceUsed')) / 128., 2))

,[DBFileName] = a.NAME

FROM sysfiles a

1

नीचे दिया गया यह उद्धरण सीधे Microsoft से है (2008-2016 के संस्करणों पर लागू होता है), और यदि / जब आपको DBCC SHRINKFILEकमांड का उपयोग करना चाहिए, तो यह मार्गदर्शन देता है ।

https://msdn.microsoft.com/en-us/library/ms189493.aspx

सर्वोत्तम प्रथाएं

जब आप किसी फ़ाइल को सिकोड़ने की योजना बनाते हैं तो निम्न जानकारी पर विचार करें:

  • एक ऑपरेशन के बाद हटना ऑपरेशन सबसे प्रभावी होता है जो बहुत सारे अप्रयुक्त स्थान बनाता है, जैसे कि एक ट्रंकट टेबल या ड्रॉप टेबल ऑपरेशन।
  • अधिकांश डेटाबेस को नियमित रूप से दिन-प्रतिदिन के संचालन के लिए कुछ खाली स्थान की आवश्यकता होती है। यदि आप किसी डेटाबेस को बार-बार सिकोड़ते हैं और ध्यान देते हैं कि डेटाबेस का आकार फिर से बढ़ता है, तो यह इंगित करता है कि सिकुड़ा हुआ स्थान नियमित संचालन के लिए आवश्यक है। इन मामलों में, डेटाबेस को बार-बार सिकोड़ना एक व्यर्थ ऑपरेशन है।
  • एक सिकुड़ा हुआ ऑपरेशन डेटाबेस में अनुक्रमित के विखंडन की स्थिति को संरक्षित नहीं करता है, और आम तौर पर विखंडन को एक हद तक बढ़ाता है। डेटाबेस को बार-बार सिकोड़ने का यह एक और कारण है।
  • समवर्ती के बजाय क्रमिक रूप से एक ही डेटाबेस में कई फ़ाइलों को सिकोड़ें। ब्लॉक करने के कारण सिस्टम टेबल पर ध्यान देने में देरी हो सकती है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.