SQL Server DB ไม่สามารถใช้งานข้ามคืนได้


9

เมื่อวานฐานข้อมูล SQL Server ของฉันใช้ได้ วันนี้มันเกือบจะใช้ไม่ได้ - มันช้าลงโดยมีปัจจัยระหว่างห้าถึงยี่สิบขึ้นอยู่กับเวลาที่ฉันโดนมัน

ข้อมูลบางอย่างถูกเพิ่มไปยังเซิร์ฟเวอร์ในกระบวนการโหลดข้ามคืน แต่ไม่มีอะไรเหมือนไดรฟ์ที่ควรส่งผลกระทบต่อฐานข้อมูลที่มาก ประมาณ 50,000 เรคคอร์ดข้อความธรรมดา (ไม่มี XML หรือ frippery อื่น ๆ )

เซิร์ฟเวอร์ได้รับการแก้ไขเมื่อเช้านี้ก่อนที่เราจะรีบูต อย่างไรก็ตามไม่มีเซิร์ฟเวอร์ฐานข้อมูลอื่น ๆ ของเราที่ได้รับการติดตั้งด้วยเช่นกัน

การตรวจสอบทรัพยากรดูเหมือนจะแนะนำว่าดิสก์ IO ของตนเป็นความผิดพลาด มันทำงานได้อย่างเต็มประสิทธิภาพ 100% ของความจุไฟล์. mdf ตลอดเวลาแม้ว่าจะมีฐานข้อมูลเกิดขึ้นไม่มากก็ตาม การเข้าถึง Templog.ldf ยังทำงานค่อนข้างสูง

ไม่มีใครที่นี่เป็นผู้เชี่ยวชาญ DBA (เราทุกคนเป็นนักพัฒนาที่มีทักษะ SQL แตกต่างกันจำนวนมาก) และเราทุกคนก็งงงันกับสิ่งที่เกิดขึ้น เราได้ลองใช้งาน sp_updatestats และย้ายดัชนีขนาดใหญ่ไปยังดิสก์ที่แตกต่างกันเพื่อไม่เกิดประโยชน์

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

เกิดอะไรขึ้นบนโลกนี้ เราจะทราบได้อย่างไรและเราจะแก้ไขได้อย่างไร

แก้ไข:

การใช้sp_WhoIsActiveไม่พบสิ่งผิดปกติ มันลงทะเบียนการใช้งาน sproc ของฉันเองและคำสั่งบางอย่างจากเพื่อนร่วมงานที่กำลังพยายามย้ายดัชนีอื่น ที่อาจถือ DB ในขณะนี้ แต่ก็ทำงานได้ไม่ดีเหมือนก่อน

เป็นรุ่นมาตรฐานของ SQL Server 2008 R2 SELECT @@VERSIONให้:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4033.0 (X64)
9 กรกฎาคม 2014 16:04:25
ลิขสิทธิ์ (c) Microsoft Corporation Standard Edition (64 บิต) บน Windows NT 6.1 (รุ่น 7601: Service Pack 1) (Hypervisor )

เซิร์ฟเวอร์นั้นมี RAM 72GB และโปรเซสเซอร์ Quad-Core 2GHz สามตัว

การแก้ไขถูกนำไปใช้กับ Windows เท่านั้น ไม่มีการเปลี่ยนแปลงอื่นนอกจากแพทช์

การตั้งค่าที่เลือก:

_id     name                        value   minimum     maximum     value_in_use    description                                 is_dynamic  is_advanced
1540    min memory per query (KB)   1024    512         2147483647  1024            minimum memory per query (kBytes)           1           1
1541    query wait (s)              -1      -1          2147483647  -1              maximum time to wait for query memory (s)   1           1
1543    min server memory (MB)      0       0           2147483647  16              Minimum size of server memory (MB)          1           1
1544    max server memory (MB)      65536   16          2147483647  65536           Maximum size of server memory (MB)          1           1

UPDATE: การย้ายดัชนีและตารางไปยังพาร์ติชันดิสก์ที่ต่างกันดูเหมือนว่ากำลังปรับปรุงสิ่งต่าง ๆ ฉันยังสับสนว่าเราจะไปถึงจุดเปลี่ยนได้อย่างไรในทันใดด้วยผลลัพธ์ที่รุนแรง


คุณสามารถเรียกใช้sp_whoisactive เป็นเวลา 5 นาทีและจับผลลัพธ์ไปยังตาราง คุณสามารถดาวน์โหลดได้จากที่นี่และจะแสดงวิธีการจับภาพเอาต์พุตไปยังตาราง
Kin Shah

ถ้าคุณรีสตาร์ทเซิร์ฟเวอร์นั่นหมายความว่าข้อมูลแคชทั้งหมดของคุณถูกทิ้งจากพูลบัฟเฟอร์และแผนการดำเนินการแคชทั้งหมดของคุณก็ถูกทิ้งเช่นกัน ซึ่งหมายความว่า SQL Server จะต้องเพิ่มทั้งสอง - แผนการดำเนินการทุกครั้งจะต้องรวบรวมใหม่และหากสถิติค้างคุณอาจไม่ได้รับแผนที่มีประสิทธิภาพมากที่สุด นอกจากนี้ยังหมายถึงข้อมูลที่จะต้องอ่านลงในหน่วยความจำจากดิสก์ในขณะที่ก่อนที่จะรีสตาร์ทอาจเป็นเสียงฮัมพร้อมกับข้อมูลในหน่วยความจำ สิ่งนี้ควรมีอายุสั้น
Aaron Bertrand

