設定 SQL Server 適用的 Cloud SQL 資料庫

下列步驟說明如何設定 SQL Server 適用的 Cloud SQL 資料庫,以便與 Datastream 搭配使用:

  1. 連線至 Cloud SQL 執行個體。您可以使用 Cloud Shell 提示中的 gcloud sql connect 指令執行這項操作。

  2. 執行下列指令,為資料庫啟用 CDC 功能:

    EXEC msdb.dbo.gcloudsql_cdc_enable_db 'DATABASE_NAME'
    

    DATABASE_NAME 替換為來源資料庫的名稱。

  3. 針對需要擷取變更的資料表啟用 CDC:

    USE [DATABASE_NAME]
    EXEC sys.sp_cdc_enable_table
    @source_schema = N'SCHEMA_NAME',
    @source_name = N'TABLE_NAME',
    @role_name = NULL
    GO
    
  4. 啟用快照隔離功能。

    從 SQL Server 資料庫回填資料時,請務必確保快照一致。如果您未套用本節所述的設定,在回填程序期間對資料庫所做的變更,可能會導致重複或不正確的結果,尤其是沒有主鍵的資料表。

    啟用快照隔離功能後,系統會在回填程序開始時建立資料庫的暫時檢視畫面。這樣一來,即使其他使用者同時對即時表格進行變更,資料仍可保持一致。啟用快照隔離功能可能會對效能造成輕微影響,但對於可靠的資料擷取作業而言,這項功能至關重要。

    如要啟用快照隔離功能,請按照下列步驟操作:

    1. 透過 SQL Server 用戶端連結至資料庫。
    2. 執行下列指令:
    ALTER DATABASE DATABASE_NAME SET ALLOW_SNAPSHOT_ISOLATION ON;
    

    請將 DATABASE_NAME 替換為資料庫名稱。

  5. 建立 Datastream 使用者:

    1. 前往 Google Cloud 控制台的「Cloud SQL 執行個體」頁面。

      前往 Cloud SQL 執行個體

    2. 建立使用者,並將 db_ownerdb_denydatawriter 角色指派給使用者:

    CREATE USER USER_NAME FOR LOGIN YOUR_LOGIN;
    
    EXEC sp_addrolemember 'db_owner', 'USER_NAME';
    EXEC sp_addrolemember 'db_denydatawriter', 'USER_NAME';
    

交易記錄 CDC 方法的額外步驟

