Puncte:1

Consecvența datelor în SQL AlwaysOn Availability Group

drapel ng

Am un cluster AlwaysOn al SQL Server 2019, care conține un grup de disponibilitate de 3 replici în modul sincron. Conform documentația Microsoft:

  1. Replica secundară întărește jurnalul și returnează o confirmare la replica primară.
  2. La primirea confirmării de la replica secundară, replica primară termină procesarea de comitere și trimite un mesaj de confirmare clientului.

Acest articol intră în mai multe detalii și explică că:

  1. În replica secundară, Log Receive primește înregistrările jurnal din replica principală și scrie în Log cache. Acest proces se repetă pe fiecare replică secundară care participă în modul de confirmare sincronă.
  2. Pe fiecare replică secundară, există firul Redo și scrie toate modificările menționate în înregistrările de jurnal în pagina de date și în pagina de index. Acesta șterge jurnalul pentru întărire pe jurnalul secundar al bazei de date.
  3. După cum sa menționat mai devreme, în comiterea datelor sincrone, replica primară așteaptă confirmarea de la replica secundară. În această etapă, replica secundară trimite o confirmare că întărirea tranzacției este finalizată pe secundar.
  4. Odată ce replica primară primește o confirmare de la replica secundară, aceasta trimite clientului mesajul de finalizare a tranzacției.

Deci daca am inteles bine: Dacă actualizez cu succes o înregistrare prin replica primară, această valoare actualizată ar trebui să fie imediat disponibil pentru clienții care interoghează replicile secundare.

Totuși, când testez asta, asta nu merge asa. Rulez un fișier batch simplu, arătând astfel:

sqlcmd -E -S tcp:SQL-AG-Listener -d TestDB -Q "ÎNCEPE TRANZACȚIA; UPDATE TestSyncTable SET CurrentTime='%currentTime%'; COMMIT TRANZACȚIE;"
sqlcmd -E -S tcp:SQL-Server01 -d TestDB -Q „SELECT * FROM TestSyncTable” -K ReadOnly
sqlcmd -E -S tcp:SQL-Server02 -d TestDB -Q „SELECT * FROM TestSyncTable” -K ReadOnly
sqlcmd -E -S tcp:SQL-Server03 -d TestDB -Q „SELECT * FROM TestSyncTable” -K ReadOnly

Așa că actualizez Ora curentă câmp prin replica principală (găzduind ascultătorul AG) și apoi citiți-l imediat prin toate cele trei replici. Fiecare sqlcmd comanda este un proces client separat, deci își deschide propria conexiune TCP independentă.

Și apoi văd ceva de genul:

SQL-Server01: CurrentTime = 20:02:19.93
SQL-Server02: CurrentTime = 20:02:16.94
SQL-Server03: CurrentTime = 20:02:19.93

(Reformatat ieșirea pentru o mai bună lizibilitate aici)

Din câte am văzut, replica primară returnează întotdeauna valoarea actualizată. Și secundarele o fac, dar doar o scurtă întârziere.

Deci intrebarea este: De ce? Modul Sincron nu ar trebui să garanteze că rezultatul operației de citire este în concordanță cu cel de scriere? Dacă replica secundară trimite confirmarea numai după ce firul său Redo actualizează pagina de date - atunci cum poate fi?

Mulțumiri, Mucius.

Puncte:1
drapel cn

Din același articol SQL Shack pe care l-ați citat în întrebarea dvs.:

  1. Replica secundară conține, de asemenea, un fir de refacere și este independent de procesul de blocare a jurnalului din SQL Server Always on. Refacere fire citește jurnalele din memoria cache. Este posibil să existe o întârziere în procesarea prin refacerea firului de execuție și este posibil ca înregistrările de jurnal să nu fie disponibile în memoria cache a jurnalului, deoarece este deja întărită pe disc. În acest caz, refaceți firul de citire blocurile de jurnal de pe discul de jurnal.

Ceea ce am citit că înseamnă că procesul de întărire a jurnalului nu face modificările imediat disponibile în baza de date secundară, ci mai degrabă că firul de refacere de pe secundar trebuie să le proceseze mai întâi.

Cat Mucius avatar
drapel ng
Da, se pare că articolul #6 din SQL Shack este înșelător. Procesul care scrie modificări în baza de date în sine este independent de procesul de consolidare a jurnalului, iar confirmarea trimisă la replica primară fără a depinde de activitatea sa. Acest articol Microsoft acceptă și acest lucru: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2012/dn135338(v=sql.110)

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.