SQL

[SQL Server] 資料庫損毀與修復


週日傍晚異常斷電,UPS 也掛了,周一早上重開後,伺服器一直跑得不順,在事件檢視器發現資訊訊息,建議跑 DBCC CHECKDB (SQL Server 2014 的資料庫)

Info:825 建議進行資料庫檢查
Info:825 建議進行資料庫檢查

另外也有錯訊息

Fail:8646 建議進行資料庫檢查
Fail:8646 建議進行資料庫檢查
Fail:824 建議進行資料庫檢查
Fail:824 建議進行資料庫檢查

周一下午跑過
DBCC CHECKDB (db)

Info:8957 資料庫修復結果
Info:8957 資料庫修復結果

,修復了 77 個錯誤。

但此之後,就頻繁發生 LOCK 錯誤

Fail:1204 無法 LOCK 資源
Fail:1204 無法 LOCK 資源

並且仍然會發生建議要跑 DBCC 的錯誤。

Info:825 建議進行資料庫檢查
Info:825 建議進行資料庫檢查

考慮了一晚,周二早上決定建新資料庫:

  1. 新建 db1 ,把 db 周日凌晨定時備份還原到 db1
  2. db 更名為 db_o ,db1 更名為 db
  3. 用匯入匯出精靈把 周日備份後的資料從 db_o 匯入到 db1
  4. 所以 db_o 除了人為測試與自動備份外,等同無人存取

週二晚上本著廢物利用的精神,平常沒機會玩資料庫修復,跑:
DBCC CHECKDB (db_o)
多次,每次跑完,錯誤數都比前一次多 (主要為索引錯誤)

Info:8957 資料庫檢查52個錯誤
Info:8957 資料庫檢查52個錯誤
Info:8957 資料庫檢查54個錯誤
Info:8957 資料庫檢查54個錯誤


DBCC CHECKDB (db_o, REPAIR_REBUILD)

Info:8957 資料庫檢查59個錯誤
Info:8957 資料庫檢查59個錯誤

無法修復

另外發生資料庫存取時間過長。

Info:833 存取超過15秒
Info:833 存取超過15秒

改跑
DBCC CHECKDB (db_o, REPAIR_ALLOW_DATA_LOSS)

Info:8957 資料庫修復60個錯誤
Info:8957 資料庫修復60個錯誤

修復了 60 個錯誤,又比上面 DBCC CHECKDB (db_o) 檢查的錯誤要多。

再跑一次:
DBCC CHECKDB (db_o, REPAIR_ALLOW_DATA_LOSS)

Info:8957 資料庫修復11個錯誤
Info:8957 資料庫修復11個錯誤

又修復了 11 個錯誤。

早上再跑一次
DBCC CHECKDB (db_o, REPAIR_ALLOW_DATA_LOSS)

Info:8957 資料庫修復結果
Info:8957 資料庫修復結果

終於沒錯誤了。

周二傍晚 db (原db1) 在事件檢視器有跳出資訊建議跑 DBCC CHECKDB ,但今天改跳出故障,建議跑 DBCC CHECKDB ,回頭翻了跳電前的 db_o 是有資訊事件建議跑 DBCC CHECKDB ,所以我想應該是還原時,把原先 db_o 的索引錯誤還原到 db1 ,利用午休的時間跑
DBCC CHECKDB (db, REPAIR_ALLOW_DATA_LOSS)
多次,直到沒有錯誤為止。

沒錯誤後,另外跑重建索引
DBCC DBREINDEX (DataTable)

但是晚上仍然發生建議跑 DBCC CHECKDB ,我有跑了

Info:825 建議進行資料庫檢查
Info:825 建議進行資料庫檢查


DBCC CHECKDB(db)

Info:8957 資料庫檢查0個錯誤
Info:8957 資料庫檢查0個錯誤

顯示 0 個錯誤,此外上面 LOCK 錯誤訊息持續出現。

