Tôi có một số cơ sở dữ liệu trên một máy chủ sản xuất có hàng trăm gigabyte và có hàng ngàn giao dịch chạy qua chúng hàng ngày.
Hầu như tất cả các cơ sở dữ liệu này đều được nhân đôi bằng SQL Server Mirroring.
Mặc dù chúng tôi đã lên kế hoạch cẩn thận các kích thước tệp nhật ký vật lý để phù hợp với hoạt động của tệp nhật ký dự kiến; đôi khi có điều gì đó không ổn và nhật ký cần phát triển vượt quá mức tối đa dự đoán của chúng tôi. Chúng tôi đã thiết lập tất cả các tệp nhật ký để tăng thêm 8192 MB, tuy nhiên khi cơ sở dữ liệu chịu áp lực phát triển tệp nhật ký, đôi khi nó sẽ chỉ phát triển nhật ký thành các phần rất nhỏ, do đó tạo ra một số trường hợp hàng trăm nghìn tệp nhật ký ảo (VLF) .
Tôi đã hiểu được tầm quan trọng của việc giữ số lượng VLF thấp khi một trong những cơ sở dữ liệu sản xuất của chúng tôi bất ngờ đi vào phục hồi với hơn 200.000 VLF. Phục hồi mất hơn 20 giờ; trong thời gian đó một phần kinh doanh của chúng tôi không thể hoạt động.
Tôi cần một giải pháp có thể giám sát số lượng tệp nhật ký ảo cho tất cả các cơ sở dữ liệu có trên máy chủ, gửi email cảnh báo nếu bất kỳ tệp nhật ký cụ thể nào có nhiều hơn một số lượng VLF nhất định.
Tôi biết DBCC LOGINFO;
trả về danh sách các VLF, tuy nhiên, tôi không muốn tự chạy nó.
Tôi đã tạo câu lệnh SQL sau đây để tạo một bảng đẹp liệt kê các cơ sở dữ liệu, cùng với số lượng VLF, tuy nhiên, tôi không biết làm thế nào tôi có thể đưa nó vào công việc Tác nhân SQL để gửi email cho nhóm của chúng tôi bất cứ khi nào cơ sở dữ liệu có số "x" của các VLF.
DECLARE @cmd_per_database_prefix nvarchar(max);
DECLARE @cmd_per_database nvarchar(max);
DECLARE @database_name nvarchar(255);
SET @cmd_per_database = '';
SET @cmd_per_database_prefix =
'
SET NOCOUNT ON;
DECLARE @vlf_count_table TABLE (database_name nvarchar(255), vlf_count int);
DECLARE @params nvarchar(max);
DECLARE @db_name nvarchar(255);
DECLARE @vlf_count int;
SET @params = ''@db_name nvarchar(255) OUTPUT, @vlf_count int OUTPUT'';
DECLARE @cmdGetVLFCount nvarchar(max);
SET @cmdGetVLFCount =
''
DECLARE @tab TABLE
(
FileId int
, FileSize nvarchar(255)
, StartOffset nvarchar(255)
, FSeqNo nvarchar(255)
, Status int
, Parity int
, CreateLSN nvarchar(255)
);
DECLARE @cmd nvarchar(max);
SET @cmd = ''''DBCC LOGINFO;'''';
INSERT INTO @tab
EXEC sp_executesql @cmd;
SET @db_name = db_name();
SET @vlf_count = (select count(*) FROM @tab t);
'';
';
DECLARE cur CURSOR FOR
SELECT NAME
FROM sys.databases
WHERE database_id > 4 and state=0;
OPEN cur;
FETCH NEXT FROM cur INTO @database_name;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd_per_database = @cmd_per_database +
'
EXEC ' + @database_name + '.sys.sp_executesql @cmdGetVLFCount, @params, @db_name OUTPUT, @vlf_count OUTPUT;
INSERT INTO @vlf_count_table (database_name, vlf_count) VALUES (@db_name, @vlf_count);
';
FETCH NEXT FROM cur INTO @database_name;
END
SET @cmd_per_database = @cmd_per_database_prefix + @cmd_per_database + char(13) + char(10) + 'select * from @vlf_count_table t;';
EXEC sp_executesql @cmd_per_database;
CLOSE cur;
DEALLOCATE cur;
Việc cố gắng xuất dữ liệu này bằng cách sử dụng INSERT...EXEC
bảng để đính kèm email bằng cách sử dụng sp_send_dbmail
là vô ích.
Máy chủ SQL cuộn cảm với:
An INSERT EXEC statement cannot be nested.
Msg 8164, Level 16, State 1, Line 5