HIS系统SQL Server数据库死锁问题的分析与解决
2023-05-08唐显岁
唐显岁
关键词:HIS系统;SQL Server数据库;死锁;数据库运维
0 引言
SQL Server是由微软公司开发的一个大型的关系型数据系统,它为用户提供了一个安全、可靠、易管理和高端的客户/服务器数据库平台。随着现代数据库应用业务范围的拓展,用户对数据库性能的要求,运维人员对数据库管理的要求都在不断提高,而SQLServer就是这样一种高性能的关系型数据库,它以客户端/服务端为设计结构,支持多个不同的开发平台,支持企业级的应用程序,支持XML等,能够满足多种类型的数据库应用场景[1]。因此,SQL Server数据库被广泛地应用在医疗、教育、商场等各行各业中,它为使用者提供了一个全面的数据管理和业务智能平台。但是,在实际应用场景中,面对繁忙的业务、复杂的场景以及海量的数据,难免会出现不同的故障需要调试,数据库死锁就是其中之一。
SQL Server数据库贯穿HIS系统设计、开发、实施和运行的全过程,HIS系统具有流程复杂,数据量庞大的特点,医院业务要求其具有相应速度快且可靠性高,在实际应用中,死锁会使数据服务的终端无法进行任务操作,并带来极大的危害且可能导致整个HIS系统瘫痪[2]。
本文通过作者在日常维护中遇到的数据库死锁问题进行分析,并将处理方法进行梳理,以方便为数据库运维人员在处理此类问题时提供一些思路及方法。
1 SQL Server 数据库锁管理机制
1.1 锁模式
在SQL Server数据库中针对不同的资源,存在不同的加锁方式,即锁存在多种模式[3],具体包括共享锁、更新锁、排它锁、结构锁、意向锁、批量修改锁,详细用途如表1所示。
1.2 锁粒度
根据SQL Server数据库中用户可以操作的数据行、索引以及数据表的不同,锁有多粒度的概念,即可以锁定资源的层次[4],资源粒度包括:数据库、表、区域、页面、键值、行标识符。多粒度锁用于保证数据的完整性和支持并发操作,收到用户SQL请求,自动分析并在数据库中加上相应的锁[5]。
1.3 死锁概述
SQL Server数据库系统中,当多个事务分别锁定了某种资源时,又发出请求试图锁定其他事务已占用的资源,每个事务都在等待另一个事务释放锁,结果造成任务一个事务都无法继续执行,从而形成了请求锁的循环,产生死锁,即产生永久阻塞的特殊场景[6]。图1为两个事务产生死锁的例子。
此时我们有两个线程,分别是线程A和线程B,假设线程A现在持有了锁A,线程B持有了锁B,然后线程A尝试去获取锁B,当然它获取不到,因为线程B还没有释放锁B。然后线程B又来尝试获取锁A,同样线程B也获取不到锁A,因为锁A已经被线程A持有了。这样一来,线程A和线程B就发生了死锁,因为它们都相互持有对方想要的资源,却又不释放自己手中的资源,形成相互等待,而且會一直等待下去[7]。
2 问题描述与分析
某三甲医院于上午九时左右多个临床科室报应用程序故障,HIS系统使用非常卡慢,部分科室甚至出现无法进行任何操作的情况,此时正值临床业务繁忙时段。接临床科室故障报修后,运维工程师根据故障信息的描述以及故障影响的范围,迅速就反馈的问题分析有可能造成此类问题的原因:
2.1 服务器集群出现故障
服务器集群即多个服务器一起工作,可以减少单点故障的数量[8]。可能会出现主机不能加电,自检报错、自检过程中所显示的配置与实际不符等多种故障。
2.2 内部网络出现故障
内部网络即医院内部的专用网络,以Web为核心应用,构成统一便利的信息交互平台[9]。可能会出现整个局域网都不能上因特网、网络适配器与计算机资源冲突和网速过慢等故障。
2.3 客户端/服务端资源空间不足
随着业务流量的剧增,客户端/服务端可能运行程序过多、应用程序没有及时释放内存、受到网络攻击等问题,导致服务器资源被大量占用,出现空间不足的情况。
2.4 SQL Server 数据库服务运行异常
常见的SQL Server数据库服务运行异常包括数据库服务未启动或直接报数据库服务异常,一般原因为数据库程序损坏或是软件安装的数据库服务未启动[10]。
2.5 SQL Server 数据库出现死锁情况
因争夺资源而造成一种互相等待的情况即死锁,可能会出现事务之间对资源访问顺序的交替、并发修改同一记录和索引不当导致死锁的情况。
3 问题处理
在本节中,我们将之前分析的故障情况具体去操作验证,以便排查出故障的根本原因并予以处理。
3.1 查看服务器集群运行状态
服务器集群管理的目的就是提高服务器性能,同时在出现故障时能及时进行故障转移,提高服务器的可用性,保障应用业务的稳定性。登录服务器集群管理平台,查看服务器运行状态是否正常,查看服务器日志有无异常记录。
3.2 检查内部网络运行情况
根据医院内网网络拓扑图,依次检查网络核心层、汇聚层及接入层的交换机运行状态是否正常,查看日志记录是否正常。特别是对于故障报修的临床科室,检查此区域内局部网络是否畅通,终端设备是否能够正常连接。
3.3 检查客户端/服务端资源空间
检查客户端终端设备资源空间使用情况,排查是否出现磁盘空间不足或内存被恶意侵占等情况;打开数据库服务器,检查服务器资源空间使用情况是否正常,如果资源不足,可通过适当扩容来解决问题。
3.4 检查SQL Server 数据库服务运行
打开SQL Server配置管理器,检查SQL Server服务状态是否运行正常。如果运行异常或未运行,可尝试重启下服务,并查看下服务日志,进一步排查原因,确保SQL Server数据库服务运行正常。
3.5 查看SQL Server 数据库应用情况
打开SQL Server数据库管理工具,通过使用sys.dm_tran_locks动态管理视图查看活动锁的信息,也可以使用sp_lock存储过程来查看,当发现死锁后,应排查引起死锁的原因和影响的范围,可选择使用KILL命令结束产生死锁的进程ID,释放资源,确保数据库的运行正常。图2为作者在数据库运维过程中创建的查看数据库死锁的存储过程,它能够非常便捷直观地显示死锁的详细信息,可供参考。
通过上述问题分析和问题排查,引起此次HIS系统卡慢的情况是由于新上线的一个小模块中某个视图产生大量的查询语句,刚好与医院业务数据操作繁忙时段相冲突,因此引起数据库死锁现象,造成应用程序卡慢,系统无法操作等故障。最后,通过清理死锁,释放资源,同时优化視图,使得数据库运行正常,HIS系统恢复正常。
4 预防和避免死锁及优化效果
4.1 预防和避免死锁
锁在数据库中是一个非常重要的概念,它可以防止事务的并发问题,在多个事务访问下能够保证数据库的完整性和一致性。本案例中,造成HIS系统卡慢的根本原因就是数据库死锁,那么在日常使用中该如何预防和避免死锁呢?
数据库设计的优劣直接影响到系统的运行效率,为了避免死锁我们遵循以下原则,首先是通过增加数据冗余和数据划分两种途径非规范化设计数据库;其次在频繁更新的列上、搜索参数上建立合适的索引;最后对频繁访问的表,应适当减少页分裂次数[11]。
同时可以依据数据库关于锁的机制、锁模式以及锁的粒度管理来有效的预防和避免死锁的产生[12]。通过适时地对数据库表结构、索引建立等进行调优,提高数据库的使用性能;优化存储过程、视图等SQL语句,避免频繁地在其内进行增删改查操作,占用过多的资源;较大数据量的查询避开临床业务使用的高峰期,降低资源抢占的现象;合理地对数据库服务器进行资源的调整,加大数据库服务器的容量提升性能等都能够有效的预防和避免数据库死锁的产生。
4.2 优化效果
经过对SQL Server数据库的上述优化处理,清理了系统中大量的垃圾,合理地规划了数据库,极大地提升了处理速度。经过系统真实的医疗数据运转环境下的业务测试,及时地预防了死锁的发生;重视数据的分布和流动性,数据量的增大及数据模型的改变均不会影响到系统的响应速度。
5 结束语
数据库的死锁问题是数据库日常维护工作中的常见问题,我们应当充分认识和了解数据库中关于锁的相关机制,如锁模式、锁粒度及死锁,并尽量做到预防和避免死锁的产生,这样既能保证数据库系统安全稳定地运行,又能为实际应用工作者节约宝贵的时间,避免了日常软件运行过程中出现停顿锁表的现象,同时还能提高运维人员的工作效率,从而为患者提供流畅、高效、便捷的医疗服务。