目前找不到問題來源,懷疑可能跳電時,硬碟或 RAID 控制卡有受損,因為有些問題是持續存取時間過久,這次事件就是純練功修復資料庫了。

廣告
Categories: SQL, 工作點滴, 技術分享 | 標籤: | 發表留言

[T-SQL] SQL認證帳號新增資料庫未正常掛入使用者


工作的資料庫其中一個資料表超過 2 億 2 千萬筆,但這個資料表常常用在 JOIN 上,導致工作日查詢網頁時,大概要拖到 20 秒以上,假日沒人用倒還好,大概 3 秒可以出來。

某個資料表超過兩億筆
某個資料表超過兩億筆

這個資料表存了超過兩百個專案的資料,所以考慮採專案切割的方式,將每個專案資料切到不同資料庫,再由各專案資料庫的資料表進行 JOIN ,減少維度障礙。

超過兩百個專案進行切割,換句話說就是要建立超過兩百個資料庫,所以打算建立完整的 T-SQL 語法,方便後續使用。

正常建立的資料庫使用者如下,考慮到管理問題,預設加入 [BUILTIN\Administrators] ,再加入自行建立的 SQL 認證的 [馬賽克B] ,以下簡稱 UserB 。

資料庫的使用者
資料庫的使用者

開發的時候用測試機來測 T-SQL ,使用本機 Windows 認證,所使用的 T-SQL 語法簡化如下:

USE [master]
GO
/* 建立資料庫 */
GO
USE [專案資料庫]
GO
/****** User [BUILTIN\Administrators] ******/
CREATE USER [BUILTIN\Administrators] FOR LOGIN [BUILTIN\Administrators] WITH DEFAULT_SCHEMA=[dbo]
GO
/* BUILTIN\Administrators Set db_owner */
/*
EXEC sp_addrolemember 'db_owner','BUILTIN\Administrators' /* Before MSSQL 2008r2 */
*/
ALTER ROLE [db_owner] ADD MEMBER [BUILTIN\Administrators]
GO
/* --分隔線-- */
/****** User [*******B] ******/
CREATE USER [*******B] FOR LOGIN [*******B] WITH DEFAULT_SCHEMA=[dbo]
GO
/* [*******B] Set db_owner */
ALTER ROLE [db_owner] ADD MEMBER [*******B]
GO


正常建立完成的 UserB 點選 [屬性] 可看到 [使用者名稱]、[登入名稱] 都如同 UserB 的內容,左下角的輸出畫面可以看到沒有錯誤。

正常建立的 UserB 帳號
正常建立的 UserB 帳號

測試完沒問題後,從我的電腦跑,變成遠端存取建立資料庫,但這一建立就發生錯誤。

遠端建立無法正常加入使用者
遠端建立無法正常加入使用者

起初發現是 UserB 無法加入這個資料庫,但用手動也加入不了,經詳細比對後,發現是 SQL Server 自動掛入的 dbo 帳號會變成:

[使用者名稱]=dbo,但 [登入名稱] =UserB ,然後 [登入名稱] 又不給我改回 dbo ,所以無法加入 UserB,只好砍掉重練。

經過多次測試,發現上面的 T-SQL 語法從分隔線處分成兩次執行,第一次執行時,SQL Server 會正常掛入 dbo 帳號,第二次執行就可以正常掛入 UserB 帳號。

目前要得到我要的資料庫安全性登入帳號的測試結論是:

  1. 本機使用 Windows 認證時,上面 T-SQL 語法可以同次執行
  2. 遠端使用 SQL Server 認證時,上面的 T-SQL 語法需要從分隔線處分兩次執行

原因我還沒找到,做個心得記錄,後面可以翻查。

本機 Windows 認證我測試過 SQL Server 2008r2、2012、2014、2016、2017 都正常。

Categories: SQL, 工作點滴, 技術分享 | 標籤: | 發表留言

在WordPress.com寫網誌.

%d 位部落客按了讚: