ฉันมีคลัสเตอร์ AlwaysOn ของ SQL Server 2019 ซึ่งมีกลุ่มความพร้อมใช้งาน 3 แบบจำลองในโหมดซิงโครนัส
ตาม เอกสารประกอบของ Microsoft:
- แบบจำลองรองทำให้บันทึกแข็งขึ้นและส่งกลับการรับทราบไปยังแบบจำลองหลัก
- เมื่อได้รับการยืนยันจากแบบจำลองรอง แบบจำลองหลักจะเสร็จสิ้นการประมวลผลคอมมิตและส่งข้อความยืนยันไปยังไคลเอ็นต์
บทความนี้ ลงรายละเอียดมากขึ้นและอธิบายว่า:
- ในแบบจำลองรอง การรับบันทึกจะได้รับบันทึกจากแบบจำลองหลักและเขียนไปยังแคชบันทึก กระบวนการนี้ซ้ำกับแบบจำลองรองแต่ละอันที่เข้าร่วมในโหมดซิงโครนัสคอมมิต
- บนแบบจำลองรองแต่ละอัน มีเธรด Redo อยู่ และเธรดจะเขียนการเปลี่ยนแปลงทั้งหมดที่กล่าวถึงในบันทึกไปยังหน้าข้อมูลและหน้าดัชนี มันล้างบันทึกสำหรับการชุบแข็งในบันทึกฐานข้อมูลรอง
- ตามที่ระบุไว้ก่อนหน้านี้ ในการส่งข้อมูลแบบซิงโครนัส แบบจำลองหลักจะรอการตอบรับจากแบบจำลองรอง ในขั้นตอนนี้ เรพลิเคตรองจะส่งการตอบรับว่าการทำให้แข็งของธุรกรรมเสร็จสมบูรณ์ในสตรอง
- เมื่อแบบจำลองหลักได้รับการตอบรับจากแบบจำลองรอง ก็จะส่งข้อความการทำธุรกรรมเสร็จสิ้นไปยังไคลเอนต์
ดังนั้นถ้าฉันเข้าใจถูกต้อง:
ถ้าฉันอัปเดตเรกคอร์ดผ่านแบบจำลองหลักสำเร็จ ค่าที่อัปเดตนี้ควรเป็น โดยทันที มีให้สำหรับลูกค้าที่สอบถามแบบจำลองรอง
อย่างไรก็ตาม เมื่อฉันทดสอบสิ่งนี้ มันใช้งานไม่ได้.
ฉันเรียกใช้แบตช์ไฟล์อย่างง่าย มีลักษณะดังนี้:
sqlcmd -E -S tcp:SQL-AG-Listener -d TestDB -Q "BEGIN TRANSACTION; UPDATE TestSyncTable SET CurrentTime='%currentTime%'; COMMIT TRANSACTION;"
sqlcmd -E -S tcp:SQL-Server01 -d TestDB -Q "เลือก * จาก TestSyncTable" -K อ่านอย่างเดียว
sqlcmd -E -S tcp:SQL-Server02 -d TestDB -Q "เลือก * จาก TestSyncTable" -K อ่านอย่างเดียว
sqlcmd -E -S tcp:SQL-Server03 -d TestDB -Q "เลือก * จาก TestSyncTable" -K อ่านอย่างเดียว
ดังนั้นฉันกำลังปรับปรุง เวลาปัจจุบัน
ฟิลด์ผ่านแบบจำลองหลัก (โฮสต์ AG Listener) จากนั้นอ่านทันทีผ่านแบบจำลองทั้งสาม แต่ละ ตร.ซม
คำสั่งเป็นกระบวนการไคลเอ็นต์แยกต่างหาก ดังนั้นจึงเปิดการเชื่อมต่อ TCP อิสระของตัวเอง
แล้วฉันเห็นสิ่งนี้:
SQL-Server01: CurrentTime = 20:02:19.93
SQL-Server02: เวลาปัจจุบัน = 20:02:16.94
SQL-Server03: เวลาปัจจุบัน = 20:02:19.93
(จัดรูปแบบเอาต์พุตใหม่เพื่อให้สามารถอ่านได้ดีขึ้นที่นี่)
เท่าที่ฉันได้เห็น แบบจำลองหลักจะส่งคืนค่าที่อัปเดตเสมอ และหน่วยรองก็เช่นกัน - แต่จะมีความล่าช้าเพียงเล็กน้อยเท่านั้น
ดังนั้นคำถามคือ: ทำไม โหมดซิงโครนัสไม่ควรรับประกันว่าผลลัพธ์ของการดำเนินการอ่านจะสอดคล้องกับการเขียนใช่หรือไม่ หากแบบจำลองรองส่งการรับทราบหลังจากเธรด Redo อัปเดตหน้าข้อมูลแล้วเท่านั้น จะเป็นไปได้อย่างไร
ขอบคุณ,
เมือก