大多数关系数据库构建教科书都讨论了能够固定页面的概念,即防止操作系统将其从内存中交换出来。这个概念是这样的,数据库软件可以使用它自己的缓冲区替换算法,这可能比OS虚拟内存策略提供的更好。
我不清楚典型的桌面操作系统是否真正为程序员提供了固定页面的能力。例如,我在OS X上找到的最好的是指有线页面,但这些似乎只能由超级用户使用。
固定页面的概念,以及定义适当的缓冲区替换策略取代操作系统的概念,仅仅是理论上的兴趣而不是真正的关系数据库系统真正实现的?或者典型的桌面操作系统(Linux,Windows,OS X)是否包含用于固定的钩子,典型的关系数据库软件(Oracle,SQL Server,PostgreSQL,MySQL等)使用它们?
答案 0 :(得分:2)
在PostgreSQL中,数据库服务器将页面从文件(或从OS,实际上)复制到PostgreSQL控制的共享内存段。操作系统不知道文件系统块和共享内存块之间的映射是什么,所以操作系统无法将这些页面写回磁盘位置,即使它想要,直到PostgreSQL告诉它这样做发出seek
和write
。
操作系统可以决定将部分共享内存交换到磁盘进入 swap 分区(例如,如果它处于严重的内存压力下),但它无法将它们写回到他们的磁盘上的本机位置,因为它不知道该位置是什么。
有一些方法可以告诉操作系统不要分页内存的某些部分,例如shmctl(shmid,SHM_LOCK,NULL)
。但这些主要用于安全目的,而不是用于性能目的。例如,您使用它来防止非常敏感的信息(如私钥的解密副本)意外地被写入交换分区,坏人可能会从中恢复它。
答案 1 :(得分:2)
@jjanes说OS不能真正写出Pg的共享内存缓冲区是正确的,并且不能控制PostgreSQL读入它的内容,所以“固定”它没有意义。但那只是故事的一半。
PostgreSQL没有提供任何功能来固定其共享内存段中的表的页面。它可以这样做,它可能有用,但没有人实现它。在大多数情况下,缓冲区替换算法的功能非常好。
部分原因是因为PostgreSQL在很大程度上依赖于操作系统的缓冲区缓存,而不是试图实现自己的缓冲区缓存。数据可能会从shared_buffers
逐出,但它通常仍在操作系统中缓存。将shared_buffers
视为第一级缓存,将操作系统磁盘缓存视为第二级缓存并非不合理。
可用于控制操作系统磁盘缓存中保留的内容的功能是操作系统提供的功能。总的来说,这并不多,因为如果你让他们独处并让他们自己管理事物,现代操作系统往往会做得更好。
手动缓冲区管理等的想法在很大程度上是IMO的遗留问题,当时系统有更简单,效率更低的算法来自动管理缓存和缓冲区。
自动化失败的主要时间是你有一些只是间歇性地使用的东西,但是你想要确保它在使用时具有非常好的响应时间;即你希望降低整个系统的吞吐量,使其中一部分响应更快。 PostgreSQL没有提供太多控制权;大多数人只是确保他们经常查询感兴趣的数据,以便在缓存中保持温暖。
你可以写一个相对简单的扩展名mmap()
一个文件和mlock()
它的范围,但它会非常浪费你必须摆弄默认的操作系统限制,以阻止你锁定太多记忆。
(FWIW,我认为Oracle对钉扎关系,索引等提供了相当多的控制,与其“手动控制所有内容,无论你是否愿意”的理念一致,它绕过了大部分的操作系统。过程。)
答案 2 :(得分:1)
对于SQL Server(显然在Windows上),有一个操作系统设置允许SQL引擎忽略来自操作系统的请求以响应内存压力。该设置称为内存中的锁定页面(LPIM)。该权限是基于每个帐户授予的,并且需要在启动服务时授予运行SQL服务的帐户。
请记住,这并不总是一个好主意。例如,在虚拟化环境中,管理程序通过guest虚拟机中的气球驱动程序进程传达其内存需求。如果虚拟机管理程序需要更多内存,则会增加guest虚拟机中气球的内存需求。如果您的SQL进程已打开LPIM,它将不会响应,并且管理程序可以开始标记结果。如果管理程序不满意,那不是没有人开心。