Dưới đây là (1) Template Incident/RCA chuẩn cho SQL Server + (2) Job SQL Server Agent mẫu chạy runbook và lưu output vào bảng log (để audit + làm dashboard).
1) Template Incident/RCA cho SQL Server
1.1. Form Incident (dùng cho FO/NOC/DBA)
A. Thông tin chung
-
Incident ID:
-
Hệ thống/Ứng dụng:
-
Server/Instance:
-
Database:
-
Mức độ (SEV1/2/3):
-
Thời gian bắt đầu:
-
Thời gian phát hiện:
-
Thời gian khôi phục:
-
Người trực / người xử lý:
-
Ảnh hưởng khách hàng (số lượng / dịch vụ):
-
Triệu chứng (timeout/slow query/error):
B. Timeline (bắt buộc)
| Thời điểm | Hành động / Quan sát | Người thực hiện | Kết quả |
|---|---|---|---|
| … | … | … | … |
C. Dữ liệu bằng chứng (Evidence)
-
CPU/RAM/IO (PerfMon/Grafana):
-
Output DMVs (đính kèm):
-
Blocking chain
-
Top CPU/Reads queries
-
waits top
-
tempdb usage
-
log reuse wait
-
-
Log liên quan:
-
SQL Error Log
-
Windows Event Log
-
Application log
-
D. Phân tích nguyên nhân theo 5 Why (hoặc Ishikawa)
-
Why1:
-
Why2:
-
Why3:
-
Why4:
-
Why5:
-
Root Cause (kết luận):
E. Khắc phục
-
Mitigation (tạm thời, để “đứng hệ thống”):
-
Fix (triệt để):
-
Kiểm thử sau fix:
-
RTO/RPO đạt chưa:
F. Phòng ngừa
-
Action items:
-
Owner:
-
Deadline:
-
Cách giám sát/alert mới:
-
Change/Release cần thực hiện:
1.2. RCA mẫu theo từng “nhóm sự cố hay gặp”
Case A — Blocking/Deadlock
Dấu hiệu
-
blocking_session_id <> 0, thời gian đợi tăng, API timeout.
Chẩn đoán nhanh (DMV)
SELECT
r.session_id, r.blocking_session_id, r.status,
r.wait_type, r.wait_time, r.wait_resource,
DB_NAME(r.database_id) AS dbname,
s.login_name, s.host_name, s.program_name,
t.text
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON r.session_id=s.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.blocking_session_id <> 0
ORDER BY r.wait_time DESC;
Mitigation
-
Xác định “đầu chuỗi blocker” → liên hệ app/owner → nếu cần thì
KILL <spid>(theo quy trình). -
Giảm transaction dài, tránh lock escalation.
Fix triệt để
-
Tối ưu index, giảm scan → giảm lock footprint
-
Rút ngắn transaction (commit sớm)
-
Cân nhắc
READ_COMMITTED_SNAPSHOT ONnếu phù hợp workload
Case B — Log Full / “Log reuse wait”
Dấu hiệu
-
DB lỗi do log đầy, hoặc
log_reuse_wait_descstuck.
Check
SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
ORDER BY name;
Mitigation
-
Nếu FULL recovery: chạy log backup ngay.
-
Nếu do long transaction: tìm session “open tran” và xử lý.
Fix triệt để
-
Lập lịch log backup 15 phút
-
Tối ưu batch, tránh transaction quá lớn
-
Nâng dung lượng log + cấu hình autogrowth hợp lý
Case C — Disk full / TempDB phình
Dấu hiệu
-
TempDB
internal_obj_MBtăng mạnh (sort/hash), version_store tăng (RCSI/snapshot).
Check
USE tempdb;
SELECT
SUM(user_object_reserved_page_count)*8/1024 AS user_obj_MB,
SUM(internal_object_reserved_page_count)*8/1024 AS internal_obj_MB,
SUM(version_store_reserved_page_count)*8/1024 AS version_store_MB,
SUM(unallocated_extent_page_count)*8/1024 AS free_MB
FROM sys.dm_db_file_space_usage;
Mitigation
-
Identify top query spilling (sort/hash), giảm concurrency batch, tăng tempdb capacity (nếu cần).
-
Giảm query gây spill (tuning, index).
Fix triệt để
-
Chuẩn hóa tempdb: nhiều file dữ liệu, size hợp lý, growth lớn
-
Tuning query + index + stats
Case D — Query tự nhiên chậm (plan regression / parameter sniffing)
Dấu hiệu
-
Hôm nay chậm, hôm qua nhanh; same query.
Mitigation
-
Dùng Query Store “force plan” (nếu đã bật)
-
Tạm dùng
OPTION (RECOMPILE)cho câu quá nhạy
Fix triệt để
-
Update stats, tạo index đúng, xử lý parameter sniffing trong stored procedure
2) Hệ thống log runbook + SQL Agent Jobs (chạy script & lưu output)
Mục tiêu:
-
FO/NOC chỉ cần xem bảng log (hoặc dashboard)
-
DBA audit được: ai chạy, khi nào, kết quả OK/FAIL, chi tiết cảnh báo.
2.1. Tạo database & bảng log
Khuyến nghị tạo 1 DB riêng:
DBAOPS(hoặc để trong msdb cũng được, nhưng tách ra sạch hơn).
IF DB_ID('DBAOPS') IS NULL
BEGIN
CREATE DATABASE DBAOPS;
END
GO
USE DBAOPS;
GO
IF OBJECT_ID('dbo.RunbookLog','U') IS NULL
BEGIN
CREATE TABLE dbo.RunbookLog
(
LogId BIGINT IDENTITY(1,1) PRIMARY KEY,
RunTime DATETIME2(0) NOT NULL DEFAULT SYSDATETIME(),
ServerName SYSNAME NOT NULL DEFAULT @@SERVERNAME,
InstanceName SYSNAME NULL,
JobName SYSNAME NULL,
TaskName NVARCHAR(200) NOT NULL,
TargetDB SYSNAME NULL,
Status VARCHAR(10) NOT NULL, -- OK/WARN/FAIL
Severity TINYINT NOT NULL DEFAULT 0, -- 0..3
Summary NVARCHAR(4000) NULL,
Details NVARCHAR(MAX) NULL
);
END
GO
CREATE INDEX IX_RunbookLog_RunTime ON dbo.RunbookLog(RunTime DESC);
GO
2.2. Stored procedure ghi log chuẩn
USE DBAOPS;
GO
CREATE OR ALTER PROCEDURE dbo.usp_LogRunbook
@JobName SYSNAME = NULL,
@TaskName NVARCHAR(200),
@TargetDB SYSNAME = NULL,
@Status VARCHAR(10),
@Severity TINYINT = 0,
@Summary NVARCHAR(4000) = NULL,
@Details NVARCHAR(MAX) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Instance SYSNAME = CAST(SERVERPROPERTY('InstanceName') AS SYSNAME);
INSERT INTO dbo.RunbookLog(JobName, TaskName, TargetDB, Status, Severity, Summary, Details, InstanceName)
VALUES(@JobName, @TaskName, @TargetDB, @Status, @Severity, @Summary, @Details, @Instance);
END
GO
2.3. “Task procedures” (Daily/Weekly/Monthly) – log WARN/FAIL có điều kiện
A) Daily Health (database offline / log reuse wait)
USE DBAOPS;
GO
CREATE OR ALTER PROCEDURE dbo.usp_RunDaily_Health
@JobName SYSNAME = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @warn INT = 0, @fail INT = 0;
DECLARE @details NVARCHAR(MAX) = N'';
;WITH x AS (
SELECT name, state_desc, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE name NOT IN ('tempdb')
)
SELECT
@fail = SUM(CASE WHEN state_desc <> 'ONLINE' THEN 1 ELSE 0 END),
@warn = SUM(CASE WHEN state_desc='ONLINE' AND log_reuse_wait_desc NOT IN ('NOTHING') THEN 1 ELSE 0 END)
FROM x;
SELECT @details = @details + CHAR(10) +
CONCAT(name, ' | ', state_desc, ' | ', recovery_model_desc, ' | ', log_reuse_wait_desc)
FROM sys.databases
WHERE name NOT IN ('tempdb')
ORDER BY name;
IF @fail > 0
EXEC dbo.usp_LogRunbook @JobName, N'DAILY_HEALTH', NULL, 'FAIL', 3,
CONCAT('Found ', @fail, ' database(s) not ONLINE'), @details;
ELSE IF @warn > 0
EXEC dbo.usp_LogRunbook @JobName, N'DAILY_HEALTH', NULL, 'WARN', 2,
CONCAT('Log reuse wait detected on ', @warn, ' database(s)'), @details;
ELSE
EXEC dbo.usp_LogRunbook @JobName, N'DAILY_HEALTH', NULL, 'OK', 0,
N'All databases ONLINE; log reuse wait = NOTHING', @details;
END
GO
B) Daily Blocking check (WARN nếu có blocking chains)
USE DBAOPS;
GO
CREATE OR ALTER PROCEDURE dbo.usp_RunDaily_Blocking
@JobName SYSNAME = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @cnt INT = 0;
DECLARE @details NVARCHAR(MAX) = N'';
SELECT @cnt = COUNT(*)
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;
IF @cnt > 0
BEGIN
SELECT @details = @details + CHAR(10) +
CONCAT('sid=', r.session_id, ' blocked_by=', r.blocking_session_id,
' wait=', COALESCE(r.wait_type,''), ' wait_ms=', r.wait_time,
' db=', DB_NAME(r.database_id))
FROM sys.dm_exec_requests r
WHERE r.blocking_session_id <> 0
ORDER BY r.wait_time DESC;
EXEC dbo.usp_LogRunbook @JobName, N'DAILY_BLOCKING', NULL, 'WARN', 2,
CONCAT('Blocking requests: ', @cnt), @details;
END
ELSE
EXEC dbo.usp_LogRunbook @JobName, N'DAILY_BLOCKING', NULL, 'OK', 0,
N'No blocking detected', NULL;
END
GO
C) Weekly CHECKDB (ví dụ cho 1 DB quan trọng)
CHECKDB chạy lâu; log “OK/FAIL” + thời gian.
USE DBAOPS;
GO
CREATE OR ALTER PROCEDURE dbo.usp_RunWeekly_CheckDB
@DbName SYSNAME,
@JobName SYSNAME = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @t0 DATETIME2(0) = SYSDATETIME();
DECLARE @sql NVARCHAR(MAX) =
N'DBCC CHECKDB (' + QUOTENAME(@DbName) + N') WITH NO_INFOMSGS, ALL_ERRORMSGS;';
BEGIN TRY
EXEC (@sql);
EXEC dbo.usp_LogRunbook @JobName, N'WEEKLY_CHECKDB', @DbName, 'OK', 0,
CONCAT('CHECKDB OK. Duration(s)=', DATEDIFF(SECOND,@t0,SYSDATETIME())), NULL;
END TRY
BEGIN CATCH
EXEC dbo.usp_LogRunbook @JobName, N'WEEKLY_CHECKDB', @DbName, 'FAIL', 3,
CONCAT('CHECKDB FAILED. Duration(s)=', DATEDIFF(SECOND,@t0,SYSDATETIME())),
CONCAT('Error: ', ERROR_MESSAGE());
THROW;
END CATCH
END
GO
D) Monthly cleanup msdb
USE DBAOPS;
GO
CREATE OR ALTER PROCEDURE dbo.usp_RunMonthly_CleanupMSDB
@Days INT = 30,
@JobName SYSNAME = NULL
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
EXEC msdb.dbo.sp_delete_backuphistory @oldest_date = DATEADD(DAY, -@Days, GETDATE());
EXEC msdb.dbo.sp_purge_jobhistory @oldest_date = DATEADD(DAY, -@Days, GETDATE());
EXEC dbo.usp_LogRunbook @JobName, N'MONTHLY_CLEAN_MSDB', NULL, 'OK', 0,
CONCAT('Cleanup msdb history older than ', @Days, ' days'), NULL;
END TRY
BEGIN CATCH
EXEC dbo.usp_LogRunbook @JobName, N'MONTHLY_CLEAN_MSDB', NULL, 'FAIL', 3,
CONCAT('Cleanup msdb failed'), ERROR_MESSAGE();
THROW;
END CATCH
END
GO
2.4. Tạo SQL Server Agent Jobs (T-SQL)
Job 1: JOB_RUNBOOK_DAILY
USE msdb;
GO
DECLARE @jobId UNIQUEIDENTIFIER;
EXEC dbo.sp_add_job
@job_name = N'JOB_RUNBOOK_DAILY',
@enabled = 1,
@description = N'Run Daily SQL Server runbook checks and log to DBAOPS.dbo.RunbookLog',
@job_id = @jobId OUTPUT;
EXEC dbo.sp_add_jobstep
@job_id = @jobId,
@step_name = N'DAILY_HEALTH',
@subsystem = N'TSQL',
@database_name = N'DBAOPS',
@command = N'EXEC DBAOPS.dbo.usp_RunDaily_Health @JobName = N''JOB_RUNBOOK_DAILY'';';
EXEC dbo.sp_add_jobstep
@job_id = @jobId,
@step_name = N'DAILY_BLOCKING',
@subsystem = N'TSQL',
@database_name = N'DBAOPS',
@command = N'EXEC DBAOPS.dbo.usp_RunDaily_Blocking @JobName = N''JOB_RUNBOOK_DAILY'';';
-- Lịch: mỗi ngày 08:00
EXEC dbo.sp_add_schedule
@schedule_name = N'SCH_RUNBOOK_DAILY_0800',
@freq_type = 4,
@freq_interval = 1,
@active_start_time = 080000;
EXEC dbo.sp_attach_schedule
@job_id = @jobId,
@schedule_name = N'SCH_RUNBOOK_DAILY_0800';
EXEC dbo.sp_add_jobserver
@job_id = @jobId,
@server_name = N'(local)';
GO
Job 2: JOB_RUNBOOK_WEEKLY (CHECKDB DB quan trọng)
Anh thay
MyDBbằng danh sách DB trọng yếu (CBS/CRM/OCS…).
USE msdb;
GO
DECLARE @jobId UNIQUEIDENTIFIER;
EXEC dbo.sp_add_job
@job_name = N'JOB_RUNBOOK_WEEKLY',
@enabled = 1,
@description = N'Weekly CHECKDB for critical DBs, log to DBAOPS',
@job_id = @jobId OUTPUT;
EXEC dbo.sp_add_jobstep
@job_id = @jobId,
@step_name = N'CHECKDB_MyDB',
@subsystem = N'TSQL',
@database_name = N'DBAOPS',
@command = N'EXEC DBAOPS.dbo.usp_RunWeekly_CheckDB @DbName=N''MyDB'', @JobName=N''JOB_RUNBOOK_WEEKLY'';';
-- Lịch: Thứ 7 23:00
EXEC dbo.sp_add_schedule
@schedule_name = N'SCH_RUNBOOK_WEEKLY_SAT_2300',
@freq_type = 8, -- weekly
@freq_interval = 64, -- Saturday
@active_start_time = 230000;
EXEC dbo.sp_attach_schedule
@job_id = @jobId,
@schedule_name = N'SCH_RUNBOOK_WEEKLY_SAT_2300';
EXEC dbo.sp_add_jobserver
@job_id = @jobId,
@server_name = N'(local)';
GO
Job 3: JOB_RUNBOOK_MONTHLY (cleanup msdb)
USE msdb;
GO
DECLARE @jobId UNIQUEIDENTIFIER;
EXEC dbo.sp_add_job
@job_name = N'JOB_RUNBOOK_MONTHLY',
@enabled = 1,
@description = N'Monthly cleanup msdb history, log to DBAOPS',
@job_id = @jobId OUTPUT;
EXEC dbo.sp_add_jobstep
@job_id = @jobId,
@step_name = N'CLEAN_MSDB',
@subsystem = N'TSQL',
@database_name = N'DBAOPS',
@command = N'EXEC DBAOPS.dbo.usp_RunMonthly_CleanupMSDB @Days=30, @JobName=N''JOB_RUNBOOK_MONTHLY'';';
-- Lịch: ngày 1 hàng tháng 02:00
EXEC dbo.sp_add_schedule
@schedule_name = N'SCH_RUNBOOK_MONTHLY_DAY1_0200',
@freq_type = 16, -- monthly
@freq_interval = 1, -- day 1
@active_start_time = 020000;
EXEC dbo.sp_attach_schedule
@job_id = @jobId,
@schedule_name = N'SCH_RUNBOOK_MONTHLY_DAY1_0200';
EXEC dbo.sp_add_jobserver
@job_id = @jobId,
@server_name = N'(local)';
GO
3) Truy vấn “Dashboard” từ bảng log (FO/NOC nhìn 1 phát biết ngay)
3.1. 24h gần nhất: WARN/FAIL
USE DBAOPS;
SELECT TOP 200
RunTime, JobName, TaskName, TargetDB, Status, Severity, Summary
FROM dbo.RunbookLog
WHERE RunTime >= DATEADD(HOUR,-24,SYSDATETIME())
AND Status IN ('WARN','FAIL')
ORDER BY RunTime DESC;
3.2. Tỷ lệ OK/WARN/FAIL theo ngày
USE DBAOPS;
SELECT
CAST(RunTime AS DATE) AS run_date,
Status,
COUNT(*) AS cnt
FROM dbo.RunbookLog
WHERE RunTime >= DATEADD(DAY,-14,SYSDATETIME())
GROUP BY CAST(RunTime AS DATE), Status
ORDER BY run_date DESC, Status;
TƯ VẤN: Click Here hoặc Hotline/Zalo 090.29.12.888
=============================
Website không chứa bất kỳ quảng cáo nào, mọi đóng góp để duy trì phát triển cho website (donation) xin vui lòng gửi về STK 90.2142.8888 - Ngân hàng Vietcombank Thăng Long - TRAN VAN BINH
=============================
Nếu bạn không muốn bị AI thay thế và tiết kiệm 3-5 NĂM trên con đường trở thành DBA chuyên nghiệp hay làm chủ Database thì hãy đăng ký ngay KHOÁ HỌC ORACLE DATABASE A-Z ENTERPRISE, được Coaching trực tiếp từ tôi với toàn bộ bí kíp thực chiến, thủ tục, quy trình của gần 20 năm kinh nghiệm (mà bạn sẽ KHÔNG THỂ tìm kiếm trên Internet/Google) từ đó giúp bạn dễ dàng quản trị mọi hệ thống Core tại Việt Nam và trên thế giới, đỗ OCP.
- CÁCH ĐĂNG KÝ: Gõ (.) hoặc để lại số điện thoại hoặc inbox https://m.me/tranvanbinh.vn hoặc Hotline/Zalo 090.29.12.888
- Chi tiết tham khảo:
https://bit.ly/oaz_w
=============================
2 khóa học online qua video giúp bạn nhanh chóng có những kiến thức nền tảng về Linux, Oracle, học mọi nơi, chỉ cần có Internet/4G:
- Oracle cơ bản: https://bit.ly/admin_1200
- Linux: https://bit.ly/linux_1200
=============================
KẾT NỐI VỚI CHUYÊN GIA TRẦN VĂN BÌNH:
📧 Mail: binhoracle@gmail.com
☎️ Mobile/Zalo: 0902912888
👨 Facebook: https://www.facebook.com/BinhOracleMaster
👨 Inbox Messenger: https://m.me/101036604657441 (profile)
👨 Fanpage: https://www.facebook.com/tranvanbinh.vn
👨 Inbox Fanpage: https://m.me/tranvanbinh.vn
👨👩 Group FB: https://www.facebook.com/groups/DBAVietNam
👨 Website: https://www.tranvanbinh.vn
👨 Blogger: https://tranvanbinhmaster.blogspot.com
🎬 Youtube: https://www.youtube.com/@binhguru
👨 Tiktok: https://www.tiktok.com/@binhguru
👨 Linkin: https://www.linkedin.com/in/binhoracle
👨 Twitter: https://twitter.com/binhguru
👨 Podcast: https://www.podbean.com/pu/pbblog-eskre-5f82d6
👨 Địa chỉ: Tòa nhà Sun Square - 21 Lê Đức Thọ - Phường Mỹ Đình 1 - Quận Nam Từ Liêm - TP.Hà Nội
=============================
cơ sở dữ liệu, cơ sở dữ liệu quốc gia, database, AI, trí tuệ nhân tạo, artificial intelligence, machine learning, deep learning, LLM, ChatGPT, DeepSeek, Grok, oracle tutorial, học oracle database, Tự học Oracle, Tài liệu Oracle 12c tiếng Việt, Hướng dẫn sử dụng Oracle Database, Oracle SQL cơ bản, Oracle SQL là gì, Khóa học Oracle Hà Nội, Học chứng chỉ Oracle ở đầu, Khóa học Oracle online,sql tutorial, khóa học pl/sql tutorial, học dba, học dba ở việt nam, khóa học dba, khóa học dba sql, tài liệu học dba oracle, Khóa học Oracle online, học oracle sql, học oracle ở đâu tphcm, học oracle bắt đầu từ đâu, học oracle ở hà nội, oracle database tutorial, oracle database 12c, oracle database là gì, oracle database 11g, oracle download, oracle database 19c/21c/23c/23ai, oracle dba tutorial, oracle tunning, sql tunning , oracle 12c, oracle multitenant, Container Databases (CDB), Pluggable Databases (PDB), oracle cloud, oracle security, oracle fga, audit_trail,oracle RAC, ASM, oracle dataguard, oracle goldengate, mview, oracle exadata, oracle oca, oracle ocp, oracle ocm , oracle weblogic, postgresql tutorial, mysql tutorial, mariadb tutorial, ms sql server tutorial, nosql, mongodb tutorial, oci, cloud, middleware tutorial, docker, k8s, micro service, hoc solaris tutorial, hoc linux tutorial, hoc aix tutorial, unix tutorial, securecrt, xshell, mobaxterm, putty