ประสิทธิภาพของเซิร์ฟเวอร์ SQL ช้าลงหลังจากจัดสรร CPU และ RAM เพิ่มเติม


33

เรามี SQL Server 2008 R2 (10.50.1600) ที่ทำงานบนเซิร์ฟเวอร์ Windows 2008 R2 เสมือน หลังจากอัปเกรด CPU จาก 1 คอร์เป็น 4 และแรมจาก 4 gb เป็น 10 gb เราได้สังเกตเห็นว่าประสิทธิภาพแย่ลง

ข้อสังเกตบางอย่างที่ฉันเห็น:

  1. ข้อความค้นหาที่ใช้เวลา <5 วินาทีในการทำงาน> 200 วินาที
  2. ซีพียูถูกตรึงที่ 100 กับ sqlservr.exe เป็นผู้ร้าย
  3. จำนวนที่เลือก (*) บนตารางที่มี 4.6 ล้านแถวใช้เวลามากกว่า 90 วินาที
  4. กระบวนการที่ทำงานบนเซิร์ฟเวอร์ไม่ได้เปลี่ยนแปลง การเปลี่ยนแปลงเพียงอย่างเดียวคือการเพิ่มซีพียูและแรม
  5. เซิร์ฟเวอร์ sql อื่นมีไฟล์เก็บเพจแบบสแตติกซึ่งเซิร์ฟเวอร์นี้ถูกตั้งค่าให้จัดการด้วยตนเอง

มีใครประสบปัญหานี้มาก่อนหรือไม่

ต่อ sp_Blitz เอริคฉันวิ่ง

EXEC dbo.sp_BlitzFirst @SinceStartup = 1;

ให้ผลลัพธ์เหล่านี้กับฉัน

รอสถิติ


9
ครั้งสุดท้ายที่ผมเห็นคำถามที่คล้ายกันใน SE มันเป็นเพราะคนหันขึ้น VM ซีพียูและแรมแต่โฮสต์ VM ไม่ได้จริงมีว่าซีพียูจำนวนมากและใช้ RAM ดังนั้นฉันจะตรวจสอบก่อน
user253751

คำตอบ:


55

มีหลายอย่างเกิดขึ้นที่นี่และส่วนใหญ่ค่อนข้างกว้างและคลุมเครือ

  1. 2008R2 RTM ออกมาในวันที่ 21 เมษายน 2010 ซึ่งไม่ได้รับการสนับสนุนทั้งหมด คุณต้องการจัดลำดับความสำคัญในการรับ Service Pack ล่าสุดซึ่งออกมาเมื่อประมาณ 3 ปีที่แล้วจนถึงวันนี้ ด้วยวิธีนี้คุณจะได้รับการคุ้มครองหากคุณพบข้อผิดพลาดแปลก ๆ หรืออะไรบางอย่าง ตรงไปที่นี่เพื่อหาว่าคุณต้องดาวน์โหลดอะไร

  2. เมื่อคุณเพิ่ม vCPU (ตั้งแต่ 1 ถึง 4) และไม่ได้เปลี่ยนการตั้งค่าใด ๆ ตอนนี้แบบสอบถามของคุณจะสามารถขนานกันได้ ฉันรู้ว่ามันฟังดูเหมือนว่าพวกเขาทั้งหมดจะเร็วขึ้น แต่แขวนไว้!

  3. คุณอาจเพิ่ม RAM แต่คุณอาจไม่ได้เปลี่ยน Max Server Memory เพื่อให้เซิร์ฟเวอร์ของคุณสามารถใช้ประโยชน์จากมันได้

  4. คิดออกว่าเซิร์ฟเวอร์ของคุณกำลังรออะไรอยู่ โครงการโอเพ่นซอร์สที่ฉันทำงานให้สคริปต์ฟรีเพื่อช่วยคุณวัด SQL Server ของคุณ หัวมากกว่าที่นี่ถ้าคุณต้องการที่จะให้พวกเขาลอง

