close
文章出處

我已經寫了好幾次內存中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
arrow
arrow
    全站熱搜

    AutoPoster 發表在 痞客邦 留言(0) 人氣()