死鎖雜談 當資料庫死鎖時,SqlServer會釋放一個優先順序較低的鎖,讓另一個事務運行;所以,即時去捕捉資料庫死鎖,是挺不容易的。 如果,資料庫死鎖比較長時間,那麼死鎖是可以被捕捉的。 可以用SqlServer活動監視器來查看,哪些進程鎖了資料庫。 首先打開SqlServer活動監視器,然後可以看到 ...
死鎖雜談
當資料庫死鎖時,SqlServer會釋放一個優先順序較低的鎖,讓另一個事務運行;所以,即時去捕捉資料庫死鎖,是挺不容易的。
如果,資料庫死鎖比較長時間,那麼死鎖是可以被捕捉的。
可以用SqlServer活動監視器來查看,哪些進程鎖了資料庫。
首先打開SqlServer活動監視器,然後可以看到,界面里有進程,查看資源,數據文件I/O,最近消耗大量資源的查詢四項。
四項顯示內容如下:
進程:在進程里可以看到哪些進程被阻塞,查看屬性【阻塞者】可以看到,【阻塞者】的會話ID。
等待資源:等待資源里有一些鎖,可以看看那些鎖累計等待時間較多。
數據文件I/O:數據文件I/O記錄一些資料庫MDF,LDF的讀寫速度。
最近消耗大量資源的查詢:記錄一些消耗資源較大的SQL查詢。
查詢進程里被死鎖的會話ID,然後執行下麵的SQL,進行解鎖。
declare @spid int Set @spid = 518 --鎖表進程會話ID declare @sql varchar(1000) set @sql='kill '+cast(@spid as varchar) exec(@sql)
也可以用下麵SQL語句查詢死鎖進程,這樣查詢死鎖進程,定位比較快。
select request_session_id spid, OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran_locks where resource_type='OBJECT'
優化雜談
最近消耗大量資源的查詢也可以用SQL查詢。
下麵SQL是查詢最耗時的前10條SQL語句。
SELECT TOP 10 total_worker_time / 1000 AS [自編譯以來執行所用的CPU時間總量(ms-毫秒)], total_elapsed_time/1000 as [完成執行此計劃所用的總時間], total_elapsed_time / execution_count/1000 as [平均完成執行此計劃所用時間], execution_count as [上次編譯以來所執行的次數], creation_time as [編譯計劃的時間], deqs.total_worker_time / deqs.execution_count / 1000 AS [平均使用CPU時間(ms)], last_execution_time AS [上次開始執行計劃的時間], total_physical_reads [編譯後在執行期間所執行的物理讀取總次數], total_logical_reads/execution_count [平均邏輯讀次數], min_worker_time /1000 AS [單次執行期間所用的最小CPU時間(ms)], max_worker_time / 1000 AS [單次執行期間所用的最大 CPU 時間(ms)], SUBSTRING(dest.text, deqs.statement_start_offset / 2 + 1, (CASE WHEN deqs.statement_end_offset = -1 THEN DATALENGTH(dest.text) ELSE deqs.statement_end_offset END - deqs.statement_start_offset) / 2 + 1) AS [執行SQL], dest.text as [完整SQL], db_name(dest.dbid) as [資料庫名稱], object_name(dest.objectid, dest.dbid) as [對象名稱] ,deqs.plan_handle [查詢所屬的已編譯計劃] FROM sys.dm_exec_query_stats deqs WITH(NOLOCK) CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest --平均使用CPU時間降序 ORDER BY (deqs.total_worker_time / deqs.execution_count / 1000) DESC
在SqlServer活動監視器里,查看資源等待。
通常可以看到等待類別是Latch的排在最上面,如下圖:
Latch 【閂鎖】雖然是一種輕量級的鎖,但等待的鎖越多,肯定越影響資料庫性能。
執行下麵SQL,查看下哪些Latch比較耗資源。
SELECT * FROM sys.dm_os_latch_stats
查詢結果如下圖所示:
從結果中可以看到各種鎖類型的請求的次數,等待時間,最大等待時間(毫秒)。
但這些鎖類型都是英文簡寫,需要使用下麵表格查詢它們的真實意義。
通過對比表格,我們發現了最消耗資源的ACCESS_METHODS_DATASET_PARENT鎖的意義是併發操作時資源訪問的鎖。那麼想降低併發操作,就可以減少ACCESS_METHODS_DATASET_PARENT鎖的資源消耗了。
Latch class | Description |
---|---|
ALLOC_CREATE_RINGBUF | Used internally by SQL Server to initialize the synchronization of the creation of an allocation ring buffer. |
ALLOC_CREATE_FREESPACE_CACHE | Used to initialize the synchronization of internal freespace caches for heaps. |
ALLOC_CACHE_MANAGER | Used to synchronize internal coherency tests. |
ALLOC_FREESPACE_CACHE | Used to synchronize the access to a cache of pages with available space for heaps and binary large objects (BLOBs). Contention on latches of this class can occur when multiple connections try to insert rows into a heap or BLOB at the same time. You can reduce this contention by partitioning the object. Each partition has its own latch. Partitioning will distribute the inserts across multiple latches. |
ALLOC_EXTENT_CACHE | Used to synchronize the access to a cache of extents that contains pages that are not allocated. Contention on latches of this class can occur when multiple connections try to allocate data pages in the same allocation unit at the same time. This contention can be reduced by partitioning the object of which this allocation unit is a part. |
ACCESS_METHODS_DATASET_PARENT | Used to synchronize child dataset access to the parent dataset during parallel operations. |
ACCESS_METHODS_HOBT_FACTORY | Used to synchronize access to an internal hash table. |
ACCESS_METHODS_HOBT | Used to synchronize access to the in-memory representation of a HoBt. |
ACCESS_METHODS_HOBT_COUNT | Used to synchronize access to a HoBt page and row counters. |
ACCESS_METHODS_HOBT_VIRTUAL_ROOT | Used to synchronize access to the root page abstraction of an internal B-tree. |
ACCESS_METHODS_CACHE_ONLY_HOBT_ALLOC | Used to synchronize worktable access. |
ACCESS_METHODS_BULK_ALLOC | Used to synchronize access within bulk allocators. |
ACCESS_METHODS_SCAN_RANGE_GENERATOR | Used to synchronize access to a range generator during parallel scans. |
ACCESS_METHODS_KEY_RANGE_GENERATOR | Used to synchronize access to read-ahead operations during key range parallel scans. |
APPEND_ONLY_STORAGE_INSERT_POINT | Used to synchronize inserts in fast append-only storage units. |
APPEND_ONLY_STORAGE_FIRST_ALLOC | Used to synchronize the first allocation for an append-only storage unit. |
APPEND_ONLY_STORAGE_UNIT_MANAGER | Used for internal data structure access synchronization within the fast append-only storage unit manager. |
APPEND_ONLY_STORAGE_MANAGER | Used to synchronize shrink operations in the fast append-only storage unit manager. |
BACKUP_RESULT_SET | Used to synchronize parallel backup result sets. |
BACKUP_TAPE_POOL | Used to synchronize backup tape pools. |
BACKUP_LOG_REDO | Used to synchronize backup log redo operations. |
BACKUP_INSTANCE_ID | Used to synchronize the generation of instance IDs for backup performance monitor counters. |
BACKUP_MANAGER | Used to synchronize the internal backup manager. |
BACKUP_MANAGER_DIFFERENTIAL | Used to synchronize differential backup operations with DBCC. |
BACKUP_OPERATION | Used for internal data structure synchronization within a backup operation, such as database, log, or file backup. |
BACKUP_FILE_HANDLE | Used to synchronize file open operations during a restore operation. |
BUFFER | Used to synchronize short term access to database pages. A buffer latch is required before reading or modifying any database page. Buffer latch contention can indicate several issues, including hot pages and slow I/Os. This latch class covers all possible uses of page latches. sys.dm_os_wait_stats makes a difference between page latch waits that are caused by I/O operations and read and write operations on the page. |
BUFFER_POOL_GROW | Used for internal buffer manager synchronization during buffer pool grow operations. |
DATABASE_CHECKPOINT | Used to serialize checkpoints within a database. |
CLR_PROCEDURE_HASHTABLE | Internal use only. |
CLR_UDX_STORE | Internal use only. |
CLR_DATAT_ACCESS | Internal use only. |
CLR_XVAR_PROXY_LIST | Internal use only. |
DBCC_CHECK_AGGREGATE | Internal use only. |
DBCC_CHECK_RESULTSET | Internal use only. |
DBCC_CHECK_TABLE | Internal use only. |
DBCC_CHECK_TABLE_INIT | Internal use only. |
DBCC_CHECK_TRACE_LIST | Internal use only. |
DBCC_FILE_CHECK_OBJECT | Internal use only. |
DBCC_PERF | Used to synchronize internal performance monitor counters. |
DBCC_PFS_STATUS | Internal use only. |
DBCC_OBJECT_METADATA | Internal use only. |
DBCC_HASH_DLL | Internal use only. |
EVENTING_CACHE | Internal use only. |
FCB | Used to synchronize access to the file control block. |
FCB_REPLICA | Internal use only. |
FGCB_ALLOC | Use to synchronize access to round robin allocation information within a filegroup. |
FGCB_ADD_REMOVE | Use to synchronize access to filegroups for add, drop, grow, and shrink file operations. |
FILEGROUP_MANAGER | Internal use only. |
FILE_MANAGER | Internal use only. |
FILESTREAM_FCB | Internal use only. |
FILESTREAM_FILE_MANAGER | Internal use only. |
FILESTREAM_GHOST_FILES | Internal use only. |
FILESTREAM_DFS_ROOT | Internal use only. |
LOG_MANAGER | Internal use only. |
FULLTEXT_DOCUMENT_ID | Internal use only. |
FULLTEXT_DOCUMENT_ID_TRANSACTION | Internal use only. |
FULLTEXT_DOCUMENT_ID_NOTIFY | Internal use only. |
FULLTEXT_LOGS | Internal use only. |
FULLTEXT_CRAWL_LOG | Internal use only. |
FULLTEXT_ADMIN | Internal use only. |
FULLTEXT_AMDIN_COMMAND_CACHE | Internal use only. |
FULLTEXT_LANGUAGE_TABLE | Internal use only. |
FULLTEXT_CRAWL_DM_LIST | Internal use only. |
FULLTEXT_CRAWL_CATALOG | Internal use only. |
FULLTEXT_FILE_MANAGER | Internal use only. |
DATABASE_MIRRORING_REDO | Internal use only. |
DATABASE_MIRRORING_SERVER | Internal use only. |
DATABASE_MIRRORING_CONNECTION | Internal use only. |
DATABASE_MIRRORING_STREAM | Internal use only. |
QUERY_OPTIMIZER_VD_MANAGER | Internal use only. |
QUERY_OPTIMIZER_ID_MANAGER | Internal use only. |
QUERY_OPTIMIZER_VIEW_REP | Internal use only. |
RECOVERY_BAD_PAGE_TABLE | Internal use only. |
RECOVERY_MANAGER | Internal use only. |
SECURITY_OPERATION_RULE_TABLE | Internal use only. |
SECURITY_OBJPERM_CACHE | Internal use only. |
SECURITY_CRYPTO | Internal use only. |
SECURITY_KEY_RING | Internal use only. |
SECURITY_KEY_LIST | Internal use only. |
SERVICE_BROKER_CONNECTION_RECEIVE | Internal use only. |
SERVICE_BROKER_TRANSMISSION | Internal use only. |
SERVICE_BROKER_TRANSMISSION_UPDATE | Internal use only. |
SERVICE_BROKER_TRANSMISSION_STATE | Internal use only. |
SERVICE_BROKER_TRANSMISSION_ERRORS | Internal use only. |
SSBXmitWork | Internal use only. |
SERVICE_BROKER_MESSAGE_TRANSMISSION | Internal use only. |
SERVICE_BROKER_MAP_MANAGER | Internal use only. |
SERVICE_BROKER_HOST_NAME | Internal use only. |
SERVICE_BROKER_READ_CACHE | Internal use only. |
SERVICE_BROKER_WAITFOR_MANAGER | Used to synchronize an instance level map of waiter queues. One queue exists per database ID, Database Version, and Queue ID tuple. Contention on latches of this class can occur when many connections are: In a WAITFOR(RECEIVE) wait state; calling WAITFOR(RECEIVE); exceeding the WAITFOR timeout; receiving a message; committing or rolling back the transaction that contains the WAITFOR(RECEIVE); You can reduce the contention by reducing the number of threads in a WAITFOR(RECEIVE) wait state. |
SERVICE_BROKER_WAITFOR_TRANSACTION_DATA | Internal use only. |
SERVICE_BROKER_TRANSMISSION_TRANSACTION_DATA | Internal use only. |
SERVICE_BROKER_TRANSPORT | Internal use only. |
SERVICE_BROKER_MIRROR_ROUTE | Internal use only. |
TRACE_ID | Internal use only. |
TRACE_AUDIT_ID | Internal use only. |
TRACE | Internal use only. |
TRACE_CONTROLLER | Internal use only. |
TRACE_EVENT_QUEUE | Internal use only. |
TRANSACTION_DISTRIBUTED_MARK | Internal use only. |
TRANSACTION_OUTCOME | Internal use only. |
NESTING_TRANSACTION_READONLY | Internal use only. |
NESTING_TRANSACTION_FULL | Internal use only. |
MSQL_TRANSACTION_MANAGER | Internal use only. |
DATABASE_AUTONAME_MANAGER | Internal use only. |
UTILITY_DYNAMIC_VECTOR | Internal use only. |
UTILITY_SPARSE_BITMAP | Internal use only. |
UTILITY_DATABASE_DROP | Internal use only. |
UTILITY_DYNAMIC_MANAGER_VIEW | Internal use only. |
UTILITY_DEBUG_FILESTREAM | Internal use only. |
UTILITY_LOCK_INFORMATION | Internal use only. |
VERSIONING_TRANSACTION | Internal use only. |
VERSIONING_TRANSACTION_LIST | Internal use only. |
VERSIONING_TRANSACTION_CHAIN | Internal use only. |
VERSIONING_STATE | Internal use only. |
VERSIONING_STATE_CHANGE | Internal use only. |
KTM_VIRTUAL_CLOCK | Internal use only. |
DBCC雜談
DBCC 語句是SQL Server 的資料庫控制台命令,共有以下四種類型。
維護:對資料庫、索引或文件組進行維護的任務。
雜項:雜項任務,如啟用跟蹤標誌或從記憶體中刪除 DLL。
信息:收集並顯示各種類型信息的任務。
驗證:對資料庫、表、索引、目錄、文件組或資料庫頁的分配進行的驗證操作。
DBCC shrinkdatabase
DBCC shrinkdatabase用於收縮資料庫,SQL語句如下:
DBCC shrinkdatabase (N'庫名' , 1)
執行結果如下:
各欄位含義如下:
DbId:資料庫引擎試圖收縮的文件的資料庫標識號。
FileId:資料庫引擎嘗試收縮的文件的文件標識號。
CurrentSize:文件當前占用的 8 KB 頁數。
MinimumSize:文件最低可以占用的 8 KB 頁數。 這與文件的最小大小或最初創建時的大小相對應。
UsedPages:文件當前使用的 8 KB 頁數。
EstimatedPages:資料庫引擎估計文件能夠收縮到的 8 KB 頁數。
如果收縮不成功,可以查看下資料庫是否有可以收縮的空間。
SQL如下:
SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB FROM sys.database_files;
如果有空間還收縮不成功,則可能是別原因。
資料庫日誌雜談
SqlServer資料庫日誌對執行的SQL語句進行了加密,所以,在日誌里,我們看不到真正執行的SQL語句。
如果想查看SQL語句,需要藉助一些工具,如ApexSQLLog。
不過,雖然看不到SQL語句,也可以通過日誌看出一些資料庫問題,比如,可以查看資料庫執行了多少次插入,更新等操作。
查看資料庫日誌的SQL如下:
SELECT * FROM [sys].[fn_dblog](NULL,NULL)
查詢結果如下:
查詢結果各欄位含義如下:
Operation |
Context |
解釋 |
LOP_SET_BITS |
LCX_DIFF_MAP |
設置點陣圖,資料: 差異(Differential)備份:只備份上次完整備份後,做修改的部分。備份單位是區(Extent)。意味著某個區內即使只有一頁做了變動,則在差異備份里會被體現.差異備份依靠一個BitMap進行維護,一個Bit對應一個區,自上次完整備份後,被修改的區會被置為1,而BitMap中被置為1對應的區會被差異備份所備份。而到下一次完整備份後,BitMap中所有的Bit都會被重置為0 而這個BitMap在資料庫第7頁: DCM頁 差異變更(Differential Changed Map,DCM)頁面他跟蹤一個文件中的哪一個區在最新一次完整資料庫備份之後被修改過。SQLSERVER用在增量備份時只對已發生數據變更的分區進行增量備份即可 |
LOP_BEGIN_XACT | 事務開始 | |
LOP_MODIFY_ROW | LCX_HEAP | 修改堆表中的某一行記錄 |
LOP_PREP_XACT | 準備啟動資料庫 | |
LOP_COMMIT_XACT | 提交事務 | |
LOP_MODIFY_ROW | LCX_BOOT_PAGE | 修改資料庫啟動頁 |
LOP_MODIFY_HEADER | LCX_PFS | 修改PFS頁的頁頭部信息 |
LOP_INSERT_ROWS | LCX_CLUSTERED | 插入數據到聚集索引的索引頁 |
LOP_INSERT_ROWS | LCX_INDEX_LEAF | 插入數據到索引的葉子節點即數據頁 |
LOP_FORMAT_PAGE | LCX_CLUSTERED | 重新組織聚集索引 |
LOP_DELETE_SPLIT | LCX_CLUSTERED | 刪除聚集索引表的一行記錄引起頁拆分 |
LOP_MODIFY_HEADER | LCX_HEAP | 修改堆表的某頁的頁頭信息 |
LOP_BEGIN_CKPT | LCX_NULL | 檢查點開始 |
LOP_END_CKPT | LCX_NULL | 檢查點結束 |
LOP_SET_FREE_SPACE | LCX_PFS | 修改PFS頁設置那個數據頁是空閑的 |
LOP_ROOT_CHANGE | LCX_CLUSTERED | 聚集索引的根節點改變 |
LOP_INSERT_ROWS | LCX_HEAP | 插入數據到堆表 |
LOP_FORMAT_PAGE | LCX_HEAP | 格式化堆里的數據頁 |
LOP_LOCK_XACT | 在事務里獲取鎖 | |
LOP_FORMAT_PAGE | LCX_HEAP | 格式化堆里的數據頁 |
----------------------------------------------------------------------------------------------------
註:此文章為原創,歡迎轉載,請在文章頁面明顯位置給出此文鏈接!
若您覺得這篇文章還不錯,請點擊下右下角的【推薦】,非常感謝!