คุณจะต้องการคว้า sp_BlitzFirst เพื่อตรวจสอบสถานะการรอของเซิร์ฟเวอร์ของคุณ คุณสามารถรันได้สองวิธี

นี่จะแสดงให้คุณเห็นว่าเซิร์ฟเวอร์ของคุณกำลังรออะไรอยู่ตั้งแต่เปิดเครื่อง

EXEC dbo.sp_BlitzFirst @SinceStartup = 1;

สิ่งนี้จะแสดงให้คุณทราบว่าข้อความค้นหาใดกำลังรออยู่ในระหว่างหน้าต่าง 30 วินาที

EXEC dbo.sp_BlitzFirst @Seconds = 30, @ExpertMode = 1;

เมื่อคุณทราบว่ามีข้อความค้นหาใดบ้าง (มีข้อความมากมายเกี่ยวกับการรอสถิติอยู่) คุณสามารถเริ่มทำการเปลี่ยนแปลงเพื่อให้ได้สิ่งต่าง ๆ ภายใต้การควบคุม

หากคุณเห็นพวกเขารออยู่CXPACKETนั่นหมายความว่าข้อความค้นหาของคุณกำลังขนานกันและอาจเหยียบย่ำกัน หากคุณพบสิ่งนี้คุณอาจต้องการพิจารณาเกณฑ์ค่าใช้จ่ายในการชนสำหรับ Parallelism สูงสุด 50 และอาจลด MAXDOP ลงเหลือ 2

หลังจากขั้นตอนนี้คือเมื่อคุณต้องการใช้บางสิ่งบางอย่างเช่นsp_WhoIsActiveหรือ sp_BlitzWho (ขั้นตอนหลังอยู่ใน GitHub repo จากก่อนหน้านี้) เพื่อเริ่มเก็บแผนแบบสอบถาม นอกเหนือจากสถานะการรอแล้วพวกเขายังเป็นหนึ่งในสิ่งที่สำคัญที่สุดที่คุณสามารถดูได้ว่าเกิดอะไรขึ้น

คุณอาจต้องการตรวจสอบบทความนี้โดย Jonathan Kehayias เกี่ยวกับVMWare Countersเพื่อตรวจสอบที่เกี่ยวข้องกับ SQL Server

ปรับปรุง

การตรวจสอบสถิติการรอคอยและเด็กชายเป็นสิ่งที่แปลก มีอะไรบางอย่างเกิดขึ้นกับซีพียู เซิร์ฟเวอร์ของคุณส่วนใหญ่นั่งเบื่อ ๆ อยู่ แต่เมื่อสิ่งต่างๆร้อนจัดสิ่งเลวร้าย ฉันจะพยายามทำลายมันให้ง่ายขึ้น

  1. คุณกำลังกดปุ่มรอพิษTHREADPOOLที่เรียกว่า คุณไม่มีตัน แต่มันก็สมเหตุสมผลเพราะเซิร์ฟเวอร์ของคุณไม่ทำงานหนักมาก ฉันจะอธิบายว่าทำไมในไม่กี่นาที

  2. คุณต้องรอนานจริงๆเฉลี่ยและSOS_SCHEDULER_YIELD CXPACKETคุณอยู่บน VM ดังนั้นคุณจะต้องตรวจสอบให้แน่ใจว่า SQL Server มีการจองหรือกล่องนั้นไม่ได้มีการสมัครสมาชิกมากเกินไป เพื่อนบ้านที่มีเสียงดังสามารถทำลายวันของคุณที่นี่อย่างแท้จริง คุณต้องแน่ใจว่าเซิร์ฟเวอร์ / VM guest / VM host ไม่ได้ทำงานในโหมด Balanced Power สิ่งนี้ทำให้ซีพียูของคุณหมุนไปที่ความเร็วต่ำโดยไม่จำเป็นและจะไม่หมุนกลับเป็นความเร็วเต็มทันที

  3. พวกเขาจะผูกได้อย่างไร ด้วย 4 ซีพียูคุณจะมี 512 เธรดผู้ทำงาน โปรดทราบว่าคุณมีจำนวนเท่ากันโดยใช้ซีพียูตัวเดียว แต่เมื่อเคียวรีของคุณสามารถขนานกันได้พวกเขาสามารถใช้เธรดผู้ทำงานได้มากขึ้น ในกรณีของคุณ 4 กระทู้ต่อสาขาขนานของแบบสอบถามแบบขนาน

