eosphoros-ai / DB-GPT

AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents
http://docs.dbgpt.cn
MIT License
13.4k stars 1.78k forks source link

更新了最新的DB-GPT后,默认知识库对话出现乱码 #67

Closed xuji755 closed 1 year ago

xuji755 commented 1 year ago

不断生成乱七八糟的数据,显卡内存暴增。重启llmserver和webserver后可以正常对话正常。

(base) root@dbaiops:~#

ERROR: Exception in ASGI application Traceback (most recent call last): File "/home/dbgpt/.local/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 435, in run_asgi result = await app( # type: ignore[func-returns-value] File "/home/dbgpt/.local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in call return await self.app(scope, receive, send) File "/home/dbgpt/.local/lib/python3.10/site-packages/fastapi/applications.py", line 276, in call await super().call(scope, receive, send) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/applications.py", line 122, in call await self.middleware_stack(scope, receive, send) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in call raise exc File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in call await self.app(scope, receive, _send) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in call raise exc File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in call await self.app(scope, receive, sender) File "/home/dbgpt/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in call raise e File "/home/dbgpt/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in call await self.app(scope, receive, send) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/routing.py", line 718, in call await route.handle(scope, receive, send) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle await self.app(scope, receive, send) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/routing.py", line 69, in app await response(scope, receive, send) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/responses.py", line 270, in call async with anyio.create_task_group() as task_group: File "/home/dbgpt/.local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 662, in aexit raise exceptions[0] File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/responses.py", line 273, in wrap await func() File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/responses.py", line 262, in stream_response async for chunk in self.body_iterator: File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/concurrency.py", line 63, in iterate_in_threadpool yield await anyio.to_thread.run_sync(_next, iterator) File "/home/dbgpt/.local/lib/python3.10/site-packages/anyio/to_thread.py", line 31, in run_sync return await get_asynclib().run_sync_in_worker_thread( File "/home/dbgpt/.local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread return await future File "/home/dbgpt/.local/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 867, in run result = context.run(func, args) File "/home/dbgpt/.local/lib/python3.10/site-packages/starlette/concurrency.py", line 53, in _next return next(iterator) File "/home/dbgpt/DB-GPT-main/pilot/server/llmserver.py", line 66, in generate_stream_gate for output in generate_stream( File "/home/dbgpt/.local/lib/python3.10/site-packages/torch/utils/_contextlib.py", line 35, in generator_context response = gen.send(None) File "/home/dbgpt/DB-GPT-main/pilot/model/inference.py", line 25, in generate_stream out = model( File "/home/dbgpt/.local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(args, kwargs) File "/home/dbgpt/.local/lib/python3.10/site-packages/transformers/models/llama/modeling_llama.py", line 687, in forward outputs = self.model( File "/home/dbgpt/.local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(*args, *kwargs) File "/home/dbgpt/.local/lib/python3.10/site-packages/transformers/models/llama/modeling_llama.py", line 577, in forward layer_outputs = decoder_layer( File "/home/dbgpt/.local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(args, kwargs) File "/home/dbgpt/.local/lib/python3.10/site-packages/transformers/models/llama/modeling_llama.py", line 292, in forward hidden_states, self_attn_weights, present_key_value = self.self_attn( File "/home/dbgpt/.local/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl return forward_call(*args, **kwargs) File "/home/dbgpt/.local/lib/python3.10/site-packages/transformers/models/llama/modeling_llama.py", line 231, in forward attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype) File "/home/dbgpt/.local/lib/python3.10/site-packages/torch/nn/functional.py", line 1845, in softmax ret = input.softmax(dim, dtype=dtype) torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 1.79 GiB (GPU 0; 23.69 GiB total capacity; 15.44 GiB already allocated; 1.73 GiB free; 19.52 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

(base) root@dbaiops:~# nvidia-smi Fri May 19 10:02:02 2023
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.105.17 Driver Version: 525.105.17 CUDA Version: 12.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA GeForce ... Off | 00000000:01:00.0 On | N/A | | 63% 44C P8 28W / 370W | 22491MiB / 24576MiB | 1% Default | | | | N/A | +-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 1101 G /usr/lib/xorg/Xorg 85MiB | | 0 N/A N/A 5442 C python3 21006MiB | | 0 N/A N/A 5583 C python3 1396MiB | +-----------------------------------------------------------------------------+ (base) root@dbaiops:~#

csunny commented 1 year ago

默认知识库是你这边自己的文件吗? 文件格式跟大小可以提供不?

xuji755 commented 1 year ago

文件就是普通的TXT格式,大小100多K,我随便找了个以前的老文档测试了一下,下面是整个文档的内容:

1数据库设计规范 1.1.对象命名规范 【规则-1】:Oracle数据库对象的名字由字母、数字和一些连接符组成。 1、多个单词之间用连接符分开,连接符用“_”字符,不建议使用其他的字符; 2、例如:存储过程:sp_create_accbak_table 【规则-2】:Oracle数据库对象的名字长度不超过30个字符。 1、如果超过30个字符,可以缩写,但一定要采用标准的缩写,常用标准缩写见附件。如果表或者是字段的名称仅有一个单词,那么建议不使用缩写,而是用完整的单词; 2、例如: 表:ATP_PARA_CFG 【规则-3】:在创建数据库对象时,不要使用引号。 1、说明:Oracle数据库自动转换为大写字符;避免使用系统保留字作为数据库对象的名称。 2、例:建存储过程SP_SET_PROCESS_STATUS时写法 正确写法:CREATE OR REPLACE PROCEDURE sp_set_process_status … … end sp_set_process_status; 错误写法:CREATE OR REPLACE PROCEDURE “sp_set_process_status” … … end sp_set_process_status; 1.1.1.表命名规范 表的命名遵循数据库对象命名的一般规则。 【规则-1】:要求表的命名尽量采用标准的翻译,能准确地表达该表的中文含义,能根据英文猜测到表的用途。 1、例如:gsm_user 用户资料表、user_imei 用户IMEI信息、hlr_operation_succ HLR成功工单表; 【规则-2】对于一些特定作用的表,除了遵循普通表命名规范外,增加特定后缀表示。 1、例如:hlr_operation_succ。 2、多种类型的组合遵循先作用,后时间的原则, 3、例如:配置历史表表示为XXX_cfg_his。 【规则-3】:配置表:一般用于存放业务、系统的配置信息,须以“_cfg”结尾, 1、例如:send_process_cfg。 【规则-4】:工单表,一般分为成功表、失败表;成功表以“_succ”后缀表示;失败表以“_fail”后缀表示。 1、例如:hlr_operation_succ,hlr_operation_fail。 【规则-5】:历史表用于保留历史记录,以“_his”结尾。 1、例如:imei_info_his、user_productinfo his。 2、严禁以bak、back、backup等命名历史表。 【规则-7】:中间表以“_interim”作为后缀。 1、说明:中间表又称过渡表,是指为了产生某个结果,需要先计算出中间结果,根据中间结果进一步计算而得出需要的结果,存放中间结果的表称为中间表,有些系统也通俗地称为临时表。 2、例如:CUSTCARE用户下的表CONTACT_INFO_INTERIM 【规则-8】:禁止用_srl、_seq等作为表名后缀,流水表、日志表,用_log作为后缀。 1、例如:CUSTCARE用户下的“外部系统操作日志表” OUTERSYS_OPERATION_LOG。 【规则-9】:表名必须要能够反映表中存放数据的意思。 1、例如:gsm_user,就是GSM用户; 【规则-10】:资源表名的命名,用_resource作为后缀。 1、例如:CUSTCARE 用户的“号码资源表”NUMBER_RESOURCE。 【规则-11】:工单表的命名:_operation作为后缀; 1、CUSTCARE 用户的“宽带工单表” INTERNET_OPERATION。 【规则-12】:和用户资料相关的表,一律用user_作为前缀。 1、例如:user_smscall、user_service_opt、user_package等;

1.1.2.字段命名规范 字段命名遵循数据库对象命名的一般规则,常见字段命名及缩写见附录常见字段列表。 【规则-1】:字段的命名由英文单词(或缩写)和下划线“_”组成,多个单词之间用下划线分开。 1、例:user_id、package_code等。 【规则-2】:要求字段名能表达字段的含义。 1、例如:Fail(Fail): 失败记录表 History( His):历史 Identity(ID):ID号 【规则-3】:字段长度,根据业务需要定义字典长度,对字符型字段,尽量用varchar2类型,不要用char、varchar类型。 【规则-4】:如果相同字段在不同的表中出现,尽量使用相同的命名,且必须保证他们的类型和长度是相同的。 1、例如:gsm_user的字段gsm_user_id,和表user_package的字段user_id,长度和类型一致。 1.1.3.索引命名规范 【规则-1】:IDX_表名缩写_字段名缩写。 1、例如: CLERK_OPERATING_DETAIL表CHECKOUT_SRL列上的索引命名:IDX_COD_CHECKOUT_SRL。 【规则-2】:如果是复合索引,字段名缩写至少要包含复合索引的头两个字段名的缩写。 1、例如: CLERK_OPERATING_DETAIL表(OPERATOR_ID,CHECKOUT_SRL)列上的复合索引命名为:IDX_COD_OPID_CHKSRL; 【规则-3】:如果是主键索引,以“PKX”为索引前缀。 1、例如: CLERK_OPERATING_DETAIL表(OPERATING_SRL,CODE_COUNTY)上的主键索引命名为:PKX_COD_OPSRL_CODECTY。 【规则-4】:给表增加主键时要显式指定约束的名字,并且要指定using index tablespace 参数。 1、例如:alter table CLERK_OPERATING_DETAIL add constraint PKX_COD_OPSRL_CODECTY --主键约束名,也是索引名 primary key (OPERATING_SRL, CODE_COUNTY) using index tablespace …; 不能写成 alter table CLERK_OPERATING_DETAIL add primary key (OPERATING_SRL, CODE_COUNTY); 2、如果不显式指定约束名系统将随机分配一个约束名字(同时也是主键索引的名字),导致四个库的名字不一样。 3、如果不指定using index tablespace 参数,否则索引会建在该用户默认的表空间上,不利于数据库性能和系统维护。

1.1.4.分区命名规范 1、使用分区表的优点: 增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用; 维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可; 均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能; 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。 2、分区命名分为两种:循环利用的分区和按月份分区 【规则-1】:循环利用的分区命名:表名各单词第一个字母的缩写_P<两位数值> 1、例如: BILL_ADJUST_SEQ 表的分区名为:BAS_P01~BAS_P13 【规则-2】:循环利用的分区如果一个月有多个分区,可以再加两位数值以区分。 1、例如: PREPAY_DETAIL_BILL_ITEM表的分区名为: PDBI_P0101~PDBI_P0105, PDBI_P0201~PDBI_P0205, … , PDBI_P1301~PDBI_P1305 其中: PDBI,P是分区(Partition),DBI是表简称; P0101,0101是指1月份的第一个分区; 【规则-3】:按月份分区的分区分区命名:表名各单词第一个字母的缩写_P(年月) 1、例如:CLERK_OPERATING_DETAIL表分区名为: COD_P0507~CODP0512; 注:COD是表的简称,0507是指2005年7月的分区。 【规则-4】:为避免数据库的bug等问题,不建议使用复合分区。 1、说明:复合分区是在分区中使用分区的方法。 1.1.5.视图/物化视图命名规范 【规则-1】:视图的命名规范遵循普通表的命名规范,并在视图前加上“v”前缀,表示是视图。 1、例如:v_cardinfo。 【规则-2】:开放给地市的视图,要求保留源表名,并在视图的末尾加上地市的缩写以区分。 1、例如:v_zone_mvalue_his_nt、v_vpmn_operation_succ_tz。 【规则-3】:物化视图命名规则:MV_源表名_源数据库。 1、例如:mv_gsm_user_11, mv_gsm_user_21, mv_gsm_user_41,分别表示从zwdb1,zwdb2和zwdb4复制过来的gsm_user表的数据。 【规则-4】:部分物化视图由于程序统一接入的原因,可以与原表名相同。 1、例如:sysmgmt.operator,sysmgmt.password。 1.1.6.触发器/函数/存储过程命名规范 【规则-1】:触发器的命名规则:trg表名<ins/upd/del>。 1、说明:其中表名为触发源表名,ins/upd/del表示insert/update/delete触发器。 2、例如:trg_msn_member_del,触发器的含义为: create or replace trigger ti_msn_member_del before delete on msnmember for each row declare … … begin end 【规则-2】:存储过程的命名以“sp”打头。 1、说明:其他规范遵循普通表的命名规范,要求名字能表达存储过程的用途。 2、例如:sp_pre_score_modify、sp_create_scpoperation。 【规则-3】:函数的命名以“fn”打头。 1、说明:其他规范遵循普通表的命名规范,要求名字能表达函数的用途。 2、例如:fn_get_packname、fn_check_brand_package。

1.1.7.约束关系设计原则 【规则-1】:尽可能为每张表设计主键。 【规则-2】:主键和唯一性约束关系必须为其创建索引 【规则-3】:外键约束关系尽可能在应用系统中实现,以减少数据库的负担 【规则-4】:存在外键约束关系的情况下,需要为外键创建索引,以避免约束检查时产生大量全表扫描,引起性能问题 【规则-5】:优化业务逻辑,尽可能避免在不同的SCHMEA之间创建外键等约束关系 1.2.数据库编程规范 1.2.1书写规范 【规则-1】:所有代码统一使用小写字母书写。 1、例如: create or replace procedure sp_check_package( i_package_code number, i_user_id number, o_flag out number ) is begin o_flag := 0; end sp_checkpackage; / 【规则-2】:确保变量和参数在类型和长度上与表数据列类型和长度相匹配。 1、说明:如果与表数据列宽度不匹配,则当较宽或较大的数据传进来时会产生运行异常。 【规则-3】:参数和变量的命名符合如下规范: 1、传入参数以“i”为前缀; 2、传出参数以“o”为前缀; 3、变量以“v”为前缀 4、例如: create or replace procedure SP_GET_GLOBAL(i_operator_id in number, i_session_id in number, o_flag out number) is v_cityID varchar(2); v_region_level number(1); begin …. end; 【规则-4】:程序块中的begin、end独立成行。 【规则-5】:程序块采用缩进风格书写,保证代码清晰易读,风格一致,缩进格数统一。 1、例如: … … begin update CFG_CDR_REFRESH set CHANGE_TIME=sysdate where CFG_TYPE=5; if sql%rowcount = 0 then insert into CFG_CDR_REFRESH(CFG_TYPE,CHANGE_TIME,STATE) values(5,sysdate,0); end if; end trg_CFG_CITY_HOST_QRY_ALL; 【规则-6】:不允许把多个语句写在一行中,即一行只写一条语句。 【规则-7】:同一条语句占用多于一行时,每行的第一个关键字应当左对齐, 1、例如: select * into v_gsm_user from gsm_user where msisdn = to_number(trim(i_phone_number)) and user_city = i_city_id; 【规则-8】:对于 Insert … values 和 update 语句,一行写一个字段,字段后面紧跟注释(注释语句左对齐),values 和 insert 左对齐,左括号和右括号与 insert、values 左对齐 1、例如: insert into table_name ( user_id,    --用户 ID,主键 user_name,   --用户名 login_name   --登录名 ) values ( v_user_id, v_user_name, v_login_name ) 【规则-9】:相对独立的程序块之间需加空行。 1、例如: --判断套餐是否可增加成员并获得专网标志 begin select use_date, decode(package_type, 1000, 1, 0) … … exception end;

--如果为手机号码 if i_number_type = 0 then begin … … end; 【规则-10】:超过110列的语句要分行书写,长表达式应在低优先级操作符处换行,操作符或关键字放在新行之首。 1、例如: v_exchangeable_score := (v_score_phone_score + v_score_bounty_score + v_score_gift_score - v_score_alr_excg_score)

【规则-11】:从表中同一笔记录中获取记录的字段值,须使用同一SQL语句得到。 1、例如: select state,brand_id into v_state,v_brand from gsm_user where gsm_user_id=s_user_id; 1.2.2注释规范 【规则-1】:所有变量定义都要加上注释,说明变量的用途及含义。 1、例如: create or replace procedure sp_sms_zone as … … v_city number(2); --监控信息变量 v_db number(2); --数据库代码 v_Total number(10) :=0; --发送总数 v_Succ number(10) :=0; --成功数 v_Fail number(10) :=0; --没有发送数 v_Srl number(10) ; --记录流水 o_flag number; --调用sp_send_query_sms返回的标识 … … end sp_sms_zone; / 【规则-2】:注释内容要清晰、明了,含义准确,防止注释二义性。 1、例如: 正确: ret_code out integer,--返回代码(0 成功 ,其它:错误,参见:错误代码定义); 错误: ret_code out integer,--返回代码 【规则-3】:对存储过程的任何修改,都需要在注释最后添加修改人、修改日期及修改原因等信息。 1、例如: /* 修改原因:修改积分兑换和积分转赠 修改人:
修改时间:2006-01-05
/ 【规则-4】:对程序分支必须书写注释。 1、例如: --如果为手机号码 if i_number_type = 0 then begin … … end; 【规则-5】:在代码的功能、意图层次上进行注释,帮助维护人员理解代码。 1、例如: case rdm_type1 when 1 then --积分奖励 ... ... when 2 then --扣减(停用) ... ... when 3 then --积分兑换 ... ... end case; 【规则-6】:代码注释应放在描述的代码上方或右方相近位置,不可放在下面。 1、例如: --查询转出用户的积分信息 SP_SCORE_QUERY( s_user_id, --用户id rdm_city_id, --地市id … … ) 【规则-7】:注释与所描述的内容进行同样的缩排。 1、例如: --未达到可兑换标准 if v_score_change_flag=0 then --对于兑换类型为961的,取消1000分门限的限制。 if rdm_type2 = 961 or rdm_type2 = 962 then end if; end if; 【规则-8】:函数应对返回的代码进行详细描述。 1、例如: create or replace function fn_check_brand_package( i_package number, i_user_id number, i_brand_id number := 0, i_pay_mode number := 0
) return number is Result number(1):=0; --0表示没有限制 ,其他表示有品牌限制 … … end fn_check_brand_package; 【规则-9】:在程序块的结束行右方加注释,以表示程序块结束。 1、例如: --未达到可兑换标准 if v_score_change_flag=0 then … … end if;--未达到可兑换标准处理结束 【规则-10】:统一文件头的注释。 1、例如: create or replace procedure sysmgmt.sp_encrypt3 ( i_pwd in varchar2, o_new_pwd out varchar2, o_flag out number ) is
/**
功能描述:密码加密脚本,本存储过程用于把指定的明文密码转化为密文 参数描述:pwd:输入明文密码, new_pwd:输出的密文, o_flag:输出结果的状态(0:right,1:error) 修改历史: 2005-12-28 ,修改加密方式为密钥方式; 2005-05-16 ,修改加密算法; 2005-01-01 *,创建脚本; **/ bl1 varchar(1); bl2 varchar(1); BEGIN … … end;

1.2.3语法规范 【规则-1】:存储过程的In、out参数应按类别分开书写,不要交叉。 1、例如: create or replace procedure sp_create_scp( i_gsm_user_id number, --用户号码 i_order_code number, --命令代码 i_operation_type number, --工单类型 i_operating_srl number, --操作流水 o_operation_srl out number, --工单流水(返回参数) o_flag out number , --成功 0 ,失败 1 o_msg out varchar2 ) begin end; 【规则-2】:存储过程中变量的声明应集中在is和begin关键字之间申明。 1、例如 create or replace procedure sp_create_scp( … … ) is … … v_user gsm_user%rowtype; --用户信息 v_value varchar2(30); nCnt number(5):=0; nPriority number(2):=0; begin … … end; 【规则-3】:尽可能使用相关表字段类型来定义相关的变量,如%type,%rowtype。 1、说明:一般变量,都可能会用于表的查询条件,或增加记录的值;当字段数据类型发生变更时,对应的变量无需修改; 1、例如: … v_user gsm_user%rowtype; --用户信息 select from gsm_user where gsm_user_id = v_user; … 当gsm_usre_id的类型变成字符型时,该段代码无需修改。 【规则-4】:确保所有的变量和参数都用到,没有用到的变量和参数要删除。 【规则-5】:存储过程有多个分支返回时,若有事务控制,需确保各个分支都结束事务。 1、异常时,应该在Exception中捕捉异常,并进行事务处理。 【规则-6】:存储过程:不要在异常部分,进行正常的业务处理。 1、说明:从程序的易读性、易维护性考虑,不要在异常处理部分,包含正常的业务处理部分。 2、例:(不好的写法) … exception When no_data_found then --没有找到记录,则重新查找其他数据 Select from …. End; 【规则-7】:原则上不要使用动态 sql,如果必须使用,需绑定变量, 1、绑定变量写法: QUERY_STRING :='select pr_template from bssp.bssp_process_template where process_id=:ora_process_id for update'; … … EXECUTE IMMEDIATE QUERY_STRING INTO LOB USING 38880003; 【规则-8】:代码中的异常捕获返回结果,要加上Oracle的异常sqlerrm(Oracle的一个session级的全局变量)。 1、例如: exception when others then rollback; oResult :=1; oMsg := 'others'||substr(sqlerrm,200); end; 【规则-10】:捕捉到异常后需要rollback回滚事务。 1、例如: exception when others then rollback; oResult :=1; oMsg := 'others'||sqlerrm; end; 1.2.4SQL性能规范 【规则-1】:批量操作,避免频繁使用commit。 1、说明:频繁的COMMIT会导致物理I/O增大,同时会产生log file sync等待,但长时间不提交将带来更多的性能问题。建议小于3秒的事务可以一次提交,大于3秒的操作尽可能3秒左右提交一次。实际应用中使用COMMIT时必须保证事务的完整性。 【规则-2】:在Java和C++开发中,避免动态SQL,要使用绑定变量方式。 1、说明: 为了不重复解析相同的SQL语句,在第一次解析之后,ORACLE将SQL语句缓存在内存中,当你执行一个SQL语句时,如果它和之前的执行过的语句完全相同,ORACLE就能很快获得内存中相同语句的执行计划,然后就直接执行该语句,而不需要进行解析。 如果没有使用绑定变量,虽然语句结构相同,但因传入的变量不一样导致语句不相同,ORACLE还是需要对每条结构相同的语句重新解析一遍,同时在内存中缓存该语句,导致共享池中存放了N条结构相同的语句,达不到共享的目的,又浪费了大量的内存空间,如果语句执行的太频繁,会导致数据库无法申请共享内存而出错。 2、Java代码示例: A、未使用绑定变量: ... try{ String sSql = "select from my_table where field=1"; pStmt = connection.prepareStatement(sSql); pstmt.executeUpdate(); //执行动态SQL语句 ... } B、使用绑定变量: ... try{ String sSql = "select from my_table where field=?"; pStmt = connection.prepareStatement(sSql); pstmt.setString(1, sCode); //sCode为传入变量 pstmt.executeUpdate(); //执行动态SQL语句 ... } 3、 C/C++代码示例 A、未使用绑定变量: //处理传入的参数,构造动态SQL语句 sprintf(sztmp1, "SELECT \ TO_CHAR(apply_date, 'yyyymmddhh24miss'), \ … … FROM user_smscall \ WHERE \ (gsm_user_id = '%s' ) ", ora_gsm_user_id);

EXEC SQL PREPARE sql FROM :sqlstmt;  //Prepare

//定义游标

EXEC SQL declare user_smscall_cu_1 cursor for sql; EXEC SQL open user_smscall_cu_1; B、使用绑定变量: //处理传入的参数,构造动态SQL语句 sprintf(sztmp1, "SELECT \ TO_CHAR(apply_date, 'yyyymmddhh24miss'), \ … … FROM user_smscall \ WHERE \ (gsm_user_id = :v1 ) ");

EXEC SQL PREPARE sql FROM :sqlstmt;  //Prepare

//定义游标
EXEC SQL declare user_smscall_cu_1 cursor for sql;
EXEC SQL OPEN user_smscall_cu_1 USING :ora_gsm_user_id;

【规则-3】:没有业务上的需求,避免不必要的排序。 1、说明:对查询结果进行排序会大大的降低系统的性能。 【规则-4】:SQL语句中,用WHERE子句替换HAVING子句。 1、例如: SELECT NAME,SUM(AGE)
FROM EMPLOYEE
GROUP BY NAME HAVING NAME!=‘ABC’ 比语句 SELECT NAME,SUM(AGE)
FROM EMPLOYEE
WHERE NAME!=‘ABC’ GROUP BY NAME
性能要差。 【规则-5】:SQL语句中:用>=替代>。 1、说明:如果在ID列上建有索引,则语句SELECT FROM EMPLOYEE WHERE ID >= 9 要比语句SELECT FROM EMPLOYEE WHERE ID > 8高效。这是由于前者DBMS将直接跳到第一个ID等于9的记录而后者将首先定位到8的记录并且向前扫描到第一个DEPT大于9的记录。 【规则-6】:删除表中所有记录时用TRUNCATE替代DELETE。 1、说明:当删除表中的记录时,在通常情况下,回滚段用来存放可以被恢复的信息,如果你没有COMMIT事务,ORACLE可以将数据恢复到删除之前的状态;而当运用TRUNCATE时,回滚段不存放任何可被用于恢复的信息,当命令运行后,数据不能被恢复,因此很少的资源被调用,执行时间也会很短,空间立即释放,detele操作后的空间可以被重新利用,但不会释放。 【规则-7】:用UNION-ALL 代替UNION。 1、说明:UNION-ALL不过虑重复记录,UNION 过滤重复记录,所以需要先排序。如果不需要过滤重复的记录,UNION-ALL 比UNION 性能更好。 【规则-8】:用(NOT) EXISTS替代(NOT) IN。 1、说明:在许多基于驱动表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用EXISTS(或NOT EXISTS)通常将提高查询的效率。 2、例如: SELECT FROM EMP WHERE EMPNO > 0 AND DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOC = 'MELB') 高效: SELECT FROM EMP WHERE EMPNO > 0 AND EXISTS (SELECT 'X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 'MELB') 【规则-9】:使用DECODE函数来减少处理时间。 1、说明:使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。 2、例如: SELECT NAME||‘UNDER AGE’FROM EMPLOYEE WHERE AGE<18
UNION SELECT NAME||‘OVER AGE’FROM EMPLOYEE WHERE AGE>=18 可以改成: SELECT DECODE(SIGN(AGE-18),-1,NAME||‘UNDERAGE’,1,NAME||‘OVERAGE’) FROM EMPLOYEE 【规则-10】:使用表的别名(Alias)。 1、说明:当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上。 A、使用表的别名可以减少解析的时间 B、使用表的别名可以减少那些由Column歧义引起的语法错误。 2、例如: 正确: select a.user_id, a.bill_month, a.detail_bill_item_def_id from account.spec_detail_bill_item a, account.detail_bill_item_def b where a.bill_month_number = :b0 and to_number(:b1) <= a.user_id and a.user_id <= to_number(:b2) and a.bill_month = :b3 and a.status = :b4 and a.detail_bill_item_def_id = b.detail_bill_item_def_id 错误: select user_id, bill_month, detail_bill_item_def_id from account.spec_detail_bill_item a, account.detail_bill_item_def b where a.bill_month_number = :b0 and to_number(:b1) <= user_id and user_id <= to_number(:b2) and bill_month = :b3 and status = :b4 and detail_bill_item_def_id = detail_bill_item_def_id 第二个语句oracle要用数据字典解析表的列,并且两个表中都有detail_bill_item_def_id列,oracle会报错ora-00918:column ambiguously defined。 【规则-11】:尽量用ROWID进行表访问。 1、如以下语句就是非常高效的删除重复记录的方法: DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO); 2、在批量操作中,能够更加充分利用Rowid,例: //取HLR工单数据 Select a.,rowid from hlr_operation where 条件; For loop //处理 …. //处理成功后删除工单 Delete from hlr_operation where rowid = v.rowid; End loop; 【规则-12】:SQL语句中,尽量减少对表的查询次数。 1、说明在含有子查询的SQL语句中,要特别注意减少对表的查询。 2、例如:如以下语句低效 UPDATE EMP SET EMP_CAT =(SELECT MAX(CTEGORY) FROM EMP_CATEGORIES), SAL_RANGE =(SELECT MAX(SAL_RANGE)FROM EMP_CATEGORIES) WHERE EMP_DEPT=’0020’ 而下面这条语句高效: UPDATE EMP SET EMP_CAT, SAL_RANGE = (SELECT MAX(CATEGORY),MAX(SAL_RANGE) FROM EMP_CATEGORIES) WHERE EMP_DEPT = ‘0020’ 【规则-13】:用表连接替换EXISTS。 1、说明:通常来说 , 采用表连接的方式比EXISTS更有效率 2、例如:低效语句如下, SELECT ENAME FROM EMP E WHERE EXISTS (SELECT 'X' FROM DEPT WHERE DEPT_NO = E.DEPT_NO AND DEPT_CAT = 'A'); 高效: SELECT ENAME FROM DEPT D, EMP E WHERE E.DEPT_NO = D.DEPT_NO AND DEPT_CAT = 'A'; 【规则-14】:避免使用DISTINCT,可以用EXISTS替换DISTINCT。 1、说明:当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换 2、例如:低效 SELECT DISTINCT DEPT_NO, DEPT_NAME FROM DEPT D, EMP E WHERE D.DEPT_NO = E.DEPT_NO 高效: SELECT DEPT_NO, DEPT_NAME FROM DEPT D WHERE EXISTS (SELECT 'X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO); EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。 【规则-15】:避免使用耗费资源的操作 1、说明:带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY,GROUP BY的SQL语句会启动SQL引擎执行耗费资源的排序(SORT)功能,如果可能,应尽量避免使用或改写。 【规则-16】:对于大表查询结果超过10%的语句,要用全表扫描代替索引扫描。 1、例如: select nvl(sum(1),0) cam_count,nvl(sum(cam_amount-real_amount)/1000,0) cam_amount from cam.cam_data a where (cam_amount-real_amount) >= 0 and (cam_amount-real_amount) <= 50000 2、大部分数据都满足条件,这时可以hint /+full(a)/使用全表扫描。 【规则-17】:使用hint提示强制使用合适索引。 1、例如:select /+ index(mms_cdr IDX_MMS_USERID)/ FROM mms_cdr WHERE (month_number >= 6 and month_number <= 7) AND user_id = to_number('1419200000741621') AND send_time >= '20070101000000' AND send_time <= '20070104235959' ORDER BY send_time; 2、像这种单个user_id的语句肯定要索引查找更快,而不能使用全表扫描而且在user_id和send_time列上均有索引的情况下使用user_id列上的索引更高效,因为user_id列上的索引选择性更高。 3、由于统计信息不全,优化器可能选择使用全表扫描或者走send_time列上的索引导致执行计划不是最优的,此时可以使用强制索引来解决。 【规则-18】:避免对索引列使用数据库函数、计算表达式等等。 1、说明:对查询索引列使用数据库函数、计算表达式会造成对全表扫描。 2、例如: select t.reserver1, count() cout from custcare.password_login_fail t where t.operating_source = 1 and to_char(t.login_time,'yyyymmdd') between 20080904 and 20080918 group by t.reserver1 having count() > 30 custcare.password_login_fail表的login_time列上建了索引,上面语句to_char函数会造成使用不上索引,把 and to_char(t.login_time,'yyyymmdd') between 20080904 and 20080918 修改成: and t.login_time between to_date('20080904','yyyymmdd') and to_date('20080918','yyyymmdd')就可以使用上索引了。 3、查询时尽可能将操作移至等式的右边,甚至去掉函数。 【规则-19】:在查询条件中,避免不必要的类型转换。 1、说明:字符类型列赋予数值型数据时会使用隐含类型转换,而数值型列赋予字符型数据时不会隐含类型转换,而是将右边值转换为数值类型。 2、例如: 例1:select from atp_para_cfg where cfg_type=35 cfg_type是字符型列,上面语句会造成隐含类型转换to_number(cfg_type)=35,即Oracle内部会做一次类型转换。 例2:select …
from number_resource n, prematch_simcard p where n.msisdn = p.msisdn(+) and n.msisdn >= ‘13951681450‘ 这些字段都是number型,不用加单引号 and n.msisdn <= '13951681480' and n.city_id = '14‘ 这些字段都是number型,不用加单引号 and (n.county_id = '99' or 99 = '99') and (n.site_id = '0' or 0 = '0') and (n.state = '0' or 0 = '0') 【规则-20】:字段上有索引,但是字段和“NULL值”比较,也不会使用到索引。 1、说明:使用NULL作为条件将不会使用索引。 2、例如:以下语句用不到索引(address有索引): select
from staff_member where address is null;(或not null) 【规则-21】:在索引列上使用<>(!=)和 like和not 将不会使用索引。 1、例如:select from staff_member where dept_no<>2001; select from staff_member where first_name like ‘%DON’; 注1: select from staff_member where first_name like ‘DON%’; 当前面没有%时,将使用索引,ORACLE内部转换为范围操作 【规则-22】:OR不能使用索引,可以用UNION (ALL)替换OR。 1、例如:select from zone_mvalue_modi_srl where is_valid = 1 and (user_id = :b0 or dest_user_id = :b0) 即使user_id和dest_user_id上都有索引,可能都不会被使用 可以改成: select from zone_mvalue_modi_srl where is_valid = 1 and user_id = :b0 union all select from zone_mvalue_modi_srl where is_valid = 1 and dest_user_id = :b0 1.2.5创建索引原则 索引是一种特殊的表,存放索引键值和ROWID,用来提高检索表数据的效率。通过索引查找数据时先通过关键字的值找到对应的索引条目,然后根据ROWID来快速的定位表的记录,所以通过索引查找时有额外的I/O操作,如果要检索的字段已经包含在索引字段中,则不需要再通过ROWID到表中找出对应行的数据,减少I/O量。 通常通过索引查询数据比全表扫描要快,但检索的数据量超过一定的比例时(通常为表的记录数10%),索引查找会比全表扫描的效率更低,所以不能简单的以是否使用了索引来判断SQL语句性能好坏,要具体分析。 【规则-1】:如果需要经常地检索大表中的少于10%的行就创建索引; 1、例如:SELECT * FROM GSM_USER WHERE GSM_USER_ID = :B1 【规则-2】:不要对表使用表外键,数据约束在业务上控制; 1、说明:表列上如果有外键,但是参照表中如果没有给参照列建立主键,会造成严重的数据库锁等待。 【规则-3】:为了改善多个表的联结的性能,在用于联结列建立索引。 1、例如:select ... from custcare.operating_fee c1, custcare.clerk_operating_detail c2 where ... and c1.operating_srl = c2.operating_srl clerk_operating_detail的operating_srl列上就应该建立索引 【规则-4】:经常出现在where子句中的字段且过滤性强的列,特别是大表的列,应该有索引。 1、例如:GSM_USER表的GSM_USER_ID,该列是表示用户代码,是唯一的,where子句中加上GSM_USER_ID可以过滤掉很多数据。 【规则-5】:小表不需要索引。 1、例如:ATP_PARA_CFG表,该表只有400条数据。 2、一般情况下对于小于1000条记录的表不用加索引。 【规则-6】:分区关键字上创建分区索引查询效率更高。 1、说明:DML性能更好,查询和DML都只需要访问一个索引分区。 2、例如:GSM_USER 按gsm_user_id分区,基于gsm_user_id的索引PKX_GU_USER_ID即为分区索引。 【规则-7】:非分区关键字上创建全局索引查询效率较高。 1、说明:非分区关键字上创建全局索引DML性能较差,如果非常频繁的使用该索引查询多个分区数据,可以创建全局索引;对分区进行DDL操作(包括truncate)会使全局索引失效,需要rebuild。 2、例如:GSM_USER表上的基于msisdn的索引为全局索引,需要通过该索引经常访问 。
【规则-8】:非分区关键字上创建分区索引查询效率较差。 1、说明:分区索引DML性能比全局索引好,且维护方便,对分区进行DDL操作(包括truncate)只需要rebuild对应的索引分区。 2、例如:ACCTBK_PAYMENT_SEQ基于(MONTH_NUMBER, ACCOUNT_ID)分区,但PAYMENT_TIME列上创建的是分区索引,虽然性能稍差,但该索引比较少访问,且维护方便。 【规则-9】:几个字段经常同时以 and 方式出现在 where 子句中,可以建立复合索引。 1、例如:account.Sync_accbk_payment_seq表中user_id和account_id在where子句中经常同时出现,所以可以在account.Sync_accbk_payment_seq表上建一个以user_id和account_id为索引字段的复合索引。 2、通常将最常用的列放在最前面,一般是选择性较好且在where 子句中常用的字段。

2数据库管理规范 2.1临时表管理 【规则-1】:临时表命名规则:N/I_创建人名字缩写_表名_创建时间_保存时间。 1、其中:“N”表示Nornal,为一般临时表;“I”表示Important,为重要临时表;创建时间表示为[YY]MMDD;保存时间以天为单位,表示需要保留的期限。 2.如果按此规则组成的文件名太长,超过30个字符,YY和保存时间可以省略。 3、如:I_ZXC_ZONE_MVALUE_1024_30、N_JDS_USER_PARTITION_050810。 4、如果保存时间忽略,默认普通临时表的保存时间为20天,重要临时表的保存时间为60天,超过此保留时间可能被管理员删除。数据库管理员对由此产生的后果不负责任。 【规则-2】:临时表只能由非生产用户模式创建。 1、是为了维护/统计而临时生成的表,生产用户严禁建临时表。 【规则-3】:如果由于上线/割接等原因,只能在生产用户模式下创建,则须在DBA或局方相关人员的同意下方可进行,并严格监控,及时删除。 【规则-4】:临时表创建时应严格按照临时表明名规范进行。 【规则-5】:临时表只能在指定表空间创建,不允许在生产表空间建任何用户模式的临时表。 【规则-6】:创建临时表的维护人员负责清除自己创建的临时表。 1、数据库管理员将定期清除超过保留规定的活占用空间很大的临时表。 2.2生产系统表管理 【规则-1】:对于经常进行delete的表,要按要求定期对表进行分析。 例如:custcare.gsm_user_modify 该表要经常进行insert和delete操作,因此要经常对该表进行分析。 2.3密码管理 【规则-1】:数据库帐号和密码由指定的维护人员和开发人员进行管理,不得向其他人员透露。 【规则-2】:用户应记住自己的口令。 不应把它记载在不保密的媒介物上,严禁将口令贴在终端上。输入的口令不应显示在显示终端上。 【规则-3】:严禁通过任何非法手段获取数据库和操作系统的口令。 【规则-4】:相关人员离开岗位时,应向数据库管理员交接用户名和口令。 2.4表空间管理 每周对表空间使用率进行检查,保证表空间的使用率在80%一下。检查语句如下: col tablespace_name for a20 col tablespace_type for a12 col "SUM_SPACE(M)" for 999999 col SUM_BLOCKS for 999999999 col "USED_SPACE(M)" for 999999 col "FREE_SPACE(M)" for 999999 col "USED_RATE(%)" for 99.99 set linesize 200 select t.tablespace_name,x.contents tablespace_type,t."SUM_SPACE(M)",t.SUM_BLOCKS,t."USED_SPACE(M)",t."USED_RATE(%)",t."FREE_SPACE(M)" from (SELECT D.TABLESPACE_NAME,SPACE "SUM_SPACE(M)",BLOCKS SUM_BLOCKS,SPACE - NVL(FREE_SPACE, 0) "USED_SPACE(M)",
ROUND((1 - NVL(FREE_SPACE, 0) / SPACE) 100, 2) "USED_RATE(%)",FREE_SPACE "FREE_SPACE(M)"
FROM (SELECT TABLESPACE_NAME,ROUND(SUM(BYTES) / (1024
1024), 2) SPACE,SUM(BLOCKS) BLOCKS
FROM DBA_DATA_FILES
GROUP BY TABLESPACE_NAME) D,
(SELECT TABLESPACE_NAME,ROUND(SUM(BYTES) / (1024 1024), 2) FREE_SPACE
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) F
WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME(+)
UNION ALL SELECT D.TABLESPACE_NAME,SPACE "SUM_SPACE(M)",blocks SUM_BLOCKS,USED_SPACE "USED_SPACE(M)", ROUND(NVL(USED_SPACE, 0) / SPACE
100, 2) "USED_RATE(%)",SPACE - USED_SPACE "FREE_SPACE(M)"
FROM (SELECT TABLESPACE_NAME,ROUND(SUM(BYTES) / (1024 1024), 2) SPACE,SUM(BLOCKS) BLOCKS
FROM DBA_TEMP_FILES
GROUP BY TABLESPACE_NAME) D,
(SELECT TABLESPACE,ROUND(SUM(BLOCKS
8192) / (1024 * 1024), 2) USED_SPACE FROM V$tempseg_USAGE GROUP BY TABLESPACE) F
WHERE D.TABLESPACE_NAME = F.TABLESPACE(+)) t,dba_tablespaces x where t.tablespace_name=x.tablespace_name
order by "USED_RATE(%)" desc; 2.5Alert日志管理 每天对alert日志、监听日志进行检查,及时排除日志中的报错等异常问题。 Alert.log的位置:$ORACLE_BASE/ADMIN/$ORACLE_SID/bdump/alert$ORACLE_SID.log Listener.log的位置:$ORACLE_HOME/network/log/listener.ora

2.6Awr性能监控 每月定期取数据库高峰期时数据库的awr性能报告,查看等待时间、事务数量、平均事务响应时间、顺序读的io等待时间等,确定是否有异常,如有异常需及时进行问题排查。 2.7数据库备份管理 每天定期检查数据库备份情况,保证数据库备份的可用性。

2.8失效对象管理 每周检查数据库中的失效对象,对失效的对象要及时联系应用开发商或其他人员进行处理。检查语句如下: set linesize 200 set pagesize 300 col owner format a12 col object_name format a30 col object_type format a30 Select substr(owner,1,12) owner, substr(object_name,1,30) object, Substr(object_type,1,30) type,status from dba_objects where status <>'VALID' order by owner,object;

2.9防误操作管理 大量的研究表明,误操作是数据库损坏的第一杀手,对于这类操作的防范是数据库安全的重要方面。 【规则-1】:严格生产系统操作权限管理,尽可能减少开发人员直接操作生产数据库 【规则-2】:采用主动防护措施,通过DDL触发器限制对生产环境中关键数据表的TRUNCATE,DROP、ALERT等操作 【规则-3】:建立重要维护操作的双人校验机制,对于必须进行TRUNCATE,DROP,ALERT等操作的时候,由操作员输入指令,校验人员校验后执行操作

3数据库日常维护指南 3.1 每日维护操作 DBA日常工作中的主要任务是让数据库能够正常的工作。并尽早对数据库潜在的问题进行分析。DBA要确保自己管理的所有数据库Instance都健康的工作。并且确认所有的资源(包括内存、存储、CPU等、表空间、限额等)都能够满足目前系统运行的需要。本节将详细介绍每个DBA的日常工作。内容包括: ?确定所有的数据库Instance都能正常工作 ?查看系统和数据库日志 ?检查例行备份是否成功 ?检查数据库各种资源是否充足

3.1.1 确定所有实例均正常工作

通过SQLPLUS能够连接到相应的INSTANCE,并能够进行正常的数据库操作: sqlplus game/game@ sqlplus> select * from dual;

3.1.2 检查和整理数据库日志 ALERT LOG是ORACLE数据库的系统日志,所有的系统信息都会在ALERT LOG中记录,因此经常检查ALERT LOG可以及时发现数据库目前的问题。下面的方法可以检查ALERT LOG: ?用TELNET登录到要检查的数据库 ?进入 $ORACLEBASE//bdump. ?用 Unix ‘tail’命令或者vi命令查看 alert.log. ?如果存在 ORA-XXXX ,把这些错误记录下来,交给数据库专家分析. ?在ALERT LOG中有日志切换的记录,如果日志切换的时间间隔过短(小于10分钟),说明日志可能太小,应该请Oracle专家协助分析 随着时间的推移,ALERT LOG的大小会越来越大。如果ALERT LOG过大,会影响数据库写日志的性能。因此要定期清理ALERT LOG。应该把ALERT LOG备份(备份ALERT LOG对于今后对数据库进行分析的时候有很重要的作用,因此建议每次清理ALERT LOG之前都进行备份),然后删除,这样Oracle就可以写入新的ALERT LOG了。 在ALERT LOG所在的目录下面,可能会存在一些扩展名为trc的文件,对于这些文件也需要进行检查,检查这些文件有助于发现一些潜在的问题。检查完毕后,应该把这些文件备份,然后从bdump目录下清除。如果一个目录下的文件数量超过1024个,对于UNIX系统来说,访问该目录的性能会有所下降,如果文件的数量很大(比如5000个或者10000个),那么访问该目录将会很慢,因此需要定期清除日志目录的文件。 可以使用tar命令将这些trc文件打包: tar cvf trace_file20041001.tar .trc rm .trc 完成后,可以把tar生成的文件备份到其他目录,并定期把过老的tar文件清理掉(比如半年前的)。 3.1.3 检查例行备份是否完成 该检查和使用的备份工具有关。比如:

1、使用LEGATO NETWORKER 在Networker安装目录下的applogs目录下的日志文件中可以查看备份的执行情况。 2、使用HP DP 在/var/opt/omni/db40/datafiles/catalog目录下面可以找到相关的报错日志文件,或者在/var/opt/omni/logs目录下面可以找到包括debug.log?,media.log?,IS_install.log,license.log等信息。

3、使用VERITAS NBU 日志记录在以下位置: ◆ 默认情况下 (如果未组对):/usr/openv/netbackup/logs/bpdm ◆ 仅限组对的日志:/usr/openv/netbackup/logs/bptm 所有其他日志记录都类似于标准备份,例如,会生成进度日志。 日志包含有关与 NearStore 进行交互的详细信息。

4、使用IBM TSM

使用set actlogretention days命令来设置服务器日志的保留时间,其中days范围在1~9999。日志内容由query actlog命令来查询 语法: query actlog 参数 参数: ◆ BEGINDate 指定要显示消息的范围的开始日期。发生在此日期之后的所有满足时间范围标准的消息都被显示。缺省值是当前日期。此参数是可选的。 可使用下列值之一指定数据: 值 描述 示例 MM/DD/YYYY 具体日期 09/15/1998 TODAY 当前日期 TODAY TODAY-days 或 -days 当前日期减去指定天数。 TODAY-7或-7。 可以指定的最大天数是 9999。
要显示以一周前创建的消息开始的信息,可以指定 BEGINDATE=TODAY-7 或 BEGINDATE= -7。 ◆ BEGINTime 指定要显示消息的范围的开始时间。发生在此时间之后的所有满足时间范围标准的消息都被显示。如果不指定时间,则将显示前一小时中发生的所有消息。 可使用下列值之一指定数据: 值 描述 示例 HH:MM:SS 指定的开始日期的具体时间 10:30:08 NOW 指定的开始日期的当前时间 NOW NOW+HH:MM或+HH:MM 当前时间加上指定开始 NOW+03:00 日期的小时和分钟 或+03:00。 NOW-HH:MM或-HH:MM 当前时间减去指定的开始日期 NOW-04:00 上的小时与分钟 或-04:00。 如果在 9:00 以 BEGINTIME=NOW+03:00 或 BEGINTIME=+03:00 发布此命令,则 TSM 显示指定开始日期 12:00 或稍后的记录。 如果在 9:00 以 BEGINTime=NOW-3:30 或 BEGINTime= -3:30 发布 QUERY ACTLOG 命令,则 TSM 显示开始日期 5:30 或稍后的消息。 ◆ ENDDate 指定要显示消息的范围的结束日期。将显示发生在该日期之前的符合时间范围条件的全部消息。如果不为此参数指定值,则将使用当前日期。此参数是可选的。 可使用下列值之一指定数据: 值 描述 示例 MM/DD/YYYY 具体日期 09/15/1998 TODAY 当前日期 TODAY TODAY-days或-days 当前日期减去指定天数。 TODAY-1或-1。 可以指定的最大天数是 9999。
要显示直到昨天创建的信息,您可以指定 ENDDATE=TODAY-1 或仅仅 ENDDATE= -1。 ◆ ENDTime 指定要显示消息的范围的结束时间。发生在此时间之前的所有满足时间范围标准的消息都被显示。如果不为此参数指定一个值,则显示到发出此命令时的所有消息。此参数是可选的。 可使用下列值之一指定数据: 值 描述 示例 HH:MM:SS 指定的结束日期的具体时间 10:30:08 NOW 指定的结束日期的当前时间 NOW NOW+HH:MM 当前时间加上指定的结束 NOW+03:00 或+HH:MM 日期上的小时与分钟 或 +03:00。 NOW-HH:MM或-HH:MM 当前时间减去指定的结束 NOW-03:30 日期上的小时与分钟 或-03:30。 如果在 9:00 以 ENDTIME=NOW+3:00 或 ENDTIME= +3:00 发布此命令,则 TSM 显示指定的结束日期 12:00 或稍后的消息。 如果在 9:00 以 ENDTIME=NOW-3:30 或 ENDTIME= -3:30 发布此命令,则 TSM 显示您指定的结束日期 5:30 或稍后的消息。 ◆ MSGno 指定一个正数,它定义要从活动日志显示的消息的数量。这是消息的数字部分,不带 ANR 前缀或消息类型后缀(即 I、W、E、S 或 D)。此参数是可选的。 ◆ Search 指定您希望在活动日志中搜索的文本串表达式。如果字符串表达式中包含空格,则必须使用引号将其括起来。可以使用通配符指定该字符串。此参数是可选的。 ◆ ORiginator 指定查询显示由服务器,客户机或它们共同记录的消息。缺省值是 ALL。可能的值有: ◆ ALL 指定查询显示由服务器或客户机生成的消息。 ◆ SErver 指定查询显示由服务器生成的消息。 ◆ CLient 指定查询显示由客户机生成的消息。 可以指定下列值中的一个来来往往最小化查询活动日志以查找该客户机已记录消息的处理时间。

◆ NODEname 指定查询显示由节点记录的消息。如果没有为该参数指定数值,则显示所有节点的消息。 ◆ OWNERname 指定查询显示由特定所有者记录的消息。如果没有为此参数指定数值,则显示所有所有者的消息。 ◆ SCHedname 指定查询显示由特定已调度的客户机活动日志的消息。如果没有为该参数指定数值,显示所有调度的消息。 ◆ DOmainname 指定查询显示由命名调度所属的特殊策略域记录的消息。该参数是可选的,除非正指定一个调度名。 ◆ SESsnum 指定查询显示从特定客户机会话号记录的消息。如果没有为该参数指定数值,显示所有客户机会话的消息。

5、检查CATALOG数据库 通过检查catalog数据库可以检查备份集的状态。 使用rman的list命令可以检查: rman rman>connect target sys/…@db; rman>connect catalog catalog/catalog@catalog; rman>list backup summary; --检查备份集的总体情况 rman>list backup; --检查备份集 rman>list backup of datafile ‘’; --检查文件的备份情况 对于使用磁带或者磁带库进行备份的备份系统,还要定期对磁带机和磁带进行检查,及时发现磁带或磁带机损坏的情况。

3.1.4 检查数据库资源是否充足

1、检查表空间空闲空间
使用ORACLE ENTERPRISE MANAGER可以监视表空间的空闲空间。或者执行如下语句进行检查: (1)FREE.SQL SELECT tablespace_name, sum ( blocks ) as free_blk , trunc ( sum ( bytes ) / (10241024) ) as free_m , max ( bytes ) / (1024) as big_chunk_k, count () as num_chunks FROM dba_free_space GROUP BY tablespace_name

(2)SPACE.SQL

-- -- space.sql

-- To check free, pct_free, and allocated space within a tablespace

SELECT tablespace_name, largest_free_chunk , nr_free_chunks, sum_alloc_blocks, sum_free_blocks , to_char(100*sum_free_blocks/sum_alloc_blocks, '09.99') || '%' AS pct_free FROM ( SELECT tablespace_name , sum(blocks) AS sum_alloc_blocks FROM dba_data_files GROUP BY tablespace_name ) , ( SELECT tablespace_name AS fs_ts_name , max(blocks) AS largest_free_chunk , count(blocks) AS nr_free_chunks , sum(blocks) AS sum_free_blocks FROM dba_free_space GROUP BY tablespace_name ) WHERE tablespace_name = fs_ts_name

2、检查数据库中将要出现空间不足的对象 检查将要出现空间不足的对象有助于及早发现系统存在的问题,避免系统由于空间不足而导致故障。要准确的找出将要出现空间不足的对象,需要经常对系统进行分析。可以运行 nr_extents.sql检查将要超出扩展限额的表和索引 及时发现将要超出扩展限额的表和索引可以尽早修改表和索引的存储参数,防止在业务系统运行过程中由于无法扩展表和索引空间而导致的系统故障。这种系统故障是一个运行系统中经常会出现的,由于这种故障导致的系统停止运行,DBA的责任十分重大。以下脚本可以进行这种检查:

SELECT e.owner, e.segment_type , e.segment_name , count() as nr_extents , s.max_extents , to_char ( sum ( e.bytes ) / ( 1024 1024 ) , '999,999.90') as MB FROM dba_extents e , dba_segments s WHERE e.segment_name = s.segment_name GROUP BY e.owner, e.segment_type , e.segment_name , s.max_extents HAVING count() > &THRESHOLD OR ( ( s.max_extents - count() ) < &&THRESHOLD ) ORDER BY count(*) desc

3、找出无法进行下一次扩展的对象 如果对象所在的表空间的空闲空间不足,那么这个表空间上的对象如果要进行扩展,就会出现空间不足的错误。如果这样的对象存在,需要扩充TABLESPACE。 本节介绍的脚本的目的是检查是否存在某个表,表的下一次扩展的大小大于表空间的空闲空间。如果这个脚本没有返回记录,说明不存在这样的表。对于非LMT表空间上的表,如果没有使用SAFE方法设计表的存储参数,表空间可能存在碎片,这种情况下,哪怕本查询没有返回记录,也可能由于表空间碎片的存在而存在下次扩展可能失败的表存在。在这种情况下,经常进行碎片整理十分重要。 SELECT a.table_name, a.next_extent, a.tablespace_name FROM all_tables a, ( SELECT tablespace_name, max(bytes) as big_chunk FROM dba_free_space GROUP BY tablespace_name ) f WHERE f.tablespace_name = a.tablespace_name AND a.next_extent > f.big_chunk

4、检查系统资源 检查操作系统的资源情况有助于发现数据库的问题。如果有一天操作系统的负载突然加大,那么就需要对数据库进行检查,是否数据库的压力发生了变化。如果操作系统的CPU、内存、IO、网络等资源中的某个资源处于超负荷状态,可能会导致数据库性能急剧下降。因此经常监控系统资源对于监控数据库来说具有十分重要的作用。 要检查操作系统资源,需要使用TELNET、SSH等远程登录工具登录到目标服务器上。对于WINDOWS系统,可以使用PC ANYWHERE或者NETMEETING等软件监控远程服务器。本节主要讨论如何在UNIX环境下监控系统。 (1)通用检查命令 由于UNIX对于系统监控的命令差别比较大,本节介绍的命令基本上是在所有的系统上都可以使用的,个别参数可能略有区别。以下是在UNIX下检查系统CPU、内存等的总体情况 vmstat 2 10 检查磁盘IO sar –d 2 10 检查文件系统空闲空间 df –k 检查系统进程情况 ps –ef ps aux top 检查网络情况 netstat –s netstat –a

(2) IBM AIX系统监控命令 本节介绍如何在AIX系统下查看系统资源的使用情况。 $ /usr/sbin/lsattr -E -l sys0 -a realmem $ /usr/sbin/lsps -s $ vmstat 5 100 $ iostat 2 100 $ /usr/local/bin/top # May not be installed by default in the server

比如

$ /usr/sbin/lsattr -E -l sys0 -a realmem

realmem 33554432 Amount of usable physical memory in Kbytes False

$ /usr/sbin/lsps -s

Total Paging Space Percent Used 30528MB 1%

注:有条件的可以使用NMON工具来查看系统资源的使用情况。 NMON工具的使用方法: nmon 工具可以帮助在一个屏幕上显示所有重要的性能优化信息,并动态地对其进行更新。这个高效的工具可以工作于任何哑屏幕、telnet 会话、甚至拨号线路。另外,它并不会消耗大量的 CPU 周期,通常低于百分之二。在更新的计算机上,其 CPU 使用率将低于百分之一。启动 nmon,然后按 h 键,就可以得到帮助信息。 nmon的输出示例: 图 1 是屏幕输出的示例。它显示了 AIX 的起始屏幕,以及大量有价值的主机配置信息。 图 1. nmon的输出示例: 图 2 说明了关于 CPU、内存使用、内核内部统计和磁盘统计的详细信息。 如:1. 每个单个CPU的用户,系统,等待和空闲的百分比,以及逻辑和物理上的平均百分比,按c键显示。 2.内存和swap的空闲和使用的实际大小和百分比,以及总的大小,按m键显示。 3.内核内部统计信息,按k键显示。 4.磁盘I/O的速度,传输和读/写比率,按d键显示。 图 2. CPU ,内存,内核,磁盘I/O的详细信息: 图 3 显示了网络、NFS 统计信息和日志文件系统使用的详细信息。 如:1. 网络I/O的速度,传输和读/写比率,按n键显示。 2. 网络文件系统(Nfs)信息,按N键显示。 3.文件系统的使用情况,按j键显示。

图 3. 网络,NFS,文件系统使用的详细信息: 在下面的图 4 中显示了共享CPU逻辑分区状态和资源占用多的进程的详细信息。 如:1. 动态 LPAR 更改,仅适用于AIX的pSeries p5,按p键显示。 2.消耗资源最多的进程,按t键显示。 图 4. LPAR状态和进程的详细信息: 按q键可以退出nmon,结束检查。

3、HP-UX系统监控命令 本节介绍如何在HP-UX系统下查看系统资源的使用情况。

root用户可以使用sam来查看系统资源的使用情况。 /opt/ignite/sbin/print_manifest

$ vmstat 5 100 $ iostat 2 100

注:有条件的可以使用glance工具来查看系统资源的使用情况。

Glance监控工具是HP-UX系统中一个强大且易用的在线监控工具,它有两种版本,一种是gpm,图形模式,另一个就是glance,文本模式。几乎可以在任何终端和工作站上使用,占用资源很少。任何一个版本都可以提供丰富的系统性能信息。默认的进程列表会列出有关系统资源和活动进程的常规信息,更多详细信息包括:CPU, Memory, Disk IO, Network, NFS, System Calls, Swap, and System Table。

语法:glance [-j interval] [-p [dest]] [-f dest] [-maxpages numpages] [-command] [-nice nicevalue] [-nosort] [-lock] [-adviser_off] [-adviser_only] [-bootup] [-iterations count] [-syntax filename] [-all_trans] [-all_instances] [-disks ] [-kernel ] [-nfs ] [-pids ] [-no_fkeys]

选项说明:

-j interval 设置屏幕刷新的时间间隔,单位为秒,默认值为5秒,数值许可范围:1~32767 -p [dest] 这个选项可以启用连续打印,对于屏幕刷新间隔很长时的打印很有效,输出会被定向到一个默认的本地打印机,除非需要输入设备参数。一旦运行开始,可以用p命令终止该操作 -f dest 这个选项可以启用连续打印,对于屏幕刷新间隔很长时的打印很有效,输出会被定向到一个给定的文件。一旦运行开始,可以用p命令终止该操作 -maxpages numpages 当用-p命令,-maxpages选项可以改变打印的最大页数,默认的是200页 -command 这个选项是用来设置进程列表不同的屏幕显示,这个键值设置会显示不同的信息,详细命令见下面的-command选项,仅有一个命令可以选择 -nice nicevalue 这个选项允许你调整glance进程的优先级别,默认值为-10 -nosort 这个选项设置后,屏幕不用将进程排序显示,这样可以减少Glance进程的CPU开销 -lock 这个选项允许你将Glance锁入内存,这样可以大大提高响应时间,但有可能会收到错误提示:"Unable to allocate memory/swap space",那样又必须取消此选项重新运行 -adviser_off 允许你关闭建议模式运行glance -adviser_only 这个选项允许glace在终端无屏幕显示下运行,仅建议提示会运行,并将结果发送到标准输出。建议提示模式可以在后台运行,可以把结果重定向到一个文件,但必须要和-bootup选项联合使用 -bootup 和-adviser_only一块儿使用,启动时就开启建议模式 -iterations count 这个选项可以在Glance运行时限制间隔的数字,这个选项和-adviser_only选项在无终端显示时联合使用。Glance执行给定次数后,迭代列入清单后退出 -syntax filename 应用这个选项启用自定义的建议文件 -all_trans 这个选项允许Glance列出系统中所有注册的任务。如果没有指明,glance仅仅列出经过滤得项 -all_instances 这个选项允许glance显示所有操作记录示例

-disks 监控磁盘 -kernel 监控系统kernel -nfs 监控NFS使用 -pids 监控指定进程 以上四个命令选项值会直接传入Midaemon(惠普的性能监控接口守护进程)和调整Midaemon的启动参数,如果Midaemon已经在运行,那样这些选项设置将不被理睬 -no_fkeys 这个选项可以屏蔽操作屏幕显示的功能键.

-command选项列表 Command Screen Displayed / Description a CPU By Processor c CPU Report d Disk Report g Process List i IO By File System l Network By Interface m Memory Report n NFS By System t System Tables Report u IO By Disk v IO By Logical Volume w Swap Space A Application List B Global Waits D DCE Global Activity G Process Threads H Alarm History I Thread Resource J Thread Wait K DCE Process List N NFS Global Activity P PRM Group List T Transaction Tracker Y Global System Calls Z Global Threads ? Commands菜单

glance运行时的键盘命令 S 选择 system/Disk/Application/Trans/Thread s 选择查看进程 F 进程打开的文件 L 进程系统调用 M 进程内存 R 进程资源 W 进程等待状态

屏幕显示控制命令 b 下一页 f 前一页 h 在线帮助 j 调节屏幕刷新间隔 o 调整进程阈值 p 输出打印终止 e/q 退出glance r 刷新当前屏幕 y 重新设置进程的nice值 z 将统计信息清零

显示下一屏幕 < 显示前一屏幕 ! 调用一个shell

3.2 夜间处理工作

每天夜间主要处理一些白天业务高峰期无法实施的维护操作。包括 ?数据逻辑备份 ?数据库物理备份 ?表分析 ?基线数据处理 3.2.1 数据库逻辑备份 虽然在备份策略中已经设计了数据库的物理备份和增量备份,但是逻辑备份仍然是十分必要的,这对于故障迅速恢复以及数据分析及其重要。建议对重要的业务数据每天晚上进行一次逻辑备份。 3.2.2 数据库物理备份 数据库物理备份必须在业务比较少的时间段进行,以防止影响系统性能。应通过备份软件设置每晚自动备份。 3.2.3 表分析 大多数OLTP系统每天白天的数据变化较大,建议每天晚上对业务量变化较大的表及其相关索引进行表分析。 3.2.4 基线数据处理 对于设置了基线数据分析脚本的客户,建议每天晚上运行相关脚本,对基线数据进行分析、处理、备份等操作。

3.3 每周工作

3.3.1 找出违反设计规则的对象 1、 NEXT_EXTENT检查 在相同TABLESPACE中的对象应该具有相同的NEXT_EXTENT参数。并且这些NEXT_EXTENT和TABLESPACE的缺省参数一致 ?检查 NEXT_EXTENT, 运行 nextext.sql. ?检查现有的EXTENT, 运行 existext.sql

-- nextext.sql

-- To find tables that don't match the tablespace default for NEXT extent. -- The implicit rule here is that every table in a given tablespace should -- use the exact same value for NEXT, which should also be the tablespace's -- default value for NEXT. -- -- This tells us what the setting for NEXT is for these objects today.

SELECT segment_name, segment_type, ds.next_extent as Actual_Next , dt.tablespace_name, dt.next_extent as Default_Next FROM dba_tablespaces dt, dba_segments ds WHERE dt.tablespace_name = ds.tablespace_name AND dt.next_extent !=ds.next_extent AND ds.owner = UPPER ( '&OWNER' ) ORDER BY tablespace_name, segment_type, segment_name

-- -- existext.sql

-- To check existing extents -- -- This tells us how many of each object's extents differ in size from -- the tablespace's default size. If this report shows a lot of different -- sized extents, your free space is likely to become fragmented. If so, -- this tablespace is a candidate for reorganizing.

SELECT segment_name, segment_type , count(*) as nr_exts , sum ( DECODE ( dx.bytes,dt.next_extent,0,1) ) as nr_illsized_exts , dt.tablespace_name, dt.next_extent as dflt_ext_size FROM dba_tablespaces dt, dba_extents dx WHERE dt.tablespace_name = dx.tablespace_name AND dx.owner = '&OWNER' GROUP BY segment_name, segment_type, dt.tablespace_name, dt.next_extent

2、没有Primary Key的表的检查 对于大多数表来说,应该具有一个唯一性的主关键字。
?检查PK, 运行 no_pk.sql. ?检查失效的PK, 运行 disPK.sql. ?所有的主键都必须唯一。运行nonuPK.sql检查非唯一主键

-- no_pk.sql -- -- To find tables without PK constraint

SELECT table_name FROM all_tables WHERE owner = '&OWNER' MINUS SELECT table_name FROM all_constraints WHERE owner = '&&OWNER' AND constraint_type = 'P'

-- -- disPK.sql

-- To find out which primary keys are disabled

SELECT owner, constraint_name, table_name, status FROM all_constraints WHERE owner = '&OWNER' AND status = 'DISABLED’ AND constraint_type = 'P'

-- -- nonuPK.sql -- -- To find tables with nonunique PK indexes. Requires that PK names -- follow a naming convention.

SELECT c.constraint_name, i.tablespace_name, i.uniqueness FROM all_constraints c , all_indexes i WHERE c.owner = UPPER ( '&OWNER' ) AND i.uniqueness = 'NONUNIQUE' AND c.constraint_type = 'P' AND i.index_name = c.constraint_name 3.3.2 查看 SQLNet 日志,检查是否有错误 服务器端日志存放在$ORACLE_HOME/network/log和$ORACLE_HOME/network/trace目录下。日志检查完毕后,把原来的日志备份,然后清空。 主要查看近两个月日志中是否有TNS-错误,列出查找相应的原因并解决。 日志文件备份后,可以按时间点删除过期的日志文件内容,例如删除2个月之前的日志文件内容。 例如: 1、ORA-12541:TNS:没有监听器 原因:没有启动监听器或者监听器损坏。若是前者,使用命令lsnrctl start即可;如果是后者,则使用“Net Configuration Assistant”工具向导的“监听程序配置”增加一个监听器即可。 2、ORA-12500:TNS:监听程序无法启动专用服务器进程 原因:ORACLE的数据库服务没有启动。 3、ORA-12154: TNSNAMES.ORA不能解析服务名 原因:检查TNSNAMES.ORA配置文件,文件的位置、服务名称、语法的正确性等 4、ORA-12560:TNS:协议适配器错误 原因:表明传输层发生了错误,通过SQLNet trace,找到12560的伴随错误进行问题定位。 5、TNS-12535 TNS:操作超时 原因:重新配置LISTENER.ORA里面的CONNECT_TIMEOUT参数 6、TNS-00511没有监听 原因:lsnrctl service检查监听程序,对比listener.ora和tnsnames.ora查找问题原因。 3.3.3备份所有的Alert Logs 由于ALERT LOG会随着系统运行的时间而增长。当系统运行一个星期后,ALERT LOG会达到几兆,过大的ALERT LOG会造成日志系统性能下降,并且也不利于日志检查。因此每个星期要对ALERT LOG进行备份。如果ALERT LOG增长较为缓慢,这个操作也可以改为月操作. 备份ALERT LOG可以按日期时间统一命名,存放到其他位置,备份之后就可以将原来的ALERT LOG内容删除,减小ALERT LOG的大小。 3.3.4 检查数据库中的无效对象 使用脚本来检查数据库系统中的无效对象。

set linesize 200
set feedback off
set termout on
COL OOWN FORMAT A20 TRUNCATE; COL ONAME FORMAT A30 TRUNCATE; COL OTYPE FORMAT A15 TRUNCATE; COL PROB FORMAT A30 TRUNCATE;
select A.Owner Oown,
A.Object_Name Oname,
A.Object_Type Otype,
'Miss Pkg Body' Prob
from DBA_OBJECTS A
where A.Object_Type = 'PACKAGE'
and A.Owner not in ('SYS','SYSTEM')
and not exists
(select 'x'
from DBA_OBJECTS B
where B.Object_Name = A.Object_Name
and B.Owner = A.Owner
and B.Object_Type = 'PACKAGE BODY')
union
select Owner Oown,
Object_Name Oname,
Object_Type Otype,
'Invalid Obj' Prob
from DBA_OBJECTS
where Object_Type in
('PROCEDURE','PACKAGE','FUNCTION','TRIGGER','PACKAGE BODY','VIEW') and Owner not in ('SYS','SYSTEM')
and Status != 'VALID'
order by 1,4,3,2;

找出无效对象名,进行重新编译。

查找无效对象,查出来后,应该保留本次检查的内容,除了重新编译外,可能系统中就存在部分对象有问题,那么就是重编译也会有问题,下回检查后和上次保留的进行对比,看看是否有新增的失效对象,对于新增的失效对象要进行严格检查。

3.4 每月工作 3.4.1查找不合理的空间增长 每个月检查主要的数据库表、索引、表空间的大小,与上月检查的情况进行对比,将得出的增长情况进行登记,并和历史记录进行比较,如果发现有超出正常水平的增长,记录下来并汇报给系统管理人员。 可以与系统管理人员共同查找造成空间过分增长的原因,是否属于不合理增长。 一般不建议自动增长数据文件大小,增大表空间采用增加数据文件的方式来实现。 3.4.2 查找需要优化的问题 1、Statspack报告 运行Statspack,生成Statspack报告,提交专业人士分析。运行Statspack的步骤: 1> 首先创建一个独立的表空间(100M),为Statspack使用 运行$ORACLE_HOME/rdbms/admin/spcreate.sql创建所有的Statspack对象,同时生成perfstat用户。 2> 安装STATSPACK只需要进行一次,今后可以通过连接上perfstat用户执行: execute statspack.snap; 生成SNAPSHOT. 3> 在两个30分钟以上的SNAPSHOT点之间生成STATSPACE报告 4> 运行$ORACLE_HOME/rdbms/admin/spreport.sql生成报告 也可以通过设置定时作业,每隔一段时间定期生成SNAPSHOT。 2、ORACLE 10G的AWR报告 ORACLE 10G有提供一种新的集数据库统计信息的工具,生成AWR报告,提交专业人士分析。运行AWR的步骤: 1> 首先AWR不用安装,是和ORACLE 10G数据库一起安装好的。 2> 可以通过执行: execute dbms_workload_repository.create_snapshot; 生成SNAPSHOT。 3> 在两个30分钟以上的SNAPSHOT点之间生成AWR报告 4> 运行$ORACLE_HOME/rdbms/admin/awrrpt.sql生成报告,html和text格式的报告都可以。 5> 也可以通过设置定时作业,每隔一段时间定期生成SNAPSHOT。 要查看当前的设置,您可以使用下面的语句: select snap_interval, retention from dba_hist_wr_control; SNAP_INTERVAL RETENTION


+00000 01:00:00.0 +00007 00:00:00.0 ??? 这些 SQL 语句显示快照每小时采集一次,采集的数据保留 7 天。 要修改设置 -- 例如,快照时间间隔为 20 分钟,保留时间为两天 -- 您可以发出以下命令,参数以分钟为单位。 begin dbms_workload_repository.modify_snapshot_settings ( interval => 20, retention => 22460 ); end; / 注:和STATSPACK不同,AWR数据缺省保留7天,为确保数据能长期保存,Oracle 10g中已经自带awr数据的导出导入脚本,建议将awr数据导出,并倒入到一个独立的数据库中,以备今后分析使用。 3.4.3 分析相关表和索引 部分表和索引按照月度周期性变化,因此每个月对所有的表和索引进行一次分析是十分必要的。 3.4.4 磁带库清洗 由于带库的驱动器脏了会影响备份的效率,甚至严重情况导致备份失败,因此要定期使用清洗带清洗带库的驱动器。该工作最好每个月能够进行一次。 3.5 半年工作 3.5.1 备份系统巡检 至少每半年对备份系统进行一次全面巡检(这个工作也可以密度加大到每个季度一次,根据实际工作量以及人力资源情况具体调整),巡检的主要任务是检查备份策略,备份集的可用性,带库状态、以及做恢复抽样测试。

3.5.2 表空间容量评估与调整 根据半年来每个月对表空间增长的评估,确定表空间以及存储的调整方案,并进行实施。

3.5.3 数据库帐号安全性检查 检查主要数据库帐号的权限,以及是否使用简单的密码。对于暂时不使用的帐号进行锁定。对于过大的授权予以回收。

3.5.4 性能优化 对于半年来存在的主要性能问题进行分析,并且形成优化方案,实施优化操作。 3.5.5 索引优化 对于变化很大的表,经过一段时间运行后,索引可能会存在较为严重的碎片,这种情况下,索引就需要定期重建,以提高索引的运行效率。 可以通过alter index rebuild online;命令来重建索引。 注意:重建索引后要对索引进行相关分析。 3.6 年终工作 3.6.1 备份恢复演练 为确保备份系统的正常工作,至少每年进行一次备份系统恢复演练,演练针对核心业务系统,最好有测试环境,可以在测试环境上进行全库的恢复演练。如果存储容量不足,无法进行全库恢复演练,针对主要数据文件,均要进行文件级或者表空间级的恢复演练。 3.6.2 存储容量规划 根据全年各个表空间数据增长情况,对明年存储容量增长进行估算。提出扩容方案。 3.6.3 初始化分区表的新分区 如果系统中有按照时间分区的分区表,需要在年底初始化下一年度的表分区。

3.6.4 数据归档 对于部分可归档数据,定期进行数据归档,清理生产表,使生产表的数据瘦身。

4 RAC维护 4.1 OCR备份与恢复 4.1.1 OCR的备份 OCR文件里包含了RAC的配置情况,因此需要定期备份。Oracle会自动对OCR进行备份。我们可以使用OCRCONFIG命令来维护OCR文件。 名称: ocrconfig - Oracle 集群注册表的配置工具。

概要: ocrconfig [option] option: -export [-s online]

注: 将在 $ORACLEHOME/log//client/ocrconfig.log 中创建日志文件。在 运行此工具前, 请确保 您具有在以上目录中创建文件的权限。

如果OCR文件出现故障可以使用以下命令查看备份的OCR文件: $ORA_CRS_HOME/bin/ocrconfig -showbackup 为了更加保险起见,在RAC做过重大配置变更后使用-export命令备份OCR。

4.1.2 OCR的恢复 1、关闭CRS Sun or Linux:

/etc/init.d/init.crs disable
/etc/init.d/init.crs stop

HP-UX or HP Tru64::

/sbin/init.d/init.crs disable
/sbin/init.d/init.crs stop

IBM AIX:

/etc/init.crs disable
/etc/init.crs stop

2、清理OCR文件 dd if=/dev/zero of= bs=1M count=100

3、重启服务器到单用户状态 cd $ORA_CRS_HOME/bin ./ocrconfig -restore <备份的OCR文件全路径文件名> 4、重新激活CRS

Sun or Linux:

/etc/init.d/init.crs enable

HP-UX or HP Tru64::

/sbin/init.d/init.crs enable

IBM AIX:

/etc/init.crs enable

备注:如果使用了export备份了OCR,可以使用import导入 4.2 VOTING备份与恢复 4.2.1 VOTING备份 VOTING是NM用于监控RAC的重要文件,因此VOTING丢失会导致RAC出现故障。为了防止VOTING出现故障,建议在RAC增加或者减少节点后,立即对VOTING进行备份。备份可以使用dd进行热备份,CRS不需要关闭。 dd if=<voting文件名> of=<备份文件名> bs=4096 count=<根据voting的大小改变> 4.2.2 VOTING恢复 使用dd恢复。 4.2.3 无备份情况下VOTING的恢复 一般情况下VOTING丢失会导致CLUSTERWARE出现故障,如果无备份可用,就需要重装crs。从10G R2开始,有一种特殊的方法可以恢复VOTING。步骤如下: 步骤 命令 说明 1 停止CRS # crsctl stop crs 2 检查CRS进程 # ps -e | grep -i 'ocs[s]d'

ps -e | grep -i 'cr[s]d.bin'

ps -e | grep -i 'ev[m]d.bin'

上述命令必须无返回信息,否则必须kill掉

3 重建VOTING # clscfg -install 参数 -nn ,1,,2 -pn ,1,,2 -ch /u01/app/crs -oh /u01/app/crs -c crs -l 'AMERICAN_AMERICA.WE8ISO8859P1' -q /dev/raw/raw1,/dev/raw/raw2,/dev/raw/raw3 -force
4 重启crs crsctl start

4.3 RAC性能分析 4.3.1 使用AWR定位RAC性能问题 AWR报告是定位RAC性能问题的重要手段,在报告中应密切观察以下指标,如果以下指标不正常,就应该进行深入分析,找到性能问题: 指标 正常值 Ave global cache convert time (ms) 6左右 Ave global cache get time (ms) 3左右 Ave receive time for current block (ms) 3左右 Ave receive time for CR block (ms) 4左右 Ave time to process current block request (ms) 3左右 Ave message sent queue time (ms):??? <=0.6 Ave message sent queue time on ksxp (ms) <=0.9 Ave message received queue time (ms) <=0.1 Ave GCS message process time (ms) <=0.3 Ave GES message process time (ms) <=0.1

4.3.2 使用AWR报告查找存在问题的对象 RAC出现性能问题,很多情况是由于某个对象(或者某些对象)的争用引起,通过AWR报告可以找到存在严重争用的对象: Segments by Global Cache Buffer BusyDB/Inst: SWLHDB/swlhdb2 Snaps: 18694-1869 -> % of Capture shows % of GC Buffer Busy for each top segment compared -> with GC Buffer Busy for all segments captured by the Snapshot

                                                                  GC
       Tablespace                      Subobject  Obj.        Buffer    % of

Owner Name Object Name Name Type Busy Capture


APPBIZ SHAPPBIZ TB_INFOCOUNTER TABLE 10 100.00

Segments by CR Blocks Received DB/Inst: SWLHDB/swlhdb2 Snaps: 18694-18695 -> Total CR Blocks Received: 1,659 -> Captured Segments account for 95.7% of Total

                                                               CR
       Tablespace                      Subobject  Obj.       Blocks

Owner Name Object Name Name Type Received %Total


APPBIZ SHAPPBIZ TB_INFOCOUNTER TABLE 753 45.39 BNET TS_PRODUCT T_PRODUCT_HIS TABLE 147 8.86 SYS SYSTEM SMON_SCN_TIME TABLE 113 6.81 BNET TS_PRODUCT T_PRODUCT TABLE 98 5.91 SYS SYSTEM JOB$ TABLE 88 5.30

Segments by Current Blocks ReceivedDB/Inst: SWLHDB/swlhdb2 Snaps: 18694-18695 -> Total Current Blocks Received: 1,785 -> Captured Segments account for 87.2% of Total

                                                             Current
       Tablespace                      Subobject  Obj.       Blocks

Owner Name Object Name Name Type Received %Total


BNET TS_DEFAULT T_PRODUCT_ACCOUNT_RE TABLE 305 17.09 BNET TS_PRODUCT T_PRODUCT TABLE 264 14.79 BNET TS_CODE T_PRODUCT_ATTR_VALUE TABLE 230 12.89 APPBIZ SHAPPBIZ TB_INFOCOUNTER TABLE 189 10.59 BNET TS_CODE T_PAYMENT_ACCOUNT TABLE 141 7.90

4.3.3 常用RAC性能分析脚本 col stat format a40 truncate; col owner format a10 truncate; ----检查GLOBAL CACHE相关指标 select STATISTIC_NAME stat,OWNER,OBJECT_NAME obj,sum(value) Val from v$segment_statistics where STATISTIC_NAME like 'global%' and value > 0 group by STATISTIC_NAME,OWNER,OBJECT_NAME order by val desc;

----检查CR REQUEST情况 select CR_REQUESTS cr, CURRENT_REQUESTS cur, DATA_REQUESTS data, UNDO_REQUESTS undo, TX_REQUESTS tx from v$cr_block_server;

--如果比例高于25%,需要调整 _fairness_threshold from 4 to 2 or 1

select DATA_REQUESTS,FAIRNESS_DOWN_CONVERTS,FAIRNESS_DOWN_CONVERTS/data_requests from v$cr_block_server;

select CR_REQUESTS+CURRENT_REQUESTS,FAIL_RESULTS, FAIL_RESULTS/(CR_REQUESTS+CURRENT_REQUESTS) from v$cr_block_server;

select CR_REQUESTS, LIGHT_WORKS,LIGHT_WORKS/CR_REQUESTS from v$cr_block_server;

----检查GES情况 select LOCAL_NID, REMOTE_NID, REMOTE_RID, TCKT_AVAIL, TCKT_LIMIT, TCKT_RCVD, TCKT_WAIT from v$ges_traffic_controller;

--检查session message send情况 SELECT inst_id, sid, name, value FROM gv$sesstat st, v$statname sn WHERE st.statistic# = sn.statistic# AND sn.name in ('gcs messages','ges messages sent') AND value > 0 ORDER BY name, value;

----检查ITL争用情况 select STATISTIC_NAME stat,OWNER,OBJECT_NAME obj,sum(value) Val from v$segment_statistics where STATISTIC_NAME like 'ITL%' and value > 0 group by STATISTIC_NAME,OWNER,OBJECT_NAME order by val desc;

---检查GLOBAL CACHE传输情况 select name, kind, partition_name, sum(xnc) from v$cache_transfer group by name, kind, partition_name order by 4 ;

-- GES LOCK BLOCKERS: -- This section will show us any sessions that are holding locks that -- are blocking other users. The inst_id will show us the instance that -- the session resides on while the sid will be a unique identifier for -- the session. The grant_level will show us how the GES lock is granted to -- the user. The request_level will show us what status we are trying to obtain. -- The lockstate column will show us what status the lock is in. The last column -- shows how long this session has been waiting.

set numwidth 5 column state format a16 tru; column event format a30 tru; select dl.inst_id, s.sid, p.spid, dl.resource_name1, decode(substr(dl.grant_level,1,8),'KJUSERNL','Null','KJUSERCR','Row-S (SS)', 'KJUSERCW','Row-X (SX)','KJUSERPR','Share','KJUSERPW','S/Row-X (SSX)', 'KJUSEREX','Exclusive',request_level) as grant_level, decode(substr(dl.request_level,1,8),'KJUSERNL','Null','KJUSERCR','Row-S (SS)', 'KJUSERCW','Row-X (SX)','KJUSERPR','Share','KJUSERPW','S/Row-X (SSX)', 'KJUSEREX','Exclusive',request_level) as request_level, decode(substr(dl.state,1,8),'KJUSERGR','Granted','KJUSEROP','Opening', 'KJUSERCA','Canceling','KJUSERCV','Converting') as state, s.sid, sw.event, sw.seconds_in_wait sec from gv$ges_enqueue dl, gv$process p, gv$session s, gv$session_wait sw where blocker = 1 and (dl.inst_id = p.inst_id and dl.pid = p.spid) and (p.inst_id = s.inst_id and p.addr = s.paddr) and (s.inst_id = sw.inst_id and s.sid = sw.sid) order by sw.seconds_in_wait desc;

-- GES LOCK WAITERS: -- This section will show us any sessions that are waiting for locks that -- are blocked by other users. The inst_id will show us the instance that -- the session resides on while the sid will be a unique identifier for -- the session. The grant_level will show us how the GES lock is granted to -- the user. The request_level will show us what status we are trying to obtain. -- The lockstate column will show us what status the lock is in. The last column -- shows how long this session has been waiting.

set numwidth 5 column state format a16 tru; column event format a30 tru; select dl.inst_id, s.sid, p.spid, dl.resource_name1, decode(substr(dl.grant_level,1,8),'KJUSERNL','Null','KJUSERCR','Row-S (SS)', 'KJUSERCW','Row-X (SX)','KJUSERPR','Share','KJUSERPW','S/Row-X (SSX)', 'KJUSEREX','Exclusive',request_level) as grant_level, decode(substr(dl.request_level,1,8),'KJUSERNL','Null','KJUSERCR','Row-S (SS)', 'KJUSERCW','Row-X (SX)','KJUSERPR','Share','KJUSERPW','S/Row-X (SSX)', 'KJUSEREX','Exclusive',request_level) as request_level, decode(substr(dl.state,1,8),'KJUSERGR','Granted','KJUSEROP','Opening', 'KJUSERCA','Cancelling','KJUSERCV','Converting') as state, s.sid, sw.event, sw.seconds_in_wait sec from gv$ges_enqueue dl, gv$process p, gv$session s, gv$session_wait sw where blocked = 1 and (dl.inst_id = p.inst_id and dl.pid = p.spid) and (p.inst_id = s.inst_id and p.addr = s.paddr) and (s.inst_id = sw.inst_id and s.sid = sw.sid) order by sw.seconds_in_wait desc;

-- LOCAL ENQUEUES: -- This section will show us if there are any local enqueues. The inst_id will -- show us the instance that the session resides on while the sid will be a -- unique identifier for. The addr column will show the lock address. The type -- will show the lock type. The id1 and id2 columns will show specific parameters -- for the lock type.

set numwidth 12 column block format a12 trunc column event format a32 tru select l.inst_id, l.sid, l.addr, l.type, l.id1, l.id2, decode(l.block,0,'blocked',1,'blocking',2,'global') block, sw.event, sw.seconds_in_wait sec from gv$lock l, gv$session_wait sw where (l.sid = sw.sid and l.inst_id = sw.inst_id) and l.block in (0,1) order by l.type, l.inst_id, l.sid;

-- LATCH HOLDERS: -- If there is latch contention or 'latch free' wait events in the WAITING -- SESSIONS section we will need to find out which proceseses are holding -- latches. The inst_id will show us the instance that the session resides -- on while the sid will be a unique identifier for. The username column -- will show the session's username. The os_user column will show the os -- user that the user logged in as. The name column will show us the type -- of latch being waited on. You can search Metalink for the latch name in -- the search bar. Example (include single quotes): -- [ 'library cache' latch ]. Metalink should return some useful information -- on the type of latch.

set numwidth 5 select distinct lh.inst_id, s.sid, s.username, p.username os_user, lh.name from gv$latchholder lh, gv$session s, gv$process p where (lh.sid = s.sid and lh.inst_id = s.inst_id) and (s.inst_id = p.inst_id and s.paddr = p.addr) order by lh.inst_id, s.sid;

-- LATCH STATS: -- This view will show us latches with less than optimal hit ratios -- The inst_id will show us the instance for the particular latch. The -- latch_name column will show us the type of latch. You can search Metalink -- for the latch name in the search bar. Example (include single quotes): -- [ 'library cache' latch ]. Metalink should return some useful information -- on the type of latch. The hit_ratio shows the percentage of time we -- successfully acquired the latch.

column latch_name format a30 tru select inst_id, name latch_name, round((gets-misses)/decode(gets,0,1,gets),3) hit_ratio, round(sleeps/decode(misses,0,1,misses),3) "SLEEPS/MISS" from gv$latch where round((gets-misses)/decode(gets,0,1,gets),3) < .99 and gets != 0 order by round((gets-misses)/decode(gets,0,1,gets),3);

-- No Wait Latches:

select inst_id, name latch_name, round((immediate_gets/(immediate_gets+immediate_misses)), 3) hit_ratio, round(sleeps/decode(immediate_misses,0,1,immediate_misses),3) "SLEEPS/MISS" from gv$latch where round((immediate_gets/(immediate_gets+immediate_misses)), 3) < .99 and immediate_gets + immediate_misses > 0 order by round((immediate_gets/(immediate_gets+immediate_misses)), 3);

-- GLOBAL CACHE CR PERFORMANCE -- This shows the average latency of a consistent block request.
-- AVG CR BLOCK RECEIVE TIME should typically be about 15 milliseconds depending -- on your system configuration and volume, is the average latency of a -- consistent-read request round-trip from the requesting instance to the holding -- instance and back to the requesting instance. If your CPU has limited idle time -- and your system typically processes long-running queries, then the latency may -- be higher. However, it is possible to have an average latency of less than one -- millisecond with User-mode IPC. Latency can be influenced by a high value for -- the DB_MULTI_BLOCK_READ_COUNT parameter. This is because a requesting process -- can issue more than one request for a block depending on the setting of this -- parameter. Correspondingly, the requesting process may wait longer. Also check -- interconnect badwidth, OS tcp settings, and OS udp settings if -- AVG CR BLOCK RECEIVE TIME is high.

set numwidth 20 column "AVG CR BLOCK RECEIVE TIME (ms)" format 9999999.9 select b1.inst_id, b2.value "GCS CR BLOCKS RECEIVED", b1.value "GCS CR BLOCK RECEIVE TIME", ((b1.value / b2.value) * 10) "AVG CR BLOCK RECEIVE TIME (ms)" from gv$sysstat b1, gv$sysstat b2 where b1.name = 'global cache cr block receive time' and b2.name = 'global cache cr blocks received' and b1.inst_id = b2.inst_id or b1.name = 'gc cr block receive time' and b2.name = 'gc cr blocks received' and b1.inst_id = b2.inst_id ;

-- GLOBAL CACHE LOCK PERFORMANCE -- This shows the average global enqueue get time. -- Typically AVG GLOBAL LOCK GET TIME should be 20-30 milliseconds. the elapsed -- time for a get includes the allocation and initialization of a new global -- enqueue. If the average global enqueue get (global cache get time) or average -- global enqueue conversion times are excessive, then your system may be -- experiencing timeouts. See the 'WAITING SESSIONS', 'GES LOCK BLOCKERS', -- 'GES LOCK WAITERS', and 'TOP 10 WAIT EVENTS ON SYSTEM' sections if the -- AVG GLOBAL LOCK GET TIME is high.

set numwidth 20 column "AVG GLOBAL LOCK GET TIME (ms)" format 9999999.9 select b1.inst_id, (b1.value + b2.value) "GLOBAL LOCK GETS", b3.value "GLOBAL LOCK GET TIME", (b3.value / (b1.value + b2.value) * 10) "AVG GLOBAL LOCK GET TIME (ms)" from gv$sysstat b1, gv$sysstat b2, gv$sysstat b3 where b1.name = 'global lock sync gets' and b2.name = 'global lock async gets' and b3.name = 'global lock get time' and b1.inst_id = b2.inst_id and b2.inst_id = b3.inst_id or b1.name = 'global enqueue gets sync' and b2.name = 'global enqueue gets async' and b3.name = 'global enqueue get time' and b1.inst_id = b2.inst_id and b2.inst_id = b3.inst_id;

-- RESOURCE USAGE -- This section will show how much of our resources we have used.

set numwidth 8 select inst_id, resource_name, current_utilization, max_utilization, initial_allocation from gv$resource_limit where max_utilization > 0 order by inst_id, resource_name;

-- DLM TRAFFIC INFORMATION -- This section shows how many tickets are available in the DLM. If the -- TCKT_WAIT columns says "YES" then we have run out of DLM tickets which could -- cause a DLM hang. Make sure that you also have enough TCKT_AVAIL.

set numwidth 7 select * from gv$dlm_traffic_controller order by TCKT_AVAIL;

-- DLM MISC

set numwidth 10 select * from gv$dlm_misc; -- TOP 10 READ PINGING/FUSION OBJECTS -- This view shows the top 10 objects for read pings. The inst_id column shows -- the node that the block was pinged on. The name column shows the object name -- of the offending object. The file# shows the offending file number -- (gc_files_to_locks). The STATUS column will show the current status of the -- pinged block. The READ_PINGS will show us read converts and the WRITE_PINGS -- will show us objects with write converts. Any rows that show up are objects -- that are concurrently accessed across more than 1 instance.

set numwidth 8 column name format a20 tru column kind format a10 tru select inst_id, name, kind, file#, status, BLOCKS, READ_PINGS, WRITE_PINGS from (select p.inst_id, p.name, p.kind, p.file#, p.status, count(p.block#) BLOCKS, sum(p.forced_reads) READ_PINGS, sum(p.forced_writes) WRITE_PINGS from gv$ping p, gv$datafile df where p.file# = df.file# (+) group by p.inst_id, p.name, p.kind, p.file#, p.status order by sum(p.forced_reads) desc) where rownum < 11 order by READ_PINGS desc;

-- TOP 10 FALSE PINGING OBJECTS -- This view shows the top 10 objects for false pings. This can be avoided by -- better gc_files_to_locks configuration. The inst_id column shows the node -- that the block was pinged on. The name column shows the object name of the -- offending object. The file# shows the offending file number -- (gc_files_to_locks). The STATUS column will show the current status of the -- pinged block. The READ_PINGS will show us read converts and the WRITE_PINGS -- will show us objects with write converts. Any rows that show up are objects -- that are concurrently accessed across more than 1 instance.

set numwidth 8 column name format a20 tru column kind format a10 tru select inst_id, name, kind, file#, status, BLOCKS, READ_PINGS, WRITE_PINGS from (select p.inst_id, p.name, p.kind, p.file#, p.status, count(p.block#) BLOCKS, sum(p.forced_reads) READ_PINGS, sum(p.forced_writes) WRITE_PINGS from gv$false_ping p, gv$datafile df where p.file# = df.file# (+) group by p.inst_id, p.name, p.kind, p.file#, p.status order by sum(p.forced_writes) desc) where rownum < 11 order by WRITE_PINGS desc;

4.4 检查监听状态(每日工作) 在两个节点上,定期检查监听的状态 $ lsnrctl service LISTENER_SD2PPB

LSNRCTL for HPUX: Version 10.2.0.4.0 - Production on 07-OCT-2008 17:34:56

Copyright (c) 1991, 2007, Oracle. All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=rac2-vip)(PORT=8521))) Services Summary... Service "racsstf" has 2 instance(s). Instance "racsstf1", status READY, has 1 handler(s) for this service... Handler(s): "DEDICATED" established:1234refused:0 state:ready REMOTE SERVER (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.100.182)(PORT=8521)) Instance "racsstf2", status READY, has 1 handler(s) for this service... Handler(s): "DEDICATED" established:231 refused:0 state:ready REMOTE SERVER (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.100.184)(PORT=8521)) Service "racsstf_XPT" has 2 instance(s). Instance "racsstf1", status READY, has 1 handler(s) for this service... Handler(s): "DEDICATED" established:0 refused:0 state:blocked REMOTE SERVER (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.100.182)(PORT=8521)) Instance "racsstf2", status READY, has 1 handler(s) for this service... Handler(s): "DEDICATED" established:0 refused:0 state:blocked REMOTE SERVER (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.100.184)(PORT=8521)) The command completed successfully 从状态上看,必须state是READY,否则监听存在问题

