SQL Server实现自动循环归档分区数据脚本详解

最近在工作中遇到了关于sql server的一个问题,通过查找相关的资料终于解决了,所以下面这篇文章主要给大家介绍了关于SQL Server如何实现自动循环归档分区数据脚本的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。

概述

大家应该都知道在很多业务场景下我们需要对一些记录量比较大的表进行分区,同时为了保证性能需要将一些旧的数据进行归档。在分区表很多的情况下如果每一次归档都需要人工干预的话工程量是比较大的而且也容易发生纰漏。接下来分享一个自己编写的自动归档分区数据的脚本,原理是分区表和归档表使用相同的分区方案,循环利用当前的文件组,话不多说了,来一起看看详细的介绍吧。

一、创建测试数据

?

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

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

—-01创建文件组

USE [master]

GO

ALTER DATABASE [chenmh] ADD FILEGROUP [Group1]

GO

ALTER DATABASE [chenmh] ADD FILEGROUP [Group2]

GO

ALTER DATABASE [chenmh] ADD FILEGROUP [Group3]

GO

ALTER DATABASE [chenmh] ADD FILEGROUP [Group4]

GO

USE [master]

GO

ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile1', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL12.MSSQLSERVER\\MSSQL\\DATA\\datafile1.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group1]

GO

ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile2', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL12.MSSQLSERVER\\MSSQL\\DATA\\datafile2.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group2]

GO

ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile3', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL12.MSSQLSERVER\\MSSQL\\DATA\\datafile3.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group3]

GO

ALTER DATABASE [chenmh] ADD FILE ( NAME = N'datafile4', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL12.MSSQLSERVER\\MSSQL\\DATA\\datafile4.ndf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) TO FILEGROUP [Group4]

GO

—-02创建分区函数

USE [chenmh]

GO

CREATE PARTITION FUNCTION [Pt_Range](BIGINT) AS RANGE RIGHT FOR VALUES (1000000, 2000000, 3000000)

GO

—-03创建分区方案,分区方案对应的文件组数是分区函数指定的数量+1

CREATE PARTITION SCHEME Ps_Range

AS PARTITION Pt_Range

TO (Group1, Group2, Group3, Group4);

—04创建表,指定的分区列的数据类型一定要和分区函数指定的列类型一致。

CREATE TABLE [dbo].[News](

[id] [bigint] NOT NULL,

[status] [int] NULL,

CONSTRAINT [PK_News] PRIMARY KEY CLUSTERED

(

[id] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Ps_Range](id)

) ON [Ps_Range](id)

—–创建归档分区表

CREATE TABLE [dbo].[NewsArchived](

[id] [bigint] NOT NULL,

[status] [int] NULL,

CONSTRAINT [PK_NewsArchived] PRIMARY KEY CLUSTERED

(

[id] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Ps_Range](id)

) ON [Ps_Range](id)

—-插入测试数据

DECLARE @id INT

SET @id=1

WHILE @id<5001000

BEGIN

INSERT INTO News VALUES(@id,@id%2)

SET @id=@id+1

END

SQL Server实现自动循环归档分区数据脚本详解

可以看到当前总共有4个分区,每一个分区定义的范围区间是100万,分区4我故意多插入了200多万的数据来验证自动归档分区。

二、自动归档分区脚本

?

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

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

CREATE PROCEDURE Pro_Partition_AutoArchiveData

(@PartitionTable VARCHAR(300),

@SwitchTable VARCHAR(300)

)

AS

BEGIN

DECLARE @FunName VARCHAR(100),@SchemaName VARCHAR(100),@MaxPartitionValue sql_variant

—根据归档表查找对应的分区方案、分区函数、最小分区数、最大分区范围值

SELECT

DISTINCT

@FunName=MAX(pf.name),

@SchemaName=MAX(ps.name),

@MaxPartitionValue=max(isnull(prv.value,0))

FROM sys.partitions p inner join sys.indexes i ON p.object_id=i.object_id and p.index_id=i.index_id

inner join sys.partition_schemes ps ON i.data_space_id=ps.data_space_id

inner join sys.destination_data_spaces dds ON ps.data_space_id=dds.partition_scheme_id and dds.destination_id=p.partition_number

inner join sys.data_spaces ds ON dds.data_space_id=ds.data_space_id

inner join sys.partition_functions pf ON ps.function_id=pf.function_id

LEFT join sys.partition_range_values prv ON pf.function_id=prv.function_id AND prv.boundary_id=p.partition_number-pf.boundary_value_on_right

LEFT join sys.partition_parameters pp ON prv.function_id=pp.function_id and prv.parameter_id=pp.parameter_id

LEFT join sys.types t ON pp.system_type_id=t.system_type_id and pp.user_type_id=t.user_type_id

WHERE OBJECT_NAME(p.OBJECT_ID)=@PartitionTable

DECLARE @MaxId BIGINT,@MinId BIGINT,@Sql NVARCHAR(MAX),@GroupName VARCHAR(100),@MinPartitionNumber INT

SET @Sql= N'SELECT @MaxId=MAX(id),@MinId=Min(id) FROM '+@PartitionTable

