question

CatMucius avatar image
0 Votes"
CatMucius asked CatMucius commented

Data consistency in SQL AlwaysOn Availability Group

I have an AlwaysOn cluster of SQL Server 2019, containing an Availability Group of 3 replicas in Synchronous mode.

According to Microsoft documentation:

The secondary replica hardens the log and returns an acknowledgement to the primary replica.
4. On receiving the confirmation from the secondary replica, the primary replica finishes the commit processing and sends a confirmation message to the client.

This article goes into greater detail and explains that:

In the secondary replica, Log Receive gets the log records from the primary replica and writes to Log cache. This process is repeated on each secondary replica participating in synchronous-commit mode.
6. On each secondary replica, Redo thread exists, and it writes all changes mentioned in log records to the data page and index page. It flushes the log for hardening on secondary database log.
7. As stated earlier, in synchronous data commit, primary replica waits for the acknowledgement from the secondary replica. At this stage, secondary replica sends an acknowledgement that transaction hardening is completed on secondary.
8. Once Primary replica, receives an acknowledgement from the secondary replica, it sends the transaction completion message to the client.

So if I understand right:
If I update a record via Primary replica successfully, this updated value should be immediately available for clients querying the Secondary replicas.

However, when I test this, this doesn't work so.

I run a simple batch file, looking like this:

 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 "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

So I'm updating the CurrentTime field via the Primary replica (hosting the AG Listener) and then reading it right away via all three replicas. Each sqlcmd command is a separate client process, so it opens its own independent TCP connection.

And then I see something like this:

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

(Reformatted the output for better readability here)

As far as I've seen, the Primary replica always returns the updated value. And the Secondaries also do - but only some short delay.

So the question is: why? Shouldn't Synchronous mode guarantee that the result of reading operation is consistent with the writing one? If the Secondary replica sends acknowledgement only after its Redo thread updates the data page - then how can it be?

Thanks,
Mucius.










sql-server-generalsql-server-transact-sqlwindows-server-clustering
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi,

Do you have any further question? Please feel free to update.

It will be much appreciated and encouraged if you could click "Accept Answer" and upvote the helpful reply.

0 Votes 0 ·

Hi @CatMucius

Have you checked if the answer helps? Do you have any further question?

If the Answer is helpful, please click "Accept Answer" and upvote it. Thanks.

0 Votes 0 ·
ElevenYu-MSFT avatar image
1 Vote"
ElevenYu-MSFT answered CatMucius commented

Hi,

Synchronous commit only guarantees the transaction is fully committed to the log on all partners, the log record will still have to be replayed by the redo thread which is single thread. If the redo queue is large, it can take a short while.

With SQL Server AlwaysOn Availability Groups, when you configure a secondary in synchronous-commit mode for read-only access, there can be data access latency.

The article mentioned the Data latency on secondary replica.

The primary replica sends log records of changes on primary database to the secondary replicas. On each secondary database, a dedicated redo thread applies the log records. On a read-access secondary database, a given data change does not appear in query results until the log record that contains the change has been applied to the secondary database and the transaction has been committed on primary database.

This means that there is some latency, usually only a matter of seconds, between the primary and secondary replicas.

Another article also explains why changes from primary replica are not reflected on secondary replica for an Always On availability group

114871-image.png

Thanks,



If the Answer is helpful, please click "Accept Answer" and upvote it. Thanks.


image.png (27.4 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you! Now it's totally clear.

0 Votes 0 ·
ErlandSommarskog avatar image
1 Vote"
ErlandSommarskog answered CatMucius commented

I don't think the article you found on Sqlshack is accurate. I'm not an expert in the AG field, but my understanding is that synchronuos means that the primary waits until the operation has been written to the transaction log on the secondary. But applying that log record to the data page is done on a separate thread asynchronously. Which means that there can be a short delay.

Note that if there would be a failover, all these log records will be applied before the secondary comes online as a primary, so in that sense there is no data loss.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks a lot!
This article also supports the same idea.


0 Votes 0 ·