Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

máy chủ sql tự động phân vùng bảng hàng ngày

Bảo trì phân vùng cửa sổ trượt thường được thực hiện bằng cách sử dụng tập lệnh đã lên lịch hoặc thủ tục được lưu trữ (công việc SQL Server Agent hoặc hệ thống lập lịch khác). Bảo trì nên được lập kế hoạch để tránh việc di chuyển dữ liệu tốn kém trong SPLITMERGE bởi vì điều đó yêu cầu khoảng 4 lần ghi nhật ký như các hoạt động DML thông thường. Để làm được điều này, hãy đảm bảo rằng phân vùng bao gồm giá trị ranh giới trống trước MERGE và không có hàng nào lớn hơn ranh giới đã chỉ định khi SPLIT . Tôi khuyên bạn nên tạo thêm một vài phân vùng trong tương lai làm bộ đệm để tránh di chuyển dữ liệu trong trường hợp việc bảo trì không được thực hiện như kế hoạch.

Dưới đây là một ví dụ về kịch bản bảo trì cửa sổ trượt hàng ngày. Điều này sử dụng một bảng phân vùng được phân vùng tương tự để thanh lọc vì bạn đang sử dụng SQL Server 2005 và TRUNCATE cấp phân vùng đã được giới thiệu trong SQL Server 2016. Lưu ý rằng SQL Server 2005 không được hỗ trợ.

Tôi thấy từ nhận xét của bạn rằng bạn tin rằng một nhóm tệp / tệp riêng biệt cho mỗi phân vùng có thể hữu ích để loại bỏ các phân vùng nhưng không phải vậy. Ví dụ này sử dụng một nhóm tệp duy nhất cho tất cả các phân vùng.

--example setup
CREATE PARTITION FUNCTION PF_Date (datetime) AS
    RANGE RIGHT FOR VALUES();
CREATE PARTITION SCHEME PS_LogTable AS
    PARTITION PF_Date ALL TO ([PRIMARY]);
DECLARE @PartitionBoundaryDate datetime = DATEADD(day, -31, DATEADD(day, DATEDIFF(day, '', GETDATE()), ''));

WHILE @PartitionBoundaryDate < DATEADD(day, 1, GETDATE())
BEGIN
    ALTER PARTITION SCHEME PS_LogTable NEXT USED [PRIMARY];
    ALTER PARTITION FUNCTION PF_Date() SPLIT RANGE(@PartitionBoundaryDate);
    SET @PartitionBoundaryDate = DATEADD(day, 1, @PartitionBoundaryDate)
END;
CREATE TABLE dbo.LogTable(DateColumn datetime INDEX cdx CLUSTERED) ON PS_LogTable(DateColumn);
CREATE TABLE dbo.LogTable_Staging(DateColumn datetime INDEX cdx CLUSTERED) ON PS_LogTable(DateColumn);
GO

