एक समझदार बफर पूल आकार के मूल्यांकन के लिए एक निर्धारक विधि क्या है?


29

मैं समझने के लिए एक समझदार तरीके से आने की कोशिश कर रहा हूं कि क्या max server memory (mb)सेटिंग उपयुक्त है (या तो कम होना चाहिए, या उच्चतर होना चाहिए, या जिस तरह से रहना चाहिए)। मुझे पता है कि max server memory (mb)हमेशा ऑपरेटिंग सिस्टम के लिए कमरा छोड़ने के लिए पर्याप्त कम होना चाहिए, आदि।

जिस वातावरण को मैं देख रहा हूं उसमें कई सौ सर्वर हैं; मुझे एक विश्वसनीय सूत्र की आवश्यकता है जिसे मैं यह निर्धारित करने के लिए उपयोग कर सकता हूं कि क्या बफ़र पूल का वर्तमान आकार उचित है क्योंकि रैम प्रत्येक सर्वर को आवंटित जीबी प्रति जीबी है। पूरे वातावरण को वर्चुअलाइज्ड किया गया है, और एक वीएम को आवंटित "भौतिक" रैम को आसानी से ऊपर या नीचे बदला जा सकता है।

मेरे पास एक विशेष SQL सर्वर इंस्टेंस है जिसे मैं अब 1,100,052 सेकंड के PLE के साथ देख रहा हूं, जो 12.7 दिनों (सर्वर के चालू होने की मात्रा) के बराबर है। सर्वर में अधिकतम सर्वर मेमोरी सेटिंग 2560MB (2.5GB) है, जिसमें से केवल 1380MB (1.3GB) वास्तव में प्रतिबद्ध है।

मैंने जोनाथन केहियास ( पोस्ट ) द्वारा एक और पॉल रैंडल ( पोस्ट ) द्वारा एक और कई अन्य सहित कई आइटम पढ़े हैं। जोनाथन बहुत कम होने के नाते बफर पूल के 300 प्रति 4GB नीचे PLE के लिए निगरानी की वकालत करता है। ऊपर SQL सर्वर इंस्टेंस के लिए, 300 * (2.5 / 4) = 187वास्तव में कम लक्ष्य 300 से नीचे PLE में परिणाम। इस उदाहरण में SQL सर्वर डेटा (लॉग फ़ाइलों को शामिल नहीं) के 290GB है, और केवल एकीकरण परीक्षण के लिए उपयोग किया जाता है। पिछले 12 दिनों को इस सर्वर के लिए विशिष्ट उपयोग का प्रतिनिधि मानते हुए, मैं कहता हूं कि max server memory (mb)सेटिंग को कम किया जा सकता है।

पैमाने के दूसरे छोर पर, मेरे पास 294 के PLE के साथ एक और एकीकरण-परीक्षण सर्वर है, जिसमें max server memory (mb)केवल 1GB की सेटिंग है। इस सर्वर में केवल 224MB SQL सर्वर डेटा शामिल नहीं है, और कुछ BizFlow डेटाबेस चला रहा है। यह सर्वर उच्च सेटिंग से लाभान्वित हो सकता हैmax server memory (mb)

मैं उन लक्ष्यों के लिए एक अच्छी शुरुआत की जगह सोच रहा हूं जिन्हें बहुत अधिक स्मृति सौंपी जा सकती है, जिनमें शामिल हैं:

SELECT 
    RamMB = physical_memory_in_bytes / 1048576
    , BufferPoolCommittedMB = bpool_committed * 8192E0 / 1048576
    , BufferPoolCommitTargetMB = bpool_commit_target * 8192E0 / 1048576
    , PercentOfDesiredSizeMB = CONVERT(INT,(CONVERT(DECIMAL(18,2),bpool_committed) 
                            / bpool_commit_target) * 100)
FROM sys.dm_os_sys_info;

यदि BufferPoolCommitTargetMB / BufferPoolCommittedMB1 से अधिक है, तो सर्वर संपूर्ण बफ़र पूल का उपयोग नहीं कर रहा है। यदि प्रश्न में मशीन में "x" से अधिक का एक PLE है, तो इसमें कमी के लिए एक अच्छा उम्मीदवार हो सकता है max server memory (mb)

चूँकि Buffer Manager:Lazy writes/secप्रदर्शन काउंटर कई बार SQLOS ने मेमोरी प्रेशर के कारण चौकियों के बीच डिस्क को लिखने के लिए पृष्ठों को ट्रैक किया है, इसलिए यह देखने के लिए एक और अच्छी बात हो सकती है।

DECLARE @WaitTime DATETIME;
SET @WaitTime = '00:00:15';
DECLARE @NumSeconds INT;
SET @NumSeconds = DATEDIFF(SECOND, 0, @WaitTime);
DECLARE @LazyWrites1 BIGINT;
DECLARE @LazyWrites2 BIGINT;

SELECT @LazyWrites1 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE 'Lazy writes/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = 'MSSQL$' + CONVERT(VARCHAR(255),
               SERVERPROPERTY('InstanceName')) + ':Buffer Manager';

