当SQL Server爱上Linux:AVAILABILITY_MODE 和 DataGuard 的实践差距

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
日志服务 SLS,月写入数据量 50GB 1个月
简介:

需要注意的是,与 Oracle DataGuard 不尽相同的概念是,在 Always On AG 每个replica 上都可以设置自己的 AVAILABILITY_MODE。

AVAILABILITY_MODE 参数有三个可选值,分别是:

d47e62d2b349aca45e42305ed6714efbe5ed61d9 SYNCHRONOUS_COMMIT
d47e62d2b349aca45e42305ed6714efbe5ed61d9 ASYNCHRONOUS_COMMIT
d47e62d2b349aca45e42305ed6714efbe5ed61d9 CONFIGURATION_ONLY。

SYNCHRONOUS_COMMIT:同步提交,意味着主 replica 的事务必须等到备 replica 将变更日志写入磁盘中才可以提交。可以设置包括主 replica 在内的最多三个replica 处于同步提交状态。

ASYNCHRONOUS_COMMIT:异步提交,意味着 replica 无需等待备 replica 的动作而可以直接提交成功。

CONFIGURATION_ONLY:仅同步 AG 配置元数据。设置为该值的 replica 仅会从主 replica 中将 AF 配置的元数据同步过来,不会同步任何用户表数据。

在一个多节点 replica 的 AG 环境中,如果:

主库和其中任何一个备库设置为 SYNCHRONOUS_COMMIT,则主库的日志提交必须等待该备库完成日志写入;

主库设置为 SYNCHRONOUS_COMMIT,而所有备库都设置为ASYNCHRONOUS_COMMIT,则主库无需等待;

主库设置为 ASYNCHRONOUS_COMMIT,则无视备库上该参数的设置,主库均无需等待。

在多节点的 AG 环境中,假设一个主库配置了两个同步的 secondary,那么是不是要等待这两个secondary都完成日志写入才能提交事务呢?此时又引入了required_synchronized_secondaries_to_commit参数

关于required_synchronized_secondaries_to_commit

required_synchronized_secondaries_to_commit 参数是在 SQL Server 2017中引入的,这个参数从直观意义上就可以看得出是指定当 commit 的时候需要有个几个同步的 secondaryreplica 存活。

这个参数在三节点的AG集群中,默认值为1,也就是如果至少要存活一个secondaryreplica,主库上的事务才可以提交,否则 commit 就会一直等待。这很好理解。

但是不好理解的是,该参数可以手工修改为 0,从字面上看应该是说,即使所有secondary replica 都不同步了,也是可以允许 commit 的。

但是实际情况却并非如此,修改为 0 是不起作用的。通过以下测试可以知道。

首先,设置 required_synchronized_secondaries_to_commit 参数为 0

sudo pcs resourceupdate ag_cluster required_synchronized_secondaries_to_commit=0

[Kamus@centos1~]$ sql
1> selectname,required_synchronized_secondaries_to_commit from sys.availability_groups;
2> GO
name required_synchronized_secondaries_to_commit
-------------------------------------------------------------------------
ag1 0

(1 rows affected)

现在三个节点都是正常状态。

1> selectr.replica_server_name,r.availability_mode_desc,r.session_timeout,rs.connected_state_desc
2> from sys.availability_replicas r,sys.dm_hadr_availability_replica_statesrs
3> where r.replica_id=rs.replica_id;
4> GO
replica_server_name availability_mode_desc session_timeout connected_state_desc
------------------------------------------------------------ --------------- ------------------------------
centos1 SYNCHRONOUS_COMMIT 10 CONNECTED
centos2 SYNCHRONOUS_COMMIT 10 CONNECTED
centos3 SYNCHRONOUS_COMMIT 10 CONNECTED

(3 rows affected)

在主节点上进行 Insert,可以成功,这很好。

1> insert intot1 select * from sys.databases;
2> GO

(6 rows affected)

停掉一个 secodary replica。显示第二个节点已经 DISCONNECTED。

1> selectr.replica_server_name,r.availability_mode_desc,r.session_timeout,rs.connected_state_desc
2> from sys.availability_replicasr,sys.dm_hadr_availability_replica_states rs
3> where r.replica_id=rs.replica_id;
4> GO
replica_server_name availability_mode_desc session_timeout connected_state_desc
------------------------------------------------------------ --------------- ------------------------------
centos1 SYNCHRONOUS_COMMIT 10 CONNECTED
centos2 SYNCHRONOUS_COMMIT 10 DISCONNECTED
centos3 SYNCHRONOUS_COMMIT 10 CONNECTED

(3 rows affected)

在主库上进行 Insert,还是可以成功,这很好。

1> insert intot1 select * from sys.databases;
2> GO

(6 rows affected)

再停掉一个 secodary replica。显示2、3节点都已经 DISCONNECTED。

1> selectr.replica_server_name,r.availability_mode_desc,r.session_timeout,rs.connected_state_desc
2> from sys.availability_replicasr,sys.dm_hadr_availability_replica_states rs
3> where r.replica_id=rs.replica_id;
4> GO
replica_server_name availability_mode_desc session_timeout connected_state_desc
------------------------------------------------------------ --------------- ------------------------------
centos1 SYNCHRONOUS_COMMIT 10 CONNECTED
centos2 SYNCHRONOUS_COMMIT 10 DISCONNECTED
centos3 SYNCHRONOUS_COMMIT 10 DISCONNECTED

(3 rows affected)

在主库上执行 Insert,此时 hang 住,这很不好。

1> insert intot1 select * from sys.databases;
2> GO

更讨厌的是,对于该表的查询也会 hang 住,这就更不好了。

2> selectcount(*) from t1;
3> GO

现在数据库中的等待是什么呢?确实是 HADR_SYNC_COMMIT。