只有在設定來源 SQL Server 資料庫,以便搭配使用交易記錄 CDC 方法時,才需要執行本節所述的步驟。

  1. 設定來源可用的變更保留期限。

    USE [DATABASE_NAME]
    EXEC sys.sp_cdc_change_job @job_type = 'capture' , @pollinginterval = 86399
    EXEC sp_cdc_stop_job 'capture'
    EXEC sp_cdc_start_job 'capture'
    

    @pollinginterval 參數以秒為單位,建議值設為 86399。也就是說,交易記錄會保留變更資料 86,399 秒 (一天)。執行 sp_cdc_start_job 'capture 程序會啟動設定。

  2. 設定記錄檔截斷保護機制。

    為確保 CDC 讀取器有足夠的時間讀取記錄檔,同時允許記錄檔截斷以免用盡儲存空間,您可以設定記錄檔截斷保護措施:

    1. 透過 SQL Server 用戶端連線至資料庫。
    2. 在資料庫中建立虛擬資料表:

      USE [DATABASE_NAME];
      CREATE TABLE dbo.gcp_datastream_truncation_safeguard (
        [id] INT IDENTITY(1,1) PRIMARY KEY,
        CreatedDate DATETIME DEFAULT GETDATE(),
        [char_column] CHAR(8)
        );
      
    3. 建立會在您指定的期間內執行有效交易的預存程序,以防記錄檔遭到截斷:

      CREATE PROCEDURE [dbo].[DatastreamLogTruncationSafeguard] @transaction_logs_retention_time INT
      AS
      BEGIN
        -- Start a new transaction
        BEGIN TRANSACTION;
        INSERT INTO dbo.gcp_datastream_truncation_safeguard (char_column) VALUES ('a')
      
      DECLARE @formatted_time VARCHAR(5)
      SET @formatted_time = CONVERT(VARCHAR(5), DATEADD(MINUTE, @transaction_logs_retention_time, 0), 108);
        -- Wait for X minutes before ending the transaction
        WAITFOR DELAY @formatted_time;
        -- Commit the transaction
        COMMIT TRANSACTION;
      END;
      
    4. 建立另一個預存程序。這次您要建立的工作會根據指定的週期,執行先前步驟中建立的預存程序:

      CREATE PROCEDURE [dbo].[SetUpDatastreamJob] @transaction_logs_retention_time INT
      AS
      BEGIN
        DECLARE @database_name VARCHAR(MAX)
        SET @database_name =  (SELECT DB_NAME());;
      
        DECLARE @command_str VARCHAR(MAX);
        SET @command_str = CONCAT('Use ', @database_name,'; exec dbo.DatastreamLogTruncationSafeguard @transaction_logs_retention_time = ' + CAST(@transaction_logs_retention_time AS VARCHAR(10)));
      
        DECLARE @job_name VARCHAR(MAX);
      SET @job_name =
        CONCAT(@database_name, '_', 'DatastreamLogTruncationSafeguardJob1')
      
          -- Add 3 schedules to the job to run again after specified time.
          IF
            NOT EXISTS(
              SELECT *
              FROM msdb.dbo.sysjobs
              WHERE name = @job_name
            )
              BEGIN
                EXEC
                  msdb.dbo.sp_add_job
                    @job_name
        = @job_name,
        @enabled = 1,
        @description = N'Execute the procedure to run an active transaction for x minutes.';
      
      EXEC msdb.dbo.sp_add_jobstep @job_name = @job_name,
      @step_name = N'Execute_DatastreamLogTruncationSafeguard',
      @subsystem = N'TSQL',
      @command = @command_str;
      
        -- Add a schedule that runs the stored procedure every given minutes starting now.
        DECLARE @schedule_name_1 VARCHAR(MAX);
        SET @schedule_name_1 = CONCAT(@database_name, '_', 'DatastreamEveryGivenMinutesFromNow')
      
        DECLARE @start_time_1 time;
        SET @start_time_1 = DATEADD(SECOND, 1, GETDATE());
        DECLARE @formatted_start_time_1 INT;
        SET @formatted_start_time_1 = CONVERT(INT, REPLACE(CONVERT(VARCHAR(8), @start_time_1, 114), ':' ,''));
      
        EXEC msdb.dbo.sp_add_schedule
        @schedule_name = @schedule_name_1,
        @freq_type = 4,  -- daily start
        @freq_subday_type = 4,  -- every X minutes daily
        @freq_interval = 1,
        @freq_subday_interval = @transaction_logs_retention_time,
        @active_start_time = @formatted_start_time_1;
      
        EXEC msdb.dbo.sp_attach_schedule
        @job_name = @job_name,
        @schedule_name = @schedule_name_1 ;
      
        -- Add a schedule that runs the stored procedure after every given minutes starting after some delay.
        DECLARE @schedule_name_2 VARCHAR(MAX);
        Set @schedule_name_2 = CONCAT(@database_name, '_', 'DatastreamEveryGivenMinutesAfterDelay');
      
        DECLARE @start_time_2 time;
        SET @start_time_2 = DATEADD(MINUTE, @transaction_logs_retention_time / 2, GETDATE());
      
        DECLARE @formatted_start_time_2 INT;
        SET @formatted_start_time_2 = CONVERT(INT, REPLACE(CONVERT(VARCHAR(8), @start_time_2, 114), ':' ,''));
      
        EXEC msdb.dbo.sp_add_schedule
        @schedule_name = @schedule_name_2,
        @freq_type = 4,  -- daily start
        @freq_subday_type = 4,  -- every x minutes daily
        @freq_interval = 1,
        @freq_subday_interval = @transaction_logs_retention_time,
        @active_start_time = @formatted_start_time_2;
      
        EXEC msdb.dbo.sp_attach_schedule
        @job_name = @job_name,
        @schedule_name = @schedule_name_2 ;
      
        -- Add a schedule that runs the stored procedure on the SQL Server Agent startup.
        DECLARE @schedule_name_agent_startup VARCHAR(MAX);
        Set @schedule_name_agent_startup = CONCAT(@database_name, '_', 'DatastreamSqlServerAgentStartupSchedule')
      
        EXEC msdb.dbo.sp_add_schedule
        @schedule_name = @schedule_name_agent_startup,
        @freq_type = 64,  -- start on SQL Server Agent startup
        @active_start_time = @formatted_start_time_1;
      
        EXEC msdb.dbo.sp_attach_schedule
        @job_name = @job_name,
        @schedule_name = @schedule_name_agent_startup ;
      
        EXEC msdb.dbo.sp_add_jobserver
        @job_name = @job_name,
        @server_name = @@servername ;
        END
      END;
      
    5. 執行會建立 Datastream 工作的預存程序。

      DECLARE @transaction_logs_retention_time INT = (INT)
      EXEC [dbo].[SetUpDatastreamJob] @transaction_logs_retention_time
      

      INT 替換為您要保留記錄的數分鐘數。例如:

      • 60 的值會將保留時間設為 1 小時
      • 24 * 60 的值會將保留時間設為 1 天
      • 3 * 24 * 60 的值會將保留時間設為 3 天
  3. 啟用時間點復原 (PITR)

後續步驟