WAITFOR DELAY @WaitTime;

SELECT @LazyWrites2 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE 'Lazy writes/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = 'MSSQL$' + CONVERT(VARCHAR(255),
               SERVERPROPERTY('InstanceName')) + ':Buffer Manager';

SELECT LazyWritesPerSecond = (@LazyWrites2 - @LazyWrites1) / @NumSeconds;

उपरोक्त कोड मानता है कि सर्वर को चलाने के लिए 15 सेकंड के दौरान लोड हो रहा है, अन्यथा यह 0 रिपोर्ट करेगा; जो भ्रामक गलत-नकारात्मक हो सकता है।

क्या मुझे PAGELATCHIO_*प्रतीक्षा आंकड़े या कुछ अन्य प्रतीक्षा प्रकार को स्मृति दबाव के संकेतक के रूप में देखना चाहिए , या इसके अभाव में क्या करना चाहिए?

मेरा सवाल है, मैं कैसे PLE के लिए "अच्छा" लक्ष्य मान निर्धारित कर सकता हूं max server memory (mb)?

जवाबों:


11

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

SQL सर्वर 2005 से 2008 R2 के लिए

कृपया SQL Server 2005 से 2008 R2 अधिकतम सर्वर मेमोरी पर ध्यान दें, केवल बफर पूल को नियंत्रित करता है। इसलिए अधिकतम सर्वर मेमोरी कॉन्फ़िगरेशन यहां थकाऊ है और इसमें कुछ गणनाएं शामिल हैं

  1. विंडोज ओएस के लिए सीधे 2 जी मेमोरी छोड़ दें।

  2. बेशक सिस्टम में एंटीवायरस चल रहा होगा। कृपया एंटीवायरस के लिए 1.5G छोड़ दें। कृपया ध्यान दें कि Mcafee और SQL सर्वर हाथ से नहीं जाते हैं इसलिए सुनिश्चित करें कि आप इसके लिए पर्याप्त छोड़ दें। आप Perfmon Process-> Private bytes and Working Setएवी और SQL सर्वर बॉक्स पर चल रहे अन्य छोटे अनुप्रयोगों द्वारा मेमोरी उपयोग की निगरानी के लिए परफ्यूम काउंटर की भी जांच कर सकते हैं

यहाँ छवि विवरण दर्ज करें

  1. ड्राइवरों / फ़र्मवारों की मेमोरी आवश्यकताओं पर विचार करें। आपको सिस्टम पर स्थापित ड्राइवरों द्वारा मेमोरी आवश्यकताओं के आधार पर इसे प्राप्त करना होगा। RAMMAP टूल मदद कर सकता है

  2. SQL सर्वर द्वारा NonbPool (उर्फ MTL या MTR) स्मृति आवश्यकताओं पर विचार करें।

    select  sum(multi_pages_kb)/1024 as multi_pages_mb from  sys.dm_os_memory_clerks

    + अधिकतम कार्यकर्ता धागे * 2MB

    + प्रत्यक्ष विंडोज के लिए मेमोरी अधिकांश मामलों में लगभग 0 से 300 एमबी आवंटित करता है, लेकिन SQL सर्वर प्रक्रिया में कई 3 पार्टी घटक लोड होने पर आपको इसे बढ़ाना पड़ सकता है (इसमें लिंक किए गए सर्वर dll, 3 पार्टी बैकअप dll आदि शामिल हैं)

    + यदि आप सीएलआर का उपयोग कर रहे हैं तो सीएलआर के लिए कुछ अतिरिक्त मेमोरी जोड़ें।

  3. नौकरियों द्वारा मेमोरी की आवश्यकता पर विचार करें (प्रतिकृति एजेंटों, लॉग शिपिंग आदि सहित) और पैकेज जो सर्वर पर चलेंगे। यह एमबी की जीबी से लेकर नौकरियों की संख्या के अनुसार चल सकता है। मध्यम आकार के सर्वर के लिए आप इसे 250 एमबी के रूप में ले सकते हैं

  4. सुनिश्चित करें कि ऑपरेटिंग सिस्टम के लिए पर्याप्त खाली जगह है।

    लगभग (प्रत्येक जीबी के लिए 4 जी तक 100 एमबी) + (12 जीबी तक प्रत्येक अतिरिक्त जीबी के लिए 50 एमबी) + (प्रत्येक अतिरिक्त जीबी के लिए 25 एमबी आपके रैम आकार तक)

  5. अन्य स्मृति आवश्यकताएं।

    यदि आपके पास अपने पर्यावरण के लिए विशिष्ट कोई अन्य स्मृति आवश्यकता है।

    अधिकतम सर्वर मेमोरी = कुल भौतिक मेमोरी - (1 + 2 + 3 + 4 + 5 + 6 + 7)

    मैंने SSIS.SSRS, SSAS के लिए मेमोरी कॉन्फ़िगरेशन को शामिल नहीं किया है, आपको इन सेवाओं द्वारा आवश्यक मेमोरी को कुल भौतिक मेमोरी मेमोरी से घटाना होगा।

    आपके द्वारा ऊपर कॉन्फ़िगर किए जाने के बाद आपको निम्न काउंटरों की निगरानी करने की आवश्यकता है

  • SQLServer: बफर प्रबंधक - पृष्ठ जीवन प्रत्याशा (PLE):

  • SQLServer: बफर प्रबंधक - CheckpointPages / sec:

  • SQLServer: मेमोरी मैनेजर - मेमोरी अनुदान लंबित:

  • SQLServer: मेमोरी मैनेजर - लक्ष्य सर्वर मेमोरी:

  • SQLServer: मेमोरी मैनेजर - कुल सर्वर मेमोरी