@AaronBertrand มันเป็นแบบนี้มาแปดชั่วโมงแล้ว เรารีบูทเซิร์ฟเวอร์เป็นประจำเพื่อทำการปะและไม่เคยสังเกตเห็นอะไรแบบนี้มาก่อน
Bob Tway

1
อย่าใช้ UI เพื่อตรวจสอบการตั้งค่า SELECT * FROM sys.configurations;- คุณต้องการสำหรับสิ่งที่ต้องการvalue, value_in_use max server memory (MB)ด้วยหมายเลขSELECT @@VERSION;บิลด์จะมีประโยชน์เช่นเดียวกับว่านี่เป็นไฮเปอร์ไวเซอร์และหากมีสิ่งใดเปลี่ยนแปลงบนโฮสต์ตั้งแต่เมื่อวาน (หรือตั้งแต่ครั้งล่าสุดที่ SQL Server เริ่มต้นใหม่)
Aaron Bertrand

2
คุณใช้ระบบย่อย IO ประเภทใด? SAN, โลคัลดิสก์, ฯลฯ ? มีโอกาสใดบ้างที่คุณบังเอิญไดรฟ์เสียหรือไม่? นอกจากนี้ยังมีฐานข้อมูลใด ๆ ของคุณที่จัดเก็บในตำแหน่งเดียวกับไฟล์ OS และคำถามสุดท้าย ส่วนหนึ่งของกระบวนการของเราก่อนที่จะทำการอัปเกรดระบบปฏิบัติการคือการทำสแน็ปช็อต VM ล่วงหน้า น่าเสียดายที่บุคคลที่รับผิดชอบลืมที่จะกระทำ เร็วมากทั้งระบบช้าลงและช้าลง มีโอกาสเกิดขึ้นกับคุณไหม?
Kenneth Fisher

คำตอบ:


3

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

มีเหตุผลพื้นฐาน 2 ประการที่เป็นไปได้สำหรับการชะลอตัวของคุณ

  1. คุณอัปเกรดระบบของคุณและรีบูตระบบ
  2. คุณโหลดข้อมูลจำนวนมากในนั้น

ลองดูที่ส่วนที่ 1

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

โปรดตรวจสอบในการตั้งค่าเซิร์ฟเวอร์พื้นฐานของคุณเป็นครั้งแรก ผู้ตั้งค่าพื้นฐานmax server memory, affinity I/O mask, และaffinity mask คุณอาจจะต้องเปิดใช้งานตัวเลือกขั้นสูงโดยใช้max degree of parallelismshow advanced options

นี่คือสคริปต์ที่สมบูรณ์:

-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'

เปรียบเทียบผลลัพธ์กับค่าเอกสารของคุณในขั้นตอนการติดตั้ง พวกเขายังคงเหมือนเดิมหรือไม่

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

ปัญหาอื่นอาจเป็นความสัมพันธ์ที่สูงถึงดิสก์หรือกระบวนการ ถ้าคุณใช้เซิร์ฟเวอร์ที่ใช้ร่วมกัน (SQL Server + บริการอื่น ๆ ) กับดิสก์เฉพาะสำหรับ SQL Server (ซึ่งอาจเป็นกรณีที่ไม่ค่อยพบ แต่อาจเป็นได้) นี่อาจเป็นปัญหาของคุณ โดยปกติเซิร์ฟเวอร์ของคุณเคยมีตัวอย่าง 3 cpus สำหรับกระบวนการและอีกหนึ่งตัวสำหรับ I / O อีก 12 ซีพียูใช้สำหรับบริการอื่น ๆ ในกรณีนี้รูปแบบความสัมพันธ์ของคุณผิดและใช้ตัวอย่างเช่นการกำหนดค่าอัตโนมัติ นี่หมายความว่าเซิร์ฟเวอร์ของคุณใช้ 16 คอร์ทั้งหมดสำหรับกระบวนการและ I / O แบบไดนามิก หากคุณมีกระบวนการขนาดใหญ่ที่ทำงานอยู่พวกเขาสามารถวางแผ่นดิสก์จำนวนมากซึ่งไม่สามารถจัดการได้ แต่ในความเป็นจริงฉันไม่เชื่อว่านี่เป็นกรณีของคุณ มันจะเร็วขึ้น (แม้ว่าจะเป็นเพียงเล็กน้อย) หากเป็นไปได้ แต่กรณีของคุณช้าลง

ปัญหาอื่นอาจเกิดจากการขนานที่สูงเกินไป ซึ่งหมายความว่าคุณมีเธรดจำนวนมากที่ไม่ทำงานบนเคียวรีบางส่วน สิ่งนี้อาจทำให้ช้าลงอย่างมากหากความขนานไม่ทำงานตามที่คาดไว้ แต่นี่จะไม่อธิบาย I / O สูงทั้งหมดของคุณ

