我有一个第三方面向对象的数据库服务器,运行在一台具有 24 GB RAM 的 Windows Server 2003 x64 计算机上。除了一些系统进程和监控工具外,数据库服务器是这台计算机上唯一运行的东西。我打开了十个 ~130GB 和一个 ~5GB 的数据库文件,后者访问最频繁,也是给我带来问题的文件。
每当数据库服务器刷新此数据库文件时,似乎都需要很长时间才能完成。因为一旦将数据写入磁盘,DBMS 就会丢弃其事务日志,因此它必须等待刷新完成。
我查看了文件 IO进程监控并且发现在刷新之前的正常操作期间,文件中有大量随机偏移量的缓冲写入(通常为 128 字节,有时会更多)。这是可以预料到的,因为小块数据以不可预测的模式添加到数据库中并进行更新。
当事务日志已满并发生刷新时,大约有 8000 次写入,大小为 4K(相关机器上的页面大小)的倍数,在我分析的一个实例中,总共约 35 MB。刷新大约需要 12 秒才能完成,在此期间数据库服务器挂起。我们的存储人员告诉我,每次写入 1.5 毫秒(12 秒除以 8000 次写入)代表 SAN 的正常性能,他们无法加快速度。
我已经了解了文件缓存的工作方式Windows 内部原理 4,其中提到,即使应用程序没有请求刷新(惰性写入),缓存管理器也会尝试在后台线程上定期将脏页写入磁盘。有没有办法让它更快地将页面写入磁盘,这样当应用程序调用时,只剩FlushFileBuffers
下几个脏页需要应用程序等待写入磁盘?
书中还提到,缓存管理器中每个文件只有一个副本。这是否意味着我可以通过在单独的进程中打开同一个文件并定期调用FlushFileBuffers
它来触发刷新,这样当数据库服务器请求刷新时,需要刷新的内容就会减少?
我还应该研究其他操作或文件系统参数吗?
我听到的一个建议是增加文件系统中的页面大小,因为这将通过增加每个 IO 写入 SAN 的字节数来提高吞吐量。由于刷新期间保存的页面不连续且间隔很远,我怀疑这不会有什么作用,对吧?