SQL सर्वर 2012/2014 के लिए।

From SQL Server 2012 onwardsअधिकतम सर्वर मेमोरी सेट करना आसान हो गया है। क्योंकि अब अधिकतम सर्वर मेमोरी लगभग सभी मेमोरी खपत के लिए खाता है। अधिकतम सर्वर मेमोरी SQL सर्वर मेमोरी आवंटन को नियंत्रित करती है, जिसमें बफर पूल, संकलन मेमोरी, सभी कैश, क्यू मेमोरी मेमोरी, लॉक मैनेजर मेमोरी, और सीएलआर मेमोरी (मूल रूप से किसी भी "क्लर्क" जैसे dm_os_memory_cnks) शामिल हैं। थ्रेड स्टैक, ढेर, SQL सर्वर के अलावा अन्य लिंक किए गए सर्वर प्रदाताओं या "गैर SQL सर्वर" DLL द्वारा आवंटित किसी भी मेमोरी के लिए मेमोरी को अधिकतम सर्वर मेमोरी द्वारा नियंत्रित नहीं किया जाता है।

आप SQL सर्वर को 75-80% आवंटित कर सकते हैं और फिर मेमोरी उपयोग की निगरानी के लिए perfmon काउंटर का उपयोग कर सकते हैं। SQL सर्वर 2012 में कुछ परफ़ॉर्मर काउंटरों को हटा दिया गया है। बफ़र प्रबंधक काउंटर को हटा दिया गया है आपको स्मृति प्रबंधक काउंटर का उपयोग करना चाहिए

  • SQL सर्वर: मेमोरी मैनेजर-- टारगेट सर्वर मेमोरी (KB)

  • SQL सर्वर: मेमोरी मैनेजर - कुल सर्वर मेमोरी (KB)

  • SQL सर्वर: मेमोरी मैनेजर- फ्री मेमोरी (KB)

  • SQL सर्वर: मेमोरी मैनेजर - डेटाबेस कैश मेमोरी (KB)

PLE के मूल्य पर, मैंने जोआथन द्वारा फार्मूला का उपयोग किया है और सौभाग्य से इसने मेरे लिए काम किया है।


6

यहां चुनौती यह है कि संख्याएं उपयोगकर्ता के अंतिम अनुभव को ध्यान में नहीं रखती हैं।

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

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

प्रदर्शन को एक प्रश्न से शुरू करने की आवश्यकता है: क्या उपयोगकर्ता प्रदर्शन से खुश हैं? यदि ऐसा है, तो सिस्टम को छोड़ दें जहां यह है।


भले ही आप आवश्यकता से अधिक मेमोरी का उपयोग कर रहे हों?
जेम्स एंडरसन

2
जेम्स - आम तौर पर, मैं उन बदलावों को नहीं करना चाहता जिनके कारण उपयोगकर्ता शिकायत करते हैं। यदि आप ऐसा करना चाहते हैं, तो आप धीरे-धीरे प्रत्येक सर्वर के लिए मेमोरी की मात्रा को कम कर सकते हैं जब तक कि उपयोगकर्ता शिकायत करना शुरू नहीं करते हैं, लेकिन जब मैं पहले से ही काम कर रहा होता हूं, तो मेरे पास आमतौर पर उन चरणों को लेने का समय नहीं होता है। मुझे उन कार्यों पर ध्यान केंद्रित करना होगा जो दुखी उपयोगकर्ताओं को खुश करेंगे - बजाय खुश उपयोगकर्ताओं को दुखी करने की कोशिश करने के। ;-)
ब्रेंट ओज़र

2
अच्छे अंक, ब्रेंट। मुझे यह देखने के लिए कहा गया था कि क्या कुछ सर्वर ओवर-प्रोवीस्ड हैं क्योंकि हम प्रति वर्ष प्रति जीबी मेमोरी के लिए भुगतान करते हैं। उदाहरणों में से कई मैं देख रहा हूँ कि क्या मैं राम की एक बहुत छोटी राशि है max server memory (mb), और इस तरह के रूप में मैं उन्हें नीचे आकार के लिए बहुत अनिच्छुक हूँ। हालाँकि, कुछ अन्य उदाहरणों में 1,000,000 + PLE हैं, और जैसे रैम में गिरावट के लिए बहुत स्पष्ट संभावित उम्मीदवार हैं। जाहिर है, को कम रैम IOPS में वृद्धि का कारण होगा, और मुझे यकीन है कि क्या की लागत नहीं कर रहा हूँ कि हो जाएगा।
मैक्स वर्नोन

