设为首页 收藏本站
查看: 1091|回复: 0

[经验分享] SQL Server中的高可用性(2)----文件与文件组

[复制链接]

尚未签到

发表于 2015-6-27 21:23:25 | 显示全部楼层 |阅读模式
  在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性。在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性。SQL Server允许在某些文件损坏或离线的情况下,允许数据库依然保持部分在线,从而保证了高可用性。
  
  文件和文件组
  有关文件和文件组的基本概念,有很多文章已经阐述过了。这里我只是提一下,文件组作为SQL Server访问文件的一个抽象层而存在。因此SQL Server上所做的操作不是直接针对文件,而是针对文件组。
  使用多个文件组和文件不仅仅是为了分散IO和提高性能,还有高可用性方面的原因。有关一个数据库应该包含几个文件或文件组,Paul Randal已经做过非常棒的阐述,请参阅:http://www.sqlskills.com/blogs/paul/files-and-filegroups-survey-results/。
  数据库中使用多个文件或文件组在高可用性方面的好处包括:
  
       
  • 某文件的IO损坏,数据库还可以保证部分在线。   
  • 将索引和表分开存放,假如索引文件不在线,数据依然可以被访问。   
  • 历史数据和热数据分开,历史归档数据损坏,不影响热数据。   
  • 分开数据文件使得在灾难恢复时仅仅恢复部分数据从而缩短了宕机时间   
  • 数据库分为多个文件使得可以通过增加文件或移动文件的方式解决空间不足的问题
  
  文件
  在SQL Server中,文件分为三类,分别为:
  
       
  • 主数据文件   
  • 辅助数据文件   
  • 日志文件
  其中,主数据文件默认以扩展名mdf结尾,辅助数据库文件默认以ndf结尾,日志文件以ldf结尾。虽然扩展名是可以修改的,但强烈建议不要去改扩展名。
  上面提到文件名值得是物理文件名,但是实际上在SQL Server中进行操作,操作的是逻辑文件名。
  任何时间,文件都会处于某一种状态,这些状态包括:
  
       
  • 在线   
  • 离线   
  • 恢复中   
  • 还原挂起   
  • 质疑
  可以通过sys.database_files这个DMV来查看数据库文件中包含状态在内的相关信息,如图1所示。
DSC0000.jpg
  图1.查看数据库中文件的状态等相关信息
  
  你甚至可以在数据库缺少NDF文件时附加数据库,具体细节,请参阅MCM黄大师的一篇文章:http://www.sqlnotes.info/2013/05/07/attach-database-with-missing-ndf-file/。
  
  文件组
  在SQL Server中,文件组中某个文件的状态决定了整个文件组的状态。但文件的状态独立于数据库的状态,比如说文件的状态是离线,但数据库依然能保证在线,这也就是所谓的数据库部分在线,举个例子,某个文件包含了名为selldata的表,如果该文件离线,但数据库在线,所有针对该selldata的表上的操作都会失败。
  如果需要数据库中的某个文件组在线,该文件组中的所有文件都应该处于在线状态。
  
  表分区
  表分区是自SQL Server 2005之后出现的一个概念,我之前已经写过一篇关于表分区的文章。表分区的概念虽然很老了,但是很多地方对于表分区的使用依然处于非常初级的阶段。
  我见过大部分想到使用表分区的例子是出现性能问题,从而考虑分散大表的IO。但实际上,表分区还会提高可用性。使用表分区的好处还包括:
  
       
  • 轻松管理大表或分区   
  • 提高并发性(产生分区锁,而不是表锁)   
  • 以文件组级别就行备份和还原,从而仅仅只备份和还原表的一部分(比如说只备份表中的热数据),从而减少了还原时间   
  • 可以仅仅在线重建某个分区
  
  值得注意的是,对表分区后,也要对表上的非聚集索引进行索引分区。否则有可能造成性能方面的例子。
  
  DEMO
  DEMO1 :仅重建某个分区
  下面例子是一个简单的分区表,并对索引进行分区后,仅仅重建某个分区,而不是整个索引。比如说表中按照数据冷热进行分区,可以仅仅对热数据进行重建,从而大大减少了重建索引所需的时间,如代码清单1所示。
  