4.5 检查CRS状态(每日工作)

cd $ORA_CRS_HOME/bin ./crs_stat

NAME=ora.rac1.gsd ----GSD DEAMON TYPE=application TARGET=ONLINE STATE=ONLINE

NAME=ora.rac1.oem -----OEM服务 TYPE=application TARGET=ONLINE STATE=ONLINE

NAME=ora.rac1.ons -----Oracle Notify Service服务 TYPE=application TARGET=ONLINE STATE=ONLINE

NAME=ora.rac1.vip ------VIP,虚拟IP TYPE=application TARGET=ONLINE
STATE=ONLINE

NAME=ora.rac2.gsd TYPE=application TARGET=ONLINE STATE=ONLINE

NAME=ora.rac2.oem TYPE=application TARGET=ONLINE STATE=ONLINE

NAME=ora.rac2.ons TYPE=application TARGET=ONLINE STATE=ONLINE

NAME=ora.rac2.vip TYPE=application TARGET=ONLINE STATE=ONLINE 正常情况下,所有节点的所有服务必须TARGET和STATE都是ONLINE状态。 4.6 使用SRVCTL检查系统状态(每日工作) 4.6.1检查数据库状态 用法: srvctl status database -d [-f] [-v] [-S ] -d 数据库的唯一名称 -f 包含禁用的应用程序 -v 详细输出 -S EM 控制台的附加信息 -h 打印用法