ขนานกันคืออะไร เป็นไปได้มากที่สุดทุกอย่าง เกณฑ์ค่าใช้จ่ายเริ่มต้นสำหรับความเท่าเทียมเป็น 5. มีจำนวนที่ถูกสร้างขึ้นบางครั้งค่าเริ่มต้นในช่วงปลายยุค 90 ที่ทำงานบนเดสก์ทอปที่มองเช่นนี้

ถั่ว

จริงอยู่ที่ฮาร์ดแวร์ของคุณมีขนาดเล็กกว่าแล็ปท็อปส่วนใหญ่ แต่คุณยังคงล้ำหน้ากว่านี้อยู่

เมื่อมีการค้นหาแบบขนานจำนวนมากเกิดขึ้นคุณจะไม่มีเธรดผู้ทำงานเหล่านั้นหมด เมื่อสิ่งนั้นเกิดขึ้นเคียวรีจะรอให้เธรดดำเนินต่อไป นอกจากนี้ยังมีที่SOS_SCHEDULER_YIELDมาด้วยคำค้นหากำลังปิดซีพียูและไม่กลับมาเป็นเวลานาน ฉันไม่เห็นการปิดกั้นใด ๆ รอดังนั้นคุณน่าจะเป็นเพียงแค่ทั้งหมดที่อัดแน่นไปด้วยความเท่าเทียมกันภายในแบบสอบถามแบบสอบถามรอ

คุณทำอะไรได้บ้าง?

  1. ตรวจสอบให้แน่ใจว่าไม่มีสิ่งใดในโหมดสมดุลพลังงาน
  2. เปลี่ยน MAXDOP เป็น 2
  3. เปลี่ยนเกณฑ์ต้นทุนสำหรับการขนานเป็น 50
  4. ทำตามบทความ Jon K. ด้านบนเพื่อตรวจสอบสุขภาพ VM
  5. ใช้สคริปต์ที่เรียกว่าsp_BlitzIndexเพื่อค้นหาคำขอดัชนีที่ขาดหายไป

สำหรับการแก้ไขปัญหาอย่างละเอียดยิ่งขึ้นให้ตรวจสอบกระดาษขาวที่ฉันเขียนให้ Googleเกี่ยวกับการปรับขนาดฮาร์ดแวร์ในคลาวด์

หวังว่านี่จะช่วยได้!


8

ใช่ ฉันเคยประสบกับสถานการณ์ประเภทนี้ใน SQL Server vms ในเซิร์ฟเวอร์ฟาร์มของเรา ดูซีพียูที่โฮสต์ของ vm พร้อมและตัวนับบอลลูนควบคุมหน่วยความจำ CPU พร้อมเวลา - บล็อกส่วนที่ 1และการ ทำความเข้าใจกับ VMware Ballooning การทำงานกับดูแลระบบของฉันเป็นกุญแจสำคัญ แต่ไม่ใช่เรื่องง่าย ...


5

สิ่งหนึ่งที่ฉันไม่เห็นชัดเจนคือการเพิ่ม vCPU ลงใน VM สามารถทำให้ช้าลงได้มากเนื่องจากการตั้งเวลา

แนวคิดพื้นฐานคือถ้า VM มี 4 vCPU ดังนั้นไฮเปอร์ไวเซอร์จะต้องรอให้มีฟิสิคัลคอร์ 4 คอร์เพื่อให้สามารถกำหนดตารางเวลาของ vCPU ทั้งหมดแม้ว่า 3 นั้นจะว่าง

หากคุณไม่มีคอร์จำนวนมากในโฮสต์ของคุณและปริมาณงานอื่น ๆ ของคุณไม่ว่างนี่อาจส่งผลให้ต้องรอเป็นพิเศษและประสิทธิภาพลดลงอย่างมาก

