博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
内存中OLTP与内存不足
阅读量:7234 次
发布时间:2019-06-29

本文共 2397 字,大约阅读时间需要 7 分钟。

我已经写了好几次内存中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_DATA12 )13 GO

这次表创建成功,因为我有足够的可用内存。现在我使坏,关掉虚拟机。我配置它只有3G的内存:

现在当我们重启虚拟机和SQL Server,你认为会发什么?你觉得SQL Server可以把我们数据库恢复在线么?或者你认为只有主文件组(PRIMARY file group)恢复在线,内存中文件组(In-Memory file group)还是离线?我们来试下!

重启后,当你在SSMS里查看对象浏览器,你可以看到我们“整个”数据库在恢复待定状态(Recovery Pending)!

这真的真的太糟糕了,因为你不能访问你的任何数据库!即使基于传统硬盘的表也不能访问!当你查看SQL Server日志,你也会看到SQL Server给你有太少可用内存的错误信息:

偶滴神哪,我们已经玩坏内存中OLTP……

小结

我知道模拟的情况非常少见,但我说过,当虚拟机管理员只从虚拟机里拿走内存时,这个情况很常见。与内存中OPTP结合,这就意味着你的整个数据库不可访问!

当你在基于内存中OLTP部署数据库时,请记住这个。你要认真考虑你的内存需求,你也要按需调整你的未来可用内存。

本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/5548674.html,如需转载请自行联系原作者

你可能感兴趣的文章
Cocos2d-x 3.0的启动流程
查看>>
ES6模板字面量
查看>>
使用SpannableString实现一个load小动画
查看>>
CSS高度自适应 height:100%;
查看>>
jboss规则引擎KIE Drools 6.3.0 Final 教程(1)
查看>>
java多线程异步执行
查看>>
原生JS实现各种经典网页特效——Banner图滚动、选项卡切换、广告弹窗等
查看>>
SEO如何写好文章标题
查看>>
Android零基础入门第3节:带你一起来聊一聊Android开发环境
查看>>
已阻止安装程序vs2015
查看>>
POJ--2406Power Strings+KMP求字符串最小周期
查看>>
zookeeper常用命令
查看>>
mysql row模式查看原始sql
查看>>
Java 泛型 五:泛型与数组
查看>>
利用js动态创建<style>
查看>>
Net分布式系统之二:CentOS系统搭建Nginx负载均衡(下)
查看>>
App上线Check List
查看>>
广播接收者实现IP拨号
查看>>
关于mysql编码问题
查看>>
c++ typedef和#define的作用范围
查看>>