[翻译]玩转 Locked Pages,AWE,Task Manager和Working Set

http://blogs.msdn.com/psssql/archive/2009/09/11/fun-with-locked-pages-awe-task-manager-and-the-working-set.aspx

我知道关于“Locked Pages”,AWE的话题会非常令人困惑。任何人被这个搞晕头我都会认为非常正常。但我也知道我们已经无数遍地发博客和讨论过这个话题,夸张地说甚至到了了解它的每一个细胞的地步了。我当然知道这个话题并不太好玩(但我起了一个有欺骗性的标题)。但我依然经常接到来自微软内部和客户的关于32位和64位SQL Server中这些特性的话题。因此我认为一篇总结几个常用问题的博客文是有价值的。你说不定在读了之后就能茅塞顿开。许多人喜欢FAQ的形式,于是这次我也采用一下。我建议你按顺序来看这些FAQ,因为有些解答你只有在读懂了前面的FAQ后才能真正理解。

1. 32位系统上的AWE和64位系统上的“Locked Page”之间有什么差别?

这两个只是称呼上的不同。在我们进入64位SQL Server的世界之前,SQL Server引入了一个被称为“AWE”的“新特性”。这个概念是用于扩展SQL Server申请更多内存的能力,突破32位系统的虚拟地址空间(VAS)的极限(2Gb-3Gb)。但是SQL开发组不可能凭空做到这个。因为Windows开发组创建了一个API--Address Windowing Extensions(AWE)来支持这个特性。如果你想进一步研究Physical Address Extensions(PAE)与AWE之间的差异,可以读这篇<http://msdn.microsoft.com/en-us/library/aa366796(VS.85).aspx>

一个关于使用AWE API的所有应用程序的有趣的效应是,这些API申请的所有内存,都不属于进程的working set。因此,Windows认为这些内存是锁住的(locked)(就是说,不能被分页到硬盘)。因此,用户运行使用了AWE API的应用程序必须拥有“Locked Pages in Memory”权限集(例如对于SQL Server使用的服务帐号)。

SQL开发组从SQL Server 2005起引入了x64位版本的SQL Server。因为在x64环境下运行的进程不会有32位下会出现的VAS限制(64位的上限非常夸张。理论上,一个64位的进程可以拥有上限为16 Exabyte(KB,MB,GB,TB,PB,EB,ZB,YB)。事实上,目前Windows把VAS限制为8TB,而物理内存被限制到2TB。。。),没有必要使用任何特殊的API来申请大于VAS的内存。换句话说,SQL Server还是可以使用以前的VirtualAlloc()来申请内存。但是,产品开发人员会发现,如果他们依然使用不必要的AWE API来分配内存,会发生两种情况:
a. 在内核会有稍许的性能优势。更多详情请参考这篇来自Slava Oks的文章:
http://blogs.msdn.com/slavao/archive/2005/04/29/413425.aspx
b. 和32位系统一样,任何使用AWE API分配的内存不是working set的一部分,因此不能被分页到硬盘,而被视为锁定的。

于是就诞生了被称作64位版本SQL Server的“locked pages”的概念。

那么现在你还记得对于任何Windows应用程序使用AWE API的要求?运行进程的用户帐号必须拥有“Locked Pages in Memory”权限集。因此在64位SQL Server引擎的内部,如果设置了该权限(还会进行一次单元检查。详情参见接下来的FAQ),我们使用AWE API来分配内存。通过使用AWE API,SQL Server就使用了“locked pages”的特性。

因此总结一下,AWE API对于32位和64位SQL Server系统是用于不同的目的。对于32位系统,它的确是被用于访问大于4GB的内存或允许AWE特性。对于64位系统,它很可能是被用于提高性能和对于缓冲区使用“lock pages”特性。

2. 我使用的是64位系统,我需要开启“awe enabled”的sp_configure选项来“lock pages”么?

不。事实上,64位SQL Server系统的代码忽略sp_configure选项。它是一个“无作业”(no-op)指令。既然如此你可能会问为什么我刚才告诉你在64位SQL Server系统里AWE API被用于“lock pages”?

答案是那个sp_configure选项的目的。32位系统上sp_configure选项的目的是允许用户启用AWE特性。我也已经说明了使用AWE API你必须拥有“Locked Pages in Memory”权限。因此如果你在32位系统上使用了sp_configure选项来开启“awe enabled”特性,但“Locked Pages in Memory”没有设置的话,该命令就会失败。
(这里好像有些答非所问,问的是64位系统怎么回答扯到32位上面去了。。。也可能是我没真正理解)

3. 为什么任务管理器没有显示所有分配给SQL Server的内存?

你很可能遇到这样的情况:
你安装了64位的SQL Server,客户告知你该计算机有8GB的物理内存,SQL Server的性能计数器诸如“Total Server Memory”显示SQL Server使用了大约3Gb内存。但你打开那台Windows Server 2008的任务管理器,查找到SQLSERVR.EXE的那行,却发现了如下的情况:

