作者 | 张乐奕:Oracle ACE 总监,ACOUG (中国 Oracle 用户组)联合发起人。Oracle 数据库高可用解决方案与  Exadata 一体机专家。长于数据库故障诊断,性能调优。作为多家知名论坛版主,热衷社区技术分享,同时也是 Exadata 用户组的发起人,组织策划并作为技术分享者的活动已超过百场。


在上一篇文章中,我们描述了 配置 SQL Server 2017 上的可用性组初体验 。在测试可用性模式时,Linux下的某些行为显得匪夷所思。在 SQL on Linux 中如果设置了 availability_mode 为 SYNCHRONOUS_COMMIT,那么必须至少有一个 secondary replica(或者一个config node)是存活的,否则 priamry replica 中就不再允许任何 DML 操作。


请看以下一些有趣的验证过程。


关于 AVAILABILITY_MODE


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

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

  • SYNCHRONOUS_COMMIT

  • ASYNCHRONOUS_COMMIT

  • 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 事件才是正常的,然而这里并没有出现。

但是我们明明把 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 之前还是允许当所有备库都失效以后,主库仍然是可以正常读写的。甚至在现在的文档中仍然保留了这样的描述。

https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-availability-group-ha?view=sql-server-linux-2017#two-synchronous-replicas

也就是说在 SQL Server 2017CU 1 之后,不再支持单纯的 read-scale 功能的 AG 了。虽然不太理解微软的 SQL Server 程序员是怎么考虑这个问题的,但是现状就是如此。

相比起 Oracle 的 Data Guard 而言,也就是现在 SQL Server 的 AG 只有同步(等同于 DG 的 Maximum protection),异步(等同于 DG 的 Maximum performance)这样两种方式,而缺少了 DG 的 Maximum availability 模式。

我只能认为这是一个设计理念的问题,微软的程序员更倾向于关注数据一致性,但是我期望在未来 SQL Server 可以对此进行改进。

资源下载

关注公众号:数据和云(OraNews)回复关键字获取

2018DTCC , 数据库大会PPT

2017DTC,2017 DTC 大会 PPT

DBALIFE ,“DBA 的一天”海报

DBA04 ,DBA 手记4 电子书

122ARCH ,Oracle 12.2体系结构图

2017OOW ,Oracle OpenWorld 资料

PRELECTION ,大讲堂讲师课程资料

当SQL Server爱上Linux:AVAILABILITY_MODE 和 DataGuard 的实践差距相关推荐

  1. 当SQL Server爱上Linux:配置 SQL Server 2017 上的可用性组初体验

    作者 | 张乐奕:Oracle ACE 总监,ACOUG (中国 Oracle 用户组)联合发起人.Oracle 数据库高可用解决方案与  Exadata 一体机专家.长于数据库故障诊断,性能调优.作 ...

  2. linux sql server硬件要求,SQL Server On Linux(20)—— SQL Server On Linux性能(6)——针对性能的配置(Linux层面)...

    前面两篇大部分属于Windows和 Linux 平台公用,但是这一篇主要集中在Linux内核层面.因为本系列是Linux上的SQL Server(以2017.2019为主体)的介绍. 完整的列表可以查 ...

  3. sql2016是否支持linux,微软 SQL Server 支持 Linux 了,2017年 中将正式推出

    微软今日宣布推出 SQL Server2016 for Linux 开放私测,并打算在明年年 中正式发布这款关系数据库产品.这是微软该旗舰产品首次登陆 Linux.就像此前 Office 产品登陆了越 ...

  4. 个性化配置你的SQL Server on Linux

    问题引入 这天老鸟满面春风找到菜鸟:"鸟儿啊,看你最近研究SQL Server On Linux如鱼得水,干得不错啊.不过呢,这是一个张扬个性的年代,要创新,要与众不同,那你怎么在Linux ...

  5. SQL Server on Linux的文件和目录结构

    问题引入 "鸟儿啊,我记得你写过一篇<SQLServer On Linux Package List on CentOS>的文章,从这篇文章,我们很清楚的知道了SQL Serve ...

  6. linux下装sqlserver安装包,【sqlServer】CentOS7.x 上Microsoft SQL Server for Linux安装和配置...

    SQL Server Documentation https://docs.microsoft.com/en-us/sql/sql-server/sql-server-technical-docume ...

  7. 问君能有几多愁,恰似不懂Linux SQL如何调优——聊聊SQL Server on Linux最佳实践

    问君能有几多愁,恰似不懂Linux SQL如何调优--聊聊SQL Server on Linux最佳实践 自从微软开始拥抱Linux, SQL Server 很快就推出了 Linux版本, linux ...

  8. 配置 sql server linux,配置SQL Server on Linux(2)

    1. 前言 前一篇配置SQL Server on Linux(1),地址:http://www.cnblogs.com/fishparadise/p/8125203.html ,是关于更改数据库排序规 ...

  9. linux sqlserver有图形化吗,SQL Server for Linux 下一版本的公共预览

    当微软宣布即将发布SQL Server for Linux版本的时候,有些人觉得很兴奋,有些人觉得然并卵,但是既然Gartner在2016年的数据库管理系统魔力象限图中将微软列在了第一位,超过了一直以 ...

最新文章

  1. 微型计算机一般按字长进行分类,关于计算机中:字,字节,字长,位的关系
  2. Visual Studio 2013开发 mini-filter driver step by step (11) driver 签名
  3. Docker系列之镜像瘦身(五)
  4. Codeforces Round #675 (Div. 2) F. Boring Queries 区间lcm + 主席树
  5. 京东物流研发岗位会背景调查吗_【秋招资讯】京东健康于港交所主板上市 | 京东健康2021校园招聘火热进行中!...
  6. 四类文法以及上下文有(无)关的理解【转】
  7. 模拟ARP报文发送,通过改变拓扑结构,观察报文发送方法以及途径
  8. 猜数字游戏python程序_【自学编程】python 小游戏—猜数字
  9. 微信网页开发那些破事儿
  10. MyCat分库分表入门示例
  11. 白天工作效率低,晚上效率高怎么调整过来?
  12. 186.MultiAutoCompleteTextView
  13. 中国制造业的突围 --首次物联网产业系列微访谈圆满结束
  14. EasyUI上传图片,前台预览,后台读取
  15. 《求职》第四部分 - 操作系统篇 - 操作系统基础
  16. SQLyog数据库导出数据 避免科学记数法
  17. sql的sum函数(与group by,having子句混合使用)
  18. 「newbee-mall新蜂商城开源啦」 页面优化,最新版 wangEditor 富文本编辑器整合案例...
  19. 如何看待软件开发新技术(转)
  20. 英特尔SSD 610p明年Q4发布:3D闪存/最大2TB

热门文章

  1. 贪吃蛇C语言源码与算法分析
  2. 深度学习笔记(30) Inception网络
  3. 2017甘肃省计算机二级考试,甘肃省2017年计算机二级考试网上报名须知及流程
  4. nokia n1 android 6,诺基亚推Nokia N1拥抱安卓,微软该怎么想?
  5. addeventlistener事件第三个参数_JavaScript 事件与事件处理机制
  6. asp.net core-5.控制台读取json文件
  7. 压缩感知——SP(subspace pursuit)重构算法前言翻译
  8. 51nod 1686 第K大区间 二分瞎搞
  9. 通过 Visual Studio 对 SQL Server 中的存储过程设置断点并进入存储过程对其进行调试...
  10. 今天才知道还有这个地址 MS 的