ใน VMware ESXi คุณสามารถดูได้ในกราฟขั้นสูงผ่าน CPU Ready

นี่คือหนึ่งในบทความจำนวนมากที่มีตัวอย่างที่โลกแห่งความจริงที่เกิดขึ้นนี้และวิธีที่จะได้รับการวินิจฉัย

การเพิ่ม RAM เพิ่มเติมอาจทำให้ประสิทธิภาพลดลงอย่างกะทันหันหากการจัดสรร RAM ของ VM มีขนาดใหญ่กว่าโหนด NUMA

นอกจากนี้การกำหนดค่า vCPU ของคุณ (vSockets vs. vCores) อาจส่งผลกระทบต่อแอปพลิเคชันบางอย่างเช่นเซิร์ฟเวอร์ SQL นี่เป็นเพราะเซิร์ฟเวอร์ SQL เป็นตัวรับรู้ NUMA (เพื่อหลีกเลี่ยงการลดลงของประสิทธิภาพการสแกนแบบ NUMA แบบเดียวกัน) และเนื่องจาก VMware อาจแสดงโหนด NUMA เสมือนที่แตกต่างกัน

นี้จะครอบคลุมในบล็อกโพสต์บนเว็บไซต์ของตัวเองของ VMware


สิ่งนี้ถูกกล่าวว่าฉันดีใจที่คุณแก้ปัญหาด้วยความช่วยเหลือของ Erik แต่คุณอาจต้องการดูและพิจารณาสิ่งเหล่านี้เช่นกัน


3

เพียงแค่ความช่วยเหลือเล็กน้อย (ไม่สามารถโพสต์สิ่งนี้เป็นความคิดเห็น) ดำเนินการตามคำตอบของ @ sp_BlitzErik ต่อไปฉันได้รับการสอบถามเกี่ยวกับ Pinal และ Max Vernon (ไม่สามารถจำได้ว่าที่ไหน) ที่พูดว่าคุณควรใช้ MAXDOP มากเท่าใด:

/*************************************************************************
Author          :   Kin Shah
Purpose         :   Recommend MaxDop settings for the server instance
Tested RDBMS    :   SQL Server 2008R2

**************************************************************************/
declare @hyperthreadingRatio bit
declare @logicalCPUs int
declare @HTEnabled int
declare @physicalCPU int
declare @SOCKET int
declare @logicalCPUPerNuma int
declare @NoOfNUMA int

select @logicalCPUs = cpu_count -- [Logical CPU Count]
    ,@hyperthreadingRatio = hyperthread_ratio --  [Hyperthread Ratio]
    ,@physicalCPU = cpu_count / hyperthread_ratio -- [Physical CPU Count]
    ,@HTEnabled = case 
        when cpu_count > hyperthread_ratio
            then 1
        else 0
        end -- HTEnabled
from sys.dm_os_sys_info
option (recompile);

select @logicalCPUPerNuma = COUNT(parent_node_id) -- [NumberOfLogicalProcessorsPerNuma]
from sys.dm_os_schedulers
where [status] = 'VISIBLE ONLINE'
    and parent_node_id < 64
group by parent_node_id
option (recompile);

select @NoOfNUMA = count(distinct parent_node_id)
from sys.dm_os_schedulers -- find NO OF NUMA Nodes 
where [status] = 'VISIBLE ONLINE'
    and parent_node_id < 64

-- Report the recommendations ....
select
    --- 8 or less processors and NO HT enabled
    case 
        when @logicalCPUs < 8
            and @HTEnabled = 0
            then 'MAXDOP setting should be : ' + CAST(@logicalCPUs as varchar(3))
                --- 8 or more processors and NO HT enabled
        when @logicalCPUs >= 8
            and @HTEnabled = 0
            then 'MAXDOP setting should be : 8'
                --- 8 or more processors and HT enabled and NO NUMA
        when @logicalCPUs >= 8
            and @HTEnabled = 1
            and @NoofNUMA = 1
            then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
                --- 8 or more processors and HT enabled and NUMA
        when @logicalCPUs >= 8
            and @HTEnabled = 1
            and @NoofNUMA > 1
            then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
        else ''
        end as Recommendations

