【问题标题】:How do I change FILEGROUP of an existing Partition (SQL Server)如何更改现有分区的 FILEGROUP (SQL Server)
【发布时间】:2021-04-10 13:22:43
【问题描述】:

我有一个非常大的表,按月分区。我还为每一年创建了文件组,因此每个文件组在那一年最多可以容纳 12 个分区。这是分区函数:

CREATE PARTITION FUNCTION [PF_MonthlyPartition](datetime) 
AS RANGE RIGHT FOR VALUES (N'2019-06-01T00:00:00.000', 
N'2019-07-01T00:00:00.000', N'2019-08-01T00:00:00.000', N'2019-09-01T00:00:00.000', 
N'2019-10-01T00:00:00.000', N'2019-11-01T00:00:00.000', N'2019-12-01T00:00:00.000', 
N'2020-01-01T00:00:00.000', N'2020-02-01T00:00:00.000', N'2020-03-01T00:00:00.000', 
N'2020-04-01T00:00:00.000', N'2020-05-01T00:00:00.000', N'2020-06-01T00:00:00.000', 
N'2020-07-01T00:00:00.000', N'2020-08-01T00:00:00.000', N'2020-09-01T00:00:00.000', 
N'2020-10-01T00:00:00.000', N'2020-11-01T00:00:00.000', N'2020-12-01T00:00:00.000', 
N'2021-01-01T00:00:00.000', N'2021-02-01T00:00:00.000')

问题是,我的最后一个分区不是在 FG_2021 中,而是在 PRIMARY 文件组中。

Data Distribution right now

如何将该分区的文件组改为FG_2021?

我当前的分区方案最终看起来像这样:

CREATE PARTITION SCHEME [PS_MonthWise] AS PARTITION [PF_MonthlyPartition] 
TO ([FG_2019], [FG_2019], [FG_2019], 
[FG_2019], [FG_2019], [FG_2019], 
[FG_2019], [FG_2019], [FG_2020], 
[FG_2020], [FG_2020], [FG_2020], 
[FG_2020], [FG_2020], [FG_2020], 
[FG_2020], [FG_2020], [FG_2020], 
[FG_2020], [FG_2020], [PRIMARY], [FG_2021])

