我已經寫了好幾次內存中OLTP的文章和”為什么我還不推薦內存中OLTP給用戶”。今天我想進一步談下內存中OLTP背后的內存需求,還有如果你內存不夠的話會發生什么。
一切都與內存有關!
我們都知道很久之前有個名人說過對于任何人,640K的內存應該足夠了。他錯了!對于內存中OLTP,內存需求非常高:
- 哈希索引的每個哈希桶由64位長的指針組成
- 每次你修改/刪除一條記錄,新版本的寫入在內存中存儲。
微軟建議內存至少是你內存優化表的2倍。當你修改或刪除記錄時,這個兩倍數量的空間是用做可能的行版本存儲。
幾個星期前,有人問我一個非常有趣的問題:當你沒有足夠的內存,在數據庫啟動期間內存中OLTP不能重建哈希索引會發生什么?這哥聽起來像非常簡單的問題,但在這個特定場景里知道內存中OLTP如何反應非常重要。
假設你在虛擬機里運行內存中OLTP,在某個時候你的虛擬機管理員給你的虛擬機比之前更少的內存。在虛擬化結合中,我經常看到這個。
讓我們玩壞內存中OLTP!
我們來模擬這樣的情景。在第一步,我想向你展示下,當你創建了內存優化表,你沒有足夠的可用物理內存,會發生什么。下列代碼創建有4個哈希索引的新的內存優化表,每個哈希索引包含250百萬的哈希桶。因此對這個整個表需要近7.4GB的內存,但我運行的虛擬機只有8G的內存。
-- 250 000 000 x 4 = 1 000 000 000 Hash Buckets of 8 bytes: 8 000 000 000 = 7.4 GB of memory overhead. -- The following query will fail, because there is too less memory available. CREATE TABLE Foo ( Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 250000000), Col2 INT NOT NULL INDEX idx_Col2 NONCLUSTERED HASH WITH (BUCKET_COUNT = 250000000), Col3 INT NOT NULL INDEX idx_Col3 NONCLUSTERED HASH WITH (BUCKET_COUNT = 250000000), Col4 INT NOT NULL INDEX idx_Col4 NONCLUSTERED HASH WITH (BUCKET_COUNT = 250000000) ) WITH ( MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA ) GO
幾秒后,CREATE TABLE語句失敗,內存中OLTP給你一個漂亮的錯誤信息:你有太少的可用內存。
Msg 701, Level 17, State 137, Line 43 There is insufficient system memory in resource pool ‘default’ to run this query.
到目前還好。讓我們重新設計表,只需要3.7G內存:
1 -- 250 000 000 x 2 = 500 000 000 Hash Buckets of 8 bytes: 4 000 000 000 = 3.7 GB of memory overhead. 2 -- The following query will fail, because there is too less memory available. 3 CREATE TABLE Foo 4 ( 5 Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 250000000), 6 Col2 INT NOT NULL INDEX idx_Col2 NONCLUSTERED HASH WITH (BUCKET_COUNT = 250000000) 7 ) 8 WITH 9 ( 10 MEMORY_OPTIMIZED = ON, 11 DURABILITY = SCHEMA_AND_DATA 12 ) 13 GO
這次表創建成功,因為我有足夠的可用內存。現在我使壞,關掉虛擬機。我配置它只有3G的內存:
現在當我們重啟虛擬機和SQL Server,你認為會發什么?你覺得SQL Server可以把我們數據庫恢復在線么?或者你認為只有主文件組(PRIMARY file group)恢復在線,內存中文件組(In-Memory file group)還是離線?我們來試下!
重啟后,當你在SSMS里查看對象瀏覽器,你可以看到我們“整個”數據庫在恢復待定狀態(Recovery Pending)!
這真的真的太糟糕了,因為你不能訪問你的任何數據庫!即使基于傳統硬盤的表也不能訪問!當你查看SQL Server日志,你也會看到SQL Server給你有太少可用內存的錯誤信息:
偶滴神哪,我們已經玩壞內存中OLTP……
小結
我知道模擬的情況非常少見,但我說過,當虛擬機管理員只從虛擬機里拿走內存時,這個情況很常見。與內存中OPTP結合,這就意味著你的整個數據庫不可訪問!
當你在基于內存中OLTP部署數據庫時,請記住這個。你要認真考慮你的內存需求,你也要按需調整你的未來可用內存。
感謝關注!
原文鏈接:
http://www.sqlpassion.at/archive/2016/05/31/in-memory-oltp-and-too-less-memory/
不含病毒。www.avast.com |
留言列表