-------------------------------------------------- -------

--MAX VERNON 

/* 
   This will recommend a MAXDOP setting appropriate for your machine's NUMA memory
   configuration.  You will need to evaluate this setting in a non-production 
   environment before moving it to production.

   MAXDOP can be configured using:  
   EXEC sp_configure 'max degree of parallelism',X;
   RECONFIGURE

   If this instance is hosting a Sharepoint database, you MUST specify MAXDOP=1 
   (URL wrapped for readability)
   http://blogs.msdn.com/b/rcormier/archive/2012/10/25/
   you-shall-configure-your-maxdop-when-using-sharepoint-2013.aspx

   Biztalk (all versions, including 2010): 
   MAXDOP = 1 is only required on the BizTalk Message Box
   database server(s), and must not be changed; all other servers hosting other 
   BizTalk Server databases may return this value to 0 if set.
   http://support.microsoft.com/kb/899000
*/
SET NOCOUNT ON;

DECLARE @CoreCount int;
SET @CoreCount = 0;
DECLARE @NumaNodes int;

/*  see if xp_cmdshell is enabled, so we can try to use 
    PowerShell to determine the real core count
*/
DECLARE @T TABLE (
    name varchar(255)
    , minimum int
    , maximum int
    , config_value int
    , run_value int
);
INSERT INTO @T 
EXEC sp_configure 'xp_cmdshell';
DECLARE @cmdshellEnabled BIT;
SET @cmdshellEnabled = 0;
SELECT @cmdshellEnabled = 1 
FROM @T
WHERE run_value = 1;
IF @cmdshellEnabled = 1
BEGIN
    CREATE TABLE #cmdshell
    (
        txt VARCHAR(255)
    );
    INSERT INTO #cmdshell (txt)
    EXEC xp_cmdshell 'powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace "root\CIMV2" -class Win32_Processor -Property NumberOfCores} | select NumberOfCores"';
    SELECT @CoreCount = CONVERT(INT, LTRIM(RTRIM(txt)))
    FROM #cmdshell
    WHERE ISNUMERIC(LTRIM(RTRIM(txt)))=1;
    DROP TABLE #cmdshell;
END
IF @CoreCount = 0 
BEGIN
    /* 
        Could not use PowerShell to get the corecount, use SQL Server's 
        unreliable number.  For machines with hyperthreading enabled
        this number is (typically) twice the physical core count.
    */
    SET @CoreCount = (SELECT i.cpu_count from sys.dm_os_sys_info i); 
END

SET @NumaNodes = (
    SELECT MAX(c.memory_node_id) + 1 
    FROM sys.dm_os_memory_clerks c 
    WHERE memory_node_id < 64
    );

DECLARE @MaxDOP int;

/* 3/4 of Total Cores in Machine */
SET @MaxDOP = @CoreCount * 0.75; 

/* if @MaxDOP is greater than the per NUMA node
    Core Count, set @MaxDOP = per NUMA node core count
*/
IF @MaxDOP > (@CoreCount / @NumaNodes) 
    SET @MaxDOP = (@CoreCount / @NumaNodes) * 0.75;

/*
    Reduce @MaxDOP to an even number 
*/
SET @MaxDOP = @MaxDOP - (@MaxDOP % 2);

/* Cap MAXDOP at 8, according to Microsoft */
IF @MaxDOP > 8 SET @MaxDOP = 8;

PRINT 'Suggested MAXDOP = ' + CAST(@MaxDOP as varchar(max));

สคริปต์ตัวแรกส่งคืนผลลัพธ์เปล่า วินาทีส่งคืนข้อเสนอแนะMAXDOP = 2ที่สอดคล้องกับ @sp_BlitzErik ขอบคุณ!
Jeff
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.