關於SQL Server 資料庫歸檔的一些思考和改進

来源:https://www.cnblogs.com/xuliuzai/archive/2018/12/24/10168858.html
-Advertisement-
Play Games

一.需求背景 SQL Server開源的歸檔工具不多,DBA一般都是通過計劃任務來觸發執行,執行的腳本多是SP或者是SSIS包。SSIS包的性能稍好一些,但是維護更新成本高些。所以更常見的是通過SP腳本來實現歸檔操作。 當資料庫規模較小時,可以方便的直接在資料庫上進行腳本的編寫部署。但是隨著資料庫越 ...


一.需求背景

SQL Server開源的歸檔工具不多,DBA一般都是通過計劃任務來觸發執行,執行的腳本多是SP或者是SSIS包。SSIS包的性能稍好一些,但是維護更新成本高些。所以更常見的是通過SP腳本來實現歸檔操作。

當資料庫規模較小時,可以方便的直接在資料庫上進行腳本的編寫部署。但是隨著資料庫越來越多,管理維護成本就會越來越大,越來越不方便。現在我們實行的方式是通過中央管理器來管理眾多的資料庫備份(這是在擁有專門的備份程式前的一個過渡方案)。我們將歸檔基礎配置信息、歸檔運行歷史記錄、異常報錯等數據統一維護在中央資料庫上。如此,可以方便統一的查看、管理和維護。

 二.主要架構

 

三.主要關聯表

2.1 歸檔基礎配置表

表欄位含義,請耐心查看欄位說明。

CREATE TABLE [dbo].[DBData_ArchiveConfig](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [IP] [varchar](50) NULL,
    [DBName] [varchar](50) NULL,
    [DataTable] [varchar](50) NULL,
    [TargetIP] [varchar](50) NULL,
    [TargetDB] [varchar](50) NULL,
    [TargetTable] [varchar](50) NULL,
    [Prerequisite] [varchar](300) NULL,
    [DelMaxQTY] [int] NULL,
    [IsCheckOrderID] [int] NULL,
    [SP_Name] [int] NULL,
    [StartTime] [datetime] NULL,
    [EndTime] [datetime] NULL
) ON [PRIMARY]

GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Server IP(數據位於中央管理器中,所以歸檔資料庫庫所在的IP要維護,可維修虛擬的IP)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'IP'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'要歸檔的資料庫' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'DBName'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'要歸檔的表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'DataTable'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'備份指向的IP' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'TargetIP'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'備份指向的資料庫' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'TargetDB'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'備份指向的表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'TargetTable'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'歸檔條件' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'Prerequisite'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'迴圈中一次歸檔刪除的數據量' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'DelMaxQTY'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'此為 備用欄位,考慮可能有些表,會和其他表關聯' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'IsCheckOrderID'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'為提高併發度,一個DB對應的歸檔SP可能是多個,通過此列,進行分組。' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'SP_Name'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'此為拓展欄位,原計劃根據 開始時間、結束時間,每天可以多個時間段內執行' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'StartTime'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'此為拓展欄位,原計劃根據 開始時間、結束時間,每天可以多個時間段內執行' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'DBData_ArchiveConfig', @level2type=N'COLUMN',@level2name=N'EndTime'
GO

2.2 歸檔運行的Log表

CREATE TABLE [dbo].[DBData_ArchiveLog](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [IP] [varchar](30) NULL,
    [DBName] [varchar](30) NULL,
    [DataTable] [varchar](80) NULL,
    [BakQTY] [varchar](30) NULL,
    [BakStartDate] [datetime] NULL,
    [BakEndDate] [datetime] NULL
) ON [PRIMARY]

GO

2.3 異常錯誤信息表

執行的過程中會外包一層 try...catch,將操作過程中的錯誤信息保存在表 DBData_ArchiveErrLog。表結構如下:

