热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

SQLServer运维

日期:2012年11月30日浏览量:1,507次1条评论分类:MSSQL,数据库作者:飞扬过海数据是一个企业的命根子,尤其是在当今绝大部分的行业都实现了信息化的管理的时代,企业所有运营的数据、财务信息等都会存放到数据库中,在用户量和数据量不断变大的情况

日期:2012年11月30日 浏览量:1,507次 1 条评论 分类:MSSQL,数据库 作者:飞扬过海 数据是一个企业的命根子,尤其是在当今绝大部分的行业都实现了信息化的管理的时代,企业所有运营的数据、财务信息等都会存放到数据库中,在用户量和数据量不断变大的情况

日期:2012年11月30日浏览量:1,507次 1 条评论 分类:MSSQL, 数据库作者:飞扬过海

数据是一个企业的命根子,尤其是在当今绝大部分的行业都实现了信息化的管理的时代,企业所有运营的数据、财务信息等都会存放到数据库中,在用户量和数据量不断变大的情况下,如何保障这些信息的安全、保证随时随地的能被用户访问,同时还需要在用户不间断访问的情况下调整、修改这些数据和结构,用以满足业务的需求和变更,这本身一门很艺术的事了。

这篇文章主要总结了SQLServer数据库运维时,在保证数据安全和DBA操作数据库时保证不影响用户访问方面的一些技巧,之所以将之形容为“虎口夺食”,是因为DBA是个风险相当高的行业,在高并发、大数据量的系统中,很多小的失误或者操作不当,都将造成严重的后果,不仅影响系统的正常运行,甚至牵连到整个数据的安全,给企业造成不可估量的损失;我们粗算一笔账,以一个日交易量2000万的网站来说(中型规模),如果因你的操作造成网站当机一个小时,我们按一天20小时交易时间来算(另外4小时可能没多少交易量),一个小时就是100万的损失,这个只是显性成本,还有因网站故障导致用户流量的隐性损失,如果企业要与员工来算这边账的话,那技术吊丝一辈子估计都得卖给这个企业了;当然,一般企业不会这么去跟员工算计(否则没人敢干活了),但是一次这种失误发生的话,个人KPI年终奖、部门奖金等就别指望了,而且因为你的错误,你的顶头上司还会受到牵连,如果你犯错“频繁”(注意DBA一年范两次这样的错就算频繁了),公司不辞你,估计也没脸在公司待下去;我就见过一些犯过类似错误的DBA,在往后进行某些数据库操作时,口中会念念有词,手还会止不住的发抖(正所谓一朝被蛇咬,十年怕井绳)。

下面将分四个部分,共十个方面来说明我整理的在SQLServer数据库运维的一些技巧:

保障数据访问

这个部分也可以叫在线容灾恢复,就是数据库发生问题后,在不中断用户访问(或者中断时间很短)的前提下,恢复数据库系统。

1. Mirror+Replication 自动切换

这种情况是在为核心数据库做了镜像,同时又做了复制的情况下,在主服务器发生问题时,系统能自动的将数据库切换到镜像机器,复制也同步切换过去(如果单纯只是做镜像切换的场景比较简单),也就是说核心服务器当机时,数据和同步链都不受影响,如果前端访问时是配置两个IP的(一个核心服务器IP,另一个是Mirror机器IP),那前端的访问就不会中断,在服务器出现问题时实现了对前端透明的切换过程;这种情况的详细过程请参考:SQLServer 数据库镜像+复制切换方案。

2. 群集在线添加节点

如果您的数据库服务器做了群集(假设是双A群集),现在群集中的某台机器出现了问题,那另外一台将承受双业务的压力,此种情况下,为防止我们单台服务器压力过大,或者再出现问题,我们应该尽快的替换掉出现问题的那台服务器,最好的方法是在线添加一个新的节点,步骤如下:

  1. 新弄一台服务器,做好必要的配置(加域、加心跳线、配置HBA卡等);
  2. 将新服务器添加到目前的Windows群集中;
  3. 将新服务器添加到SQLServer群集中;
  4. 将原本在出现问题机器上的业务切换到新添加的服务器中;
  5. 将出现问题的节点从群集中删除。