4.6.2检查实例状态 用法: srvctl status instance -d -i "" [-f] [-v] [-S ] -d 数据库的唯一名称 -i "<inst,...>" 逗号分隔的实例名 -f 包含禁用的应用程序 -v 详细输出 -S EM 控制台的附加信息 -h 打印用法

4.6.3检查服务状态 用法: srvctl status service -d [-s ""] [-f] [-v] [-S ] -d 数据库的唯一名称 -s "<serv,...>" 逗号分隔的服务名 -f 包含禁用的应用程序 -v 详细输出 -S EM 控制台的附加信息 -h 打印用法 4.6.4检查NODEAPPS状态 用法: srvctl status nodeapps -n -n 节点名 -h 打印用法 4.6.5检查ASM状态 用法: srvctl status asm -n -n 节点名 -h 打印用法

4.7 检查日志 日志检查应该是DBA每日例行工作。DBA应该每天检查OS、数据库、CRS、LISTENER等的日志文件。以确定数据库工作正常。 4.7.1检查OS日志(每周工作) 很多RAC的问题是由于日志引起的,因此应定期(每周,如果条件允许可以每日)检查OS的日志。OS日志检查应着重于: ?盘阵相关错误日志 ?网络相关错误日志 ?系统硬件报错 4.7.2检查数据库ALERT日志(每日工作) ALERT日志应该每日检查,以确定数据库工作正常。如果发现存在ORA-XXXX错误(比如ORA-600,ORA-7445)需要进行分析。以确定是由于BUG还是其他原因引起。 ALERT LOG应该每个月备份,并在备份后清理。 4.7.3检查LISTENER日志(每周工作) 定期检查LISTENER日志,发现SQL*NET连接的错误。LISTENER日志每个月应该进行备份和清理。 4.7.4检查CRS日志(每周) CRS日志存放于多个目录下: Alert 文件 CRSHOME/log//alert.log CRS 组件的目录 CRSHOME/log/
CRSHOME/log/
CRSHOME/log//crsd
CRSHOME/log//cssd CRSHOME/log//evmd CRSHOME/log//client CRSHOME/log//racg 应定期检查CRS的相关日志,如果发现异常就进行诊断。 5 权限与安全管理规范