1
इसके अलावा, max server memoryसेटिंग की तुलना में PLE को देखना चिकन और अंडे की तरह है; कम max server memoryसेटिंग, कम से कम "स्वीकार्य" PLE होगा, इसलिए मैं कभी कम होने वाले सर्पिल में फंस सकता हूं। मुझे यकीन है, जैसा कि आप उल्लेख करते हैं, उपयोगकर्ता का प्रदर्शन किसी बिंदु पर प्रभावित होगा।
मैक्स वर्नोन

PLE काउंटर्स वह है जिसे आपको 2012 के बाद से देखने से बचना चाहिए या जब आपके पास NUMA सिस्टम होता है, जहां प्रत्येक नोड स्वयं की छोटी मेमोरी एलोकेटर के रूप में व्यवहार करता है। यदि आप चाहते हैं कि आपको प्रत्येक NUMA नोड के लिए PLE दिखना चाहिए, तो आप गलत मूल्य प्राप्त नहीं कर सकते हैं
Shanky

3

PLE vs max server memoryका मूल्यांकन करने के लिए मैं वर्तमान T-SQL का उपयोग कर रहा हूं :

/*
    Purpose:            Returns a resultset describing various server level stats including PLE
                        Max and Min Server Memory, etc.
    By:                 Max Vernon
    Date:               2014-12-01
*/
SET NOCOUNT ON;

/*
    wait stats for PAGELATCH_IO
*/
DECLARE @Debug BIT;
SET @Debug = 0;
DECLARE @HTMLOutput BIT;
SET @HTMLOutput = 1;
DECLARE @WaitTime DATETIME;
SET @WaitTime = '00:00:15';
DECLARE @NumSeconds INT;
SET @NumSeconds = DATEDIFF(SECOND, 0, @WaitTime);
DECLARE @InstanceName NVARCHAR(255);
SET @InstanceName = CONVERT(NVARCHAR(255), SERVERPROPERTY('InstanceName'));
DECLARE @Version NVARCHAR(255);
DECLARE @VersionINT INT;
SET @Version = CONVERT(NVARCHAR(255),SERVERPROPERTY('ProductVersion'));
SET @VersionINT = CONVERT(INT, SUBSTRING(@Version,1 ,CHARINDEX('.',@Version)-1));
DECLARE @cmd NVARCHAR(MAX);
SET @cmd = '';
DECLARE @TaskCount INT;
DECLARE @TasksPerSecondAvg INT;
DECLARE @AvgWaitTimeInMSPerTask DECIMAL(10,2);
DECLARE @AvgWaitTimeInMSPerSecond DECIMAL(10,2);
DECLARE @TotalWaitTimeInMSOverall DECIMAL(10,2);
DECLARE @LazyWrites1 BIGINT;
DECLARE @LazyWrites2 BIGINT;
DECLARE @FreeListStallsSec1 BIGINT;
DECLARE @FreeListStallsSec2 BIGINT;
DECLARE @BatchReq1 BIGINT;
DECLARE @BatchReq2 BIGINT;
DECLARE @ws TABLE
(
    RunNum INT
    , wait_type SYSNAME
    , waiting_tasks_count BIGINT
    , wait_time_ms BIGINT
    , max_wait_time_ms BIGINT
    , signal_wait_time_ms BIGINT
);
INSERT INTO @ws
SELECT 1, dows.*
FROM sys.dm_os_wait_stats dows
WHERE dows.wait_type LIKE 'PAGEIOLATCH_%'
ORDER BY dows.waiting_tasks_count DESC;

SELECT @LazyWrites1 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE N'Lazy writes/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = N'MSSQL$' + @InstanceName + N':Buffer Manager';

SELECT @FreeListStallsSec1 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE N'Free list stalls/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = N'MSSQL$' + @InstanceName + N':Buffer Manager';

SELECT @BatchReq1 = cntr_value
FROM sys.dm_os_performance_counters dopc
WHERE dopc.counter_name LIKE N'Batch Requests/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    AND dopc.object_name = N'MSSQL$' + @InstanceName + N':SQL Statistics';

WAITFOR DELAY @WaitTime;

INSERT INTO @ws
SELECT 2, dows.*
FROM sys.dm_os_wait_stats dows
WHERE dows.wait_type LIKE N'PAGEIOLATCH_%'
ORDER BY dows.waiting_tasks_count DESC;

SELECT @LazyWrites2 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE N'Lazy writes/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = N'MSSQL$' + @InstanceName + N':Buffer Manager';

