星期六, 11月 27, 2021

[SQL] 還原至某時間點

被告知要救回誤刪資料,透過在測試機上還原至某時間點後,再從測試機把資料更新至正式機上,該篇紀錄還原至特定時間點作法

建立 Lab 環境
use AdventureWorks2017
go 

-- Step1:建立 tblRestore
CREATE TABLE [dbo].[tblRestore](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[InsertDateTime] [datetime] NULL,
	CONSTRAINT [PK_tblRestore] PRIMARY KEY CLUSTERED 
	( [ID] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

-- Step2:新增 5 筆資料
INSERT INTO tblRestore (InsertDateTime) VALUES(getdate())
GO 5

-- Step3:進行完整備份
BACKUP DATABASE AdventureWorks2017 TO DISK = N'D:\RestoreDemo.bak'

-- Step4:間隔一段時間,再新增 5 筆資料
INSERT INTO tblRestore (InsertDateTime) VALUES(getdate())
GO 5

-- Step5:進行第一次交易備份
BACKUP LOG AdventureWorks2017 TO DISK = N'D:\RestoreDemo.bak'

-- Step6:刪除全部資料,並記錄刪除時間 2021-11-26T23:15:35.0595818+08:00
DELETE FROM tblRestore

-- Step7:進行第二次交易備份
BACKUP LOG AdventureWorks2017 TO DISK = N'D:\RestoreDemo.bak'

-- Step8:透過語法來確定 bak 檔案內容
RESTORE HeaderOnly FROM DISK = N'D:\RestoreDemo.bak'
用 RESTORE HeaderOnly 可以查詢 bak 內的備份紀錄,下圖則使用 SSMS 還原功能,把備份紀錄從 bak 內顯示出來,方便閱讀

[SQL] 還原至某時間點-1

還原流程

筆記就沒有進行結尾備份,直接下參數 replace 處理囉
use master
GO

-- Step1:切換單人模式
ALTER DATABASE AdventueWorks2017 SET SINGLE_USER WITH ROLLBACK IMMEDIATE

-- Step2:還原 File = 1 完整備份
RESTORE DATABASE [AdventureWorks2017] FROM DISK = N'D:\RestoreDemo.bak'
	WITH FILE = 1 , 
		NORECOVERY , 
		REPLACE

-- Step3:還原 File = 2 第一次交易備份
RESTORE DATABASE [AdventureWorks2017] FROM DISK = N'D:\RestoreDemo.bak'
	WITH FILE = 2 , 
		NORECOVERY

-- Step4:還原 File = 3 第二次交易備份,並指定還原時間點
RESTORE DATABASE [AdventureWorks2017] FROM DISK = N'D:\RestoreDemo.bak'
	WITH FILE = 3 , 
		RECOVERY , 
		STOPAT = '2021-11-26 23:15:00'

-- Step5:切換多人模式
ALTER DATABASE [AdventureWorks2017] SET MULTI_USER WITH ROLLBACK IMMEDIATE
查詢 Table 內資料就可以看見全部資料都回來囉

  [SQL] 還原至某時間點-2

官方文件範例

官方文件上,看見下圖範例,觀念上是最後一個 Log 才指定 stopat 參數並進行 recovery,測試該範例用法,是每一個 Log 都指定 stopat 參數,一樣能夠正常還原的
 
[SQL] 還原至某時間點-3

星期五, 11月 26, 2021

[SQL] 1032 錯誤

在測試環境中發現事件檢視器內有 ESENT 相關錯誤訊息,只要 SQL Server 2019 服務重啟就會產生

[SQL] 1032 錯誤-1

事件 455
sqlservr (3628,R,98) SoftwareUsageMetrics-Api: 當開啟日誌檔案 C:\Windows\system32\LogFiles\Sum\Api.log 時,錯誤-1032 (0xfffffbf8) 發生。
[SQL] 1032 錯誤-2

事件 490
sqlservr (6520,R,98) SoftwareUsageMetrics-Api: 嘗試開啟檔案 "C:\Windows\system32\LogFiles\Sum\Api.chk" 供讀 / 寫存取失敗並出現系統錯誤 5 (0x00000005): "存取被拒。 "。 開啟檔案作業將會失敗並出現錯誤 -1032 (0xfffffbf8)。
[SQL] 1032 錯誤-3

在 Windows Server 2012 的應用程式記錄中的錯誤1032訊息 內有找到解決方式,只要在 \Windows\System32\LogFiles\Sum 內加入 SQL Server 服務啟動帳號讀寫權限就行

[SQL] 1032 錯誤-4

星期四, 11月 25, 2021

[Win] 設定自動更新

紀錄關閉 Windows Server 2019 Windows Update 自動下載更新的設定 

本機群組原則 => 電腦設定 => 系統管理範本 => Windows 元件 => Windows Update => 設定自動更新

[Win] 設定自動更新-1

把 [設定自動更新] 停用

[Win] 設定自動更新-3

在 Windows Update 內就可以看見 [您的組織已經關閉自動更新] 字樣的文字說明

[Win] 設定自動更新-2

星期三, 11月 24, 2021

[SQL] 備份成功紀錄

開啟 MS SQL 錯誤紀錄檔,會看到滿滿備份成功紀錄,錯誤紀錄檔案內重點,應該放在錯誤訊息的紀錄,因此透過 Trace flag 3226 關閉備份成功訊息紀錄,開啟後只會紀錄備份失敗訊息

[SQL] 備份成功紀錄-1

Trace flag 3226 說明
By default, every successful backup operation adds an entry in the SQL Server error log and in the system event log. If you create very frequent log backups, these success messages accumulate quickly, resulting in huge error logs in which finding other messages is problematic.

With this trace flag, you can suppress these log entries. This is useful if you are running frequent log backups and if none of your scripts depend on those entries.
在啟動參數內新增 3226,請輸入 [-T 3226]

[SQL] 備份成功紀錄-2

[SQL] 備份成功紀錄-3

最後可以透過 DBCC TracesStatus 來查詢 Trace Flags 的狀態,下列語法列出所有針對目前工作階段而啟用的 Trace Flags

星期日, 11月 21, 2021

[SQL] Nested Loops Join

Join 有三種主要演算法,分別為 Nested Loops、Merge Join 和 Hash Join,該篇紀錄 Nested Loops 相關

閱讀 Nested Loops 要先了解 Outer Table (執行計畫上方) 和 Ineer Table (執行計畫下方) 運作方式,會先從 Outer Table 取出一筆符合篩選條件資料後,去 Inner Table 內尋找符合篩選條件的資料,從程式角度來看,像是從 Outer Table 跑 foreach, 一筆一筆進 Inner Table 內把對應篩選資料抓出來

下面兩張圖為 [TSQL] 和 [執行計畫] Outer Table 和 Inner Table 對應,Outer Table 和 Inner Table 要從執行計畫去觀察,無法從 TSQL 得知,TSQL 圖片只是方便對應了解 



另外一個常見的 Nested Loops 情況就是 Key Lookup,當 nonclustered index 沒有辦法滿足所需資料,就會透過 Nested Loops 跑 Key Lookup 去取回所需資料
SELECT * 
FROM Person.Person
WHERE LastName = 'Duffy'

觀察 Nested Loops 要注意 Outer Table 資料量,基本上會希望 Outer Table 要從資料量小的開始,Turning 時剛好發現一個案例,Outer Table 資料量大於 Inner Table

星期四, 11月 18, 2021

[SQL] Service Pack

最近要升級為 SQL Server 2019 才注意到,原來 Service Pack 更新在 SQL Server 2017 開始就沒有了,只會有 Cumulative Updates (CUs) 和 critical updates (GDRs) 這兩種更新,詳見該文章 - KB4041553 - SQL Server Service Packs are discontinued starting from SQL Server 2017

下圖出處為 適用於 Microsoft SQL Server 的最新更新

[SQL] Service Pack

星期三, 11月 17, 2021

[VFP] UseCursorSchema

跟同事討論的 Cursor Schema 欄位名稱是以哪個設定為主,在 CursorAdapter 內各有一種設定和
一種呼叫方式,分別為

CursorAdapter.UseCursorSchema,下圖紅框 [Use CursorSchema when filling cursor] 即是
CursorAdapter.CursorFill() 時的第一參數


測試範例為下圖,把 Col2 名稱改為 ColName,並同時測試上述兩種方式

loDemo = CreateObject("VCXName.caDemo")
lbDemo = loDemo.CursorFill(.T.) // 第一參數 lUseCursorSchema 為 .T.
IF lbDemo = .F.
	AERROR(laError)
	MESSAGEBOX(laError(2))
ELSE 
	SELECT Demo
	BROWSE
ENDIF 

從下圖可以看見 Cursor 欄位名稱為 ColName

星期六, 11月 13, 2021

[C#] TreeView - 更新閃爍情形

遇上 TreeView 更新時發生閃爍 (Flicker) 情況,應用情境是把使用者權限總表用 TreeView 畫出,之後每位使用者把擁有權限的 TreeNode.Checked 打勾並 Hightlight 顯示,一開始想說有開啟 DoubleBuffer 也有使用 BeginUpdate()、EndUpdate() 來進行 TreeView 更新,查發現原來更新 TreeViewNode.Checked 和 Hightlight 時,並沒有使用到 BeginUpdate()、EndUpdate() 也才發現閃爍情況原來也有差異

Setting the DoubleBuffered property does not affect the TreeView control. If you want to reduce flicker when the TreeView is drawn, use the BeginUpdate and EndUpdate methods.

情況一:沒有應用上 BeginUpdate()、EndUpdate()

可以從下圖發現,TreeView 會一直閃爍且 ScrollBar 會上下跑

情況二:使用 BeginUpdate()、EndUpdate()

this.BeginUpdate();
// 填入 TreeNode.CheckBox 並 Highlight
this.EndUpdate();
可以從下圖發現,TreeView 只會閃一下

情況三:禁止清除背景訊息

protected override void WndProc(ref Message m)
{
	if (m.Msg ==  0x0014) // 禁止清除背景訊息,也可以查關鍵字 WM_ERASEBKGND
		return;

	base.WndProc(ref m);
}
可以從下圖發現,TreeView 就完全不會閃爍