[翻译]玩转 Locked Pages,AWE,Task Manager和Working Set
(sqlservr.exe显示只占用了100+Mb的内存)
你可以在这个例子中看到,任务管理器的“内存”栏只显示了大约135Mb的值。但是如果看Perfmon并勾选“Total Server Memory”,你可以看到:

[翻译]玩转 Locked Pages,AWE,Task Manager和Working Set
(占用了3Gb+的内存)
为什么会有这个差别?嘛,最主要的原因就是我之前解释过的:64位SQL Server实例使用了“locked pages”。请注意任务管理器的那栏的名字为Memory(Private Working Set)。请记住我们已经说过64位SQL Server实例使用“locked pages”的话,这部分内存不属于working set。这就是这部分内存不会在任务管理器中显示出来的原因。在Windows Server 2003中,这栏的名字是“Mem Usage”,不过它也显示了进程的working set。

我们如何证明这个“差异”是由locked pages导致的?嘛,方法不止一种,但最简单的方法是在SQL Server 2008中查询sys.dm_os_process_memory DMV。在我的电脑上我得到了如下结果:

(locked_page_allocation_kb的值为3169600)
你可以从这个DMV看到locked_page_allocation_kb列的值接近Total Server Memory perfmon计数器,显示了“被锁住”的内存。

4. 我知道了64位上的SQL Server可以使用“Locked Pages”,那么到底是哪部分内存被锁住了?

关于这个问题最直接最简单的答案是所有通过SQL Server的缓冲池管理(Buffer Pool Manager)的内存。缓冲池管理是什么?是不是这是指只有“数据库”页被锁定了?从SQL Server 2005开始,所有的内存分配(换句话说就是所有关于内存的Windows API访问)是经过引擎的SQLOS组件。SQL引擎内所有需要分配<=8Kb内存的代码使用的是SQLOS内被称为“单页分配器(Single Page Allocator,SPA)”。然后SQLOS会把所有的SPA请求转向到缓冲池管理。从SQL 7.0以来这个缓冲池的代码就没改变过,执行着分配内存的任务。因此所有申请“单页”的内存最终也会通过缓冲池。而且缓冲池也是包含通过AWE API锁页的代码。

因此,SPA的背后是缓冲池管理,所有使用了SPA的代码,会在缓冲池管理使用了锁页时把它自己的内存“锁住”。那么哪些代码使用了SPA?你可能已经猜到了数据库页会使用到,另外你还可以通过查询sys.dm_os_memory_clerks DMV来发现其他什么类型的内存使用了SPA。搜索所有single_pages_kb列>0的任何行。如果你在你的服务器上运行了该查询,你很可能看到CACHESTORE_OBJCP和CACHESTORE_SQLCP的clerk类型。这个过程会缓存内存。更多的就不一一列举了。

5. 32位标准版SQL Server是否支持AWE?64位的对于“Locked Pages”的支持又是怎样?

一些人就32位标准版SQL Server是否支持“AWE”特性问过我和微软其他同事。我认为这个混淆是由知道前不久标准版的SQL Server还是不支持锁页而导致的。

那么让我们在这里澄清这个迷团:
a. 32位标准版SQL Server 2005与2008 支持 AWE特性。证据之一见:http://msdn.microsoft.com/en-us/library/cc645993.aspx。其中将“动态AWE”列举为标准版和企业版的特性。我还检查过了我们的代码,然后发现了关于“允许AWE”的逻辑是基于企业版 或 标准版。
b. 但直到不久之前“locked pages”特性还是不被支持的,就如我之前提到过的。基于客户的反馈,我们在最近的2005与2008的积累更新中修改了这个。要在标准版中启用,你需要一个trace flag。更多详情请参考:http://blogs.msdn.com/psssql/archive/2009/05/19/an-update-for-standard-sku-support-for-locked-pages.aspx

6. 我如何知道32位SQL Server上AWE被启用了?我如何知道“Locked Pages”在64位SQL Server上起效?

你可以读以下这篇博客来获知算法的详细信息:
http://blogs.msdn.com/psssql/archive/2007/10/18/do-i-have-to-assign-the-lock-privilege-for-local-system.aspx

对于32位系统,有一个小窍门。如果你设置了“awe enabled”为1,但你没有在错误日志中看到“Address Windowing Extensions is enabled”,有两种可能:你没有运行RECONFIGURE,或“Lock Pages in Memory”权限没有设。如果权限没有设置,RECONFIGURE命令会报错:

Msg 5845, Level 16, State 1, Line 1
Address Windowing Extensions (AWE) requires the 'lock pages in memory' privilege which is not currently present in the access token of the process.

(翻译到最后我发现我还是不能确定某些专业名词比如“Lock Pages in Memory”是用英文原文还是中文翻译比较好。。。)

你可能感兴趣的:(manager)