首先我们讲一个故事:
?
你是上帝视角【1】,你给了小明100个棒槌【2】,这个时候来了10个叫做小花的人,小花可以去仓库里拿面粉做包子,但是做一次包子,需要借用小明的棒槌,假如每一个小花都借用掉了10个棒槌,如果同时来了11个小花,前10个小花都能接到棒槌,第11个小花去找小明借棒槌的时候,小明就告诉她;“超出我的棒槌个数了,小花做包子失败。”—— 这句话翻译一下就是:“数据库服务器报错超出全局hashjoin空间,应用请求在数据库执行失败。”
?
但是呢,故事其实复杂一点,就是每一个小花,根据自己的工作量,需要的棒槌个数,并不一定需要10个,所以也就是说,只有来的所有小花把棒槌都借用完了之后,小明才会报错。但是小明也不是一直会报错,只要有任何一个小花,做完了,把借用的棒槌还回来了,小明就又可以支撑新的小花了。
?
上面这个故事,对应的就是这两个参数:
(来源:达梦数据库dba手册2.1.1中dm.ini的介绍)
小明一共有多少个棒槌,就是 HJ_BUF_GLOBAL_SIZE 设置的,默认值是500;
一个小花最多可以借多少个棒槌,就是HJ_BUF_SIZE设置的,默认值是50;
?
但是呢,其实小花如果要借用10个棒槌,实际上还有一个参数控制小明一次给小花多少个棒槌(比如小明要给小花10个棒槌,可以一次给1个给10次,也可以一次给5个给两次——这两种代价其实会不一样的)。一次给多少个,就是这个参数:
(来源:达梦数据库dba手册2.1.1中dm.ini的介绍)
?
好了,我们回到问题,如果遇到小明报错了怎么办呢?
?
【解决方法一】
很多情况下,小花其实是个傻子,就是实际上只需要1跟棒槌、一分钟内就干完的事情,结果她却用了10跟棒槌,一天死活都干不完,占用的这10根棒槌也一直没有还给小明。
换句话说就是要优化语句,消除掉这些傻小花。遇到这个问题的优先核心方法是:找出傻小花,让她变聪明——找到慢语句,优化掉。
?
【解决方法二】
1) 扩大小明的棒槌个数——改大HJ_BUF_GLOBAL_SIZE
2) 减小单个小花可以借用的棒槌上限——改小HJ_BUF_SIZ (有人会问,小花要10个棒槌,现在你给她设置成5个,她还能干活么?其实一定可以,哪怕你限制她最多只能借用1个,她也可以干活,只是同样的或要干的久一点而已——同样的,也不是越多越好,如果本身只需要5个,设置成10个,也没有意义。)
如果确认系统中,预期的sql均是符合预期的计划,效率均没有问题,确实需要高并发,就必须提高 HJ_BUF_GLOBAL_SIZE/HJ_BUF_SIZ的比值。同时,又由于前一个参数是静态参数(修改该参数后,需要重启数据库服务后才可以生效),所以应急策略(不能重启数据)的处理方式,仅仅只有【调小HJ_BUF_SIZ——这个参数是动态参数,修改后立即生效】。等有机会重启数据库服务时,再在重启数据库服务前,适当调大HJ_BUF_SIZ的同时,也保持较高的HJ_BUF_GLOBAL_SIZE/HJ_BUF_SIZ的值。
?
备注:
修改数据库参数的方式:
Sp_set_para_value(1,’参数名字’,参数值);--当成sql执行;对于动态参数,直接修改后,立即生效;如果是静态参数,如此修改,会报错:无法修改静态配置参数
Sp_set_para_value(2,’参数名字’,参数值);--当成sql执行;对于动态参数或者静态参数都可以用,修改后,需要重启数据库服务后才生效。
原文地址:https://blog.51cto.com/12196785/2470680