最近忙的要死,手底下各种优化,数据库系统,各种问题,恨不得长上8只手干这些活,而偏偏屋漏偏逢连夜雨,SQL SERVER  ALWAYS ON  又出了问题,SQL SERVER 目前公司使用的是 WINDOWS 2016 ENTERPRISE +  SQL SERVER 2016 ENTERPRISE ALWAYS ON 的集群,来支撑公司部分业务。

SQL SERVER  Always on 生产故障解决_数据文件

SQL SERVER ALWAYS ON 作为成熟的SQL SERVER 集群解决方案已经在很多企业中应用,但任何系统都不是完美的,故障也是有的,这两天运维的同事和我说,SQL SERVER  ALWAYS ON  的日志不在截取,疯狂的增长。 其实我听到这个消息后,并不紧张,因为以前我供职的某家公司,使用的SQL SERVER 2012 也有这样的问题,最后虽然没有找到根本原因,但问题是解决了。 


OK ,我们先看看SQL SERVER 的日志,SQL SERVER 的日志文件是LDF,对于外行来说,它就是一个文件,但实际上,对DBA来说他是一个可循环的 capped collection (此概念为MONGODB的一个概念,这里引用一下虽然不完全相同,但意思是这个意思)。

下面就是 一个LDF 的文件结构,每个文件里面有 多个 VLF 块,而这些块时可以复用的,也就是当 CHECK POINT 将 dirty data  FLUSH 到数据文件后,其实这些LOG 在某些层面上已经对数据库没有太大意义,是可以被DUMP掉的。

SQL SERVER  Always on 生产故障解决_sql_02

但为什么有时候,日志不能被截断,并且日志不能被reuse 


1  VLF 块中有没有被 CHECK POINT 的日志 ,也就是活动日志,例如一个大事务,一直没有做完,那么这个VLF的文件块时不会被覆盖的,直到数据刷到数据文件后,才可以被CHECK POINT ,这个VLF 才可以被重用


2 VLF 的尾部必须是 FREE  VLF ,如果碰巧你的 有 4个 VLF 而恰巧  TAIL 和 HEAD  在一个 VLF 中,那这样的日志也是不能被收缩的,除非数据写到VLF1 ,举个例子,如果有一个壁虎,如果让他释放自己的空间,你说他是愿意从头砍下去,还是从尾部砍下去。所以下面的情况也是不能收缩日志。

SQL SERVER  Always on 生产故障解决_数据文件_03


另外我们还要明白,收缩日志有没有必要,在我看来,还好,因为日志如果涨到800G (不是因为错误,或者各种烂 DML)造成的,那就可以不释放,因为他会REUSE 空间的,你SHRINK他后,早晚还是要占用空间,而且和系统交换空间也有损耗,干嘛呢。


如果你想看你的日志文件到底什么状态,键入 dbcc loginfo 就可以知道了,状态为 2的 是激活的,不可以SHRINK的文件

SQL SERVER  Always on 生产故障解决_sql_04


我们回到为什么日志不能被截取,其实这个说法不准确,应该是问日志为什么一直在激活的状态,而不能背释放,在我们这次故障中,明显就是 ALWAYS ON 的日志没有在从库上被应用完毕。造成的问题


查询数据库一直是在 AVALIABILITY_REPLCA 的状态,一般这样状态都是因为从库有问题造成,例如从库宕机,从库由于查询(一般从库查询,都是大查询,OLAP的需求),造成日志无法应用,或者一些稀奇古怪的问题。

SQL SERVER  Always on 生产故障解决_数据文件_05

这里的经验我们要重新启动从库即可,另外在从库的错误日志中我发现了

下面的错误日志:


Error: 19432, Severity: 16, State: 0. Always On Availability Groups transport has detected a missing log block for availability database "database_name". LSN of last applied log block is (xxxx:xxxxxxx:x). Log scan will be restarted to fix the issue. This is an informational message only. No user action is required.


按照微软官方的 FIX (微软官方对错误的解释和解决)


SQL SERVER  Always on 生产故障解决_sql_06

我们需要打上 SQL SERVER 2016 SP1  SP2的补丁来解决问题


下面的网址有详细的信息可以查看,如果使用SQL SERVER 2016 ALWAYS ON  ,还请尽快打上 SP1  SP2的补丁

​https://support.microsoft.com/en-us/help/4338746/fix-error-19432-when-you-use-always-on-availability-groups-in-sql-serv​



SQL SERVER  Always on 生产故障解决_错误日志_07