沉痛的教训,SQL SERVER 2008 R2升级到SQL2012 SP1导致的系统全线崩溃
2014年07月23日01:00~05:00,公司的系统与往常一样,进行升级。但是这次更新,是比较大的改动,“大”在于系统新功能的添加,BUG的修复,以及一个我始料未及的SQL SERVER升级(事前,我不知道今晚会更新SQL SERVER)。光是程序的改动,是经过了45天左右的改动,然后决定今天发布的,改动的地方有100+。
正是因为这一系列的问题,导致了“看似偶然,实则必然”的系统全线崩溃。本文并非来说谁对谁错,仅仅是针对这次的教训,要狠狠的记住它!
沉痛的教训,SQL SERVER 2008 R2升级到SQL2012 SP1导致的系统全线崩溃
这次的灾难,可以说是本人所经历过最沉重的、最具毁灭性的灾难。本人从事.NET软件开发3年以来,第一次遇到这么大的灾难性故障,最终造成公司300+分店,几千个客户端系统,19.5小时的全部瘫痪,一直到20:30才“无奈的解决”(被迫降级,全部回滚旧版本)。
虽然本人没有参与本次系统更新,但是作为一个小组团队,我也是除了经理以外的唯一一个开发人员(我们这个小组有2人(还有几个其他的开发小组),此外,最近新来了1人,这次更新部分代码他也参与改动),我有着难辞其咎的责任。因为,我没有提前发现问题,没有给出合理的建议,导致问题出现了。问题出现之后,我也没有尽快把问题解决,中间走了很多弯路,导致故障很晚才被修复,经理,以及其他管理层,因为这件事情全都被扣了5K工资,我也是非常不安,实在是沉痛的教训!
今天经历的事情(或者是背景说明):
1、本次系统更新改动很大,测试工作不到位。虽然所有功能都经过测试,但是没有模拟足够大的并发,也没法模拟“真实”的环境,导致问题一直无法发现。(因为在测试版运行了2个多月,一直正常)
2、公司也为了节约成本,测试服务器配置,完全跟正式服务器不同。这也就导致后面的SQL SERVER出了大问题;
3、SQL2008 R2升级为SQL2012 SP1,导致本人之前提供更新的文件配置,全部不对了(例如:里面的SQL地址连接,帐号密码等,全都没用了。而且,由于更新的系统很多个版本,共有5个版本)。虽然,参与更新的同事换成SQL2012之后,也修改了这些配置,但是残留了一个Log4net.config,忘记修改它的连接,于是乎,导致系统死机的第一个原因产生了。
4、SQL2008 R2升级到SQL2012 SP1,谁知道2012企业版还有Licensed限制,通过CAL方式注册的(也就是大家网上搜索的那种验证码注册),会有CPU线程数限制,不能超过40个(详情这里)。但是我们的正式服务器是4*12=48个逻辑CPU,超出了8个,这样的话,就会导致之前的跨NUMA问题。关于这个问题,看这个文章:《SQL2008 R2 分库后出现“查询处理器未能为执行并行查询启动必要的线程资源”解决方法》。还有另一种Core方式注册的(正版购买的SQL2012企业版),是不会有这个限制的。正是因为正式服务器,测试服务器这个微妙的差异,所以这个问题被忽视了,公司也没有DBA,于是导致了毁灭性的灾难,所有的系统,完全卡死……重新建立索引,更新统计信息,重新设置最大并行度,全部没用。
5、其实,我们尝试了各种方法,一开始的时候,我们就在分析程序原因。但是整个早上都没有找到原因。下午的时候,才把目标转向SQL SERVER 2012。一开始的时候,我们就想回滚整个程序、数据库,但是SQL2008升级到SQL2012,是通过分离,附加的方式加上去的,根本不可能降级了。而且新版本,老版本的数据库结构有一些差异,而且过了这么久,2012上面的系统数据肯定多了很多账务,想要通过之前的备份还原也是不可能了。这就导致,我们没有及时回滚程序、数据库。而是一心想要找到原因,把问题解决……其实,现在想起来,这个做法是严重错误的。因为正确的方法是:立刻还原,回滚。而不是找原因,因为所有分店系统全部崩溃了……
6、挣扎了很久,直到下午,我突然想起那个“万能的数据库导入、导出”,于是建议经理通过这个方式,把2012的数据,全部弄回去。操作过程中,我们发现“数据库复制”速度更快些,而且整个库复制,比较方便。就这样,我们把SQL2012的数据成功的降级到SQL2008 R2。详细操作:通过SQL导入导出方式,把SQL2012降级为SQL2008(用之前的SQL2008备份,附加回2008,然后TRUNCATE TABLE XXX,再把2012数据导入)。也可以用SQL的复制功能(任务--复制数据库)实现相同的效果。……然而这个“新技能”的代价就是5K,4个管理层都扣了,那就是2W……
7、原以为到了这里,问题就可以解决了……可是,仅仅是比之前的卡死好了一点,但依然很卡。还没有从根本上解决这个问题……反正都把数据库还原了,就干脆把程序一起还原吧,还原之后,发现确实不卡了。使用新版本的程序,SQL某个数据库的连接数居然有400+,但是旧版代码只有几十个……看来,除了上面的问题,还有代码问题。估计是某些地方没有释放连接……
8、截止到现在,系统已经恢复工作了,其实,中间发生了很多很多其他的故障。本文没法一一举例了,就说这些比较重要的吧。目前关于代码的这个问题,我们还没有找到原因,明天会跟进严查。看看是什么原因导致的……说到这里,标题可能有点跑偏了,应该是“程序+SQL2012,导致系统全线崩溃”!之所以写这个标题,是因为让我记住,SQL不是每个人都能玩得起的……
9、经过这次事故,公司决定成立相关的应急方案,以及提供可靠的灾备服务器。(其实,原本是有灾备服务器,也有历史备份库的,但是上周这个机子发神经,同步中断了,系统也出问题了。昨天刚刚好被运维重装系统了,现在都是裸机一枚……真心伤不起)
最后,我想大吼一声:DBA,你在哪里?
============================2014年7月27日更新补充============================
前几天坑爹问题,罪魁祸首,应该找到了……(暂未最终确认,但应该就是它导致的)
这个写法,在不同版本的EF里面,实现方式不同,导致我们公司23号,所有系统全线崩溃……详细背景:https://www.wuleba.com/?p=25767
EF6.0,EF6.1 调用都是上面的代码……但是SQL连接数 6.1会增加25个连接(3~5秒关闭),EF6.0的话仅有1个连接(瞬间关闭,现在改为Contains方法查询,一次解决)……
后果是:2000个客户端 ,每隔3分钟调用1次,每次25个连接……数据库服务器CPU100%,所有系统全部崩溃……
2,000 * 20 * 25 = 1000,000 次/小时
============================2014年7月28日更新补充============================
目前找到的主要原因,是因为:
EF6.1.1在处理WithRequiredPrincipal映射跟EF6.0处理方式不同,导致升级到EF6.1.1之后,每次的查询的SQL连接会增加25个,需要等到3~5秒才会自动关闭。。。而EF6.0里面只会有1个连接,立即关闭。。。我们测试了EF6.1、EF6.0.XXX都发现处理结果相同,但是EF6.1.1是有问题的。。。。保险起见,现在改回原来的EF6.0.0-alpha3版本
测试的时候发现EF6.1虽然生成的语句跟EF6.0的一样,但是他依然会增加25个连接,关闭也没那么快。(之所以产生这个问题,涉及到两个概念:“EF 双向一对一关系”、“EF 单向一对一关系”)
============================2014年8月13日更新补充============================
上面是微软官方针对EF6.1.1一对一关系查询语句bug的回复邮件,该bug在EF6.1.2修复,目前6.1.2还是试用版。
下载说明:① 请不要相信网站的任何广告;② 当你使用手机访问网盘时,网盘会诱导你下载他们的APP,大家不要去下载,直接把浏览器改成“电脑模式/PC模式”访问,然后免费普通下载即可;③ 123云盘限制,必须登录后才能下载,且限制每人每天下载流量1GB,下载 123云盘免流量破解工具
版权声明:
小编:吾乐吧软件站
链接:https://wuleba.com/8152.html
来源:吾乐吧软件站
本站资源仅供个人学习交流,请于下载后 24 小时内删除,不允许用于商业用途,否则法律问题自行承担。


