none
数据表水平拆分之后出现18056和17189错误 RRS feed

  • 问题

  • 简单的说,某个论坛数据库中保存了接近2个亿的回帖数据,实在太臃肿了。所以小弟做了如下水平拆分:

    1.按主贴id进行拆分,每10万个主贴数据所对应的全部回帖保存在一张数据表中;
    2.根据步骤1中的划分规则,每10张数据表的数据放在一个单独的数据库中

    这样就将原来的数据划分成了100多张小表(12个数据库),并对应修改了论坛页面的数据调用SQL。正式上线之后观察了一下,白天访问量低的时候没有发现太多异常,但是当夜间访问高峰期到来的时候,论坛的流量下降了超过一半儿。查看了下数据库服务器在该时段的日志,发现这段时间主要的错误有两个。

    首先是下午接近7点的时候,服务器日志记录到了这么一个信息:“由于内存不足,将 AppDomain 2 (mssqlsystemresource.dbo[runtime].1)标记为要卸载。”

    之后马上开始出现错误日志。在上一条信息之后的12秒左右开始出现如下错误:“客户端无法重新使用 SPID 为 xxx 的会话,该会话已被重置用于连接池。失败 ID 为 xx。此错误可能是由于先前的操作失败引起的。请查看错误日志,了解紧位于此错误消息之前的失败操作。”,错误代码18056,一秒钟大概会报告20到30个这种错误,失败ID绝大部分是29,少部分是46。

    几分钟之后错误信息就变成了“SQL Server 无法生成线程来处理新的登录或连接,错误代码 0xc0000000。请查看 SQL Server 错误日志和 Windows 事件日志,获取有关可能发生的相关问题的信息。 [客户端: xxx.xxx.xxx.xxx] ”,错误代码17189,一秒钟也会报告20到30次,之前的18056错误就已经没有了。

    最后这个17189错误一直持续到凌晨1点左右访问高峰期过去之后,这令小弟困惑不已。难道真的是因为水平拆分之后服务器的内存不足导致的?

    运行环境为.NET Framework 3.5 + SQL SERVER 2008,不清楚是否打过SP1补丁。Web.Config文件中的连接字符串都启用了连接池,每个数据库允许最多600个连接(Pooling=true;Max Pool Size=600;Min Pool Size=1),不清楚这样做会不会导致数据库实例的连接数超出最大范围导致错误,不过拆分前的数据库也是这样配置的没有出现过错误。

    现在小弟暂时回滚了这次水平拆分操作,但是BOSS天天在询问这次拆分的进度,让小弟感到进退两难,目前的打算是将水平拆分之后的12个数据库都部署到另外的数据库上,但是小弟心里也没底不知道这样做是不是有效果,如果这样还是有问题小弟确实是没办法了。所以向各位求救。不知道各位高手没有接触过类似的情况,望不吝赐教。小弟不胜感激!

    2010年10月10日 13:33

全部回复

  • What's sql2k8 edition? Total db size? Amount of memory on the server? How much allocated to sql? Is it dedicated sql server? Sql2k8 sp2 is ready by the way.
    2010年10月10日 17:38
  • What's sql2k8 edition? Total db size? Amount of memory on the server? How much allocated to sql? Is it dedicated sql server? Sql2k8 sp2 is ready by the way.


    目前论坛的数据库保存在专门的服务器上,除了数据库之外没有其它应用;

    数据库是SQL SERVER 2008企业版,硬件上是Inter Xeon X5460 @3.16GHz,32G内存,数据库实例中配置的内存上线是2147483647MB。

    小弟也不清楚是不是安装SQL2K8 SP2补丁之后能解决这个问题,不敢贸然动手

    2010年10月11日 0:33
  • 楼主你们的web服务器应该不止一台吧?web.config中的 Pooling=true;Max Pool Size=600;Min Pool Size=1 是否有必要开600这么大呢?
    2010年10月11日 1:45
    版主
  • 另外内存的话建议配置下上限,譬如30G
    楼主的程序中如果有用到类似分布式查询、链接服务器、扩展存储过程、CLR等功能,请试试在SQL服务器的启动项里面加上-g参数来增大虚拟地址空间大小,默认是256M.
    2010年10月11日 1:53
    版主
  • Is it 64-bit machine with 64-bit sql2k8?
    2010年10月11日 2:23
  • 另外内存的话建议配置下上限,譬如30G
    楼主的程序中如果有用到类似分布式查询、链接服务器、扩展存储过程、CLR等功能,请试试在SQL服务器的启动项里面加上-g参数来增大虚拟地址空间大小,默认是256M.


    小弟查了一下目前服务器的配置,数据库实例中的内存设置为0至2147483647MB,看起来是已经允许数据库实例使用所有的内存了。现在小弟调整了一下WEB服务器中设置的连接池大小,只在最新的回复数据库中保留比较多的连接数,剩下的尽量缩小。不知道这样做能不能解决问题。

    如果还不行的话我再试试在启动项里增加-g参数的方法。非常感谢

    2010年10月12日 5:41
  • Is it 64-bit machine with 64-bit sql2k8?

    是的,64位操作系统安装了64位的SQL 2K8企业版
    2010年10月12日 5:42
  • I'll set max memory to 28gb in sql, leave 4gb for OS and other processes because you got out of memory error.
    2010年10月12日 13:20
  • 信息“由于内存不足,将 AppDomain 2 (mssqlsystemresource.dbo[runtime].1)标记为要卸载。”说明使用了CLR。可以试试楼上说的-g选项。

    另外,查查book online看看"max worker threads"是否够用。

    2010年10月19日 11:56