Sự kiện mở rộng so với Kiểm toán SQL - hàm ý hiệu suất


8

Tôi muốn thiết lập một loại hệ thống kiểm toán trên cơ sở dữ liệu của mình để theo dõi các UPDATE/INSERTbáo cáo trên một bảng cụ thể có hoạt động rất cao. Tôi có hai tùy chọn trước mặt: sử dụng hệ thống Kiểm toán tích hợp SQL Server hoặc đi với Sự kiện mở rộng.

Vì SQL Server Audit sử dụng nội bộ Sự kiện mở rộng, tôi cho rằng sẽ có một số loại chi phí khi tôi sử dụng Kiểm toán thay vì trực tiếp Sự kiện mở rộng.

Có cách nào tôi có thể thực hiện một số thử nghiệm để phân tích hệ thống nào đang tác động đến máy chủ nhiều hơn không? Nếu tôi có thể biết điều gì thực sự xảy ra khi bất kỳ phiên XE nào được tạo ra, nó sẽ giúp tôi phân tích tác động trên máy chủ.

Chúng tôi đã xem xét kích hoạt và bỏ qua tùy chọn đó vì chi phí hoạt động. Nhưng đó chỉ là quyết định dựa trên thông tin từ Internet.



Không phải tất cả các sự kiện được ghi lại thông qua Kiểm toán SQL đều có thể truy cập được thông qua XEvents. SQL Audit sử dụng cùng một công cụ đằng sau XEvents, nhưng chúng là các tính năng riêng biệt.

Yeah.came để biết về điều đó. Nhưng khi chúng tôi thực hiện một số loại thử nghiệm tải (xem bên dưới), chúng tôi đã quan sát thấy XE có nhiều chi phí hoạt động hơn Audit. Nếu kiểm toán sử dụng XE trong nền, bất kỳ ý tưởng tại sao nó gây ra nhiều chi phí hơn?
karun_r

Câu trả lời:


3

Tôi đã tạo một thử nghiệm đơn giản để dùng thử SQL Server Audit dựa trên các trình kích hoạt và các tùy chọn tiềm năng khác. Trong các thử nghiệm của tôi về việc chèn 1 triệu hàng vào bảng tôi đã nhận được 52, 67 và 159 giây cho đường cơ sở, Kiểm toán SQL và trình kích hoạt của tôi tương ứng:

Kết quả kiểm tra

Bây giờ điều này không đặc biệt khoa học nhưng có khả năng cung cấp cho bạn một cách so sánh các phương pháp. Hãy xem qua kịch bản, xem nó có thể được sử dụng cho bạn không:

USE master
GO

SET NOCOUNT ON
GO

IF EXISTS ( SELECT * FROM sys.databases WHERE name = 'testAuditDb' )
ALTER DATABASE testAuditDb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
IF EXISTS ( SELECT * FROM sys.databases WHERE name = 'testAuditDb' )
DROP DATABASE testAuditDb
GO


CREATE DATABASE testAuditDb
ON PRIMARY
( NAME = N'testAuditDb', FILENAME = N's:\temp\testAuditDb.mdf', SIZE = 1GB, MAXSIZE = UNLIMITED, FILEGROWTH = 128MB )
LOG ON 
( NAME = N'testAuditDb_log', FILENAME = N's:\temp\testAuditDb_log.ldf', SIZE = 100MB, MAXSIZE = 2048GB, FILEGROWTH = 128MB )
GO

ALTER DATABASE testAuditDb SET RECOVERY SIMPLE
GO



------------------------------------------------------------------------------------------------
-- Setup START
------------------------------------------------------------------------------------------------

USE testAuditDb
GO

CREATE SCHEMA auditSchema

-- Create a table
CREATE TABLE auditSchema.auditTable ( 
    rowId INT IDENTITY PRIMARY KEY, 
    someData UNIQUEIDENTIFIER DEFAULT NEWID(), 
    dateAdded DATETIME DEFAULT GETDATE(), 
    addedBy VARCHAR(30) DEFAULT SUSER_NAME(), 
    ts ROWVERSION 
)
GO


-- Setup END
------------------------------------------------------------------------------------------------



------------------------------------------------------------------------------------------------
-- Test 01 - Baseline START
-- Normal timing; no triggers or audits
------------------------------------------------------------------------------------------------


