Locking
鎖地址和頁面地址不匹配
今天,我發現了這個命令
DBCC PAGE()
。我了解它顯示有關儲存在頁面級別的數據的資訊。(這個問題是關於 SQL Server 2017 - v14.0)
所以這就是我所做的:
- 我想從名為的表中獲取數據
user
- 我通過使用訪問此表的頁碼和文件號
DBCC IND()
DBCC IND('gescom', 'user', -1)
- 上一條命令的結果是:
PageFID PagePID IAMFID IAMPID ObjectID IndexID PartitionNumber PartitionID iam_chain_type PageType IndexLevel NextPageFID NextPagePID PrevPageFID PrevPagePID ------- ----------- ------ ----------- ----------- ----------- --------------- -------------------- -------------------- -------- ---------- ----------- ----------- ----------- ----------- 4 8 NULL NULL 917578307 0 1 72057594043105280 In-row data 10 NULL 0 0 0 0 5 8 4 8 917578307 0 1 72057594043105280 In-row data 1 0 0 0 0 0
- 我正在尋找第二行中的數據,因為它是 PageType = 1 的行(數據頁)
- 所以我使用
DBCC PAGE
帶有以下參數的命令:database = ‘gescom’, file num = 5, page num = 8, display option = 3DBCC TRACEON(3604) -- Activate display trace DBCC PAGE('gescom', 5, 8, 3)
- 上一個命令的結果是 (truncated result…) :
Page @0x0000018E2D3D6000 [...] Memory Dump @0x0000005DD33FA000 0000005DD33FA000: 01010000 08020001 00000000 00001400 00000000 .................... 0000005DD33FA014: 00000400 b1000000 8a1e3f03 08000000 05000000 ....±....?......... 0000005DD33FA028: 26000000 b00f0000 6b000000 2a100000 00000000 &...°...k...*....... 0000005DD33FA03C: 70954bd5 00000000 00000000 00000000 00000000 pKÕ................ 0000005DD33FA050: 00000000 00000000 00000000 00000000 30001400 ................0... 0000005DD33FA064: b6ec768b aadc3c49 9ef64911 a2bb0766 04000003 ¶ìvªÜ<IöI.¢».f.... 0000005DD33FA078: 00290031 0041004a 65616e4d 69636865 6c427570 .).1.A.JeanMichelBup 0000005DD33FA08C: 7550554f 494a6561 6e4d6940 7961686f 6f2e636f uPUOIJeanMi@yahoo.co 0000005DD33FA0A0: 6d300014 0076cf59 d2c044d1 49866422 8f4afddf m0...vÏYÒÀDÑId".Jýß
然後我終於嘗試更新這些數據:
BEGIN TRAN T1 UPDATE [USER] SET pseudo = 'newPseudo' WHERE email LIKE '%Mi%'
然後,我想查看在哪個地址上設置了鎖,所以我在不結束前一個事務的同時執行以下查詢:
SELECT * FROM sys.dm_tran_locks
這是結果(查看 lock_owner_address 列):
resource_type resource_subtype resource_database_id resource_description resource_associated_entity_id resource_lock_partition request_mode request_type request_status request_reference_count request_lifetime request_session_id request_exec_context_id request_request_id request_owner_type request_owner_id request_owner_guid request_owner_lockspace_id lock_owner_address ------------------------------------------------------------ ------------------------------------------------------------ -------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------- ----------------------- ------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------ ----------------------- ---------------- ------------------ ----------------------- ------------------ ------------------------------------------------------------ -------------------- ------------------------------------ -------------------------------- ------------------ DATABASE 5 0 0 S LOCK GRANT 1 0 57 0 0 SHARED_TRANSACTION_WORKSPACE 0 00000000-0000-0000-0000-000000000000 0x0000018E3B366130:0:0 0x0000018E36E1AE80 PAGE 5 5:8 72057594043105280 0 IX LOCK GRANT 0 33554432 57 0 0 TRANSACTION 218160 00000000-0000-0000-0000-000000000000 0x0000018E3B366130:1:1 0x0000018E2D61E380 OBJECT 5 917578307 0 IX LOCK GRANT 1 33554432 57 0 0 TRANSACTION 218160 00000000-0000-0000-0000-000000000000 0x0000018E3B366130:1:1 0x0000018E2D61D9C0
這裡我不明白為什麼對象鎖的地址與之前用DBCC PAGE命令看到的地址(= 0000005DD33FA078)不同(= 0x0000018E2D61D9C0)?
我看到頁碼匹配:@ 0x0000018E2D 3D6000 但我不明白為什麼對象鎖定地址與結果中的任何地址都不匹配
DBCC PAGE
…請告訴我我在哪裡做錯了:|
我找到了解決方案。這比我想像的要容易得多。
我會為有興趣的人說明它。
BEGIN TRAN T1 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ UPDATE [USER] SET nom = 'Vincent' WHERE id = 2 SELECT * FROM sys.dm_tran_locks
查看resource_type為PAGE的行上的**resource_description列
-- Resource_description (result will be different for you of course) : -- file_id :page_in_file -- 1 :384 -- 1 :440
但你會問,為什麼是兩頁?這是因為一個用於數據(384),第二個用於相關索引(440)。
我們可以使用以下命令進行檢查:
-- DBCC IND([database_name|database_id|0], table_name, [index_id|index_display_option {-1 for index and Index Allocation Map|-2 for IAM only}] DBCC IND(0, 'USER', -1)
查看結果,在PagePID為384、440 的行的PageType列中
-- PagePID :PageType -- 384 :1 -- 440 :2
現在我們可以訪問數據頁面來查看我們的數據是如何被 SQL SERVER 儲存的。為此,請按以下步驟進行。
-- DBCC TRACEON(3604) -- To redirect display in the console (or you'll not displaying anything) -- DBCC PAGE(database_name, file_num, page_num, display_option : {1|2|3}) [WITH TABLERESULTS] DBCC TRACEON(3604) DBCC PAGE('gescom', 1, 384, 3) WITH TABLERESULTS
我們到了 !這是 SQL SERVER 獲取鎖的頁面!只需通過儲存按您自己的主鍵排序的數據的值列,您應該找到我們正在尋找的數據!
(對不起我糟糕的英語,我是法國人)