这个过程因为要在添加完节点后,将业务切换过来,所以会有短暂的业务暂停(相当于重启了一次SQLServer服务),但一般是可以接受的,这样我们就将损坏的机器做了在线的替换,基本不影响业务的正常进行。

提高数据库访问能力

3. 在线扩充数据库读能力

能在线扩充读能力的,一般都是需要做了数据库复制的环境,很多互联网企业在做企业的促销活动时,经常采取这种方案(尤其是电商);在线扩充读能力一般分两种情况,第一种是提前准备好了读的服务器,数据也同步了,只需要在读出现瓶颈时,将准备好的服务器添加到负载均衡的缓冲池即可;另外一种是没有提前准备好读的服务器,而是临时添加,我们就来说下这个过程:

  1. 准备好需要添加的服务器;
  2. 将其他读的机器上的数据库备份,还原到新的机器;
  3. 从分发机器上创建到这台机器的同步链并暂时禁用(可以参考其他读机器同步链);
  4. 同步链通过数据库比较工具(BCP、TableDiff等)修复缺失的数据,
  5. 启用同步链,跳过数据已经存在的冲突错误;
  6. 没有问题后,与其他只读机器比较数据量的情况,如果没问题即添加完成;
  7. 将新机器添加的负载均衡缓冲池,提供前端访问。

从整个过程来看,临时扩充系统读能力还是比较麻烦的,需要操作的DBA技能比较熟练,而且数据修复部分可能需要的时间比较长,一般应是提前准备的好,防止临时添加时时间过紧而犯错。

4. SSB + Replication

SSB是SQLServer数据库的异步通信功能,如果企业对数据实时性要求不是那么高的话,是完全可以采用这项技术的,它的最大好处就是缓解瞬时的高峰压力,将部分操作异步处理,保证前端用户其他操作的顺畅;举个例子,我们在线预订酒店就可以用SSB技术,当你在网页上面提交订单后,系统不会马上告诉你订单是否成功,这时我们就用SSB技术传递一个消息给后端去处理,处理完成后再向用户手机发送一条信息,提示他是否预订成功,这样就缓解了网上大量用户在同一时刻下单时,造成网站阻塞的情况;如果能在结合复制技术,在读的机器上完成下单操作,然后通过SSB技术再到主服务器上去完成事务的处理,效果会更加(因为读的机器比较多,下单压力会分散到多台机器),这个技术大家可以参考

数据库架构 这篇文章。

5. 架构设计扩充系统读能力

架构设计中,加快系统读能力的方案比较多(因为读比较频繁,容易出现瓶颈),比较普遍的是以空间换时间方案,按不同的维度将数据存放多份,在用户进行查找时根据查找的条件将查询定位到不同的服务器;例如我们将数据按三个维度来存放:普通维度、用户维度和产品维度,当前端写入数据时,就根据规则算法将数据按不同的维度写入不同的数据库服务器(前端写入的操作会变得复杂),而在用户查找时,就可以按用户选择的条件定位到相应的数据库上面去查找相关的数据了(如果还能结合Lucence等搜索引擎,效果会更好)。

在线数据库操作

6. 在线系统添加非空字段(带默认值)

为在线系统的某个表添加一个非空的字段,这个操作是经常会遇到的,在数据量小,用户访问量不那么频繁时不存在什么问题,一旦表的数据量达到千万级别,而且用户对这个表访问频繁时,这个看似简单的操作就变得不是那么容易了;如果直接操作往往消耗时间很长,而且其他用户的操作被大量阻塞,甚至出现数据库假死现象;这种情况下处理这些操作的方式就必须改变,可能的方案如下:

  1. 选择业务低峰时间进行操作(如:晚上);
  2. 加一个带默认值,且可以为NULL的字段,完成后将为NULL的数据改成默认值;
  3. 先加一个为NULL的字段,将数据填充后,改成带默认值的非NULL字段。