SELECT @FreeListStallsSec2 = cntr_value 
FROM sys.dm_os_performance_counters dopc
WHERE (
        dopc.counter_name LIKE N'Free list stalls/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    )
    AND dopc.object_name = N'MSSQL$' + @InstanceName + N':Buffer Manager';

SELECT @TaskCount = SUM(w2.waiting_tasks_count - w1.waiting_tasks_count)
    , @TasksPerSecondAvg = CONVERT(DECIMAL(10,2), (SUM(w2.waiting_tasks_count) - SUM(w1.waiting_tasks_count))) / @NumSeconds
    , @AvgWaitTimeInMSPerTask = CONVERT(DECIMAL(10,2),(SUM(w2.wait_time_ms) - SUM(w1.wait_time_ms))) / CONVERT(DECIMAL(10,2),(SUM(w2.waiting_tasks_count) - SUM(w1.waiting_tasks_count)))
    , @AvgWaitTimeInMSPerSecond = (CONVERT(DECIMAL(10,2), (SUM(w2.waiting_tasks_count) - SUM(w1.waiting_tasks_count))) / @NumSeconds) * (CONVERT(DECIMAL(10,2),(SUM(w2.wait_time_ms) - SUM(w1.wait_time_ms))) / CONVERT(DECIMAL(10,2),(SUM(w2.waiting_tasks_count) - SUM(w1.waiting_tasks_count))))
    , @TotalWaitTimeInMSOverall = SUM(w2.wait_time_ms) - SUM(w1.wait_time_ms)
FROM (SELECT * FROM @ws ws1 WHERE ws1.RunNum = 1) w1
    INNER JOIN (SELECT * FROM @ws ws2 WHERE ws2.RunNum = 2) w2 ON w1.wait_type = w2.wait_type
WHERE (w2.waiting_tasks_count - w1.waiting_tasks_count) > 0;

SELECT @BatchReq2 = cntr_value
FROM sys.dm_os_performance_counters dopc
WHERE dopc.counter_name LIKE N'Batch Requests/sec%' COLLATE SQL_Latin1_General_CP1_CI_AS
    AND dopc.object_name = N'MSSQL$' + @InstanceName + N':SQL Statistics';

/*
    configured values for max server memory and min server memory, etc
*/
DECLARE @MaxServerMemory BIGINT;
DECLARE @MaxServerMemoryPages BIGINT;
DECLARE @MinServerMemory BIGINT;
DECLARE @MinPLE BIGINT;
DECLARE @RamMB BIGINT;
DECLARE @BufferPoolCommittedMB BIGINT;
DECLARE @BufferPoolCommitTargetMB BIGINT;
DECLARE @PercentOfDesiredSizeMB INT;
DECLARE @TargetPageLifeExpectancyPer4GB BIGINT;
SET @TargetPageLifeExpectancyPer4GB = 60 * 120; /* 120 minutes */
/*DECLARE @VMType VARCHAR(255);*/
DECLARE @PLESeconds BIGINT;

SELECT @MaxServerMemory = CONVERT(BIGINT,c.value)
FROM sys.configurations c
WHERE c.name = N'max server memory (mb)'

SET @MaxServerMemoryPages = @MaxServerMemory / 128; /* 8KB pages */

SELECT @MinServerMemory = CONVERT(BIGINT,c.value)
FROM sys.configurations c
WHERE c.name = N'min server memory (mb)'

SET @MinPLE = @MaxServerMemory / 4096E0 * @TargetPageLifeExpectancyPer4GB;

IF @VersionINT < 11
BEGIN
    SET @cmd = 'SELECT 
    @RamMB = dosi.physical_memory_in_bytes / 1048576
    , @BufferPoolCommittedMB = dosi.bpool_committed * 8192E0 / 1048576
    , @BufferPoolCommitTargetMB = dosi.bpool_commit_target * 8192E0 / 1048576
    , @PercentOfDesiredSizeMB = CONVERT(INT,(CONVERT(DECIMAL(18,2),dosi.bpool_committed) / dosi.bpool_commit_target) * 100)
FROM sys.dm_os_sys_info dosi;
';
END
ELSE 
BEGIN 
SET @cmd = 'SELECT 
    @RamMB = dosi.physical_memory_kb / 1024
    , @BufferPoolCommittedMB = dosi.committed_kb / 1024
    , @BufferPoolCommitTargetMB = dosi.committed_target_kb / 1024
    , @PercentOfDesiredSizeMB = CONVERT(INT,(CONVERT(DECIMAL(18,2),dosi.committed_kb) / dosi.committed_target_kb) * 100)
FROM sys.dm_os_sys_info dosi;';
END
EXEC sp_executesql @cmd
    , N'@RamMB BIGINT OUTPUT, @BufferPoolCommittedMB BIGINT OUTPUT, @BufferPoolCommitTargetMB BIGINT OUTPUT, @PercentOfDesiredSizeMB INT OUTPUT' 
    , @RamMB = @RamMB OUT
    , @BufferPoolCommittedMB = @BufferPoolCommittedMB OUT
    , @BufferPoolCommitTargetMB = @BufferPoolCommitTargetMB OUT
    , @PercentOfDesiredSizeMB = @PercentOfDesiredSizeMB OUT;

/*
    Page Life Expectancy for all memory nodes
*/
SELECT @PLESeconds = CONVERT(BIGINT, cntr_value) 
FROM sys.dm_os_performance_counters dopc
WHERE dopc.counter_name LIKE N'Page Life Expectancy%' COLLATE SQL_Latin1_General_CP1_CI_AS
    AND dopc.object_name = N'MSSQL$' + @InstanceName + N':Buffer Manager';

/*
    Total data in all user-databases.
*/
DECLARE @TotalDBSpaceUsed TABLE
(
    TotalSpaceUsedInMB BIGINT
);
DECLARE @SpaceUsedInMB BIGINT;
SET @cmd = '';
SELECT @cmd = @cmd + CASE WHEN @cmd = '' THEN '' ELSE '
UNION ALL
' END + 
'
SELECT DatabaseName = ''' + d.name + ''' 
    , AllocType = au.type_desc
    , TotalPagesInMB = SUM(au.total_pages) * 8192E0 / 1048576
FROM ' + QUOTENAME(d.name) + '.sys.allocation_units au
WHERE au.type > 0
GROUP BY au.type_desc
'
FROM master.sys.databases d
WHERE d.database_id > 4;
SET @cmd = 'SELECT SUM(TotalPagesInMB)
FROM (
' + @cmd + '
) t;'; 
INSERT INTO @TotalDBSpaceUsed (TotalSpaceUsedInMB)
EXEC sp_executesql @cmd;
SELECT @SpaceUsedInMB = TDSU.TotalSpaceUsedInMB
FROM @TotalDBSpaceUsed TDSU;

IF @Debug = 1
BEGIN
    SELECT ServerName = @@SERVERNAME
        , InstanceName = @InstanceName
        , DatabaseSpaceUsedMB = @SpaceUsedInMB
        , PLEinSeconds = @PLESeconds
        , MinAcceptablePLE = @MinPLE
        , MinServerMemoryMB = @MinServerMemory
        , MaxServerMemoryMB = @MaxServerMemory
        , TotalServerRAMinMB = @RamMB
        , BufferPoolCommittedMB = @BufferPoolCommittedMB
        , BufferPoolCommitTargetMB = @BufferPoolCommitTargetMB
        , PercentBufferPoolCommitted = @PercentOfDesiredSizeMB
        , BatchReqPerSecond = (@BatchReq2 - @BatchReq1) / @NumSeconds
        , LazyWritesPerSecond = (@LazyWrites2 - @LazyWrites1) / @NumSeconds
        , FreeListStallsPerSecond = (@FreeListStallsSec2 - @FreeListStallsSec2) / @NumSeconds
        /*, VMType = @VMType*/
        , IOTaskCount = @TaskCount 
        , TaskPerSecondAvg = @TasksPerSecondAvg 
        , AvgWaitTimeInMSPerTask = @AvgWaitTimeInMSPerTask 
        , AvgWaitTimeInMSPerSecond = @AvgWaitTimeInMSPerSecond 
        , TotalWaitTimeInMSOverall  = @TotalWaitTimeInMSOverall
        , SamplePeriodinSec = @NumSeconds;

    SELECT MaxServerMemorySuggested = 
            CASE WHEN @BufferPoolCommittedMB < @BufferPoolCommitTargetMB 
            THEN @BufferPoolCommittedMB 
            ELSE ((CONVERT(DECIMAL(18,4), @MinPLE) / @PLESeconds) * @MaxServerMemory) 
                    + (((@LazyWrites2 - @LazyWrites1) / @NumSeconds) * 64) 
                    + ((@FreeListStallsSec2 - @FreeListStallsSec2) / @NumSeconds) * 64 
            END
        , Reason = CASE WHEN @BufferPoolCommittedMB < @BufferPoolCommitTargetMB THEN N'Committed MB less than current Max Server Memory'
            ELSE N'Calculated based on PLE, Lazy Writes / second and List Stalls / second' END
        , LazyWritesX64 = (((@LazyWrites2 - @LazyWrites1) / @NumSeconds) * 64)
        , ListStallsX64 = ((@FreeListStallsSec2 - @FreeListStallsSec2) / @NumSeconds) * 64;
END

DECLARE @Out TABLE
(
    KeyID INT IDENTITY(1,1)
    , ItemDesc NVARCHAR(255)
    , ItemValue SQL_VARIANT
    , IsDebug BIT DEFAULT(0)
);

INSERT INTO @Out (ItemDesc, ItemValue, IsDebug)
VALUES (N'Server Name', CONVERT(NVARCHAR(255),@@SERVERNAME), 1);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Data Space Used (MB)', @SpaceUsedInMB);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Page Life Expectancy (sec)', @PLESeconds);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Minimum Acceptable Page Life Expectancy (sec)', @MinPLE);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Minimum Server Memory (MB)', @MinServerMemory);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Maximum Server Memory (MB)', @MaxServerMemory);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Total Server RAM in MB', @RamMB);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Buffer Pool Committed MB', @BufferPoolCommittedMB);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Buffer Pool Commit Target MB', @BufferPoolCommitTargetMB);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Percent of Buffer Pool Committed', @PercentOfDesiredSizeMB);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Batch Requests Per Second', (@BatchReq2 - @BatchReq1) / @NumSeconds);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Lazy Writes Per Second', (@LazyWrites2 - @LazyWrites1) / @NumSeconds);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Free List Stalls Per Second', (@FreeListStallsSec2 - @FreeListStallsSec2) / @NumSeconds);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'IO Task Count', @TaskCount);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Task Per Second Avg', @TasksPerSecondAvg);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Avg Wait Time In MS Per Task', @AvgWaitTimeInMSPerTask);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Avg Wait Time In MS Per Second', @AvgWaitTimeInMSPerSecond);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Total Wait Time In MS Overall', @TotalWaitTimeInMSOverall);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Sample Period in Seconds', @NumSeconds);

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Lazy Writes per Second', ((@LazyWrites2 - @LazyWrites1) / @NumSeconds));

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'List Stalls per Second', ((@FreeListStallsSec2 - @FreeListStallsSec2) / @NumSeconds));

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Recommended Max Memory (MB)', N'');