EXEC sp_executesql @Sql,N'@MaxId BIGINT out,@MinId BIGINT out',@MaxId OUT,@MinId OUT

SELECT @FunName AS FunName,@SchemaName AS SchemaName,@MaxPartitionValue AS MaxPartitionValue ,@MaxId AS MaxId,@MinId AS MinId

—判断当前表的最大的id是否已经在最大的分区中

IF @MaxId>=@MaxPartitionValue

BEGIN

—-归档分区数据,根据表的最小值找到它所属的分区.

SET @Sql= N'SELECT @MinPartitionNumber=$PARTITION.'+@FunName+N'('+CONVERT(VARCHAR(30),@MinId)+N')';

EXEC sp_executesql @Sql,N'@MinPartitionNumber INT out',@MinPartitionNumber OUT

SET @Sql=N'ALTER TABLE ' +@PartitionTable+ N' SWITCH PARTITION '+CONVERT(VARCHAR(10),@MinPartitionNumber)+ N' TO ' +@SwitchTable+ N' PARTITION ' +CONVERT(VARCHAR(10),@MinPartitionNumber);

–PRINT @Sql

EXEC (@Sql)

—修改分区方案,增加新的分区对应的文件组,根据最小的分区id找到对应的文件组。

SELECT

DISTINCT

@GroupName=ds.name

FROM sys.partitions p inner join sys.indexes i ON p.object_id=i.object_id and p.index_id=i.index_id

inner join sys.partition_schemes ps ON i.data_space_id=ps.data_space_id

inner join sys.destination_data_spaces dds ON ps.data_space_id=dds.partition_scheme_id and dds.destination_id=p.partition_number

inner join sys.data_spaces ds ON dds.data_space_id=ds.data_space_id

inner join sys.partition_functions pf ON ps.function_id=pf.function_id

WHERE pf.name=@FunName AND ps.name=@SchemaName AND p.partition_number=@MinPartitionNumber

SET @Sql=N'ALTER PARTITION SCHEME '+@SchemaName+N' NEXT USED '+@GroupName

–PRINT @Sql

EXEC (@Sql)

—修改分区函数,增加新的分区,增加新的分区范围值,在现有的最大的值的基础上加100万(需要和现有的分区函数的范围保持一致)

SET @MaxPartitionValue=CONVERT(BIGINT,@MaxPartitionValue)+1000000

SET @Sql=N'ALTER PARTITION FUNCTION '+@FunName+N'('+N')'+N' SPLIT RANGE ('+CONVERT(VARCHAR(30),@MaxPartitionValue)+N')'

–PRINT @Sql

EXEC (@Sql)

END

END

三、自动归档分区数据

1.首次测试

?

1

EXEC Pro_Partition_AutoArchiveData 'news','NewsArchived';

注意:每调用一次归档一个最小分区的数据。

SQL Server实现自动循环归档分区数据脚本详解

SQL Server实现自动循环归档分区数据脚本详解

分区表的News分区1的数据被归档到了NewsArchived表中,且创建了分区5,分区5使用的是已归档的分区1的文件组,达到了循环利用文件组的效果。

2.再调用一次归档分区脚本

SQL Server实现自动循环归档分区数据脚本详解

当分区表最大的id小于最大的分区值时自动归档分区脚本就不会生效。所以当前的测试表数据还可以再归档分区3的数据。

3.经过一段时间的运行归档数据可能是这样的效果

SQL Server实现自动循环归档分区数据脚本详解

Group1→Group4→Group1→…….

四、脚本注意事项

1.@PartitionTable和@SwitchTable表必须使用同名的分区方案和分区函数,否则@SwitchTable就需要单独修改分区方案和函数,且表结构完全一致。

2.归档的表分区列数据类型必须是INT类型,且值是自增规律.

3.分区归档作业在备份作业后执行

4.建议使用Right分区,Left分区会出现有的最后一个分区文件组不会循环替换,一直处于分区的最后,比如Group1,Group2,Group3,Group1,Group2,Group3,Group1,Group4。期望的应该是Group1,Group2,Group3,Group4,Group1,Group2,Group3,Group4,Group1

5.注意我当前的每个分区大小是100万和分区函数保持一致,如果范围值不同,需要修改最末尾代码的"修改分区函数"处代码.

总结

当前自动归档分区脚本如果要拷贝去用还是得能完全理解每一段代码,根据自己的业务做适当的修改,毕竟数据是无价的!!!。最后只需要创建一个作业定期跑作业就行,重复执行也不影响。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对钦钦技术栈的支持。

原文链接:http://www.cnblogs.com/chenmh/p/7576128.html

版权声明:本文(即:原文链接:https://www.qin1qin.com/catagory/25051/)内容由互联网用户自发投稿贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 630367839@qq.com 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年9月23日 下午12:20
下一篇 2022年9月23日 下午12:20
软件定制开发公司

相关阅读

发表回复

登录后才能评论
通知:禁止投稿所有关于虚拟货币,币圈类相关文章,发现立即永久封锁账户ID!