-- Add a million rows to the table and time it.
DECLARE @i INT = 0, @startTime DATETIME2, @endTime DATETIME2

SET @startTime = SYSDATETIME()

WHILE @i < 1000000
BEGIN

    INSERT INTO auditSchema.auditTable DEFAULT VALUES

    SET @i += 1
END

SET @endTime = SYSDATETIME()

SELECT DATEDIFF( second, @startTime, @endTime ) AS baseline
GO


-- Cleanup
TRUNCATE TABLE auditSchema.auditTable 
GO

-- Test 01 - Baseline END
------------------------------------------------------------------------------------------------





------------------------------------------------------------------------------------------------
-- Test 02 - SQL Audit START
-- Try SQL Audit
------------------------------------------------------------------------------------------------

-- Create server audit in master database
USE master
GO

------------------------------------------------------------------------------------------------------------------------
-- The server audit is created with a WHERE clause that limits the server audit to only the auditTable table.
------------------------------------------------------------------------------------------------------------------------
CREATE SERVER AUDIT auditTableAccess TO FILE ( FILEPATH = 'S:\SQLAudit\' ) WHERE object_name = 'auditTable';
GO
ALTER SERVER AUDIT auditTableAccess WITH ( STATE = ON );
GO

-- Create the database audit specification in the testAuditDb database 
USE testAuditDb;
GO

CREATE DATABASE AUDIT SPECIFICATION [dbAudit1]
FOR SERVER AUDIT auditTableAccess
ADD ( 
    SELECT, INSERT, UPDATE ON SCHEMA::[auditSchema]
    BY [public]
    ) WITH ( STATE = ON );
GO


-- Add a million rows to the table and time it.
DECLARE @i INT = 0, @startTime DATETIME2, @endTime DATETIME2

SET @startTime = SYSDATETIME()

WHILE @i < 1000000
BEGIN

    INSERT INTO auditSchema.auditTable DEFAULT VALUES

    SET @i += 1
END

SET @endTime = SYSDATETIME()

SELECT DATEDIFF( second, @startTime, @endTime ) AS sqlAudit
GO


-- Cleanup
TRUNCATE TABLE auditSchema.auditTable
GO
ALTER DATABASE AUDIT SPECIFICATION [dbAudit1] WITH ( STATE = Off );
DROP DATABASE AUDIT SPECIFICATION [dbAudit1]
GO

USE master
ALTER SERVER AUDIT auditTableAccess WITH ( STATE = OFF );

DROP SERVER AUDIT auditTableAccess
GO



/*
-- Inspect the audit output
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp

SELECT *
INTO #tmp
FROM fn_get_audit_file ( 'S:\SQLAudit\auditTableAccess_*.sqlaudit', DEFAULT, DEFAULT );
GO


SELECT statement, MIN(event_time), MAX(event_time), COUNT(*) AS records
FROM #tmp
GROUP BY statement
GO
*/

-- Test 02 - SQL Audit END
------------------------------------------------------------------------------------------------




------------------------------------------------------------------------------------------------
-- Test 03 - Triggers START
-- Trial INSERT/UPDATE trigger with log table
------------------------------------------------------------------------------------------------
USE testAuditDb
GO

CREATE TABLE dbo.auditLog
    (
    auditLogLog     INT IDENTITY PRIMARY KEY,
    schemaName      SYSNAME NOT NULL,
    tableName       SYSNAME NOT NULL,
    dateAdded       DATETIME NOT NULL DEFAULT GETDATE(),
    addedBy         SYSNAME NOT NULL DEFAULT SUSER_NAME(),
    auditXML        XML
    )
GO


-- Generic audit trigger
CREATE TRIGGER trg_dbo__triggerTest ON auditSchema.auditTable
FOR INSERT, UPDATE, DELETE

AS

BEGIN

    IF @@rowcount = 0 RETURN

    SET NOCOUNT ON

    DECLARE @action VARCHAR(10)

    IF EXISTS ( SELECT * FROM inserted )
    AND EXISTS ( SELECT * FROM deleted )
        SET @action = 'UPDATE'
    ELSE IF EXISTS ( SELECT * FROM inserted )
        SET @action = 'INSERT'
    ELSE IF EXISTS ( SELECT * FROM deleted )
        SET @action = 'DELETE'

    INSERT INTO dbo.auditLog ( schemaName, tableName, auditXML )
    SELECT OBJECT_SCHEMA_NAME( parent_id ) schemaName, OBJECT_NAME( parent_id ) tableName,
        (
        SELECT
            @action "@action",
            ( SELECT 'inserted' source, * FROM inserted FOR XML RAW, TYPE ),
            ( SELECT 'deleted' source, * FROM deleted FOR XML RAW, TYPE )
        FOR XML PATH('mergeOutput'), TYPE
        ) x
    FROM sys.triggers
    WHERE OBJECT_ID = @@procid
      AND ( EXISTS ( SELECT * FROM inserted )
         OR EXISTS ( SELECT * FROM deleted )
          )

END
GO


-- Add a million rows to the table and time it.
DECLARE @i INT = 0, @startTime DATETIME2, @endTime DATETIME2

SET @startTime = SYSDATETIME()

WHILE @i < 1000000
BEGIN

    INSERT INTO auditSchema.auditTable DEFAULT VALUES

    SET @i += 1
END

SET @endTime = SYSDATETIME()

SELECT DATEDIFF( second, @startTime, @endTime ) AS triggers
GO

-- Cleanup
TRUNCATE TABLE auditSchema.auditTable
DROP TABLE dbo.auditLog
DROP TRIGGER auditSchema.trg_dbo__triggerTest
GO

-- Test 03 - Triggers END
------------------------------------------------------------------------------------------------

Mặc dù tùy chọn kích hoạt không hoạt động tốt ở đây, mã kích hoạt của tôi có thể được đơn giản hóa tùy thuộc vào những gì bạn muốn nắm bắt và nó cho phép bạn truy cập vào các giá trị cũ và mới theo định dạng khá hữu dụng mà SQL Audit không sử dụng được. Tôi đã sử dụng kỹ thuật này cho một bảng cấu hình hoạt động thấp hơn và nó hoạt động khá tốt. Tùy thuộc vào những gì bạn muốn chụp, bạn cũng có thể xem xét Thay đổi dữ liệu .

Hãy cho tôi biết làm thế nào bạn có được với các thử nghiệm của bạn. Chúc may mắn.


3

Một lợi ích của Kiểm toán xuất hiện là nó sẽ tự động ghi lại ai bật và tắt, XE sẽ không làm điều đó ngay lập tức (mặc dù bạn có thể tìm thấy một sự kiện theo dõi dừng / khởi động XE). Bạn cũng có thể thấy rằng cả hai thu thập dữ liệu khác nhau, tùy thuộc vào chính xác những gì bạn muốn.

Về việc thực hiện một số thử nghiệm, bạn sẽ cần có một bản sao lưu cơ sở dữ liệu, ghi lại dấu vết của ứng dụng đang tải và sau đó khôi phục bản sao trong khi thực hiện phát lại / phát lại bằng kiểm toán / thay thế bằng XE và so sánh dữ liệu hiệu suất.

Dữ liệu hiệu suất nào? Tuỳ bạn. Đối với một số ý tưởng - Linchi Shea đã so sánh giữa Audit và Trace bằng cách tập trung vào Giao dịch / giây, trong khi Kehayias thực hiện so sánh giữa Trace và XE bằng cách tập trung vào các đợt / giây và thời gian chạy lại tổng thể.

Tôi khuyến khích bạn đọc cả hai và nhận xét của họ bởi vì bạn nên biết rằng bất kể bạn làm gì, nó sẽ được mở để giải thích. Thật khó để có được một quả táo để so sánh táo. Ngoài ra, theo dõi / phát lại có thể không mô phỏng tải đúng cách - ví dụ: khi ứng dụng của bạn đang thực hiện nhiều tải hàng loạt từ các tệp đĩa không còn tồn tại.

Nhưng điều quan trọng là bạn cố gắng ít nhất một điều, vì vậy bạn có thể biện minh cho các quyết định của mình, và cũng viết blog về nó cho phần còn lại của chúng tôi.


Khi bạn nói rằng kiểm toán sẽ tự động nắm bắt các sự kiện BẬT / TẮT kiểm toán, bạn có đang nói về các loại hành động AUSC trong quy trình kiểm toán không? Ngoài ra, để kiểm tra hiệu năng lý tưởng, tôi đoán tôi nên xem xét các tắc nghẽn hiện tại của ứng dụng và xem liệu kiểm toán hoặc XE có làm cho chúng tồi tệ hơn không.
karun_r
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.