简体   繁体   中英

How do I change FILEGROUP of an existing Partition (SQL Server)

I have a very large table which I partitioned by months. I have also created filegroups for each year, so each filegroup would hold at most 12 partitions for that year. Here is the partition function:

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')

The problem is, my last partition, instead of being in FG_2021 ended up in the PRIMARY filegroup.

Data Distribution right now

How do I change the file group of that partition to FG_2021?

My current partition sheme ended up looking like this:

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])

Do you have the ability to have the errant partition be unavailable/empty while the data is being moved to the correct FG? If so, switch out the partition to an empty table, issue the necessary create index... with (drop_existing = on...) on [FG_2021] commands to physically move the data, alter the partition function to merge out the "bad" partition, alter the partition function again to re-add the partition boundary (this time with the right FG), and then switch the partition (from step 1) back into the main table. The errant partition doesn't look that big, so this should be quick.


Update

Here's a quick repro in a dummy database:

/*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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM