事務 (SQL Server)
一、事務概念
事務是一種機制、是一種操作序列,它包含了一組數據庫操作命令,這組命令要么全部執行,要么全部不執行。因此事務是一個不可分割的工作邏輯單元。在數據庫系統上執行並發操作時事務是作為最小的控制單元來使用的。這特別適用於多用戶同時操作的數據通信系統。例如:訂票、銀行、保險公司以及證券交易系統等。
二、事務屬性
事務4大屬性:
1 原子性(Atomicity):事務是一個完整的操作。
2 一致性(Consistency):當事務完成時,數據必須處於一致狀態。
3 隔離性(Isolation):對數據進行修改的所有並發事務是彼此隔離的。
4 持久性(Durability):事務完成后,它對於系統的影響是永久性的。
三、創建事務
T-SQL中管理事務的語句:
1 開始事務: begin transaction
2 提交事務:commit transaction
3 回滾事務: rollback transaction
事務分類:
1 顯式事務:用begin transaction明確指定事務的開始。
2 隱性事務:打開隱性事務:set implicit_transactions on,當以隱性事務模式操作時,SQL Servler將在提交或回滾事務后自動啟動新事務。無法描述事務的開始,只需要提交或回滾事務。
3 自動提交事務:SQL Server的默認模式,它將每條單獨的T-SQL語句視為一個事務。如果成功執行,則自動提交,否則回滾。
事務日志 (SQL Server)
每個 SQL Server 數據庫都有事務日志,用於記錄所有事務以及每個事務所做的數據庫修改。
事務日志是數據庫的一個關鍵組件。 如果系統出現故障,你將需要依靠該日志將數據庫恢復到一致的狀態。
重要
永遠不要刪除或移動此日志,除非你完全了解執行此操作的后果。
提示
檢查點會創建一些正常點,在數據庫恢復期間將從這些正常點開始應用事務日志。 有關詳細信息,請參閱數據庫檢查點 (SQL Server)。
事務日志支持的操作
事務日志支持以下操作:
-
恢復個別的事務。
-
在 SQL Server 啟動時恢復所有未完成的事務。
-
將還原的數據庫、文件、文件組或頁前滾至故障點。
-
支持事務復制。
-
支持高可用性和災難恢復解決方案: AlwaysOn 可用性組、數據庫鏡像和日志傳送。
恢復個別的事務
如果應用程序發出 ROLLBACK 語句,或者數據庫引擎檢測到錯誤(例如失去與客戶端的通信),使用日志記錄回退未完成的事務所做的修改。
在 SQL Server 啟動時恢復所有未完成的事務
當服務器發生故障時,數據庫可能處於這樣的狀態:還沒有將某些修改從緩存寫入數據文件,在數據文件內有未完成的事務所做的修改。 啟動 SQL Server 實例時,它將對每個數據庫執行恢復操作。 前滾日志中記錄的、可能尚未寫入數據文件的每個修改。 在事務日志中找到的每個未完成的事務都將回滾,以確保數據庫的完整性。
將還原的數據庫、文件、文件組或頁前滾至故障點
在硬件丟失或磁盤故障影響到數據庫文件后,可以將數據庫還原到故障點。 先還原上次完整數據庫備份和上次差異數據庫備份,然后將后續的事務日志備份序列還原到故障點。
還原每個日志備份時,數據庫引擎將重新應用日志中記錄的所有修改,前滾所有事務。 最后的日志備份還原后,數據庫引擎將使用日志信息回退到該點上未完成的所有事務。
支持事務復制
日志讀取器代理程序監視已為事務復制配置的每個數據庫的事務日志,並將已設復制標記的事務從事務日志復制到分發數據庫中。 有關詳細信息,請參閱 事務復制的工作原理。
支持高可用性和災難恢復解決方案
備用服務器解決方案、AlwaysOn 可用性組、數據庫鏡像和日志傳送極大程度上依賴於事務日志。
在 AlwaysOn 可用性組方案中,數據庫的每個更新(主要副本)在數據庫的完整且獨立的副本(次要副本)中直接再現。 主要副本直接將每個日志記錄發送到次要副本,這可將傳入日志記錄應用到可用性組數據庫,並不斷前滾。 有關詳細信息,請參閱 AlwaysOn 故障轉移群集實例
在日志傳送方案中,主服務器將主數據庫的活動事務日志發送到一個或多個目標服務器。 每個輔助服務器將該日志還原為其本地的輔助數據庫。 有關詳細信息,請參閱 關於日志傳送。
在數據庫鏡像方案中,數據庫(主體數據庫)的每次更新都在獨立的、完整的數據庫(鏡像數據庫)副本中立即重新生成。 主體服務器實例立即將每個日志記錄發送到鏡像服務器實例,鏡像服務器實例將傳入的日志記錄應用於鏡像數據庫,從而將其繼續前滾。 有關詳細信息,請參閱 數據庫鏡像。
Transaction Log characteristics
SQL Server 數據庫引擎 事務日志的特征:
- 事務日志是作為數據庫中的單獨的文件或一組文件實現的。 日志緩存與數據頁的緩沖區高速緩存是分開管理的,因此可在數據庫引擎中生成簡單、快速和功能強大的代碼。 有關詳細信息,請參閱事務日志物理體系結構。
- 日志記錄和頁的格式不必遵守數據頁的格式。
- 事務日志可以在幾個文件上實現。 通過設置日志的 FILEGROWTH 值可以將這些文件定義為自動擴展。 這樣可減少事務日志內空間不足的可能性,同時減少管理開銷。 有關詳細信息,請參閱 ALTER DATABASE (Transact-SQL)。
- 重用日志文件中空間的機制速度快且對事務吞吐量影響最小。
事務日志截斷
日志截斷將釋放日志文件的空間,以便由事務日志重新使用。 必須定期截斷事務日志,防止其占滿分配的空間(絕對會!)。 幾個因素可能延遲日志截斷,因此監視日志大小很重要。 某些操作可以最小日志量進行記錄以減少其對事務日志大小的影響。
日志截斷可從 SQL Server 數據庫的邏輯事務日志中刪除不活動的虛擬日志文件,釋放邏輯日志中的空間以便物理事務日志重用這些空間。 如果事務日志從不截斷,它最終將填滿分配給物理日志文件的所有磁盤空間。
為了避免空間不足,除非由於某些原因延遲日志截斷,否則將在以下事件后自動進行截斷:
-
簡單恢復模式下,在檢查點之后發生。
-
在完整恢復模式或大容量日志恢復模式下,如果自上一次備份后生成檢查點,則在日志備份后進行截斷(除非是僅復制日志備份)。
有關詳細信息,請參閱本主題后面的 可能延遲日志截斷的因素。
備注
日志截斷並不減小物理日志文件的大小。 若要減少物理日志文件的物理大小,則必須收縮日志文件。 有關收縮物理日志文件大小的信息,請參閱 Manage the Size of the Transaction Log File。
Factors that can delay log truncation
在日志記錄長時間處於活動狀態時,事務日志截斷將延遲,事務日志可能填滿,這一點我們在本主題(很長)前面提到過。
[!IMPORTANT} 有關如何響應已滿事務日志的信息,請參閱解決事務日志已滿的問題(SQL Server 錯誤 9002)。
實際上,日志截斷會由於多種原因發生延遲。 查詢 sys.databases 目錄視圖的 log_reuse_wait 和 log_reuse_wait_desc 列,了解哪些因素(如果存在)阻止日志截斷。 下表對這些列的值進行了說明。
log_reuse_wait 值 | log_reuse_wait_desc 值 | 說明 |
---|---|---|
0 | NOTHING | 當前有一個或多個可重復使用的虛擬日志文件。 |
1 | CHECKPOINT | 自上次日志截斷之后,尚未生成檢查點,或者日志頭尚未跨一個虛擬日志文件移動。 (所有恢復模式) 這是日志截斷延遲的常見原因。 有關詳細信息,請參閱數據庫檢查點 (SQL Server)。 |
2 | LOG_BACKUP | 在截斷事務日志前,需要進行日志備份。 (僅限完整恢復模式或大容量日志恢復模式) 完成下一個日志備份后,一些日志空間可能變為可重復使用。 |
3 | ACTIVE_BACKUP_OR_RESTORE | 數據備份或還原正在進行(所有恢復模式)。 如果數據備份阻止了日志截斷,則取消備份操作可能有助於解決備份直接導致的此問題。 |
4 | ACTIVE_TRANSACTION | 事務處於活動狀態(所有恢復模式): 一個長時間運行的事務可能存在於日志備份的開頭。 在這種情況下,可能需要進行另一個日志備份才能釋放空間。 請注意,長時間運行的事務將阻止所有恢復模式下的日志截斷,包括簡單恢復模式,在該模式下事務日志一般在每個自動檢查點截斷。 延遲事務。 “延遲的事務 ”是有效的活動事務,因為某些資源不可用,其回滾受阻。 有關導致事務延遲的原因以及如何使它們擺脫延遲狀態的信息,請參閱延遲的事務 (SQL Server)。 長時間運行的事務也可能會填滿 tempdb 的事務日志。 Tempdb 由用戶事務隱式用於內部對象,例如用於排序的工作表、用於哈希的工作文件、游標工作表,以及行版本控制。 即使用戶事務只包括讀取數據( SELECT 查詢),也可能會以用戶事務的名義創建和使用內部對象, 然后就會填充 tempdb 事務日志。 |
5 | DATABASE_MIRRORING | 數據庫鏡像暫停,或者在高性能模式下,鏡像數據庫明顯滯后於主體數據庫。 (僅限完整恢復模式) 有關詳細信息,請參閱數據庫鏡像 (SQL Server)。 |
6 | REPLICATION | 在事務復制過程中,與發布相關的事務仍未傳遞到分發數據庫。 (僅限完整恢復模式) 有關事務復制的信息,請參閱 SQL Server Replication。 |
7 | DATABASE_SNAPSHOT_CREATION | 正在創建數據庫快照。 (所有恢復模式) 這是日志截斷延遲的常見原因,通常也是主要原因。 |
8 | LOG_SCAN | 發生日志掃描。 (所有恢復模式) 這是日志截斷延遲的常見原因,通常也是主要原因。 |
9 | AVAILABILITY_REPLICA | 可用性組的輔助副本正將此數據庫的事務日志記錄應用到相應的輔助數據庫。 (完整恢復模式) 有關詳細信息,請參閱:AlwaysOn 可用性組概述 (SQL Server)。 |
10 | — | 僅供內部使用 |
11 | — | 僅供內部使用 |
12 | — | 僅供內部使用 |
13 | OLDEST_PAGE | 如果將數據庫配置為使用間接檢查點,數據庫中最早的頁可能比檢查點 LSN 早。 在這種情況下,最早的頁可以延遲日志截斷。 (所有恢復模式) 有關間接檢查點的信息,請參閱數據庫檢查點 (SQL Server)。 |
14 | OTHER_TRANSIENT | 當前未使用此值。 |
可盡量減少日志量的操作
最小日志記錄是指只記錄在不支持時間點恢復的情況下恢復事務所需的信息。 本主題介紹在大容量日志恢復模式下(以及簡單恢復模式下)按最小方式記錄、但在運行備份時例外的操作。
備注
內存優化表不支持最小日志記錄。
備注
在完整 恢復模式下,所有大容量操作都將被完整地記錄下來。 但是,可以通過將數據庫暫時切換到用於大容量操作的大容量日志恢復模式,最小化一組大容量操作的日志記錄。 最小日志記錄比完整日志記錄更為有效,並在大容量事務期間,降低了大規模大容量操作填滿可用的事務日志空間的可能性。 不過,如果在最小日志記錄生效時數據庫損壞或丟失,則無法將數據庫恢復到故障點。
下列操作在完整恢復模式下執行完整日志記錄,而在簡單和大容量日志恢復模式下按最小方式記錄日志:
- 批量導入操作(bcp、BULK INSERT 和 INSERT...SELECT)。 有關在何時對大容量導入表按最小方式進行記錄的詳細信息,請參閱 Prerequisites for Minimal Logging in Bulk Import。
啟用事務復制時,將完全記錄 BULK INSERT 操作,即使處於大容量日志恢復模式下。
- SELECT INTO 操作。
啟用事務復制時,將完全記錄 SELECT INTO 操作,即使處於大容量日志恢復模式下。
-
插入或追加新數據時,使用 UPDATE 語句中的 .WRITE 子句部分更新到大型值數據類型。 注意,在更新現有值時沒有使用最小日志記錄。有關大型值數據類型的詳細信息,請參閱數據類型 (Transact-SQL)。
-
在UPDATETEXT 、 nUPDATETEXT 和 UPDATETEXT, nUPDATETEXT, 、 UPDATETEXT 語句。 注意,在更新現有值時沒有使用最小日志記錄。
重要
不推薦使用 WRITETEXT 語句和 UPDATETEXT 語句,應該避免在新的應用程序中使用這些語句。
-
如果數據庫設置為簡單或大容量日志恢復模式,則無論是脫機還是聯機執行操作,都會按最小方式記錄一些索引 DDL 操作。 按最小方式記錄的索引操作如下:
-
CREATE INDEX 操作(包括索引視圖)。
-
ALTER INDEX REBUILD 或 DBCC DBREINDEX 操作。
重要
不推薦使用“DBCC DBREINDEX 語句”;請不要在新的應用程序中使用該語句。
-
DROP INDEX 新堆重新生成(如果適用)。 ( DROP INDEX 操作期間將 始終 完整記錄索引頁的釋放操作。)
-