APEXSQL LOG 解析sql server 事務日志(整體默認DML)
create by : chaoqun.guo
基本介紹:
該軟件工具主要是用來解析DML,通過分析事務日志得出redo和undo的SQL腳本。
【0】構建測試數據庫與數據
【0.1】創建test數據庫(完整模式)
create database test on primary
(
name='test_data',
filename='d:\MSSQL_FIle\test_data.mdf',
size=10MB,
filegrowth=10MB
)
log on
(
name='test_log',
filename='d:\MSSQL_FIle\test_log.ldf',
size=10MB,
filegrowth=10MB
)
【0.2】創建測試表
--(1) create test1 table , use create table
use test;
create table test1(
id int identity(1,1) primary key,
num1 int,
num2 int,
str1 varchar(100),
str2 varchar(200)
)
insert into test1(num1,num2,str1,str2) values(1,2,'a','b');
insert into test1(num1,num2,str1,str2) values(3,3,'aa','bb'),(4,4,'cc','dd');
--(2) select * into new_table from tablename
use test;
go
;with a as (
select 1 as id1 ,2 as id2
union all
select id1+1,id2+1 from a
where id1<=100
)
select * into test2 from a option(maxrecursion 0)
--(3) insert into exists_table select from tableName
select * into test3 from test1 where 1=2
insert into test3 select num1,num2,str1,str2 from test1;
【1】apexSql log 操作
【1.1】連接數據庫
連接數據庫,可以解析在線/正在使用的ldf文件,我們這里選擇 test 庫。這里可以使用windows登錄方式和SQL登錄方式,我這里是軟件和數據庫在同一台機器上,就用windows了。
【1.2】添加備份目錄/備份文件
此功能可以查看歷史備份出來的事務日志內容。
由於sql server 備份事務日志會截斷事務日志信息(截斷的概念:就是把某個位置之前的所有事務日志信息全都設置為可重用,后續就可以被其他信息覆蓋),所以如果要追查的事務日志已經被截斷,那么則需要添加上事務日志備份
【1.3】功能選擇-- open results in grid
這里以網格結果為演示案例
【1.3.0】open results in grid 在網格中打開所有事務日志記錄
注意,設置好過濾條件,否則可能會因為事務日志記錄過多加載很久
【1.3.1】Filter setup過濾器設置
(1)Time range過濾器設置
1-》過濾時間范圍
2-》Operations 過濾操作行為
這里可以選擇增刪改以及DDL等。我們這里把create table 也勾上
3-》Tables 表過濾操作
這里可以選擇用戶表/系統表 等等,這里我們勾上所有用戶表
4-》advanced options 高級選項
<transactions>事務過濾
這里可以設置事務的狀態以及事務的持續時間篩選
<Users>操作賬戶過濾
<Field values>值范圍過濾
可以選擇表/列,值范圍篩選
<Server process ID>服務器進程過濾
這里可以添加你要過濾篩選的進程ID
<Transaction descriptions>事務描述過濾
5=》additional options補充選項
<display columns>顯示的列名
<Old table ID mappings>老表映射現有表
有時候有改名的情況,所以加上映射操作。
選完之后,直接點擊完成。
【1.3.2】結果展示
這樣,所有的操作就都出來了。下面的是操作詳情
我選中insert行,下面的操作詳情界面會出現我具體之前操作的值,對應我們【0.2】中的第1個insert into test1(num1,num2,str1,str2) values(1,2,'a','b') 語句。
我們可以查看它的redo/undo以及相關的行歷史/事務信息。
行歷史操作記錄
Undo腳本
Redo腳本
事務信息
【1.3.3】不同插入方式的記錄情況
我們可以從【0.2】得知,我們用了3種插入方式
-
insert into table values
-
create new_table select * from tablename
-
insert into select
我們來看一下他們的區別;
create new_table select * from tablename
很明顯,在事務日志記錄中上圖把語句與插入拆開了,然后insert這個整體 是一個操作語句中包含了100記錄。
后面這個insert into select ,很明顯在事務日志中所有語句都被拆成了單行記錄操作。
【1.3.4】測試增刪改操作
--(1)刪除 test2表id1<50的行
Use test;
Delete test2 where id1<50;
--(2)更新 test3 表 num1=3的把 num2=num1*11
Use test;
Update test3 set num2=num1*11 where num1=3
--(3)插入操作,在【0.2】中的(1)已經操作過了。
點擊一下刷新,最新的信息就出來了。
<update>選中update查看下面的詳情
redo
Undo,直接就可以生成腳本還原成之前值,同時也記錄了該語句是什么時候執行的
操作詳情可以查看,修改的一個前后情況
行列式記錄可以查看,改行之前做過哪些草走
<insert>
在[1.3.1.2]中已經展示過了,這里就不再展示了。
<delete>
Undo
Redo
【1.3.5】持續審計
會有一個跟蹤文件,記錄當前所有記錄和后續跟蹤。
刷新之后,就只會顯示該面板之后操作的記錄情況了。
查看
進行一些操作;
use test;
delete test2 where id1<20;
insert into test2(id1,id2) values(100,100);
delete test2 where id1<60;
點擊一下刷新,結果如下,只有最新的操作記錄了。並且,由於 delete test2 where id1<20;沒有刪除任何行,所以事務日志里並沒有記錄
【1.4】批量恢復
【1.4.1】選擇生成undo/redo腳本
我們可以勾上我們想要生成對應undo/redo的記錄操作,然后點擊對應的redo/undo按鈕即可
這里我隨便選2條記錄生成undo腳本
然后腳本就出來了。
【1.4.2】根據事務ID生成undo/redo腳本
如果說,並發很多或者行數太多,我們手電操作恢復比較困難。一個是行數比較多,另外一個是行與行之間會有各種正常不正常的操作。
比如,我們這里的誤操作是
Delete test2 where id1<50;
但實際運行的時候可能中間還夾雜了很多 insert/update以及其他行的delete
我們只想要這個事務語句操作的undo腳本。
(1)我們可以看到誤操作的事務信息
(2)選中該事務的其中一行,點擊上方的select transaction
-
然后全部選中
(4)生成undo
看到這個腳本的上方按鈕了嗎?我們可以直接在這個工具里點擊 execute 運行這個undo腳本,相當於遠程連接執行SQL。
【1.5】功能選擇—undo/redo
過濾器是一樣的,這里就不再贅述
、
選擇生成redo還是undo腳本,並選擇存儲位置
完成,下面還有命令行,這里我們可以用cmd 以dos命令來執行
打開文件查看,對照一下,沒有問題,的確實從最后的update反向先執行,然后用insert回滾我們的delete,最后用delete回滾我們最開始的insert 數據
【1.6】功能選擇—create before-after report
這個,顧名思義,就是創建一個操作前后的對比報告
過濾器,詳細描述見見[1.3.1]
只能對時間,和表進行篩選
選擇生成的文件類型,根據需求選擇類型
結果集:
就是把操作前后的值變化情況一一列舉出來。
這里我們看看SQL結果集和HTML結果集;
SQL:會建表,收集操作類型信息和集體值信息
HTML:這里會顯示操作類型和每一步操作對應的值信息
【1.7】功能選擇—Export results
過濾器詳情,見【1.3.1】
結果:和【1.6】一樣,只是多了更多的過濾選項
【2】使用批處理腳本 .bat 操作
如何知道腳本怎么寫?用界面操作后,保存下來腳本,直接復制到dos界面即可。
執行成功。
【3】解析離線備份文件
【3.1】測試腳本
create database test;
go
use test;
go
select getdate()
create table test1(num1 int,num2 int);
insert into test1 values(1,1)
insert into test1 values(2,1)
insert into test1 values(3,1)
insert into test1 values(4,1)
insert into test1 values(5,1)
insert into test1 values(6,1)
checkpoint
select * from test1
backup database test to disk='D:\backup_bak\test.bak' with init
insert into test1 values(11,11)
insert into test1 values(22,21)
insert into test1 values(33,31)
insert into test1 values(44,41)
insert into test1 values(55,51)
insert into test1 values(66,61)
checkpoint
backup log test to disk='D:\backup_bak\test_1.trn' with init
update test1 set num2=100
checkpoint
backup log test to disk='D:\backup_bak\test_2.trn'with init
delete test1 where num1<3
checkpoint
backup log test to disk='D:\backup_bak\test_3.trn' with init
select * into test2 from test1
insert into test2 values(11,11)
delete test1 where id <5
delete test2 where id<5
backup log test to disk='D:\backup_bak\test_4.trn' with init
【3.2】查看使用
(1)恢復全備到本地起名test
(2)打開軟件選擇我們剛恢復的test庫
(3)把bak和trn都加進來
(4)查看結果
可以看到我們這個是因為是 對 test2表操作,所以未知。因為在我們恢復的全被 test庫中,並沒有test2表的元數據。
【3.3】數據什么時候能直接讀,什么時候需要還原
-
直接利用bak+trn恢復到數據庫之后,用apexsql查看
-
直接利用bak恢復到數據庫,然后連接選擇該數據庫,然后添加文件選擇bak+你要解析的事務日志文件,可以不連續。
但如果這段事務日志中間有DDL,DDL所在事務日志LSN之后全不可用。
見測試腳本:這里有個 select * into test2 from test1; 在倒數第5行,這是一個新的object_id
后續的對於 delete test2表的操作解析,也失敗了,顯示的是unknowin