INSERT INTO @Out (ItemDesc, ItemValue)
VALUES (N'Recommended Max Memory Reason', N'');

INSERT INTO @Out (ItemDesc, ItemValue, IsDebug)
VALUES (N'Recommended Max Memory Signal', 0, 1);

/*
    Add memory if Lazy Writes occurred
    Add 64MB per Lazy Write (just for fun)
*/
DECLARE @LazyWritesMB INT;
SET @LazyWritesMB = (((@LazyWrites2 - @LazyWrites1) / @NumSeconds) * 64);

/*
    Add memory if Free List Stalls occurred
    Add 128MB per Free List Stall
*/
DECLARE @FreeListStallMB INT;
SET @FreeListStallMB = (((@FreeListStallsSec2 - @FreeListStallsSec2) / @NumSeconds) * 128);

/*
    Add the Additional memory requirements to the Recommended Max Memory row
*/
DECLARE @AdditionalMemory INT;
SET @AdditionalMemory = 
    @LazyWritesMB
    + @FreeListStallMB;

IF (@MaxServerMemory + @AdditionalMemory < 1024) AND (@PLESeconds >= @MinPLE)
BEGIN
    UPDATE @Out 
    SET ItemValue = @MaxServerMemory
    WHERE ItemDesc = N'Recommended Max Memory (MB)';

    UPDATE @Out 
    SET ItemValue = 'Max Server Memory is low, however PLE is acceptable'
    WHERE ItemDesc = N'Recommended Max Memory Reason';

    UPDATE @Out 
    SET ItemValue = 1
    WHERE ItemDesc = N'Recommended Max Memory Signal';
