通常我们知道,DB2的package在统计信息或依赖对象发生变化后需要做下重新绑定,否则DB2优化器会采用效率较差或者错误的执行计划运行该package,造成执行性能严重下降或者SP一直会处于卡死状态。所以定期对SP进行重新绑定操作,对数据库整体性能和效率都有较大的提升,但是查一查,关于DB2的SP重新绑定,提供了三个命令:db2rbind、rebind和bind,很多人都分不清这三者区别,如何使用的问题,所以本文就重点对着三个命令用法进行分析。
其实三者都是提供SP重新绑定,不过传入参数不一样,bind需要带入.bnd的文件,缺陷情况下,C或嵌入式SQL编写的SP在precompile时,都会创建一个以.bnd的结尾的文件,数据库中使用程序包和应用程序编译的原因相同,即就是提高性能和压缩,在程序包构建过程而不是执行过程中,SP中的相关语法语义都得到分析,并且程序包中存储的是被解释效率更高的操作字符组,在服务器管理器调用预编译生生成的代码,只需要提供相应的输入变量就可以执行执行,提高了效率。并且预编译仅仅适用静态SQL,而不适合如prepare execute和execute immediate 动态SQL。这些动态SQL还是需要重新进行编译解释。db2提供绑定文件描述工具db2bfd工具可以查看bnd文件。其用法如下:
C:\Program Files (x86)\IBM\SQLLIB\bnd>db2bfd
Usage: db2bfd [ [-b] [-h] [-s] [-v] ] <filespec>
Where: <filespec> is at least a V7 bind file
Options: -b = display bind file header
-h = display this information
-s = display SQL statements
-v = display host variable declarations
C:\Program Files (x86)\IBM\SQLLIB\bnd>db2bfd -b db2sampl_SQL.bnd
db2sampl_SQL.bnd: Header Contents
Header Fields:
Field Value
----- -----
releaseNum 0x800
Endian 0x4c
numHvars 16
maxSect 14
numStmt 26
optInternalCnt 4
optCount 10
Name Value
------------------ -----
Isolation Level Cursor Stability
Creator "NULLID "
App Name "SQLE6H02"
Timestamp "AAAAABIU:2004/08/01 00:00:00:00"
Cnulreqd Yes
Sql Error No package
Block Block All
Validate Bind
Date Default/local
Time Default/local
*** All other options are using default settings as specified by the server ***
C:\Program Files (x86)\IBM\SQLLIB\bnd>db2bfd -s db2sampl_SQL.bnd
db2sampl_SQL.bnd: SQL Statements = 26
Line Sec Typ Var Len SQL statement text
---- --- --- --- --- ---------------------------------------------------------
55 0 5 0 21 BEGIN DECLARE SECTION
76 0 2 0 19 END DECLARE SECTION
275 0 14 0 32 WHENEVER SQLERROR GOTO ENDOFPROC
3366 1 9 1 26 EXECUTE IMMEDIATE :H00001
3416 2 0 1 40 VALUES CURRENT SQLID INTO :H00008
3418 3 0 1 32 SET CURRENT SQLID = :H00009
3437 4 0 1 34 SET CURRENT SQLID = :H00008
3459 5 0 1 40 VALUES CURRENT SQLID INTO :H00008
3461 6 0 1 32 SET CURRENT SQLID = :H00009
3547 7 11 1 24 PREPARE S1 FROM :H00001
3582 7 11 1 24 PREPARE S1 FROM :H00001
3598 8 0 1 34 SET CURRENT SQLID = :H00008
3616 0 5 0 21 BEGIN DECLARE SECTION
3619 0 2 0 19 END DECLARE SECTION
3652 7 9 4 56 EXECUTE S1 USING :H00004 , :H00015, :H00005, :H00006
3674 7 9 4 56 EXECUTE S1 USING :H00004 , :H00016, :H00005, :H00006
3720 9 0 1 41 VALUES CURRENT SCHEMA INTO :H00008
3774 10 0 1 33 SET CURRENT SCHEMA = :H00009
3977 11 11 1 32 PREPARE BLOBUPDATE FROM :H00001
4005 12 11 1 32 PREPARE CLOBUPDATE FROM :H00001
4248 13 0 1 86 SELECT NUM_DB_STORAGE_PATHS INTO :H00014 FR
OM TABLE(SNAP_GET_DB('', -1))
4416 14 0 1 35 SET CURRENT SCHEMA = :H00008
4475 11 9 3 58 EXECUTE BLOBUPDATE using :H00010 , :H00005, :H00012
4492 11 9 3 58 EXECUTE BLOBUPDATE using :H00010 , :H00005, :H00012
4551 12 9 3 59 EXECUTE CLOBUPDATE using :H00011 , :H00005, :H00013
4573 12 9 3 59 EXECUTE CLOBUPDATE using :H00011 , :H00005, :H00013
确切来说package都是用如C等嵌入式语言开发编译而来,所以在执行绑定操作,我们通常需要使用bind,因为bind命令需要传入bnd参数文件名称,如:
C:\Program Files (x86)\IBM\SQLLIB\bnd>db2 bind db2sampl_SQL.bnd
LINE MESSAGES FOR db2sampl_SQL.bnd
------ --------------------------------------------------------------------
SQL0061W The binder is in progress.
SQL0091N Binding was ended with "0" errors and "0" warnings.
就是将这个程序包和当前数据库绑定。当然还有其他参数,对于每个单独进行预编译的源代码模块,都将创建一个程序包。如果应用程序有 5 个源文件,其中 3 个需要进行预编译,那么将创建 3 个程序包或绑定文件。缺省情况下,为每个程序包指定的名称与 .bnd 文件所基于的源模块的名称相同,但此名称将被截断为 8 个字符。要以显式方式指定另一个程序包名,必须在 PREP 命令中使用 PACKAGE USING 选项。程序包的版本由 VERSION 预编译选项指定,并且缺省为空字符串。如果这个新创建的程序包的名称和模式与目标数据库中当前存在的某个程序包相同,但版本标识有所不同,那么将创建新程序包并保留先前的程序包。但是,如果存在与所绑定程序包的名称、模式和版本匹配的程序包,那么该程序包将被删除并替换为正在绑定的新程序包。如果绑定时指定了 ACTION ADD,那么将不允许发生这种情况,而是返回错误(SQL0719)。
如下都是一些系统默认的绑定文件名称,其实都是DB2提供的实用程序包的绑定文件,这些文件当然也是采用了C等嵌入式语言开发的SP。但大部分我们的程序包都是用SQL语言开发的SP,所以这个时候一般都是用rebind
C:\Program Files (x86)\IBM\SQLLIB\bnd>ls
ASNDONE.bnd asnmdata.bnd asntdiff.bnd db2advmisc.bnd db2dropv.bnd db2stats.bnd ddcsvm.lst
ASNLOAD.bnd asnmig4c.bnd asntdiff.lst db2advmqt.bnd db2dsproc.bnd db2uImpInsUpdate.bnd ddcsvse.lst
altobj_sp.bnd asnmig8.bnd asntdsql.bnd db2advsimulation.bnd db2evmon.bnd db2ubind.lst gseClAdv.bnd
altobj_util.bnd asnmoncs.lst asnuow.bnd db2advworkload.bnd db2exdyn.bnd db2ucktb.bnd gseClIdx.bnd
applycs.lst asnmonit.bnd bhunt.bnd db2ajgrt.bnd db2exfmt.bnd db2ueiwi.bnd gseClSQL.bnd
applyur.lst asnmonit.lst cAdmCancelWork.bnd db2am.bnd db2exmig.bnd db2uexpm.bnd hleoFwMine.bnd
asnaapp.bnd asnmonur.lst cAdmGetConfig.bnd db2arxcs.bnd db2expln.bnd db2ugtpi.bnd hleoFwPop.bnd
asnacmp.bnd asnmproc.bnd cAdmGetMessage.bnd db2arxnc.bnd db2exsrv.bnd db2uiDescribe.bnd mdcadvise.bnd
asnadmin.bnd asnmupdt.bnd cAdmGetPlanHint.bnd db2arxrr.bnd db2gpmap.bnd db2uiXmlparse.bnd mqlConfig.bnd
asnadmsp.bnd asnprune.bnd cAdmGetSystemInfo.bnd db2arxrs.bnd db2lk390.bnd db2uigsi.bnd mqlRun.bnd
asnafet.bnd asnqahkt.bnd cAdmSetConfig.bnd db2arxur.bnd db2lkfun.bnd db2uiici.bnd partadvise.bnd
asnaiso.bnd asnqapag.bnd cAdmSetPlanHint.bnd db2ats_sps.bnd db2lkmig.bnd db2uiict.bnd psmgtptp.bnd
asnaman.bnd asnqapp.bnd capture.lst db2cat.bnd db2lksp.bnd db2uimpm.bnd qapply.lst
asnanalyze.bnd asnqarow.bnd db2ExplainRtns.bnd db2cli.lst db2look.bnd db2uimtb.bnd qcapture.lst
asnappwk.bnd asnqasub.bnd db2_adminotm.bnd db2clipk.bnd db2move.bnd db2uipkg.bnd redistrb.bnd
asnaprs.bnd asnqbrwz.bnd db2_aram.bnd db2clist.bnd db2pctsp.bnd db2ulxld.bnd reval.bnd
asnawpn.bnd asnqload.bnd db2admDbUtil.bnd db2clpcs.bnd db2policy.bnd db2updv97.bnd sgSql.bnd
asnccpwk.bnd asnqmon.bnd db2admcs.bnd db2clpnc.bnd db2rbind.bnd db2uqtnm.bnd snaputil.bnd
asncdins.bnd asnqp2pa.bnd db2advcatalog.bnd db2clprr.bnd db2sampl_SQL.bnd db2uqtpd.bnd st_admin.bnd
asncmon.bnd asnqp2pi.bnd db2advindex.bnd db2clprs.bnd db2sampl_V8.bnd db2uredp.bnd tbscont.bnd
asndb2cn.bnd asnqspil.bnd db2advio.bnd db2clpsy.bnd db2sampl_XML.bnd db2xdbmig.bnd xdb.lst
asndb2sq.bnd asnreg.bnd db2advis.bnd db2clpur.bnd db2schema.bnd db2xdbsg.bnd xdbSPImpl.bnd
asndbcon.bnd asnsqlcd.bnd db2advisSP.bnd db2common.bnd db2spcat.bnd ddcs400.lst xdbSPutil.bnd
asnluwcon.bnd asntdapi.bnd db2advmdc.bnd db2dclgn.bnd db2spcdb.bnd ddcsmvs.lst xdbTupleWriter.bnd
其实工作中我们最常用的还是rebind命令,db2 rebind package packagename,不过该pakagename是存储在数据库中的P打头的数字名称,无法使用直接创建的名称,所以rebind前需要获取这个名称。一般可以这样获取:
db2 "select ' db2 rebind package '||rtrim(r.routineschema)||'.'||'P'||substr(char(r.lib_id+10000000),2) from syscat.routines r where r.routinetype = 'P'"
但其实不是所有的SP都有lib_id的,所以貌似这个不能绑定像上面的嵌入式程序包。
最后再说db2rbind,这个其实最简单,可以选择只绑定无效的程序包或者整库绑定,因而无法指定对个别SP进行绑定,当然在数据库刚恢复或升级了,就需要重新bind,否则无法使用新的包,并且还得使用replace参数才能完全覆盖之前的包中的信息,为了保证性能,可以这样做,后期的维护中大部分都不需要整库进行绑定,当对表的统计信息进行更新,创建索引,或者reorg操作了,就的需要对依赖的SP做一个rebind,以便于更新package中存储的解释执行信息。
默认这三个工具绑定的效果都是一样的,不同的是,各自有各自的参数,尤其是rebind和bind,绑定参数的使用有的时候直接对性能有很大的提升。
还有,现在DB2提供了一些管理例程工具就像这个专门做SP的重新绑定操作,只需要指定SP例程的类型和名称,当然也可以指定像rebind等指定的参数可选项,就可以对SP进行绑定了,如下:
CALL SYSPROC.REBIND_ROUTINE_PACKAGE ('P','SODS0.DP_INSRT_RT_VALID_SALES_ORD','')