הגדרת מסד נתונים של Cloud SQL ל-SQL Server ל-CDC

כדי להעביר בסטרימינג עדכונים של סימון נתונים שהשתנו (CDC) ליעדים נתמכים, כמו BigQuery או Cloud Storage, אתם יכולים לחבר מסד נתונים של Cloud SQL ל-SQL Server אל Datastream. מפעילים את CDC במסד הנתונים ובטבלאות, מפעילים את בידוד snapshot ומגדירים משתמש Datastream. אם אתם משתמשים בשיטת CDC של יומני טרנזקציות, אתם צריכים גם להגדיר את שמירת היומנים ולהפעיל שחזור מערכת מנקודה מסוימת בזמן (PITR).

כדי להגדיר את מופע המקור:

  1. מתחברים למכונה של Cloud SQL. אפשר לעשות את זה באמצעות הפקודה gcloud sql connect בהנחיה של Cloud Shell.

  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. הפעלת בידוד snapshot.

    כשמבצעים מילוי חוזר של נתונים ממסד נתונים של SQL Server, חשוב לוודא שמתקבלים צילומים עקביים. אם לא תפעילו את ההגדרות שמתוארות בקטע הזה, שינויים שיתבצעו במסד הנתונים במהלך תהליך המילוי החוזר עלולים להוביל לתוצאות כפולות או שגויות. חובה להחיל הגדרות של בידוד snapshot אם הזרם כולל טבלאות ללא מפתחות ראשיים.

    כשמפעילים בידוד snapshot, נוצרת תצוגה זמנית של מסד הנתונים בתחילת תהליך המילוי של החוסרים בנתונים. כך מוודאים שהנתונים שמועתקים יישארו עקביים, גם אם משתמשים אחרים מבצעים שינויים בטבלאות הפעילות בו-זמנית. הפעלת בידוד ה-snapshot עשויה להשפיע מעט על הביצועים, אבל היא חיונית לחילוץ נתונים אמין.

    כדי להפעיל בידוד snapshot:

    1. מתחברים למסד הנתונים באמצעות לקוח של SQL Server.
    2. מריצים את הפקודה הבאה:
    ALTER DATABASE DATABASE_NAME SET ALLOW_SNAPSHOT_ISOLATION ON;
    

    מחליפים את DATABASE_NAME בשם של מסד הנתונים.

  5. יוצרים משתמש ב-Datastream:

    1. נכנסים לדף Cloud SQL Instances במסוף Google Cloud .

      כניסה לדף Cloud SQL Instances

    2. יוצרים משתמש ומקצים לו את התפקידים db_owner ו-db_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 מגדיר את זמן השמירה לשעה אחת
      • הערך 24 * 60 מגדיר את משך השמירה ליום אחד
      • הערך של 3 * 24 * 60 מגדיר את זמן השמירה ל-3 ימים
  3. מפעילים שחזור לנקודת זמן (PITR).

המאמרים הבאים