END

IF ((@BufferPoolCommittedMB + @AdditionalMemory) < @BufferPoolCommitTargetMB) AND (@PLESeconds >= @MinPLE)
BEGIN
    UPDATE @Out 
    SET ItemValue = @BufferPoolCommittedMB + @AdditionalMemory
    WHERE ItemDesc = N'Recommended Max Memory (MB)';

    UPDATE @Out 
    SET ItemValue = 'Buffer pool committed is less than Max Server Memory, and PLE is acceptable.'
    WHERE ItemDesc = N'Recommended Max Memory Reason';

    UPDATE @Out 
    SET ItemValue = 2
    WHERE ItemDesc = N'Recommended Max Memory Signal';
END

DECLARE @PLEMultiplier DECIMAL(10,2);
SET @PLEMultiplier = (CONVERT(DECIMAL(10,2),@MinPLE) / CONVERT(DECIMAL(10,2), @PLESeconds));
IF @PLEMultiplier < 0.90 SET @PLEMultiplier = 0.90;
IF @PLEMultiplier > 1.10 SET @PLEMultiplier = 1.10;

INSERT INTO @Out (ItemDesc, ItemValue, IsDebug)
VALUES (N'PLE Multiplier', @PLEMultiplier, 1);

IF /*(@MaxServerMemory + @AdditionalMemory >= 1024) AND*/ (@PLESeconds <= @MinPLE)
BEGIN
    UPDATE @Out 
    SET ItemValue = 
        (SELECT TOP(1) Inc
        FROM (
            SELECT Inc = t.RowNum * 256
            FROM (
                SELECT RowNum = CONVERT(BIGINT,ROW_NUMBER() OVER (ORDER BY o.object_id))
                FROM sys.objects o, sys.objects o1
                ) t
            WHERE (t.RowNum * 256) <  CONVERT(BIGINT,POWER(2,30))
            ) t1
        WHERE t1.Inc > CONVERT(INT, (@MaxServerMemory * @PLEMultiplier))
        ORDER BY t1.Inc)
    WHERE ItemDesc = N'Recommended Max Memory (MB)';

    UPDATE @Out 
    SET ItemValue = 'Low PLE indicates Max Server Memory should be adjusted upwards.'
    WHERE ItemDesc = N'Recommended Max Memory Reason';

    UPDATE @Out 
    SET ItemValue = 3
    WHERE ItemDesc = N'Recommended Max Memory Signal';