从这三种方式来看,第二种方式是比较好的,因为它既能满足后面不断增加数据为非NULL值的需要,也不会造成大面积的阻塞,而且能满足时间上的需求(这种修改一般可能要当场就进行,而不是等上一天);当然在做NULL值数据修复时,需要分批进行(一次性操作又会遇到大量的阻塞和操作时间过长的问题),如按下面的代码形式修改:

declare @rowcount int

if OBJECT_ID(‘tempdb.dbo.#temp1′) is not null

drop table dbo.#temp1

–更新临时表

create table dbo.#temp1(id int primary key not null)

while 1=1

begin

–每次修改条记录

insert into dbo.#temp1(id)

select top 1000 id from dbo.Table1 where IsUpdate is null

update dbo.Table1 set a.IsUpdate=0 where ID in(select ID from #temp1)

set @rowcount=@@rowcount

if @rowcount=0

break;

else

waitfor delay ’00:00:00.500′ –暂停.5秒

truncate table #temp1

end

这类型的操作还有:添加索引,删除一个大表的部分数据等,操作的时候都需要使用一定的技巧才顺利完成。

7. 数据库收缩

数据库变大,磁盘空间不足时,DBA往往都会采取收缩数据库或者数据文件的操作,但是这个操作在数据库很大时往往是一个相当耗时的过程,我们在对数据库(或者文件)收缩前最好先看一下最多能释放多少空间(下图的最小值)


然后选择能释放空间比较大的文件进行收缩,而且收缩时一定要分部进行,不要一次性收缩,可以每次选择收缩5G;刚开始收缩时是比较快的,越往后面收缩需要的时间也越长(因为系统需要挪动的数据更多),如果觉得收缩时间过长了,我们可以终止掉,这样就不会有一次性收缩时造成数据库假死的现象;收缩的同时我们还需要查看下阻塞的情况,如果有用户进程被收缩进程阻塞了,而且一定的时间内不能释放,应该马上终止收缩进程,防止影响业务的运行:

select * from sys.sysprocesses with(nolock) where blocked<>0

8. 在线CPU调整

在线系统如果CPU变得比较高了,我们在做调整时往往要对症下药,不能盲目处理,否则可能造成更严重的CPU性能问题;CPU 突然走高,70%的可能是因为新进来的一些语句缺乏相关的索引,尤其是一些有GroupBy、 OrderBy 这类型的语句,那我们如何来找到这些语句呢?一个常见的方法是查找DMV,找出当时消耗CPU最多的语句,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

--总耗CPU最多的前个SQL:
SELECT TOP 20
total_worker_time/1000 AS [总消耗CPU 时间(ms)],execution_count [运行次数],
qs.total_worker_time/qs.execution_count/1000 AS [平均消耗CPU 时间(ms)],
last_execution_time AS [最后一次执行时间],max_worker_time /1000 AS [最大执行时间(ms)],
SUBSTRING(qt.text,qs.statement_start_offset/2&#43;1,
(CASE WHEN qs.statement_end_offset = -1
THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset END -qs.statement_start_offset)/2 &#43; 1)
AS [使用CPU的语法], qt.text [完整语法],
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName
FROM sys.dm_exec_query_stats qs WITH(nolock)
CROSS apply sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE execution_count>1
ORDER BY total_worker_time DESC


--平均耗CPU最多的前个SQL:
SELECT TOP 20
total_worker_time/1000 AS [总消耗CPU 时间(ms)],execution_count [运行次数],
qs.total_worker_time/qs.execution_count/1000 AS [平均消耗CPU 时间(ms)],
last_execution_time AS [最后一次执行时间],min_worker_time /1000 AS [最小执行时间(ms)],
max_worker_time /1000 AS [最大执行时间(ms)],
SUBSTRING(qt.text,qs.statement_start_offset/2&#43;1,
(CASE WHEN qs.statement_end_offset = -1
THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset END -qs.statement_start_offset)/2 &#43; 1)
AS [使用CPU的语法], qt.text [完整语法],
qt.dbid, dbname=db_name(qt.dbid),
qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName
FROM sys.dm_exec_query_stats qs WITH(nolock)
CROSS apply sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE execution_count>1
ORDER BY (qs.total_worker_time/qs.execution_count/1000) DESC

不过DMV记录的是一些瞬时或者部分时间内系统收录的语句,往往不够全面,如果我们能每天在服务器上开一个Trace文件,通过Trace文件来分析就会比较全面了,如下:


如果你平时有对Trace文件进行分析和&#26684;式化并生成相关图表的话,那优化起来就更加有针对性了(&#26684;式化后,前十位消耗CPU的语句):

找到了语句,就可以来优化语句了,该加索引的加索引,该做调整的做调整,但是如果我们分析出来的语句该有的索引都有,该改进的地方也都改进了,它因为数据量或者访问频繁等原因暂用CPU的资源依然相当高,那怎么办?我们还有其他的方法处理吗?还是有的,主要的途径有如下几种:

  1. 查找等待信息,如果CPU类型的等待排在前面(主要是CXPACKET和SOS_SCHEDULER_YIELD两类),我们就可以认为是CPU的处理能力不足,此时为不影响其他的用户进程,可以将CPU的并行开销(调大cost threshold for parallelism)和并行度做调整(调小max degree of parallelism);
  2. 限制相关的语句使用CPU的数量(加上Option参数),如限制语句最多使用两颗CPU:select * from Products with(nolock) option(maxdop 2)
  3. 看看数据库使用的内存是否还可以做调整,或者系统内存是不是大部分被数据库使用;
  4. 查看一下索引的碎片是否过大,过大的话需要做索引的重新整理(这个操作需要在业务低峰时进行);
  5. 查看下统计信息是否是最新的,如果不是,更新统计信息(这个操作往往比较有效);
  6. 判断语句是否使用了正确的执行计划,如果不是,删除已有的执行计划,再重新执行;如果是存储过程可以加 WITH RECOMPILE。

相信采取了这些措施后,应该能让服务器的CPU压力有所缓解,如果还是不能解决问题,那就需要更换更好的CPU了(或者是添加更多的内存)。

数据安全

9. 备份与还原

备份与还原是DBA一个很重要的任务,再怎么强调都不过分,就像国家花大价钱培养军人一样,养兵千日,用兵一时,它是关键时刻最后的救命稻草;备份还原也有一些使用的技巧,如:备份计划和频率的制定,需不需要远程和本地双重备份,备份时我们是否要加“CheckSum”参数,是否需要做压缩备份,是否需要定期做还原测试,还原有问题时加“CONTINUE_AFTER_ERROR”尽量挽救数据,是否只需要做页还原,以及尾日志的备份和还原等等,如果要保证备份的数据绝对的安全可靠的话,做远程和本地双备份,做定期的还原测试这些都是必要的;如果还有人问做了Mirror或者LogShipping之后,还需要做备份吗?那请想下,如果某个重要的表被某个不小心的人删除了,你能通过Mirror或者LogShipping找回吗?

10. 核心数据多层保障

核心的数据做多重的保障是必要的(虽然成本会变高),毕竟核心的数据很大程度上对一个企业能否继续运营起着关键作用,在出现问题时,如果一套保护方案出现问题,我们还有其他的方案来恢复数据,这些保护的投入是&#20540;得的,下图罗列了常用的保护方案,DBA可以根据企业的实际情况(主要是成本因素),选取其中的某些技术方案,来保障数据的安全。


以上十点只是我个人在做DBA的过程中总结的一些技巧,如大家有其他的一些方面的技巧,欢迎留言交流。

推荐阅读
  • 2021年Java开发实战:当前时间戳转换方法详解与实用网址推荐
    在当前的就业市场中,金九银十过后,金三银四也即将到来。本文将分享一些实用的面试技巧和题目,特别是针对正在寻找新工作机会的Java开发者。作者在准备字节跳动的面试过程中积累了丰富的经验,并成功获得了Offer。文中详细介绍了如何将当前时间戳进行转换的方法,并推荐了一些实用的在线资源,帮助读者更好地应对技术面试。 ... [详细]
  • 在Java分层设计模式中,典型的三层架构(3-tier application)将业务应用细分为表现层(UI)、业务逻辑层(BLL)和数据访问层(DAL)。这种分层结构不仅有助于提高代码的可维护性和可扩展性,还能有效分离关注点,使各层职责更加明确。通过合理的设计和实现,三层架构能够显著提升系统的整体性能和稳定性。 ... [详细]
  • 提升 Kubernetes 集群管理效率的七大专业工具
    Kubernetes 在云原生环境中的应用日益广泛,然而集群管理的复杂性也随之增加。为了提高管理效率,本文推荐了七款专业工具,这些工具不仅能够简化日常操作,还能提升系统的稳定性和安全性。从自动化部署到监控和故障排查,这些工具覆盖了集群管理的各个方面,帮助管理员更好地应对挑战。 ... [详细]
  • 小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限
    小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限 ... [详细]
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • 负载均衡基础概念与技术解析
    随着互联网应用的不断扩展,用户流量激增,业务复杂度显著提升,单一服务器已难以应对日益增长的负载需求。负载均衡技术应运而生,通过将请求合理分配到多个服务器,有效提高系统的可用性和响应速度。本文将深入探讨负载均衡的基本概念和技术原理,分析其在现代互联网架构中的重要性及应用场景。 ... [详细]
  • Java EE 平台集成了多种服务、API 和协议,旨在支持基于 Web 的多层应用程序开发。本文将详细介绍 Java EE 中的 13 种关键技术规范,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • 面试题总结_2019年全网最热门的123个Java并发面试题总结
    面试题总结_2019年全网最热门的123个Java并发面试题总结 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • 直播带货系统中的推流技术详解
    本文介绍了RTMP(实时消息传输协议)及其在直播带货系统中的应用,并详细探讨了带货直播系统的连麦方案,包括服务端合流和客户端合流的优势与劣势。 ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • 本文通过思维导图的形式,深入解析了大型网站技术架构的核心原理与实际案例。首先,探讨了大型网站架构的演化过程,从单体应用到分布式系统的转变,以及各阶段的关键技术和挑战。接着,详细分析了常见的大型网站架构模式,包括负载均衡、缓存机制、数据库设计等,并结合具体案例进行说明。这些内容不仅有助于理解大型网站的技术实现,还能为实际项目提供宝贵的参考。 ... [详细]
  • 第二章:Kafka基础入门与核心概念解析
    本章节主要介绍了Kafka的基本概念及其核心特性。Kafka是一种分布式消息发布和订阅系统,以其卓越的性能和高吞吐量而著称。最初,Kafka被设计用于LinkedIn的活动流和运营数据处理,旨在高效地管理和传输大规模的数据流。这些数据主要包括用户活动记录、系统日志和其他实时信息。通过深入解析Kafka的设计原理和应用场景,读者将能够更好地理解其在现代大数据架构中的重要地位。 ... [详细]
  • 【并发编程】全面解析 Java 内存模型,一篇文章带你彻底掌握
    本文深入解析了 Java 内存模型(JMM),从基础概念到高级特性进行全面讲解,帮助读者彻底掌握 JMM 的核心原理和应用技巧。通过详细分析内存可见性、原子性和有序性等问题,结合实际代码示例,使开发者能够更好地理解和优化多线程并发程序。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
author-avatar
蓝色春天绿意长
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有