Category Archives: SQL Server

取消利用 Query Store 強制的執行計畫

select * from sys.query_store_plan p
join sys.query_store_query q on p.query_id=q.query_id
where is_forced_plan=1

select * from sys.query_store_query

exec sp_query_store_unforce_plan 164,61

設定完 SQL Server Extended Events Session 後一直 mini dump

非常詭異的狀況,透過 SSMS 設了 Extended Events Session,沒有設 Target,按下確定後就一直出現 mini dump。其 Log 類似如下:

2021-08-19 08:39:24.84 spid51 CImageHelper::Init () Version-specific dbghelp.dll is not used
2021-08-19 08:39:24.84 spid51 **Dump thread – spid = 0, EC = 0x0000021C19F20A00
2021-08-19 08:39:24.84 spid51 *
2021-08-19 08:39:24.84 spid51 * User initiated stack dump. This is not a server exception dump.
2021-08-19 08:39:24.84 spid51 *
2021-08-19 08:39:24.84 spid51 ***Stack Dump being sent to C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\LOG\SQLDump1053.txt
2021-08-19 08:39:24.84 spid51 * ***
2021-08-19 08:39:24.84 spid51 *
2021-08-19 08:39:24.84 spid51 * BEGIN STACK DUMP:
2021-08-19 08:39:24.84 spid51 * 08/19/21 08:39:24 spid 51
2021-08-19 08:39:24.84 spid51 *
2021-08-19 08:39:24.84 spid51 * Dump triggered by event ‘sql_statement_completed’.
2021-08-19 08:39:24.84 spid51 *
2021-08-19 08:39:24.84 spid51 * Input Buffer 510 bytes –
2021-08-19 08:39:24.84 spid51 * DECLARE @edition sysname; SET @edition = cast(SERVERPROPERTY
2021-08-19 08:39:24.84 spid51 * (N’EDITION’) as sysname); SELECT case when @edition = N’SQL Azure’ then
2021-08-19 08:39:24.84 spid51 * 2 else 1 end as ‘DatabaseEngineType’, SERVERPROPERTY(‘EngineEdition’)
2021-08-19 08:39:24.84 spid51 * AS DatabaseEngineEdition, SERVERPROPERTY(‘ProductVersion’) AS ProductVe
2021-08-19 08:39:24.84 spid51 * rsion, @@MICROSOFTVERSION AS MicrosoftVersion; select host_platform fr
2021-08-19 08:39:24.84 spid51 * om sys.dm_os_host_info if @edition = N’SQL Azure’ select ‘TCP’ as C
2021-08-19 08:39:24.84 spid51 * onnectionProtocol else exec (‘select CONVERT(nvarchar(40),CONNECTION
2021-08-19 08:39:24.84 spid51 * PROPERTY(“net_transport")) as ConnectionProtocol’)
2021-08-19 08:39:24.84 spid51 *
2021-08-19 08:39:24.84 spid51 * ***
2021-08-19 08:39:24.84 spid51 * ——————————————————————————-
2021-08-19 08:39:24.84 spid51 * Short Stack Dump
2021-08-19 08:39:24.89 spid51 Stack Signature for the dump is 0x00000000A54D996E
2021-08-19 08:39:26.03 spid51 External dump process return code 0x20000001.
External dump process returned no errors.

只好透過 -f 最小啟動 SQL Server 後,用 sqlcmd 砍掉該 extended events session 就好了

DROP EVENT SESSION mySession ON SERVER;

GO

測試 Page Split 和 Fillfactor 的關係

測試語法

use northwind
set nocount on
drop table if exists t,t1
–故意讓 page 容易塞滿,多一點 page split
create table t(c1 int,c2 datetime2(7) default(sysdatetime()),
c3 uniqueidentifier default(newid()),c4 char(10) default(‘hi’))
declare @i int=1
while @i < 50000
begin
insert t(c1) values(@i)
set @i+=1
end
go
drop table if exists t1
select * into t1 from t
create clustered index idx on t1(c1)
waitfor delay ’00:00:03′
select ‘next’,SYSDATETIME()
go
insert t1(c1) values(convert(int,rand()*50000))
go 50000

select ‘end’,sysdatetime()
waitfor delay ’00:00:03′
go
drop table if exists t1
select * into t1 from t
create clustered index idx on t1(c1) with(fillfactor=50,pad_index=on)
waitfor delay ’00:00:03′
select ‘begin’,SYSDATETIME()
go
insert t1(c1) values(convert(int,rand()*50000))
go 50000
select ‘end’,sysdatetime()

綠色線標示著 go 50000 的範圍,所以 fillfactor = 50 是有減少些許 page split。

整體時間差不多

Piecemeal 還原

透過 filegroup 備份,還原時指定 partial,則 log 還原時可以指定 recovery 選項,進行多次還原,還原多少用多少

use master
drop database if exists db
go
CREATE DATABASE db
on primary
(
NAME = N’f1′,
FILENAME = N’C:\temp\forSystemTable.mdf’,
SIZE = 1MB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB
),
filegroup month1
(
NAME = N’month1′,
FILENAME = N’C:\temp\month1.mdf’,
SIZE = 1MB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB
),
filegroup month2
(
NAME = N’month2′,
FILENAME = N’C:\temp\month2.ndf’,
SIZE = 1MB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB
),
filegroup month3
(
NAME = N’month3′,
FILENAME = N’C:\temp\month3.ndf’,
SIZE = 1MB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB
)
LOG ON
(
NAME = N’log’,
FILENAME = N’c:\temp\log.ldf’,
SIZE = 1MB , MAXSIZE = 2048GB , FILEGROWTH = 10%
)
go
use db
go
CREATE PARTITION FUNCTION pf(datetime)
AS RANGE RIGHT FOR VALUES (‘20190201’, ‘20190301’);

CREATE PARTITION SCHEME ps
AS PARTITION pf
TO (month1, month2, month3);

create table tbMonth(c1 int identity,d datetime) on ps(d)

insert tbMonth(d) values(‘20190101’)

create table tbOther(c1 int)
insert tbOther values(1)
go
ALTER DATABASE [db] MODIFY FILEGROUP [month1] READONLY
go
backup database db filegroup=’month1′ to disk=’c:\temp\dbR.bak’ with init
go
insert tbMonth(d) values(‘20190201’),(‘20190301’)
backup database db read_write_filegroups to disk=’c:\temp\dbRW.bak’ with init
insert tbMonth(d) values(‘20190202’),(‘20190301’)
backup log db to disk=’c:\temp\dbLdf.bak’ with init

select * from tbMonth

alter DATABASE [db] MODIFY FILEGROUP [month2] READONLY
backup database db filegroup=’month2′ to disk=’c:\temp\dbR2.bak’ with init

insert tbMonth(d) values(‘20190302’)
backup database db read_write_filegroups to disk=’c:\temp\dbRW.bak’ with init
insert tbMonth(d) values(‘20190303’)
backup log db to disk=’c:\temp\dbLdf.bak’ with init

use master
drop database db
go
restore database db from disk=’c:\temp\dbRW.bak’ with partial,norecovery –雖然有所有的 read_write_filegroups,但只還原 primary
–因為下了 Partial,log 可以下 recovery,就變成還原多少,使用多少
restore log db from disk=’c:\temp\dbLdf.bak’
select * from db.dbo.tbOther
/*
訊息 679,層級 16,狀態 1,行 78
資料表 ‘dbo.tbMonth’ (分割區識別碼 72057594043170816) 的索引 " 的分割區之一,位於無法存取的檔案群組 (“month1″) 中,因為該檔案群組已離線、正在還原或已解除功能。這可能會限制查詢結果。
*/
select * from db.dbo.tbMonth

–過程中不能完整查詢
restore database db filegroup=’month3′ from disk=’c:\temp\dbRW.bak’ with norecovery –partial 這必須明確地寫出 filegroup
restore log db from disk=’c:\temp\dbLdf.bak’ with recovery
–有空的資料結構
/*
訊息 679,層級 16,狀態 1,行 87
資料表 ‘dbo.tbMonth’ (分割區識別碼 72057594043170816) 的索引 " 的分割區之一,位於無法存取的檔案群組 (“month1″) 中,因為該檔案群組已離線、正在還原或已解除功能。這可能會限制查詢結果。
*/
select * from db.dbo.tbMonth

restore database db filegroup=’month1′ from disk=’c:\temp\dbR.bak’ with norecovery
restore log db from disk=’c:\temp\dbLdf.bak’ with recovery
–有一月的資料
/*
訊息 679,層級 16,狀態 1,行 96
資料表 ‘dbo.tbMonth’ (分割區識別碼 72057594043236352) 的索引 " 的分割區之一,位於無法存取的檔案群組 (“month2″) 中,因為該檔案群組已離線、正在還原或已解除功能。這可能會限制查詢結果。

*/
select * from db.dbo.tbMonth

–正常查全部的資料
restore database db filegroup=’month2′ from disk=’c:\temp\dbR2.bak’ with norecovery
restore log db from disk=’c:\temp\dbLdf.bak’ with recovery
select * from db.dbo.tbMonth

線上還原 Page 損毀

Enterprise 版才可以

https://docs.microsoft.com/zh-tw/sql/relational-databases/backup-restore/restore-pages-sql-server?view=sql-server-ver15

  • 線上頁面還原
    SQL Server Enterprise Edition 支援線上頁面還原,但是當資料庫目前離線時,該版本會使用離線還原。 在大部分情況下,損毀的頁面可以在資料庫保持上線時還原,包括正進行還原頁面的檔案群組在內。 即使有一個或多個次要檔案群組離線,只要主要檔案群組還在線上,通常就會在線上執行頁面還原。 但是,偶爾損毀的頁面可能需要進行離線還原。 例如,一些重要頁面損毀可能會讓資料庫無法啟動。 警告若受損的頁面正在儲存重要資料庫中繼資料,則在嘗試線上頁面還原時,中繼資料的必要更新可能會失敗。 在此情況下,您可以執行離線頁面還原,但是您必須先建立 結尾記錄備份 (使用 RESTORE WITH NORECOVERY 來備份交易記錄)。
  • 線上分頁還原會利用改良的頁面層級錯誤報告 (包括頁面總和檢查碼) 和追蹤。 因總和檢查碼或寫入損壞偵測為損毀的頁面 (「損毀頁面」 ) 可由頁面還原作業加以還原。 只有明確指定的頁面才會還原。 每一個指定的頁面都是由指定之資料備份中該頁面的複本所取代。當您還原後續的記錄備份時,這些備份只會套用到至少包含一個正在復原之頁面的資料庫檔案。 必須套用未中斷的記錄備份鏈結至最後一個完整或差異還原,將包含該頁面的檔案群組向前帶到目前的記錄檔。 在檔案還原中,向前復原集會以單一記錄重做行程向前進行。 頁面還原若要成功,還原的頁面必須復原到與資料庫一致的狀態。


alter database northwind set recovery full
backup database northwind to disk=’c:\temp\nwind.bak’ with init,compression
use northwind
go


drop table if exists t
go


create table t(c1 int identity, c2 datetime2(7) default(sysdatetime()),c3 int)
go


set nocount on
declare @i int=1
while @i<10000
begin
insert t(c3) values(@i)
set @i+=1
end
go

backup database northwind to disk=’c:\temp\nwinddiff.bak’ with init,compression
insert t(c3) values(10000)
backup log northwind to disk=’c:\temp\nwindlog.bak’ with init,compression
insert t(c3) values(10001)
go

begin tran
update t set c3=100000 where c1=1000
go

exec sp_lock @@spid

rollback
go

— 破壞一個 page
/*
訊息 8939,層級 16,狀態 5,行 39
資料表錯誤: 物件識別碼 0,索引識別碼 -1,分割區識別碼 0,配置單位識別碼 0 (類型 Unknown),頁面 (0:0)。測試 (hdr->m_headerVersion == Page::HEADER_7_0) 失敗。值為 0 和 1。
訊息 8939,層級 16,狀態 6,行 39
資料表錯誤: 物件識別碼 0,索引識別碼 -1,分割區識別碼 0,配置單位識別碼 0 (類型 Unknown),頁面 (0:0)。測試 ((hdr->m_type >= Page::DATA_PAGE && hdr->m_type <= Page::UNDOFILE_HEADER_PAGE) || (hdr->m_type == Page::UNKNOWN_PAGE && level == AUDIT_BASIC_HEADER)) 失敗。值為 0 和 0。
訊息 8939,層級 16,狀態 7,行 39
資料表錯誤: 物件識別碼 0,索引識別碼 -1,分割區識別碼 0,配置單位識別碼 0 (類型 Unknown),頁面 (0:0)。測試 (hdr->m_freeData >= page->PageHeaderOverhead () && hdr->m_freeData <= (UINT)PAGESIZE – hdr->m_slotCnt * sizeof (PageSlot)) 失敗。值為 0 和 8192。
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。

*/

dbcc writepage (‘northwind’,1,10875,0,40,0×00000000000000000000000000000000000000000000000000000000000000000000000000000000)

— 清掉 data buffers 確定接下來從硬碟讀取 page 並檢查 checksumm
checkpoint
dbcc dropcleanbuffers

–到紀錄 924 後斷掉
/*
訊息 824,層級 24,狀態 2,行 48
SQL Server 偵測到邏輯的一致性 I/O 錯誤: 不正確的頁面識別碼 (預期是 1:10875; 實際是 0:0)。此錯誤發生在檔案 ‘C:\Program Files\Microsoft SQL Server\MSSQL15.S2019\MSSQL\DATA\Northwind.mdf’ 中位移 0x000000054f6000 之資料庫識別碼 5 的頁面 (1:10875) 進行 讀取 期間。SQL Server 錯誤記錄檔與作業系統錯誤記錄檔中的其他訊息,可能可以提供更多的詳細資訊。這是嚴重的錯誤狀況,可能會危及資料庫的完整性,必須立即更正。請執行完整的資料庫一致性檢查 (DBCC CHECKDB)。此錯誤的成因許多; 如需詳細資訊,請參閱 SQL Server 線上叢書。

*/
select * from t

select * from msdb.dbo.suspect_pages
–先前在測試時,已經做了兩次 851 頁的損毀,為了寫 blog,第三次重做,以抓畫面,所以 msdb 留有前兩次錯誤的紀錄

go
— sql server enterprise 版本線上還原單一 page,依然可以操作
use master
/*
已處理資料庫 ‘northwind’ 的 0 頁,檔案 1 上的檔案 ‘Northwind’。
RESTORE DATABASE … FILE= 已於 0.099 秒內成功處理了 0 頁 (0.000 MB/sec)。
*/
restore database northwind page=’1:10875′ from disk=’c:\temp\nwind.bak’ with norecovery
–依然可以存取
select * from northwind.dbo.customers
–依然會錯
/*
訊息 829,層級 21,狀態 1,行 66
資料庫識別碼 5,頁面 (1:10875) 標示為 RestorePending,這可能代表磁碟損毀。若要從此一狀態復原,請執行還原。

*/
select * from northwind.dbo.t
–若用 differential backup 接下來無法使用了
–restore database northwind from disk=’c:\temp\nwinddiff.bak’ with norecovery,replace
restore log northwind from disk=’c:\temp\nwindlog.bak’ with norecovery
–備份 tail_log
backup log northwind to disk=’c:\temp\nwindtail.bak’ with init,compression
–還原 tail log
restore log northwind from disk=’c:\temp\nwindtail.bak’ with recovery
–線上救回該頁
select * from northwind.dbo.t

在 Bulk 行為時,Log Backup 可能使用的空間遠大於 ldf 檔案

–bulk 行為時,若 recovery mode 是 bulk_logged,則 ldf 僅記載受影響的 extend,但 log 備份時,會把 mdf/ndf 內的 extent 也抄寫到備份檔案中

drop database if exists dbTest
create database dbTest
alter database dbTest set recovery bulk_logged
backup database dbTest to disk=’nul’
use dbTest
select top(0) * into t from sys.objects
checkpoint

backup log dbTest to disk=’nul’

select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –0.62500000000

–bulk insert
insert t with(tablock) select top(1000000) a.* from sys.objects a,sys.objects b,sys.objects c,sys.objects d
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –1.98828125000

–mdf 內 data page 的用量
select dpages from sys.sysindexes where id=object_id(‘t’) –11512
/*
已處理資料庫 ‘dbTest’ 的 11520 頁,檔案 1 上的檔案 ‘dbTest’。
已處理資料庫 ‘dbTest’ 的 160 頁,檔案 1 上的檔案 ‘dbTest_log’。
BACKUP LOG 已於 0.097 秒內成功處理了 11680 頁 (940.721 MB/sec)。
*/
backup log dbTest to disk=’c:\temp\dbTest.bak’
select 11520 * 8/1024. –90.000000 MBytes

所以 bulk insert 後,ldf 約略用了 1.3 MBytes 記載交易,但備份時,讀出了 93 MBytes 的資料

–create index 也是 bulk 行為
create index idx on t(name)
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –2.26953125000
select dpages from sys.sysindexes where id=object_id(‘t’) and name=’idx’ –4478
/*
已處理資料庫 ‘dbTest’ 的 4512 頁,檔案 1 上的檔案 ‘dbTest’。
已處理資料庫 ‘dbTest’ 的 36 頁,檔案 1 上的檔案 ‘dbTest_log’。
BACKUP LOG 已於 0.047 秒內成功處理了 4548 頁 (755.900 MB/sec)。
*/
backup log dbTest to disk=’c:\temp\dbTest2.bak’
select 4512 * 8/1024. –35.25 MBytes

也因此大量記錄復原模式可以使用 log shipping:

交易紀錄傳送必要條件

  • 主要資料庫必須使用完整或大量記錄復原模式;若將資料庫切換為簡單復原模式,會使記錄傳送停止運作。

https://docs.microsoft.com/zh-tw/sql/database-engine/log-shipping/configure-log-shipping-sql-server?view=sql-server-ver15#Prerequisites

Bulk Insert 時,考慮暫停索引

alter database northwind set recovery simple with no_wait

use northwind

drop table if exists t
select top(0) * into t from customers
set statistics io on
set statistics time on

checkpoint
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage

insert t select top(1000000) a.* from customers a,customers b,customers c,customers d
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –197.28515625000

checkpoint
insert t with(tablock) select top(1000000) a.* from customers a,customers b,customers c,customers d
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –70.50000000000

truncate table t
create index idx on t(customerid)

checkpoint
insert t with(tablock) select top(1000000) a.* from customers a,customers b,customers c,customers d
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –184.27734375000

truncate table t

checkpoint
alter index idx on t disable –alter index all on t disable
insert t with(tablock) select top(1000000) a.* from customers a,customers b,customers c,customers d
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –58.62109375000

alter index idx on t rebuild –alter index all on t rebuild
select used_log_space_in_bytes/1024./1024 from sys.dm_db_log_space_usage –58.78515625000

select count(*) from t –證明會用索引

truncate table t
drop table t

劇變,請三思

要將大型系統上雲,請三思。

資料庫在大型企業內有數百個,但 Data warehouse DW 只有一個。

技術沒優劣,只有適不適合。適合與否沒有定論,單看當下落差。沒有不能克服的落差,但看人、時、成本。落差靠時間累積經驗、形成 Best practice、SOP,透過教育訓練、合作分享達成共識。化入系統分析、設計、開發、測試、上線、維護、更版的生命週期中,難靠預想,無法一時三刻。

若企業內尚未有小型系統已經上雲,且運行一陣子,然後兩三個系統上雲,協同一陣子。那上雲有共識、流程。否則,基於技術落差,不要貿然移轉大型系統。

近來在評估多人直接存取的 DW 是否可以上雲,但 IT 團隊未有上述前提,讓我憂心:

  • 如何監控與警示:監控資源使用狀況、效能、安全稽核
    • SSMS、Azure Data Studio 對 Synapse 的 UI 並不完備,無法完整呈現物件結構與功能、屬性,Synapse 需要以 T-SQL 維護
    • SQL Agent Services 並未上 Azure,傳統的維護與應變需要重新規劃、熟悉
    • SQL Server 內建的 DMV 和 system sp、view、function 有很多差異, books on line 可查到不支援,但不會說明最佳替代方式
    • T-SQL 也很多語法不支援,如 Waitfor、Output、Drop if exists、IIF…
    • Synapse 的 MPP 架構讓資料表設計、載入、增/刪/修/查之特性與一般 SMP 架構的 SQL Server 不同,缺乏效能調教經驗
    • 缺乏 Synapse 安全授權、管理、維護的經驗,如何跨服務整合權限(例如:以往 Single sign on 可運用的 Impersonate 和 Delegate 的存取權限)
    • Platform as Services PAS 相關服務與技術的整合,以往用來貫穿且可固定版本和功能的 OS,現在變成各個服務間動態地更新版本。連名字都常換,Ex: DW->Synapse, Document DB -> Cosmos DB,Blob Storage 加功能變成 Azure Data Lake Storage Service,要能隨時調整彼此間的整合方式與處理不相容。
    • Windows OS 上固定的機制與工具:Performance Counter、Event Log、Process Monitor、Process Explorer、User account、Disk 使用…隨著 PAS 各服務而不同,Call Help 開 Case 時,以往 Memory Dump、Network Monitor、Registry…等方式都要改變。
    • 地端,OS 為明顯邊界,透過 OS 的 Directory/Security Policy/Access Control List ACL/Identity and Access Management IAM、 FW 統一控管,但 Azure 每個 PAS 都有自己的邊界。可能要先建立企業的主 Policy ,再依 PAS 各服務功能特徵,設計成符合企業規範的運作方式
    • 雲的開發、測試環境如何做?地的開發、測試環境可以不算版權,但雲是否要兩份的錢?
    • DW 現有自動的 Backup/Restore 可防 7 日週期內的天然災難,但如何處理人為災難,例如 錯誤 Drop/Delete/Update 了某個 Table,8 天後才發現,要如何單一回復這個 Table?
  • 整合開發環境改變,改用 Visual Studio Code,連帶 Source Control 換 Git,SQL 開發換 Azure Data Studio,管理工具依然是 SSMS,但不知道還能用多久…
  • 有多少 Client 並未搬上 Azure?使用者在地端執行 SAS、Python、Excel、Power BI 撈 DW,大量資料傳回地?

之前有幫大型企業裝 DW,以 SQL on Linux 架成 AG,本體成功可行。但最後配套措施無法配合,再重新安裝成 SQL on Windows。畢竟 DW 不是透過單一前端 AP 包裝起來,讓 User 僅憑 AP 介面存取,完全不知 DB 的存在。DW 是各種分析人員用手中工具直接存取的,可能有系統面的 Analysis Services、SAS、Cognos、Tableau…,但還有一大群個人使用 SSMS(有金控要使用者自己透過 SSMS 下 T-SQL 再貼到 Excel 分析)、Excel、Power BI Desktop、Python、R…一堆各式各樣的工具直接存取。這些人各自行之有年地利用 DW 分析,沒有集中的 AP Server。一旦移轉到雲,這眾人的劇變不是一小群 IT 人可以立刻解決的。

SQL on Linux 的那個 DW,因為是新規劃,所以尚無人使用。退回 Windows 平台,僅花費時間、錢、人力。但沒有大的災難。如今是使用數年,有數 T 的 DW 移轉,每次轉換平台可能都要花費 6 個月以上的時間,請務必考慮風險。

等待

疫情下,這十來天,白天轉一家電信業的資料,8 TB 從 Oracle 到 SQL Server,晚上轉另一家電信業的資料,7TB 從 Teradata 到 SQL Server。大資料表的筆數都是從數億到數十億,容量從數百 GB 到 6TB,耗時指令按下後,少則數十分鐘,多則一兩天才能看到結果。

上星期五疲憊地離開電信業辦公室,星期一進去看到因為硬碟空間用完,同時規劃執行的多個工作都以紅叉告終,資料庫進入有疑問狀態,這在上星期四晚上就已經發生,星期一擴充至 10TB 的空間依然用完,畢竟 Oracle 與 SQL Server 存放的格式可能不同,且為了處理 Oracle 可以接受而 SQL Server 無法接受的髒資料,耗用了一倍的空間,而今準備了 36TB 的空間來完成這次移轉 POC。任何一個效能嘗試,都會耗用大量資源。以 5 億和 50 億筆為基數,任何索引行為都可能耗掉大量的 ndf 和 ldf。(例如建一欄位型別為 bigint 8 byte 的索引,外加索引結構的指標 8 byte,則 5 億筆紀錄的索引要 8G 的記憶體和硬碟空間 16 byte * 500 M),一切都要壓縮來降低 I/O。

上星期同樣地另一家電信業因為大量建索引和刪資料,也把其中一個硬碟用完,導致其上的一個資料庫進入疑問狀態。因為該企業的資訊同仁尚不熟悉 SQL Server,而超大型資料的迴旋所耗用的空間都是數百 G 到數 T,但我們仍停留在數十 G 的想像中。

除了儲存空間的困擾外,髒資料一直是異質系統間的夢靨。兩大電信的系統都經歷十數年,代代工程師的各種設計與成千上萬使用者的想像,換來各種髒法。大量批次作業往往數小時後嘎然而止,僅是一筆不明原因,不知藏在哪個欄位的髒資料。一連串不知所云的 Oracle、Teradata、SQL Server ODBC/OLEDB/.NET 錯誤訊息,Google 海裡只有 NULL。如何排除這筆紀錄讓批次排程得以繼續,或是在一定範圍下改成單筆作業,找出錯誤讓相關工程師了解問題,並找出因應解法。如何以二進位找尋並呈現 utf-8、utf-16 和 big5 碼與錯誤碼的內容,再再考驗著耐心與寫 code 的能力。徒手 2 分搜尋只能在百萬筆的範疇,因為一筆紀錄找個 20 來次,人已經累了。

這個星期在頭皮發麻中度過,因為下錯一個指令就要以數小時補救,在懊悔與自責中等待。同時執行而處於等待的工作往往是 4 到 6 個,隨便下個 count(*) 查詢,就需等待 Oracle 1.5 小時回傳。看著 SQL Server 以 3~4 Gbit/s 存取 NAS,而 Oracle 以什麼樣的速度 Scan NAS 我觀察不到,但工程師告知設備相同,只好猜測可能近似。換句話說,要確認兩個資料庫最大資料表筆數需要數個小時。

抱著希望等待是這星期的模式,從星期一看到前個星期五安排的 4 個工作全以錯誤告終的無奈,滑鼠在一個個紅叉中切換,到星期二、三逐一完成 100 多個資料表的轉換,不管是空間、髒資料、格式差異…等,逐步克服,而漸漸和工程師彼此有了笑談。昨天離開前,已經可以開始討論效能調校,而非克服轉換系統的錯誤與差異。

晚上轉另一個電信將近 60 個 Table,四五天來每晚觀察排程、設計批次,處理錯誤,驗證筆數,終在今早結束,而開始處理另外四個新的 Table 需求。由於 Teradata 轉 SQL Server 的案子已經做了近半年,早習慣了錯誤重作,麻木反倒不傷心情,平淡地修設定後再重來,進入下一循環等待。白天的慌張終會轉成這個模式,希望下個星期即可有新心境。

安全地收集失敗,或許,是成長的必要。

XXXXXXXXXXXXXXXXXXXXXX

進入了第三個星期,星期二看著硬碟空間 mdf/ndf 尚有 5 TB、LDF 仍有 1.5 TB、Tempdb 1.5TB/600 GB,對有著 5 個索引,資料量 5 億筆紀錄/1 TB 的 Table 建叢集索引,因為原本是從 Oracle 轉過來,不了解使用狀況下,未先建叢集索引,但已經比照 Oracle 既有索引的方式建立非叢集索引。離開辦公室前下了建叢集以及其他可能提升效能之索引的指令。星期三一早,除了使用者 DB 掛了外,因為 tempdb 的 ldf 無法擴增而導致 SQL Server 都掛了。

不能遠端 VPN 處理是這工作的最大阻礙,總是看著遺跡,而無法在判讀將毀掉前調整作業與空間。必須一再耗時從疑問狀態回復,甚至是SQL Server無法啟動下救回,浪費了一堆工時。

且因為資料量太大,但總要在固定時間離開,而無法有效收尾,至今也未備份資料庫。人生第一次在疑懼中進行 POC。

現在,我將用 59TB 來處理這個 8TB 的 Oracle DB,這迴旋空間留著處理髒資料和調效能。

XXXXXXXXXXXXXXXXXXXXXX

今天,因新冠肺炎,電信公司拒絕外人進入…嘎然而止

新聞說,川普總統簽署 2.2 兆美元的振興經濟方案。60 多兆台幣,2.4千兆韓元,這代表韓國人無法用 SQL Server 的 Money 資料類型記載這個法案…

資料類型範圍儲存體
money-922,337,203,685,477.5808 到 922,337,203,685,477.5807 8 個位元組

SQL Server 是否要出個 BigMoney 資料類型來因應人類膨脹數字…要進入 peta 了嗎?

https://gan.wikipedia.org/wiki/%E5%9C%8B%E9%9A%9B%E5%96%AE%E4%BD%8D%E7%B3%BB%E7%B5%B1

10n詞頭記号表記十進位表記
1024yottaY一秭1 000 000 000 000 000 000 000 000
1021zettaZ十垓1 000 000 000 000 000 000 000
1018exaE百京1 000 000 000 000 000 000
1015petaP千兆1 000 000 000 000 000
1012teraT一兆1 000 000 000 000
109gigaG十億1 000 000 000
106megaM百萬1 000 000
103kilok1 000
102hectoh100
101deca,dekada10
100  1
10−1decid十分之一 / 分0.1
10−2centic百分之一 / 厘0.01
10−3millim千分之一 / 毫0.001
10−6microµ百万分之一 / 微0.000 001
10−9nanon十億分之一 / 奈0.000 000 001
10−12picop一兆分之一 / 皮0.000 000 000 001
10−15femtof千兆分之一 / 飛0.000 000 000 000 001
10−18attoa百京分之一0.000 000 000 000 000 001
10−21zeptoz十垓分之一0.000 000 000 000 000 000 001
10−24yoctoy一秭分之一0.000 000 000 000 000 000 000 001

XXXXXXXXXXXXXXXXXXXXXX

今天討論一個政府的標案,需要預想 SQL Server 如何處理 peta 資料,真要進入 peta 世紀了嗎?

若兩台 DTC 可能因為複製 Windows Image 而無法進行分散式交易

可試試

To Correct this an uninstall and reinstall of MSDTC on the non sql server must be done to foce the creating of a new CID.

Open a command prompt as administrator and run the command

msdtc -uninstall

followed by
msdtc –install

參考

https://support.microfocus.com/kb/doc.php?id=7018535

完成後要重開機