END

IF (@MaxServerMemory + @AdditionalMemory >= 1024) AND (@PLESeconds > @MinPLE)
BEGIN
    UPDATE @Out 
    SET ItemValue = 
        (SELECT TOP(1) Inc
        FROM (
            SELECT Inc = t.RowNum * 256
            FROM (
                SELECT RowNum = CONVERT(BIGINT,ROW_NUMBER() OVER (ORDER BY o.object_id))
                FROM sys.objects o, sys.objects o1
                ) t
            WHERE (t.RowNum * 256) <  CONVERT(BIGINT,POWER(2,30))
            ) t1
        WHERE t1.Inc <= CONVERT(INT, (@MaxServerMemory * @PLEMultiplier))
        ORDER BY t1.Inc DESC)
    WHERE ItemDesc = N'Recommended Max Memory (MB)';

    UPDATE @Out 
    SET ItemValue = 'High PLE indicates Max Server Memory could be adjusted downwards.'
    WHERE ItemDesc = N'Recommended Max Memory Reason';

    UPDATE @Out 
    SET ItemValue = 4
    WHERE ItemDesc = N'Recommended Max Memory Signal';
END

DECLARE @RecommendedMaxServerMemory INT;
SELECT  @RecommendedMaxServerMemory = CONVERT(INT,ItemValue)
FROM @Out o 
WHERE o.ItemDesc = N'Recommended Max Memory (MB)';

IF @RecommendedMaxServerMemory > (@MaxServerMemory * 0.96)
    AND @RecommendedMaxServerMemory < (@MaxServerMemory * 1.04)
BEGIN
    UPDATE @Out
    SET ItemValue = @MaxServerMemory
    WHERE ItemDesc = N'Recommended Max Memory (MB)';
    UPDATE @Out
    SET ItemValue = 'No changed recommended'
    WHERE ItemDesc = N'Recommended Max Memory Reason';
    UPDATE @Out 
    SET ItemValue = 0
    WHERE ItemDesc = N'Recommended Max Memory Signal';
END 

IF (@HTMLOutput = 1)
BEGIN
    SELECT ItemValue
        , HTMLOutput = '<table>' + 
            (
                SELECT 'td' = ItemDesc
                    , ''
                    , 'td' = ItemValue
                    , ''
                FROM @Out o
                WHERE CASE WHEN @Debug = 0 THEN o.IsDebug ELSE 0 END = 0
                ORDER BY o.KeyID
                FOR XML PATH('tr')
            ) +
            '</table>'
    FROM @Out o
    WHERE o.ItemDesc = N'Recommended Max Memory Signal';
END
ELSE
BEGIN
    SELECT *
    FROM @Out o
    WHERE CASE WHEN @Debug = 0 THEN o.IsDebug ELSE 0 END = 0
    ORDER BY o.KeyID;
END

इस कोड ने PLE की तुलना उस न्यूनतम "स्वीकार्य" PLE से max server memoryकी है जिसके लिए सिस्टम कॉन्फ़िगर किया गया है। यदि PLE स्वीकार्य संख्या से काफी अधिक है, तो यह अधिकतम 10% कम होने का सुझाव देता है max server memory। यदि PLE स्वीकार्य PLE से कम है, तो यह अधिकतम 10% अधिक सुझाता है max server memory

यदि प्रतिबद्ध बफ़र पूल की वास्तविक मात्रा लक्ष्य बफ़र पूल आकार से कम है, तो यह max server memoryउस राशि को कम करने का सुझाव देता है , साथ ही थ्रेड्स के लिए कुछ अतिरिक्त मेमोरी, आलसी राइट्स आदि।

कोड आलसी राइट्स / सेकंड, फ्री लिस्ट स्टॉल और बैच अनुरोध जैसी चीजों के लिए विभिन्न प्रदर्शन काउंटरों को भी देखता है।

कोड सही नहीं है, मैं इसे इनपुट प्राप्त करने के लिए, और भविष्य के SO उपयोगकर्ताओं के लाभ के लिए यहाँ साझा कर रहा हूँ।


1
मैक्स माइंड आप SQL सर्वर 2012 बफर पूल लक्ष्य से शुरू करते हैं और प्रतिबद्ध होने का कोई मतलब नहीं है और इन काउंटरों को हटा दिया जाता है। इसके बजाय आपको मेमोरी मैनेजर टार्गेट कमेड (KB) और करंट का उपयोग करना चाहिए। यदि आप अधिक पढ़ना चाहते हैं तो यह गलत मूल्य क्यों देता है। social.technet.microsoft.com/wiki/contents/articles/…
Shanky
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.