【问题讨论】:

    标签: sql-server partitioning table-partitioning


    【解决方案1】:

    在将数据移动到正确的 FG 时,您是否能够使错误分区不可用/为空?如果是这样,将分区切换到空表,发出必要的create index... with (drop_existing = on...) on [FG_2021] 命令以物理移动数据,更改分区函数以合并出“坏”分区,再次更改分区函数以重新添加分区边界(这次使用正确的 FG),然后将分区(从步骤 1)切换回主表。错误的分区看起来没有那么大,所以应该很快。


    更新

    这是一个虚拟数据库中的快速重现:

    /*setup*/
    use master;
    drop database if exists prtTest;
    create database prtTest;
    alter database prtTest add FILEGROUP [FG_2019];
    alter database prtTest add file (
        name = 'FG_2019', 
        filename = 'c:\temp\FG_2019.ndf', 
        size = 10mb) 
    to filegroup [FG_2019];
    
    alter database prtTest add FILEGROUP [FG_2020];
    alter database prtTest add file (
        name = 'FG_2020',
        filename = 'c:\temp\FG_2020.ndf',
        size = 10mb
    ) to filegroup [FG_2020];
    
    alter database prtTest add FILEGROUP [FG_2021];
    alter database prtTest add file (
        name = 'FG_2021',
        filename = 'c:\temp\FG_2021.ndf',
        size = 10mb
    ) to filegroup [FG_2021];
    
    use prtTest;
    go
    CREATE PARTITION FUNCTION [PF_MonthlyPartition](datetime) 
    AS RANGE RIGHT FOR VALUES (N'2019-06-01T00:00:00.000', 
        N'2019-07-01T00:00:00.000', N'2019-08-01T00:00:00.000', N'2019-09-01T00:00:00.000', 
        N'2019-10-01T00:00:00.000', N'2019-11-01T00:00:00.000', N'2019-12-01T00:00:00.000', 
        N'2020-01-01T00:00:00.000', N'2020-02-01T00:00:00.000', N'2020-03-01T00:00:00.000', 
        N'2020-04-01T00:00:00.000', N'2020-05-01T00:00:00.000', N'2020-06-01T00:00:00.000', 
        N'2020-07-01T00:00:00.000', N'2020-08-01T00:00:00.000', N'2020-09-01T00:00:00.000', 
        N'2020-10-01T00:00:00.000', N'2020-11-01T00:00:00.000', N'2020-12-01T00:00:00.000', 
        N'2021-01-01T00:00:00.000', N'2021-02-01T00:00:00.000');
    CREATE PARTITION SCHEME [PS_MonthWise] AS PARTITION [PF_MonthlyPartition] 
    TO ([FG_2019], [FG_2019], [FG_2019], 
        [FG_2019], [FG_2019], [FG_2019], 
        [FG_2019], [FG_2019], [FG_2020], 
        [FG_2020], [FG_2020], [FG_2020], 
        [FG_2020], [FG_2020], [FG_2020], 
        [FG_2020], [FG_2020], [FG_2020], 
        [FG_2020], [FG_2020], [PRIMARY], [FG_2021]
    );
    
    create table dbo.foo (dt datetime) on [PS_MonthWise](dt);
    create clustered index [IX_foo] on dbo.foo(dt) on [PS_MonthWise](dt);
    
    insert into dbo.foo (dt)
    values 
        ('2021-01-01'), 
        ('2021-01-02'), 
        ('2021-02-01'), 
        ('2021-02-02');
    select *, $partition.[PF_MonthlyPartition](dt)
    from dbo.foo;
    
    /*end setup*/
    
    /*run this query after any partition function changes*/
    select p.partition_number, prv.[value], fg.name, p.[rows]
    from sys.partitions as p
    left join sys.allocation_units as au
        on au.container_id = p.hobt_id
        and au.[type] in (1, 3)
    left join sys.filegroups as fg
        on fg.data_space_id = au.data_space_id
    left join sys.partition_range_values as prv
        on prv.boundary_id = p.partition_number
    where object_id = object_id('dbo.foo')
    order by partition_number;
    
    create table dbo.temp_foo (dt datetime) on [PRIMARY];
    create clustered index [IX_foo] on dbo.temp_foo(dt) on [PRIMARY];
    
    alter table dbo.foo switch partition 21
        to dbo.temp_foo;
    
    create clustered index [IX_foo] on dbo.temp_foo(dt) 
        with (drop_existing = on) on [PS_MonthWise](dt);
    
    alter partition function [PF_MonthlyPartition]()
        merge range (N'2021-01-01T00:00:00.000');
    
    alter partition scheme [PS_MonthWise]
        next used [FG_2021];
    
    alter partition function [PF_MonthlyPartition]()
        split range (N'2021-01-01T00:00:00.000');
    
    alter table dbo.temp_foo switch partition 21
        to dbo.foo partition 21;
    

    【讨论】:

    • 不会CREATE INDEX...WITH (DROP_EXISTING=ON)重建所有分区吗?
    • 肯定会的。但在该过程中,错误分区已切换到单独的表。因此,此时“所有分区”等于“一个”。
    • 谢谢本。这就说得通了。我刚试过。我收到一条错误消息,告诉我即使我的表已分区,但我的主键没有。我想我需要先分区我的主键。我想知道这需要多长时间,哈哈
    • 啊,是的。我假设表上的所有索引都已分区。这确实是一个先决条件。
    • 所以这并不完全有效。我以为会,但没有。我通过分区功能重建了主键,并且能够很好地切换分区。然后我对“坏”分区进行了合并,并尝试使用正确的 FG 重新添加分区边界。这是它再次添加回 PRIMARY 文件组上的分区的地方,即使我告诉它使用 FG_2021 和 ALTER Partition SCHEME PS_MonthWise NEXT USED [FG_2021] 命令。这正是我第一次这样做时发生的事情。我不太确定为什么会这样
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多