ทีนี้ลองดูส่วนที่ 2 ด้วย

คุณโหลดหลายแถวเข้าสู่ระบบของคุณ แม้ว่านี่จะเป็นงานปกติ แต่ก็สามารถเพิ่มขีด จำกัด ที่แผนแบบสอบถามของคุณเพิ่มขึ้น อาจเป็นได้ว่าในกรณีที่การแทรกของคุณร่วมกับ SQL Server ก่อให้เกิดพฤติกรรมนี้

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

อาจเป็นได้ว่าดัชนีของคุณแตกหัก, แผนของคุณแตกหักหรือว่าสถิติของคุณล้าสมัยไปแล้ว

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

SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes

สิ่งนี้จะให้ข้อมูลที่สมบูรณ์กับแต่ละดัชนี (และฮีป) และสถิติเบื้องหลัง แม้ว่าคุณจะรันsp_updatestatsมันไม่ได้หมายความว่าสถิติได้รับการปรับปรุง ส่วนเมื่อมีการอัพเดทค่อนข้างยุ่งยากแม้ว่าคุณจะทำงานsp_updatestatsหรือแม้กระทั่งถ้าauto update statisticsมีการเปิดใช้สถิติที่จะไม่ได้รับการปรับปรุงเพียงในเวลา นี่คือบางจุดที่ขอบเมื่อต้องการการปรับปรุง / สร้าง:

  • ตารางว่างรับหนึ่งแถวขึ้นไป
  • ตารางที่มีแถวมากกว่า 500 แถวจะอัปเดตเพิ่มเติม 20% + 500 แถวและมีการแทรกเกิดขึ้นในภายหลัง
  • เมื่อมีการเปลี่ยนแปลง 500 แถวในตารางที่มีน้อยกว่า 500 แถว

ซึ่งหมายความว่าสถิติของคุณอาจล้าสมัยแม้ว่าคุณจะรันการอัพเดทก็ตาม

คุณสามารถดูคำถามข้างต้น หากคุณพบสถิติเก่า ๆ ในบางตารางคุณอาจต้องการเรียกใช้การปรับปรุงสถิติด้วยตนเองสำหรับตารางนี้:

UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN

หลังจากนั้นคุณอาจต้องการให้เซิร์ฟเวอร์ของคุณเตะในลาเพื่อทิ้งแผนเก่าทั้งหมด

DBCC FREEPROCCACHE 

หากคุณต้องการล้างแคชทั้งหมดคุณอาจต้องการเรียกใช้สิ่งนี้แทน:

DBCC FREESYSTEMCACHE ('ALL')

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

เหตุผลอื่นอาจเป็นดัชนีแยกส่วนโดยสิ้นเชิง สามารถตรวจสอบได้บนเซิร์ฟเวอร์ทั้งหมดโดยใช้คำสั่งนี้:

SELECT * 
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)

หากการแตกแฟรกเมนต์สูงมากคุณอาจต้องจัดระเบียบใหม่ (การแตกแฟรกเมนต์ <20%) หรือสร้างใหม่ทั้งหมด (> 20%) การทำเช่นนี้อาจทำให้เกิดแรงกดดันต่อแผ่นดิสก์ของคุณและทำให้เกิดปัญหา ในทางกลับกันหากดัชนีเป็นสิ่งที่ไม่ดีมันอาจจะช่วยได้ในท้ายที่สุดมากกว่าจะเป็นอันตราย

นอกเหนือจากเหตุผลสองข้อนั้นยังอาจมีปัญหาที่สาม

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

คุณสามารถตรวจสอบได้โดยใช้คำสั่งนี้:

SELECT * FROM sys.dm_exec_query_memory_grants

มันจะให้รายการของเซสชันทั้งหมดที่ใช้หน่วยความจำ อาจมีข้อความค้นหาบางส่วนที่ยังรอรับหน่วยความจำอยู่ สามารถกรองแบบสอบถามเหล่านั้นได้อย่างง่ายดาย granted_memory_kb IS NULLทุกครั้งที่ นี่คือเซสชันที่ร้องขอหน่วยความจำ แต่ไม่ได้รับ อีกสิ่งหนึ่งอาจเป็นหน่วยความจำที่ได้รับซึ่งอาจต่ำ คุณสามารถเปรียบเทียบคอลัมน์ด้วยrequested_memory_kb granted_memory_kbร้องขอแสดงจำนวนหน่วยความจำที่กระบวนการต้องการให้ทำงานได้ดีที่สุดในขณะที่ให้สิทธิ์แสดงหน่วยความจำที่เปิดใช้งานสำหรับกระบวนการ หากกระบวนการต้องการใช้งาน 2GB แต่ได้รับเพียง 2MB ... คุณอาจได้รับด้วยตัวเอง ;-)

อีกวิธีคือตรวจสอบRESSOURCE_SEMAPHORE:

SELECT * FROM sys.dm_exec_query_resource_semaphore

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


0

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

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