可用性组同步提交 - 写/读问题
Availability Group synchronous commit - Write / Read Question
我们为我们的客户配置了一个具有同步提交模式和两个集群的可用性组。一个集群是主集群并且是 writable 和可读的。另一个集群是辅助集群,只能读取。我们使用辅助集群进行只读操作。此外,我们在 asp.net 门户上使用此集群读取数据库,并使用主集群写入数据库。
通过测试 AG 的门户和功能,我们发现了一个问题。通过在某些数据库 tables 中更改门户中的数据并单击 "save",站点的刷新显示旧数据,直到我们再次刷新站点。
第一个问题是同步提交模式到底是什么意思?我可以在主服务器上提交数据后立即从辅助服务器读取数据吗?
我在数据库上写了一个 table 和脚本来测试读/写功能。
创建一个 table 用于测试:
CREATE Table temp.tblAuthors
(
Id int identity primary key,
Author_name nvarchar(50),
country nvarchar(50)
)
用于在主集群上插入 30000 行数据的第一个脚本:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
GO
BEGIN TRANSACTION A;
DECLARE @Id INT
SET @Id = 1
WHILE @Id <= 30000
BEGIN
INSERT INTO TEMP.tblAuthors
VALUES (
'Author - ' + CAST(@Id AS NVARCHAR(10)),
'Country - ' + CAST(@Id AS NVARCHAR(10)) + ' name'
)
SET @Id = @Id + 1
END
COMMIT TRANSACTION A;
PRINT CONVERT(VARCHAR, SYSDATETIME(), 121)
循环中每 2 毫秒读取一次辅助集群的第二个脚本:
DECLARE @i INT = 1;
DECLARE @PrintVarchar NVARCHAR(max)
WHILE (@i <= 60000)
BEGIN
WAITFOR DELAY '00:00:00.002'
SELECT Count(*),
CONVERT(VARCHAR, SYSDATETIME(), 121)
FROM TEMP.tblAuthors
PRINT @PrintVarchar
SET @i = @i + 1;
END
第一步我运行第二个脚本连接到辅助集群来跟踪时间点我可以看到辅助集群上的数据。
在下一步中,我 运行 第一个脚本将数据插入到主集群上的 table 中。
最后,当插入的数据在辅助设备上可读时,我检查了主设备上提交的日期时间和辅助设备上的日期时间。
结果:
Commit on primary: 2019-11-26 06:55:58.9978911
Readable on secondary: 2019-11-26 06:55:59.8104941
在主集群上提交大约一秒后,辅助集群上的数据就可以读取了。这解释了门户网站上的保存刷新问题。我们将数据保存在主数据库上,刷新速度与提交后的延迟一样快。
任何人都可以解释这种现象吗? asp.net 门户的这种情况是正确的还是我们应该仅将主集群用于门户?
抱歉我的英语不好。
此致,
亚历克斯
您的门户应用程序没有只读工作负载。它应该使用主集群进行所有数据库访问。
同步模式保证事务日志在辅助节点上得到强化,并确认主节点,然后主节点提交事务。这并不意味着在提交事务时更改的数据在辅助节点上可用。辅助有一个重做线程来在辅助上应用事务,这就是延迟的来源。
我们为我们的客户配置了一个具有同步提交模式和两个集群的可用性组。一个集群是主集群并且是 writable 和可读的。另一个集群是辅助集群,只能读取。我们使用辅助集群进行只读操作。此外,我们在 asp.net 门户上使用此集群读取数据库,并使用主集群写入数据库。 通过测试 AG 的门户和功能,我们发现了一个问题。通过在某些数据库 tables 中更改门户中的数据并单击 "save",站点的刷新显示旧数据,直到我们再次刷新站点。 第一个问题是同步提交模式到底是什么意思?我可以在主服务器上提交数据后立即从辅助服务器读取数据吗?
我在数据库上写了一个 table 和脚本来测试读/写功能。
创建一个 table 用于测试:
CREATE Table temp.tblAuthors
(
Id int identity primary key,
Author_name nvarchar(50),
country nvarchar(50)
)
用于在主集群上插入 30000 行数据的第一个脚本:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
GO
BEGIN TRANSACTION A;
DECLARE @Id INT
SET @Id = 1
WHILE @Id <= 30000
BEGIN
INSERT INTO TEMP.tblAuthors
VALUES (
'Author - ' + CAST(@Id AS NVARCHAR(10)),
'Country - ' + CAST(@Id AS NVARCHAR(10)) + ' name'
)
SET @Id = @Id + 1
END
COMMIT TRANSACTION A;
PRINT CONVERT(VARCHAR, SYSDATETIME(), 121)
循环中每 2 毫秒读取一次辅助集群的第二个脚本:
DECLARE @i INT = 1;
DECLARE @PrintVarchar NVARCHAR(max)
WHILE (@i <= 60000)
BEGIN
WAITFOR DELAY '00:00:00.002'
SELECT Count(*),
CONVERT(VARCHAR, SYSDATETIME(), 121)
FROM TEMP.tblAuthors
PRINT @PrintVarchar
SET @i = @i + 1;
END
第一步我运行第二个脚本连接到辅助集群来跟踪时间点我可以看到辅助集群上的数据。 在下一步中,我 运行 第一个脚本将数据插入到主集群上的 table 中。 最后,当插入的数据在辅助设备上可读时,我检查了主设备上提交的日期时间和辅助设备上的日期时间。
结果:
Commit on primary: 2019-11-26 06:55:58.9978911
Readable on secondary: 2019-11-26 06:55:59.8104941
在主集群上提交大约一秒后,辅助集群上的数据就可以读取了。这解释了门户网站上的保存刷新问题。我们将数据保存在主数据库上,刷新速度与提交后的延迟一样快。
任何人都可以解释这种现象吗? asp.net 门户的这种情况是正确的还是我们应该仅将主集群用于门户?
抱歉我的英语不好。
此致,
亚历克斯
您的门户应用程序没有只读工作负载。它应该使用主集群进行所有数据库访问。
同步模式保证事务日志在辅助节点上得到强化,并确认主节点,然后主节点提交事务。这并不意味着在提交事务时更改的数据在辅助节点上可用。辅助有一个重做线程来在辅助上应用事务,这就是延迟的来源。