TB 級數據初始化、歷史歸檔、異構遷移、數據交換,大容量導入導出是 DBA 必修課。SQL Server 提供 `bcp`、`BULK INSERT`、`OPENROWSET(BULK...)`、`SSIS`、`AzCopy` 等工具鏈,**工具選型錯誤、日志模式失配、格式不匹配**是導致「跑 10 小時、日志爆盤、數據截斷」三大慘案的核心原因。本文構建標準化作業指導書 (SOP)。
| 工具 | 適用場景 | 性能 | 功能豐富度 | 自動化友好 |
|---|---|---|---|---|
| bcp.exe | 命令行、腳本、跨平台、純文本/原生格式 | 高 (流式、無日志選項) | 中 (格式化文件支持) | 高 (參數化、返回碼) |
| BULK INSERT | T-SQL 內嵌、存儲過程、調度作業步驟 | 高 (引擎內部、最小日志) | 中 (格式化文件、錯誤文件) | 高 (動態 SQL 構造) |
| OPENROWSET(BULK...) | Ad-hoc 查詢、聯邦查詢、臨時導入 | 高 | 中 | 低 (單語句) |
| SSIS | 複雜 ETL、異構源、數據清洗、並行、斷點續傳 | 極高 (緩衝區、並行、引擎優化) | 極高 (組件生態、腳本、表達式) | 高 (DTExec、目錄、參數化) |
| PolyBase (2016+) | 外部表查詢 Hadoop/Blob/ADLS、ELT 模式 | 高 (推下計算) | 新興 | 高 |
| 恢復模式 | 大容量操作日志行為 | 適用性 | 風險 |
|---|---|---|---|
| 簡單恢復 | 最小日志 (僅分配頁記錄) | ✅ 最佳 | 無時間點恢復 |
| 大容量日志恢復 | 最小日志 (分配頁 + 頁映射) | ✅ 生產首選 (保留日志鏈) | 還原需完整備份基礎,不可時間點恢復到大容量操作內部 |
| 完整恢復 | 全量日志 (每行 INSERT 記錄) | ❌ 禁用 (日志爆盤、性能崩塌) | 空間、IO、時間三重懲罰 |
操作流程:導入前切換 `BULK_LOGGED` → 導入 → 導入後切回 `FULL` → **立即完整備份** 重建日志鏈基點。
BULK INSERT dbo.BigTable
FROM 'D:\Data\BigTable.bcp'
WITH (
DATAFILETYPE = 'native', -- 原生格式,最高性能
FORMATFILE = 'D:\Fmt\BigTable.fmt',
TABLOCK, -- 表級鎖,避免行鎖升級、最小日志前提
BATCHSIZE = 100000, -- 批次大小,平衡事務日志/鎖/並行
MAXERRORS = 0, -- 零容忍,失敗快速回滾
CHECK_CONSTRAINTS, -- 啟用約束檢查 (可選,信任源則關閉提速)
FIRE_TRIGGERS -- 觸發器 (通常關閉)
);
-- XML 格式化文件 (可讀、可版本控制)-- INT -- VARCHAR(50) -- DATE |
| 慘案 | 根因 | 預防措施 |
|---|---|---|
| 日志填滿磁盤 | 完整恢復模式導入 | 切換 BULK_LOGGED/SIMPLE + TABLOCK |
| 數據截斷/溢出 | 格式化文件長度不匹配 / 隱式轉換 | 強制格式化文件 + CHECK_CONSTRAINTS |
| NULL/空值語義錯誤 | CSV 空字符串 vs NULL 混淆 | 格式化文件 `NULLIF` / `KEEPNULLS` 選項 |
| 編碼亂碼 | 文件 UTF-8 / 代碼頁 936 混用 | 統一 UTF-8 (bcp -C 65001) 或指定代碼頁 |
| 身份列衝突 | 源含 ID 但目標為 IDENTITY | 格式化文件映射跳過 / `KEEPIDENTITY` |
| 觸發器/約束導致極慢 | 未禁用 FIRE_TRIGGERS/CHECK_CONSTRAINTS | 導入後重建/驗證,導入過程關閉 |
| 並行導入死鎖 | 多會話無分區策略並寫同表 | 分區表並行 / 串行化批次 / TABLOCK |
| 統計信息過期導致後續查詢慢 | 導入未更新統計 | 導入後 `UPDATE STATISTICS ... WITH FULLSCAN` |
| 備份鏈斷裂 | BULK_LOGGED 導入後未完整備份 | 強制流程:導入 → 切回 FULL → 完整備份 |
| 網絡中斷導致半數據 | 無斷點續傳 / 無驗證機制 | SSIS 斷點 / 校驗和 / 行數核對 / 幂等重跑 |
# PowerShell 參數化框架 param($Server, $Database, $Table, $DataFile, $FmtFile, $BatchSize=100000) $sql = @" ALTER DATABASE [$Database] SET RECOVERY BULK_LOGGED WITH NO_WAIT; BULK INSERT [$Table] FROM '$DataFile' WITH (FORMATFILE='$FmtFile', DATAFILETYPE='native', TABLOCK, BATCHSIZE=$BatchSize, MAXERRORS=0); ALTER DATABASE [$Database] SET RECOVERY FULL WITH NO_WAIT; BACKUP DATABASE [$Database] TO DISK='...' WITH COMPRESSION, INIT; "@ Invoke-Sqlcmd -ServerInstance $Server -Query $sql -QueryTimeout 0 # 郵件通知、日志記錄、驗證行數核對
大容量導入導出核心三板斧:原生工具 + 原生格式 + 格式化文件 (消除解析歧義)、**BULK_LOGGED/SIMPLE + TABLOCK** (最小日志 + 表鎖)、**分區並行 + 導入後重建索引統計** (線性擴展)。將此封裝為參數化模板、納入 CI/CD、建立驗證核對清單,才能在 TB 級數據面前保持「可控、可重複、可審計」。