信息的安全、保密和对组织的财产、数据的保护在任何业务系统中都是极其重要的。目前客户在用的数据库基本上是Oracle10g R2,该版本的数据库本身就提供了先进的安全特性,如深度数据保护、审计、可调整安全等级、安全主机和数据交换,从而全方位满足信息安全的需要。 在安全性方面,Oracle10G R2数据库服务器在业界处于领先地位。然而,为了在任何业务环境中最大限度地发挥Oracle10G R2的安全特性,Oracle10G R2自身的安全保护就很必要。另外,正确使用其安全特性,遵循基本的安全设置,有助于防范针对数据库的威胁和攻击,从而为Oracle10G R2数据库提供一个更加安全的操作环境。 本手册遵循并建议在数据库部署上使用业界标准“最佳安全实践”,提供如何对Oracle10G R2进行安全配置的指导。 5.1 常规安全规则 【规则-1】:只安装必要的组件,Oracle10g R2 CD-pack中除了数据库服务器之外还包括许多附加的选件和产品。应只在必需的时候才安装这些附加的产品和选件,或者在进行典型安装(如果不想使用自定义安装)完成后再卸载不需要的选件和产品。对于那些没有安装的选件和产品就不需要对它们进行维护。而且在需要时也可以很方便的重新安装它们。 【规则-2】:锁定缺省用户账号并使其密码过期,ORACLE通常会安装许多缺省的数据库用户账号。数据库配置助手工具(DBCA)在创建数据库时会自动把除了SYS、SYSTEM、SCOTT和DBSNMP之外所有的缺省数据库用户账号锁定并使其密码过期。 随后在安装附加产品和组件时会创建更多的缺省数据库用户账号。DBCA会自动锁定所有附加创建的用户账号并使其密码过期。应只解锁那些必须使用的账号并为其指定一个健壮的、有意义的密码。Oracle提供了SQL和密码管理来执行这些操作。 【规则-2】:修改缺省的用户密码,最普通的能危及Oracle的安全的方法就是使用缺省数据库用户账号和缺省密码。 3a. 修改管理员的缺省密码 在任何Oracle环境中(产品或测试),在成功安装数据库服务器后都应立即为SYS和SYSTEM用户指定健壮的、有意义的密码。DBCA在安装数据库时会要求输入SYS和SYSTEM账号的密码。绝不应该把SYS和SYSTEM的密码保持在它们的缺省状态。 在数据库创建过程的最后,DBCA会显示一个窗口要求输入并确认SYS和SYSTEM用户账号的新密码。 3b. 修改所有用户的缺省密码 在Oracle9iR2中,SCOTT的缺省密码是TIGER,DBSNMP的缺省密码是DBSNMP。通常,Oracle中大多数的用户账号的缺省密码和用户账号相同。 在成功安装后应立即修改SCOTT和DBSNMP账号的密码。如果任何在安装过程中被锁定或密码已过期的用户账号需要激活,则应指定一个新的有意义的密码。 虽然Oracle没有明确要求修改用户SCOTT的缺省密码,但是建议在产品库中把SCOTT用户账号锁定。 3c. 加强密码管理 我们建议把数据库提供的基本密码管理规则(例如密码长度,密码历史,复杂度)应用到所有用户密码上,所有用户都必须定期修改他们的密码。 【规则-4】:启用数据字典保护,建议应对数据字典进行保护以防止具有“ANY”系统权限的用户在数据字典上应用这些权限。 要启用字典保护,可以下面方式设置参数文件中的配置参数: O7_DICTIONARY_ACCESSIBILITY = FALSE 这么做以后,就只有那些经过授权的特权用户(比如CONNECT / AS SYSDBA)才能在数据字典上应用“ANY”系统权限。如果这个参数没有被设置为上面所推荐的值,则任何具有DROP ANY TABLE (比如说)系统权限的用户都将能够恶意删除部分数据字典。 如果用户需要查看数据字典,可以授予用户SELECT ANY DICTIONARY系统权限。 注意,在Oracle9i和Oracle9iR2以后的版本O7_DICTIONARY_ACCESSIBILITY = FALSE 是缺省设置。 【规则-5】:最小权限法则 5a. 只授予必需的权限 不要授予数据库用户多于其实际所需要的权限。换句话说,最小权限法则就是仅仅授予用户可以使其有效方便地完成任务所必需的权限。 要实行最少权限,应限制: 1)授予给数据库用户的系统权限和对象权限的数量;2)可以特权身份连接到数据库的用户数量。例如,通常没必要把CREATE ANY TABLE权限授予给任何非DBA用户。 5b. 撤销PUBLIC不必要的权限 撤销PUBLIC用户组的所有不必要的权限和角色。PUBLIC是一个缺省被授予给Oracle数据库中所有用户的角色。任何数据库用户都可以行使授予给PUBLIC的权限。其中就包括了执行一些PL/SQL包的权限,这就可能会导致只具有最小权限的用户可以访问并执行本来并不允许其访问的包。一些功能强大的可能潜在被误用的包包括: UTL_SMTP 这个包允许一个用户发送任意邮件信息给另一个用户。把这个包授予给PUBLIC可能会发生未经授权的邮件信息交换。 UTL_TCP 这个包允许数据库服务器建立与正在监听的网络服务的连接。从而,在数据库服务器和网络服务之间可传递任何数据。 UTL_HTTP 这个包允许数据库服务器通过HTTP请求并接收数据。把这个包授予给PUBLIC可能会发生把数据通过HTML表单发送到恶意网站的情况。 UTL_FILE 如果没有正确配置,这个包将允许访问操作系统中的任何文件。即使正确配置了,这个包也不会区分调用它的各个应用从而可能会导致一个应用通过UTL_FILE包重写了另一个应用使用的文件。 DBMS_RANDOM 这个包可被用来加密存储的数据。通常,大多数用户不应该具有加密数据的权限,因为如果没有安全的生成、保存和管理密钥的话被加密的数据将不可恢复。 这些包对于那些需要它们的应用是非常有用的,而对其它应用则不需要。因此,除非绝对需要都应把它们从PUBLIC撤销。 5c. 只在用户需要某一角色的所有权限时才把这个角色授予用户 角色是权限组,通过角色可快速方便地把权限授予用户。如果应用不要求用户具有角色的所有权限那么可以创建自己的角色包含适当权限。 比如要撤销SCOTT的create dblink权限从而限制SCOTT的权限。要注意到通过角色授予给用户的权限不能被个别撤销,必须首先撤销整个角色,重建一个只包含必需的权限的角色并把这个新角色授予给用户。要得到更好的安全性,可用类似的方式撤销所有不需要create dblink的用户的create dblink权限。 5d. 限制运行时工具的权限 不要把 “ALL PERMISSIONS”授予给任何数据库服务器运行时工具,例如Oracle Java Virtual Machine (JVM)。对于可以执行数据库服务器之外的文件和包的那些工具,应把特定权限授予给确定的文件路径。 【规则-6】有效加强访问控制 6a. 严格验证客户端 远程验证是Oracle9iR2提供的一个安全特性。如果开启此功能,将使用连接到Oracle数据库的远程客户端进行用户验证。从而,数据库就要求所有客户端能够正确验证它自己。要注意到客户端通常不被信任(例如个人电脑)可以正确执行操作系统验证,因此,开启这个功能会有安全风险。关闭此功能会更安全。此功能关闭后将基于服务器对正在连接到Oracle数据库的客户端进行验证。 要禁止远程验证从而由数据库对客户端进行验证,可以下面方式设置参数文件中的数据库配置参数: REMOTE_OS_AUTHENT = FALSE 在Oracle9iR2中这是缺省设置。 6b. 限制操作系统用户的数量 尽可能限制安装Oracle的主机(物理机器)的操作系统用户账号(管理的、root权限的或最少权限的)的数量。 我们建议任何特权操作系统用户和Oracle所有者都不能被允许修改Oracle主目录和其中的缺省文件和目录的权限,除非Oracle 公司另有规定。

  1. 限制网络访问 7a. 使用防火墙 应把数据库服务器放在防火墙后面。Oracle的网络基础结构,Oracle Net Services (以前称为Net8和SQL*Net),提供了对多家厂商的防火墙的支持。 7b. 不要使防火墙出现漏洞 如果Oracle在防火墙的后面,任何情况下都不要使防火墙出现漏洞。例如,不要开放Oracle Listener的1521端口使其能连到Internet,反之亦然。 如果防火墙存在漏洞将带来许多重大安全隐患,包括开放的端口过多、多重操作系统服务器问题和数据库的重要信息被泄露。此外,如果没有为Oracle Listener设定密码,它正在监听的数据库的重要信息就可能被刺探。例如跟踪和日志信息、banner信息以及数据库描述符和服务名。 如此多的信息再加上防火墙漏洞百出将为攻击者提供充足的机会对目标数据库进行恶意攻击。 7c. 防止对Oracle Listener未经授权的管理 应为Oracle Listener设置一个有意义的形式好的密码以防止远程配置Oracle Listener。另外,也可以下面方式设置listener.ora (Oracle Listener控制文件)安全配置参数: ADMIN_RESTRICTIONS_listener_name=ON 这样做可以防止对Oracle Listener未经授权的管理。 7d. 检测网络IP地址 利用Oracle Net“有效节点检测”安全特性来允许或禁止指定IP地址的网络客户端访问Oracle服务器进程。要使用这个功能,可设置下面的protocol.ora (Oracle Net配置文件)参数: tcp.validnode_checking = YES tcp.excluded_nodes = {IP地址列表} tcp.invited_nodes = { IP地址列表} 第一个参数打开此功能,而后面两个参数分别拒绝或允许指定的客户端IP地址连接到Oracle监听器(从而可以预防潜在的拒绝服务攻击)。 7e. 加密网络传输 如果可能,应使用Oracle Advanced Security加密客户端、数据库和应用服务器之间的网络传输(只有Oracle企业版才支持Oracle Advanced Security)。在典型安装模式中会安装Oracle Advanced Security。如果得到了许可,可用Oracle Net Manager工具或手工设置6个sqlnet.ora参数以启用网络加密。 7f. 加固操作系统 可通过禁用所有不必要的操作系统服务来加固操作系统。UNIX和Windows平台都提供了许多操作系统服务,而其中大多数的服务对于大多数的部署都不是必需的。这些服务包括FTP、TFTP、TELNET等等。在禁用某个服务时要确保那个服务的UDP端口和TCP端口都被关闭了。只禁用一种类型的端口不会使操作系统更安全。 【规则-8】:应用所有的安全补丁和解决方法 在Oracle所安装在的操作系统、Oracle本身和安装的所有Oracle组件上应用当前所有的安全被丁。 定期检查Oracle Technology Network上的安全站点查看Oracle公司发布的安全报警。 5.2 合规性访问

通过Oracle DATABASE VAULT组件增强数据库的安全级别,通过更为细粒度的权限管理进一步限制超级用户和SYSDBA权限用户对业务数据的访问。既可以避免不必要的误操作,也可以防止不必要的泄密。 DATABASE VAULT的主要目的是实现数据库管理的职责分离,业务部门管理业务数据,系统管理员管理系统,通过细粒度管理,实现双方访问数据的全面分离:

5.3 数据遮蔽

开发部门需要业务部门提供测试数据,从生产系统直接复制下来的业务数据包含了大量的商业机密,这些数据在提供给开发人员使用之前必须进行数据遮蔽,以确保数据的安全。

Aries-ckt commented 1 year ago

是最新代码吗?

MimeZoe0628 commented 1 year ago

我用的v0.0.6,对话也是响应的是乱码 test @Aries-ckt

csunny commented 1 year ago

There are too many tokens, in subsequent releases, we will limit the token length, you can try the latest release.