1> selectSTATUS,COMMAND,DATABASE_ID,WAIT_TYPE,WAIT_TIME from sys.dm_exec_requests wherecommand='INSERT';
2> GO
STATUS COMMAND DATABASE_IDWAIT_TYPE WAIT_TIME
------------------------------------------------------------ ----------- -----------------------------------------
suspended INSERT 5HADR_SYNC_COMMIT 1670

(1 rows affected)

如果我们更进一步做一个session的xevent trace,可以看到等待的是 WaitForHarden,而 Harden 的意思即是 remote replica 的日志写入。现在主库在等待一个备库的日志完成写入,然后自己才能提交成功。在正常情况下,当主库不再需要等待备库而可以自行 commit 的情况下,在 xevent trace 中应该出现将备库的 commit_policy标志为donothing状态,也就是在xevent中应该要出现hadr_db_partner_set_policy 事件才是正常的,然而这里并没有出现。

d650df8f83b71a39e903219d2399e4750049951a

但是我们明明把 required_synchronized_secondaries_to_commit 参数设置为0了。所以也许微软需要更新一下文档,明确说明在多个 sync 的 secondary 存在的情况下,该参数即使修改为 0 也仍然按照 1 来处理。

结论

在 SQL on Linux 中如果设置了 availability_mode 为 SYNCHRONOUS_COMMIT,那么必须至少有一个 secondary replica(或者一个config node)是存活的,否则 priamry replica 中就不再允许任何 DML 操作,而尝试对于某表进行 DML 之后,还会进一步阻塞对于该表的查询,即使设置了required_synchronized_secondaries_to_commit=0 也是无效的。

这是一个很奇怪的 design,因为这强制去掉了当一个集群中所有备库都崩溃时,主库能够自动转为异步提交模式的功能,从而造成了所有备库失效则会影响主库业务正常进行这样一个大问题。

实际上这个 design 是在 SQL on Linux 2017 CU1 之后才修改的,在 CU1 之前还是允许当所有备库都失效以后,主库仍然是可以正常读写的。甚至在现在的文档中仍然保留了这样的描述。


原文发布时间为:2018-05-24

本文作者:张乐奕

本文来自云栖社区合作伙伴“数据和云”,了解相关信息可以关注“数据和云”。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
2月前
|
SQL 存储 API
Flink实践:通过Flink SQL进行SFTP文件的读写操作
虽然 Apache Flink 与 SFTP 之间的直接交互存在一定的限制,但通过一些创造性的方法和技术,我们仍然可以有效地实现对 SFTP 文件的读写操作。这既展现了 Flink 在处理复杂数据场景中的强大能力,也体现了软件工程中常见的问题解决思路——即通过现有工具和一定的间接方法来克服技术障碍。通过这种方式,Flink SQL 成为了处理各种数据源,包括 SFTP 文件,在内的强大工具。
163 15
|
3月前
|
SQL 存储 Unix
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
Flink SQL 在快手实践问题之设置 Window Offset 以调整窗口划分如何解决
56 2
|
8天前
|
关系型数据库 MySQL Linux
Linux环境下MySQL数据库自动定时备份实践
数据库备份是确保数据安全的重要措施。在Linux环境下,实现MySQL数据库的自动定时备份可以通过多种方式完成。本文将介绍如何使用`cron`定时任务和`mysqldump`工具来实现MySQL数据库的每日自动备份。
26 3
|
27天前
|
监控 Linux 云计算
Linux操作系统在云计算环境中的实践与优化###
【10月更文挑战第16天】 本文探讨了Linux操作系统在云计算环境中的应用实践,重点分析了其在稳定性、安全性和高效性方面的优势。通过具体案例,阐述了Linux如何支持虚拟化技术、实现资源高效分配以及与其他开源技术的无缝集成。文章还提供了针对Linux系统在云计算中的优化建议,包括内核参数调整、文件系统选择和性能监控工具的应用,旨在帮助读者更好地理解和应用Linux于云计算场景。 ###
34 3
|
1月前
|
SQL 关系型数据库 MySQL
Go语言项目高效对接SQL数据库:实践技巧与方法
在Go语言项目中,与SQL数据库进行对接是一项基础且重要的任务
54 11
|
1月前
|
SQL 存储 关系型数据库
添加数据到数据库的SQL语句详解与实践技巧
在数据库管理中,添加数据是一个基本操作,它涉及到向表中插入新的记录
|
1月前
|
SQL 关系型数据库 数据库
SQL数据库:核心原理与应用实践
随着信息技术的飞速发展,数据库管理系统已成为各类组织和企业中不可或缺的核心组件。在众多数据库管理系统中,SQL(结构化查询语言)数据库以其强大的数据管理能力和灵活性,广泛应用于各类业务场景。本文将深入探讨SQL数据库的基本原理、核心特性以及实际应用。一、SQL数据库概述SQL数据库是一种关系型数据库
51 5
|
1月前
|
SQL 开发框架 .NET
ASP连接SQL数据库:从基础到实践
随着互联网技术的快速发展,数据库与应用程序之间的连接成为了软件开发中的一项关键技术。ASP(ActiveServerPages)是一种在服务器端执行的脚本环境,它能够生成动态的网页内容。而SQL数据库则是一种关系型数据库管理系统,广泛应用于各类网站和应用程序的数据存储和管理。本文将详细介绍如何使用A
53 3
|
1月前
|
Ubuntu Linux
Linux实践|设置静态 IP 地址
Linux实践|设置静态 IP 地址
62 0
Linux实践|设置静态 IP 地址
|
1月前
|
SQL 消息中间件 分布式计算
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(一)
大数据-143 - ClickHouse 集群 SQL 超详细实践记录!(一)
71 0