วิธีที่ดีในการโทรงานตัวแทนของเซิร์ฟเวอร์ SQL หลายงานตามลำดับจากงานหลักหนึ่งงานหรือไม่


11

ฉันมีงานตัวแทนของเซิร์ฟเวอร์ SQL หลายงานที่ควรเรียกใช้ตามลำดับ เพื่อให้ภาพรวมที่ดีของงานที่ควรจะดำเนินการฉันได้สร้างงานหลักที่เรียกงานอื่น ๆ EXEC msdb.dbo.sp_start_job N'TEST1'ที่มีการเรียกร้องให้ sp_start_jobเสร็จสิ้นทันที (งานขั้นตอนที่ 1) แต่แล้วฉันต้องการงานหลักของฉันจะรอจนกว่างานTEST1จะเสร็จสิ้นก่อนที่จะเรียกงานต่อไป

ดังนั้นฉันจึงได้เขียนสคริปต์ขนาดเล็กนี้ที่เริ่มดำเนินการทันทีหลังจากงานถูกเรียก (ขั้นตอนงาน 2) และบังคับให้งานหลักรอจนกว่างานย่อยจะเสร็จสิ้น:

WHILE 1 = 1
  BEGIN
    WAITFOR DELAY '00:05:00.000';

    SELECT *
    INTO   #jobs
    FROM   OPENROWSET('SQLNCLI', 'Server=TESTSERVER;Trusted_Connection=yes;',
           'EXEC msdb.dbo.sp_help_job @job_name = N''TEST1'',
           @execution_status = 0, @job_aspect = N''JOB''');

    IF NOT (EXISTS (SELECT top 1 * FROM #jobs))
      BEGIN
        BREAK
      END;

    DROP TABLE #jobs;

  END;

มันใช้งานได้ดีพอ แต่ฉันได้รับความรู้สึกที่ชาญฉลาดและ / หรือWHILE 1 = 1วิธีแก้ปัญหาที่ปลอดภัยกว่า ( ?) ควรเป็นไปได้

ฉันอยากรู้เกี่ยวกับสิ่งต่าง ๆ ต่อไปนี้หวังว่าคุณจะสามารถให้ข้อมูลเชิงลึกแก่ฉัน:

  • อะไรคือปัญหาของวิธีการนี้?
  • คุณช่วยแนะนำวิธีที่ดีกว่าให้ทำสิ่งนี้ได้ไหม?

(ฉันโพสต์คำถามนี้ที่StackOverflowก่อนเพราะฉันมุ่งเน้นไปที่การปรับปรุงโค้ดยังคงใช้ได้ แต่ฉันเดาว่าคนทั่วไปที่นี่จะมีสิ่งที่ฉลาดกว่าที่จะพูดเกี่ยวกับสาเหตุที่ฉันไม่ควรพยายามทำสิ่งนี้ในแบบของฉัน m ทำมันตอนนี้หรือเสนอทางเลือกที่ดี)

แก้ไข (25 กรกฎาคม)
เห็นได้ชัดว่าสคริปต์ของฉันไม่ผิดมากนักตามคำตอบที่มีจำนวนน้อยซึ่งชี้ให้เห็นปัญหาที่เกิดขึ้นกับมัน :-) ทางเลือกของสคริปต์ประเภทนี้ดูเหมือนจะใช้เครื่องมือที่ออกแบบมาสำหรับสิ่งเหล่านี้ งาน (เช่น SQL Sentry Event Manager หรือ ... ) - หรือเพื่อเขียนเครื่องมือด้วยตัวเอง เราจะไม่ซื้อเครื่องมือเช่นนี้ที่ บริษัท ปัจจุบันของฉันดังนั้นตอนนี้ฉันจะติดกับสคริปต์


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

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

คำตอบ:


9

ข้อจำกัดความรับผิดชอบ: ฉันทำงานกับ SQL Sentry

ผลิตภัณฑ์ตัวจัดการเหตุการณ์ SQL Sentryของเรามีสิ่งอำนวยความสะดวกที่สร้างขึ้นสำหรับสิ่งนี้: เพื่อเชื่อมโยงงานและจัดเรียงไว้ในคำสั่งเวิร์กโฟลว์ต่างๆ

ฉันเริ่มใช้ SQL Sentry เมื่อหลายปีก่อนก่อนที่ฉันจะเข้าร่วม บริษัท เพื่อทำสิ่งนี้ สิ่งที่ฉันต้องการคือวิธีเริ่มงานคืนค่าบนเซิร์ฟเวอร์ทดสอบของเราทันทีหลังจากการสำรองข้อมูลในการผลิตเสร็จสิ้น

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

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

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

ป้อนคำอธิบายรูปภาพที่นี่

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


2

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

ดังนั้นวิธีการเกี่ยวกับการใช้วิธีการข้อมูลกับปัญหาของคุณ? ตัวอย่างเช่นสร้างตาราง 'การตรวจสอบ' ที่แต่ละงานเขียนถึงเมื่อเริ่มต้นและเสร็จสิ้น:

ชื่องาน | เริ่มเวลา | เวลาสิ้นสุด
--------- + + ------------------ -------------------
ทดสอบ 1 2012-07-26 07:30 2012-07-26 07:35

สร้างตาราง 'การประมวลผล' ที่แสดงรายการงานทั้งหมดและลำดับที่ต้องดำเนินการใน:

ชื่องาน | เรียกใช้คำสั่ง
--------- + ---------
ทดสอบ 1 | 1
ทดสอบ 2 | 2
ทดสอบ 3 | 3

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

ประโยชน์ของวิธีนี้คือ:

  1. มันค่อนข้างง่ายในการพัฒนาและบำรุงรักษา
  2. มันให้ความสามารถในการเพิ่มงานใหม่หรือเปลี่ยนลำดับของงานที่มีอยู่ผ่านตารางการประมวลผลโดยไม่ต้องเปลี่ยนบรรทัดของรหัส
  3. ตารางการตรวจสอบจะให้ทัศนวิสัยว่าเกิดอะไรขึ้น
  4. ไม่เสียรอบ CPU ทริกเกอร์จะยิงก็ต่อเมื่อมีบางอย่างเกิดขึ้น
  5. มันรู้สึก 😉ขวา

HTH


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