彦达
数据库升级几个关键注意点1、摸黑上阵,大家都睡觉的时候,是你干活的最好时机。天要是亮了,大家开始干活了,没有完成升级就回滚。2、进行模拟升级测试,将数据库备份还原到测试机器,然后将测试机器升级到2012,模拟测试看程序是否OK。3、数据库停机,然后把数据库整体用fastcopy复制到另外一台机器,在执行“如何在 SQL Server 实例之间传输登录和密码”,参考链接https://www.qqworker.com/post/31.html ,把数据库启动好,不行就把请求转到这个机器上面。这样子就算天塌下来也不怕。4、其实数据库建议没事别升级高版本,看看阿里云用的也只是2008R2就知道了。我们到现在还在用2005呢。最起码,我现在看来,他们的性能差别不会特别大的。。。
吾乐吧软件站@彦达
1、是半夜更新的,不过系统是24小时运作的,24小时都有人在使用2、备份到测试机,数据库文件有300GB左右,每次都要备份?传输?3、这个看不懂啥意思,请赐教,谢谢!4、2012以及之前的版本,确实没有太大的变化,都差不多的。不过,SQL2014跟之前的版本相比,就有太多的优势了,目前没有正式发布,所以不考虑用。以后的话,还是要升级的,呵呵
彦达@吾乐吧软件站
挺悲催的。。。兄弟我同情你哈。不过经验就是这样子一点一滴的训练起来的。哪个医生手上没有几条人命哦。升级这个玩意,最好能公布一个时间内暂停服务,预留8个小时。不然可能造成的数据异常就损失大了。阿里云这么大的公司,升级的时候都会暂停服务。。别说我们这些中小型数据库了。。我的建议前三条,都是建立在数据库停机的前提下的。我以前从2000升级到2005,是买了一台新的服务器,配置好2005的环境,用sp_help_revlogin这个存储过程将原来数据库的登陆复制到新主机(这样子原来数据库的用户换到新服务器还可以正常登陆)。然后把数据库的mdf、ldf文件用FastCopy(一个局域网内拷贝文件把硬盘IO、网络榨光的软件)拷贝到新主机上面去,边传输边附加数据库,200G的数据大概花了一个多小时传输和附加完。测试软件正常之后,我就把老机器的IP换到新机器上面。这样子就升级完成了。我们的数据库,在2007年之前用的都是2000,2008年至今用的都是2005, 2014我也一直在关注,估计我下次升级应该会考虑它的,不过应该不是三年内的事情了。作为基础服务,还是稳定好些。。
MySql
2012 果然是末日!
Steve
用MariaDB