--example partition maintenance scheduled nightly after midnight
BEGIN TRY
    SET NOCOUNT ON;
    SET XACT_ABORT ON;
    DECLARE @RetentionDays int = 31;
    DECLARE @FutureDays int = 7;
    DECLARE @OldestRetainedDate datetime = DATEADD(day, [email protected], DATEADD(day, DATEDIFF(day, '', GETDATE()), ''));
    DECLARE @LatestRetainedDate datetime = DATEADD(day, DATEDIFF(day, '', GETDATE()), '');
    DECLARE @LatestFutureBoundaryDate datetime = DATEADD(day, @FutureDays, @LatestRetainedDate);
    DECLARE @PartitionBoundaryDate datetime;
    DECLARE @Message nvarchar(2048);

    --make sure staging table is empty
    TRUNCATE TABLE dbo.LogTable_Staging;

    BEGIN TRAN;
    --aquire exclusive table lock to avoid deadlocking during maintenance
    SELECT TOP(0) @PartitionBoundaryDate = DateColumn FROM dbo.LogTable WITH(TABLOCKX);

    --purge partition 1 in case data older than the first boundary was inserted
    SET @Message = 'Purging partition 1';
    PRINT @Message;
    ALTER TABLE dbo.LogTable SWITCH
        PARTITION 1 TO
        dbo.LogTable_Staging PARTITION 1;
    TRUNCATE TABLE dbo.LogTable_Staging;

    --purge and remove expired partitions
    DECLARE @PartitionBoundaries TABLE(PartitionBoundaryDate datetime NOT NULL PRIMARY KEY);
    INSERT INTO @PartitionBoundaries(PartitionBoundaryDate)
        SELECT CAST(prv.value AS datetime)
        FROM sys.partition_functions AS pf
        JOIN sys.partition_range_values AS prv ON prv.function_id = pf.function_id
        WHERE
            pf.name = N'PF_Date'
            AND CAST(prv.value AS datetime) < @OldestRetainedDate;
    DECLARE ExpiredPartitionBoundaries CURSOR LOCAL FAST_FORWARD FOR
        SELECT PartitionBoundaryDate
        FROM @PartitionBoundaries;

    OPEN ExpiredPartitionBoundaries;
    WHILE 1 = 1
    BEGIN
        FETCH NEXT FROM ExpiredPartitionBoundaries INTO @PartitionBoundaryDate;
        IF @@FETCH_STATUS = -1 BREAK;
        SET @Message = 'Purging data for ' + CONVERT(char(10), @PartitionBoundaryDate, 120);
        PRINT @Message;
        ALTER TABLE dbo.LogTable SWITCH
            PARTITION $PARTITION.PF_Date(@PartitionBoundaryDate) TO
            dbo.LogTable_Staging PARTITION $PARTITION.PF_Date(@PartitionBoundaryDate);
        TRUNCATE TABLE dbo.LogTable_Staging;
        ALTER PARTITION FUNCTION PF_Date() MERGE RANGE(@PartitionBoundaryDate);
    END;
    CLOSE ExpiredPartitionBoundaries;
    DEALLOCATE ExpiredPartitionBoundaries;

    --create partitions for future days
    SET @PartitionBoundaryDate = DATEADD(day, 1, @LatestRetainedDate);
    WHILE @PartitionBoundaryDate < = @LatestFutureBoundaryDate
    BEGIN
        IF NOT EXISTS(SELECT 1
            FROM sys.partition_functions AS pf
            JOIN sys.partition_range_values AS prv ON prv.function_id = pf.function_id
            WHERE
                pf.name = N'PF_Date'
                AND CAST(prv.value AS datetime) = @PartitionBoundaryDate
        )
        BEGIN
            SET @Message = 'Creating partition for ' + CONVERT(char(10), @PartitionBoundaryDate, 120);
            PRINT @Message;
            ALTER PARTITION SCHEME PS_LogTable NEXT USED [PRIMARY];
            ALTER PARTITION FUNCTION PF_Date() SPLIT RANGE(@PartitionBoundaryDate);
        END;
        SET @PartitionBoundaryDate = DATEADD(day, 1, @PartitionBoundaryDate);
    END;

    COMMIT;
END TRY
BEGIN CATCH

    IF @@TRANCOUNT > 0 ROLLBACK;

    --better to use THROW in SQL 2012 and later
    DECLARE
         @ErrorNumber int
        ,@ErrorMessage nvarchar(2048)
        ,@ErrorSeverity int
        ,@ErrorState int
        ,@ErrorLine int;

    SELECT
        @ErrorNumber =ERROR_NUMBER()
        ,@ErrorMessage =ERROR_MESSAGE()
        ,@ErrorSeverity = ERROR_SEVERITY()
        ,@ErrorState =ERROR_STATE()
        ,@ErrorLine =ERROR_LINE();

    RAISERROR('Error %d caught at line %d: %s'
        ,@ErrorSeverity
        ,@ErrorState
        ,@ErrorNumber
        ,@ErrorLine
        ,@ErrorMessage);

END CATCH;
GO



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server COALESCE () Giải thích

  2. Làm cách nào để chuyển đổi hh:mm:ss thành hh:mm trong SQL Server?

  3. Cách tốt nhất để nhận Hướng dẫn PK của hàng đã chèn

  4. Số thập phân được truyền không chính xác từ C # sang SQL Server với TableAdapters

  5. FOR XML PATH và nối chuỗi