CREATE TABLE [dbo].[DBData_ArchiveErrLog](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [IP] [varchar](30) NULL,
    [DBName] [varchar](60) NULL,
    [DataTable] [varchar](80) NULL,
    [TargetIP] [varchar](30) NULL,
    [TargetDB] [varchar](60) NULL,
    [TargetTable] [varchar](80) NULL,
    [Errormsg] [nvarchar](max) NULL,
    [TransDateTime] [varchar](30) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

四. 存儲過程相應的主要代碼

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:        <Author,,Name>
-- Create date: <Create Date,,>
-- Description:    <Description,,>
-- =============================================
CREATE PROCEDURE [dbo].[SP_XXXXX_DataArchive]
AS
    SET NOCOUNT ON;

    DECLARE @sql1 VARCHAR(MAX) 
    DECLARE @sql VARCHAR(MAX) 
    DECLARE @sql2 VARCHAR(MAX)
    DECLARE @IP VARCHAR(MAX) 
    DECLARE @DBName VARCHAR(MAX) 
    DECLARE @DataTable VARCHAR(MAX) 
    DECLARE @TargetIP VARCHAR(MAX) 
    DECLARE @TargetDB VARCHAR(MAX) 
    DECLARE @TargetTable VARCHAR(MAX) 
    DECLARE @Prerequisite VARCHAR(MAX) 
    DECLARE @DelMaxQTY INT
    DECLARE @StartTime DATETIME
    DECLARE @EndTime DATETIME
    DECLARE @qty INT 
    DECLARE @ISCHECKORDERID INT 
----Carson   2018-12-17 備份數據的時間往往比刪除的時間長3倍,因此,如果考慮將備份的操作轉移到輔助庫,將會對線上的操作影響降至更低
    DECLARE @BakDateIP VARCHAR(30)  
    set @BakDateIP='[XXX.XXX.XXX.XXX].'-------後面一定要有一個點
--------------------------------------------------歸檔操作---------------------------------
    DECLARE DBName CURSOR
    FOR
        SELECT  IP ,
                DBName ,
                DataTable ,
                TargetIP ,
                TargetDB ,
                TargetTable ,
                Prerequisite ,
                DelMaxQTY ,
                ISCHECKORDERID ,
                StartTime ,
                EndTime
        FROM    [中央管理器].[中央管理資料庫].[dbo].[DBData_ArchiveConfig]
        WHERE   DataTable <> ''
                AND TargetTable <> ''
                AND DBNAME = 'XXXXXXXXX' and SP_Name='?????'
    OPEN DBName    
    FETCH NEXT FROM DBName INTO @IP, @DBName, @DataTable, @TargetIP, @TargetDB,
        @TargetTable, @Prerequisite, @DelMaxQTY, @ISCHECKORDERID,
        @StartTime, @EndTime   
    WHILE ( @@fetch_status = 0 )
    BEGIN  
        DECLARE @datetime DATETIME
        IF @ISCHECKORDERID <> '1'  AND @DataTable <> ''
        BEGIN
            SET @datetime = CONVERT(VARCHAR(10), GETDATE() - 30, 120)                
            SET @sql = 'Insert into [' + @TargetIP + '].'
                + @TargetDB + '.' + 'dbo.' + @TargetTable + '
                 select * FROM ' + @BakDateIP + @DBName + '.' + 'dbo.' + @DataTable + ' 
                 with(nolock) where ' + @Prerequisite + ''
                
            SET @sql1 = 'DECLARE @icount INTEGER  
                        SELECT @icount = COUNT(1)  
                        FROM ' + @BakDateIP + @DBName + '.' + 'dbo.' + @DataTable + '
                        where ' + @Prerequisite + '  
                        insert into [中央管理器].[中央管理資料庫].dbo.DBData_ArchiveLog (IP, DBName, DataTable, BakQTY, BakStartDate, BakEndDate)
                        select ''' + @IP + ''',''' + @DBName + ''',''' + @DataTable
                                    + ''',@icount,getdate(),null

                        WHILE @icount > 0   
                        BEGIN  
                    
                            DELETE TOP (' + CAST(@DelMaxQTY AS VARCHAR(10)) + ')  
                            FROM ' + @DBName + '.' + 'dbo.' + @DataTable + ' 
                            where ' + @Prerequisite + '
      
                            SET @icount = @icount -('
                                    + CAST(@DelMaxQTY AS VARCHAR(10)) + ')  
                            WAITFOR DELAY ''00:00:01''  
                        END  '                    
          BEGIN TRY
            EXEC (@sql)
            EXEC (@sql1) 
          END TRY
          BEGIN CATCH
             DECLARE @Errmsg AS nvarchar(MAX)
             SELECT @Errmsg=ERROR_MESSAGE()
               ------0001 BEGIN SAVE ERR LOG IN TABLE
               INSERT INTO [中央管理器].[中央管理資料庫].[dbo].DBData_ArchiveErrLog  ([IP] ,[DBName],[DataTable],[TargetIP],[TargetDB],[TargetTable],[Errormsg] ,[TransDateTime])
               VALUES(@IP, @DBName, @DataTable, @TargetIP, @TargetDB, @TargetTable,@Errmsg,convert(VARCHAR(25),GETDATE(), 120))       
               ------0001 END
                -------------0002 BEGIN SEND EMAIL MESSAGE----------------              
                    DECLARE @Subject AS nvarchar(200)
                    DECLARE @Body AS nvarchar(MAX)
                    DECLARE @SPName AS nvarchar(MAX)
            
                    SET @Subject = '資料庫歸檔異常 -重要!;ServerIP:' + @IP + ' DB:' + @DBName
                                SET @SPName = ''
                                SET @Body = '<html><body>Dear All,<br> <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerIP:' +@IP + ' ; DataBase:' + @DBName+ '上的Table歸檔異常,請及時檢查!!!
                               <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You can get detail information from the table. <br><br><table border=1 bgcolor=#aaff11>' 
                                SET @Body = @Body+ '<tr bgcolor=#ff3311><td>ServerIP</td><td>DBName</td><td>TableName</td><td>TargetIP</td><td>TargetDB</td><td>Errmsg</td><td>TransDateTime</td></tr>'
                                SELECT  @SPName = @SPName + '<tr bgcolor=#ffaa11><td>'+ CAST(@IP AS NVARCHAR(50))+ '</td><td>' + CAST(@DBName AS NVARCHAR(50)) + '</td><td>'+CAST(@DataTable AS NVARCHAR(50))+ '</td>
                                <td>'+ CAST(@TargetIP AS NVARCHAR(20))+ '</td><td>'+ CAST(@TargetDB AS NVARCHAR(50))+ '</td><td>'+ SUBSTRING(@Errmsg,1, 100)+ '</td><td>'+ CONVERT(varchar(100), GETDATE(), 21)+ '</td></tr>'
                                SET @Body = @Body + @SPName + '</table>'

                    SET @BODY=REPLACE(@BODY,'''','')

                    IF REPLACE(@BODY,' ','')<>''
                        BEGIN
                            DECLARE @AllEmailToAddress varchar(3000)=''
                            DECLARE @AllEmailCcAddress varchar(3000)=''
                            DECLARE @Allprofile_name varchar(100)=''
                            SELECT @AllEmailToAddress=''
                            SELECT @AllEmailCcAddress=''
                            SELECT TOP 1 @Allprofile_name=NAME FROM msdb.dbo.sysmail_profile 
                            ORDER BY profile_id

                            EXEC msdb..sp_send_dbmail @profile_name = @Allprofile_name   -- profile 名稱 
                             ,@recipients   =  @AllEmailToAddress      

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • cat----文本輸出命令 格式:cat [選項] [文件] 主要三大功能:1.一次性顯示整個文件# cat 文件 cat /路徑/文件名2.從鍵盤創建一個文件# cat > 文件3.將幾個文件合併成一個文件# cat 文件1 文件2 >文件3 主要參數:-n 從1開始對所有輸出行進行行數編號-b ... ...
  • 原創作品,轉載請在文章明顯位置註明出處:https://www.cnblogs.com/sunshine5683/p/10170009.html 使用命令關閉和重啟系統: 一、條件:只有root用戶才可以執行關機和重啟操作 二、常用關機重啟的命令: 1、立即關機: shutdown -h now 2 ...
  • 1、node.js 守護進程組件 forever 安裝 npm install forever -g 安裝完成後截圖: 2、安裝完成後在控制台輸入 forever 出現 -bash: forever: command not found 3、添加環境變數 執行命令 vim /etc/profile ...
  • 我是 Centos 最小化安裝的,安裝網後 Centos 竟然無法上網。。。有點奇葩, 應該是網卡沒有激活的問題了,下麵是解決的過程 ...
  • 一 前期準備 節點 IP 備註 falcon 私網:172.24.10.95 臨時公網:120.132.23.107 Open-Falcon服務端 node01 172.24.10.216 被監控端 節點 IP 備註 falcon 私網:172.24.10.95 臨時公網:120.132.23.10 ...
  • 同步更新於 "wendster大佬的個人博客" 搬運自 "我的洛谷博客" 可能會不定期更新! 因為前幾天給我的小炸雞加了一根記憶體條;而且先前裝的Xubuntu是32位的,使用極其不方便;再加上wendster大佬的慫恿,我決定給自己的電腦換一個Archlinux系統。由於安裝這個系統的麻煩程度~~世 ...
  • 1、簡介 如果你的伺服器的總是報告記憶體不足,並且時常因為記憶體不足而引發服務被強制kill的話,在不增加物理記憶體的情況下,啟用swap交換區作為虛擬記憶體是一個不錯的選擇。 為了測試一些功能我在阿裡雲購買了1核1G的ECS伺服器幾台(最便宜的了,再貴捨不得啊),一臺伺服器就安裝了LANMP,redis, ...
  • # **1.1 資料庫系統概述:** ## **1.1.1 資料庫的組成**![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20181224232336368.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naG ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...