--创建分区函数
CREATE PARTITION FUNCTION [t](int) AS RANGE LEFT FOR VALUES (100, 500)
--分区架构
CREATE PARTITION SCHEME [x] AS PARTITION [t] TO ([PRIMARY], [FileGroup1], [FileGroup1])
--创建表
CREATE TABLE [Sales].[SalesOrderDetailPartition](
[SalesOrderID] [int] NOT NULL,
[SalesOrderDetailID] [int] IDENTITY(1,1) NOT NULL,
[CarrierTrackingNumber] [nvarchar](25) NULL,
[OrderQty] [smallint] NOT NULL,
[ProductID] [int] NOT NULL,
[SpecialOfferID] [int] NOT NULL,
[UnitPrice] [money] NOT NULL,
[UnitPriceDiscount] [money] NOT NULL,
[LineTotal]  AS (isnull(([UnitPrice]*((1.0)-[UnitPriceDiscount]))*[OrderQty],(0.0))),
[rowguid] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
) ON x(SalesOrderID)
INSERT INTO [Sales].[SalesOrderDetailPartition]([SalesOrderID],
[CarrierTrackingNumber],
[OrderQty] ,
[ProductID] ,
[SpecialOfferID],
[UnitPrice],
[UnitPriceDiscount],ModifiedDate,rowguid)
SELECT [SalesOrderID],
[CarrierTrackingNumber],
[OrderQty] ,
[ProductID] ,
[SpecialOfferID],
[UnitPrice],
[UnitPriceDiscount],ModifiedDate,rowguid FROM [Sales].[SalesOrderDetail]

go
--创建索引分区
CREATE NONCLUSTERED INDEX test_partition_idx ON [Sales].[SalesOrderDetailPartition](ProductID) on x(SalesOrderID)
--仅仅重建某个分区
ALTER INDEX test_partition_idx
ON [Sales].[SalesOrderDetailPartition]
REBUILD Partition = 1
  代码清单1.仅仅重建某个分区,而不是整个索引
  
  关于这里,更深入的文章可以参阅:http://www.mssqltips.com/sqlservertip/1621/sql-server-partitioned-tables-with-multiple-filegroups-for-high-availability/
  
  DEMO2:数据库部分在线和文件还原



--创建测试数据库
CREATE DATABASE test
GO
--改成完整恢复模式
ALTER DATABASE test SET  RECOVERY FULL
--添加一个文件组
ALTER DATABASE test
ADD FILEGROUP WW_GROUP
GO
--向文件组中添加文件
ALTER DATABASE test
ADD FILE
( NAME = ww,
FILENAME = 'D:\wwdat1.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB)
TO FILEGROUP ww_Group
--在不同文件组上分别创建两个表
CREATE TABLE test..test ( id INT IDENTITY )
ON  [primary]
CREATE TABLE test..test_GR ( id INT IDENTITY )
ON  ww_Group

--做完整备份
BACKUP DATABASE test
TO DISK='D:\Test_backup.bak'WITH INIT
--做文件备份
BACKUP DATABASE test
FILE = 'ww',
FILEGROUP = 'ww_Group'
TO DISK='D:\CROUPFILES.bak'WITH INIT
--备份日志
BACKUP LOG test
TO DISK='D:\Test__log.ldf'WITH INIT

--删除文件组中的表内的数据
TRUNCATE TABLE test..test_GR
--还原备份,日志仅仅被应用于那个还原状态的文件
RESTORE DATABASE test
FILE = 'ww',
FILEGROUP = 'ww_Group'
FROM DISK ='D:\CROUPFILES.bak'
WITH FILE = 1,NORECOVERY
RESTORE LOG test
FROM DISK='D:\Test__log.ldf'
WITH FILE = 1, NORECOVERY
--备份尾端日志
BACKUP LOG test
TO DISK='D:\Test__log.ldf' WITH NOINIT,NO_TRUNCATE
--还原尾端日志
RESTORE LOG test
FROM DISK='D:\Test__log.ldf'
WITH FILE = 2, RECOVERY
GO
--查看数据,删除数据的操作被成功恢复
SELECT  *
FROM    test..test_GR
--清除数据库
DROP DATABASE test
  代码清单2.备份还原单个文件
  
  代码清单2很好的阐述了整个文件备份还原的过程,其中,在文件还原的过程中我们可以看到数据库本身是在线的,但数据库中有一个文件处于还原状态,如图2所示。
DSC0001.jpg
  图2.ww文件处于还原中状态
  
  此时对于表test_GR做操作的话,会提示因文件组没有联机而失败,如图3所示。
DSC0002.jpg
  图3.因为文件组没有联机而导致操作失败
  
  再对尾端日志进行备份还原之后,该文件组成功上线。
  

小结
  本篇文章阐述了文件和文件组在高可用性中的作用。了解这些特性对于降低还原时间非常有必要。在数据库开始上线之前,尽量合理的把一个数据库分为多个文件组和文件,不仅仅提升性能和并发性,还可以使得DR更加容易。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-81085-1-1.html 上篇帖子: SQL SERVER 表分区实施步奏 下篇帖子: SQL Server的数据库连接的极限在哪儿?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表