欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

SQL Server 内存相关博文

程序员文章站 2022-05-14 20:13:07
...

Dont confuse error 823 and error 832 本文大意: 错误832: A page that should have been constant has changed (expected checksum: 1dcb28a7, actual checksum: 68c626bb, database 13, file 'E:\Program Files\microsoft sql server\MSSQL\data\BlahBl

Don’t confuse error 823 and error 832

本文大意:

错误832:

A page that should have been constant has changed (expected checksum: 1dcb28a7, actual checksum: 68c626bb, database 13, file 'E:\Program Files\microsoft sql server\MSSQL\data\BlahBlah.mdf', page (1:112644)). This usually indicates a memory failure or other hardware or OS corruption.

当一个页从磁盘读入,被标记为干净,如果被修改,变成脏页,检查checksum,发现checksum不再可用,832错误发生,发生这个错误一般出现在:1.内存问题,2.操作系统内存管理器问题,或者流氓程序写入到sql server。

1.通过微软产品支持,跟踪内存

2.通过替换法,替换内存

SQL Server and Large Pages Explained….

本文大意:

windows是支持大数据页的,关于windows大数据页的支持可以看Microsoft windows internal,X64支持2MB的大数据页。

有3个条件决定了是否使用大数据页:

1.sql server企业版

2.内存在8G以上

3.Lock Page in Memory权限

这个检查Lock Page in Memory和buffer pool使用AWE API没有关系,因为Large Page 也是不在work set中,也是不能被page out的。

如果Large Page启用会在error log中有一下信息:

2009-06-04 12:21:08.16 Server Large Page Extensions enabled.

2009-06-04 12:21:08.16 Server Large Page Granularity: 2097152

2009-06-04 12:21:08.21 Server Large Page Allocated: 32MB

但是有人会怀疑,明明没有开启TF 834为什么会用large page,因为TF834只限制buffer pool用不用large page。

开启834之后,buffer pool使用large page,因为large page通过virtualalloc()分配内存,比较慢所以会在开机时一次性分配。

启动时,分配算法:

1.会根据max server memory 和物理内存的最小值,若没有设置max server memory那么会分配所有内存。所以max server memeory的设置很总要

2.当使用large page的时候最让是sql server专用服务器。

3.如果不能分配,那么会分配的少一点,还是不能分配就会报错,服务无法启动。

注意:

内存size必须是连续的,并且在使用过程中buffer pool 不会自动增长。

使用large page导致开机时间变成,因为virtualalloc分配内存比较慢,并且时间不单单是分配内存的时间

总结

1.large page在内存>8gb,并有lock page权限

2.需要开启TF834,擦能让buffer pool使用large page

3.large page 并不适用所有场景应该测试后再决定

Come on 64bit so we can leave the mem….

本文大意:

作者在64BIT环境下看到一个错误,并且被问是否和MemToLeave有关。

作者解释了在64bit下并没有MemToLeave。

当32bit的年代,虚拟地址空间只有4个g,内核2g,用户2g,也可以通过4g选项调整为内核1g,用户3g,反正就是很少,设计者会为buffer pool保留地址,buffer pool有地址了,才不会影响内存的使用。buffer pool尽量大的保留地址空间了,但还是没有用完地址空间,因为有记下几个也需要用内存的:

1.线程stack,2.heap,3.SQL Server多页分配,4.其他DDL分配。

MemToLeave的意思就是留下来用来做别的事情,比如上面的,当服务启动的时候sql server 会先保留一部分地址空间,然后buffer pool保留地址空间,保留完之后,memtoleave释放地址空间。保留的地址的大小如下:线程堆栈大小*线程数+g参数的大小(默认256M)。

当64位来临,带来了大量的地址空间,所以没有必要在再服务启动时去保留地址空间,直接在需要用的时候分配就好了。

TechNet Magazine: October 2009 SQL Q&A column

本文大意:

1.sql server 2005启动的时候发现一致性检查信息,但是不管数据库大小,检查都很快,为什么?

其实这些并不是实际上的检查,只是把上次最后一次检查的信息输出出来。当dbcc checkdb运行完之后会写入到boot page 上。启动服务的检查只是把boot page的信息print出来。

2.如何确定内存被使用在那个数据库?

sql server会占用大量内存,并且在没必要的时候是不会释放啊内存,除非os有内存压力。sql server主要的内存都使用在buffer pool中,还有一部分是使用在plan cache中,内存多可以减少io,可以减少编译所占用的时间。可以通过sys.dm_os_buffer_descriptors是buffer pool的信息,来确定是那个数据库占用了内存。当然也可以使用 dbcc memorystatus 来确定实例内存的使用。

3.数据库偶尔会出现SUSPECT和RECOVERY_PENDING的情况,就会需要通过被备份恢复,会有数据丢失的问题,如何解决?

这2个状态都是由故障恢复的时候出现的,当crash 恢复,读不到日志的时候会出现RECOVERY_PENDING。当日志可读,但是日志可以访问,但是无法完成恢复,一致性不对的时候会出现SUSPECT。有2个原因会导致恢复无法完成,1.日志数据问题,2.数据文件有问题。

还有一个会进入SUSPECT状态就是,当事务回滚,在回滚时出现错误。

可以使用备份来恢复数据,如果没有备份可以转入应急模式,来恢复。

4.高安全的数据库镜像使用witness是如何识别错误的?

错误识别有一下几种:

1.sql server实例级crash,每秒ping,能ping通但是发现sql server没有监听端口,立即报告

2.服务器级别crash,每秒ping 不能ping通马上报告

3.事务磁盘问题,当日志写入的队列太高,香港虚拟主机,20秒后会写入到error log,服务器空间,40秒后认为log 磁盘offline,触发切换

4.数据库页出错,数据库会变成suspect状态,马上触发切换

5.如果文件或者文件组offline,primary正常,当碰到错误是切换。

Performance issues from wasted buffer pool memory

本文大意:

内存浪费是可耻,特别是对于数据库来说,内存不足有一下几个特点:

1.物理io变多,不管读还是写

2.Lazy write变多

3.RESOURCE_SEMAPHORE等待变多,因为查询需要内存

4.大量的plan重编译,因为没有地方放plan cache

低数据密度:

使用sys.dm_os_buffer_descriptors可以看,到底buffer pool 里面有多少是空的,也就是浪费的。

低数据密度引起的原因一般就怎么几个:

1.宽行,那么就使用小的数据类型

2.分页,合理设置填充因子

3.行删除,导致内部碎片

低数据密度也会有一下几个代价:

1.io变多,因为空间被浪费了

2.磁盘空间被浪费

3.内存被浪费

低数据密度解决办法:

1.小数据类型

2.使用顺序的key,不要用随机降低分页

3.调整填充因子,填充因子本身就是一种浪费,所以要合理不能太大

4.重建索引

5.数据压缩

作者各处了一些脚本,自己去原文看,个人觉得还是蛮有用的。

Database mirroring: avoiding ‘cannot obtain a LOCK resource’ problems

本文大意:

在镜像服务器出现不能获取LOCK资源,很有趣,镜像是不会动的,为什么会出现这个错误?

原因很简单,比如一个事务主体回顾的时候,镜像也回滚,会滚就会产生事务,不信自己试试看。