大數據“復活”記
632
2025-04-01
當開啟transaction,執行updata的語句執行成功,不執行commit或rollback;再開啟另一個窗口,執行upadate語句,會出現失敗(報錯:鎖等待超時)的情況,但是如果對于上一個窗口執行rollback,此窗口update可以執行成功,該種情況應考慮該表是否為列存表。
【問題根因】
如果使用的是列存表,在事務中執行update操作時,是以CU為單位進行加鎖的,所以在事務未提交時并發更新同一CU的其他數據時會出現鎖等待的情況,等待超時時會出現報錯
【機制原理】
1.?CU為壓縮單元(Compress Unit),列存儲的最小單位,導入數據時生成,生成后數據固定不可更改,單個CU最多存儲1列60000行數據。同一列的CU連續存儲在一個文件中,當大于1G時,切換到新文件中。其中的Ctid字段標識列存表的一行,由cu_id和CU內行號(cu_id, offset)組成;一次性寫入的多條的數據位于同一CU。
2.??為了防止頁面同一個元組被兩個事務同時更新,在進行update時,都會加上行級鎖,對于行存來說是對一行數據加鎖,對于列存來說就是對一個CU加鎖,當一個事務update未提交時,其他事務是無法同時去更新同一CU的數據的。
3. 進行update操作后,舊元組被標記為deleted,新元組會寫到一個新的CU中
【案例分析】
1.根據現場的報錯信息,可以確定是并發更新報錯;進行update時,會申請行級鎖,在申請行級鎖之前會申請transactionid鎖,等待超時后報錯信息為:waiting for ShareLock on transaction xxx after ..ms
2.? ?客戶反應更新的并不是同一條數據,id不同,詢問客戶后得知出現問題的是列存表,查詢更新的數據是否處于同一CU。
查詢后發現處于同一CU,符合預期。
3.? ?本地場景復現:
起事務執行update操作:
事務未提交并發更新數據出現等待:
查詢后發現兩條數據位于同一cu:
【相關問題】
為什么update成功一次之后,下一次update就不會互相等鎖了?
這是因為update成功之后,舊數據被標記為deleted,新數據寫入新的CU,這兩條數據不再是同一個CU了,也就不存在這種鎖沖突
【處理方案】
列存表不適合頻繁的update場景,列存頻繁的update容易觸發并發更新等鎖超時,并且會導致小CU過多,而每個CU都會擴展至8192字節進行對齊,從而導致磁盤空間迅速膨脹;頻繁的點查或頻繁update場景建議使用行存表
EI企業智能 Gauss AP 數據倉庫服務 GaussDB(DWS)
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。