存档

2014年6月 的存档,文章数:5

本文的目的在于给出一种方法(或者workaround)来屏蔽错误Error: 9561。

在老环境ASE 12.5上测试某程序时,执行一些命令会报Error: 9561!

环境介绍:

ASE版本为: Adaptive Server Enterprise/12.5/SWR 9616 GA/P/NT (IX86)/OS 4.0/main/1647/32-bit/OPT/Fri Jun 01 16:58:25 2001
此版本为ASE 12.5 GA,裸奔很久了。

lock scheme=allpages

系统库model、tempdb以及用户数据库均启用了选项:allow nulls by default

本文介绍我遇到的一例ASE Error: 624的解决过程;所使用的方法仅对我遇到的案例时适用的。

对于Error: 624,主要有两种情况:

一、ASE服务器联机状态中,损坏的非聚簇索引的叶页指向不正确或不存在的RID;

二、ASE服务器自动恢复过程中,事务日志中最后一条检查点记录的数据结构指向日志中不正确或不存在的记录;

问题确认:

我所遇到的这个案例是属于第二种情况,事务日志页指向有错误。

客户反映ASE 15.0.3无法启动,错误日志报错:Error: 624

Adaptive Server failed to retrieve a row via its RID in database 'master' because the requested RID has a higher number than the last RID on the page. 0x28.0xbdb.

ASE将索引标记为“可疑”时,或者ASE的排序顺修改后,索引状态会设置:-32768, patrol指标SuspectIndex会监控数据库中可疑索引的个数。   查找出现索引索引损坏的表: 存储过程:sp_indsuspect [table_name]                     如果不加表名,就是查找当前数据库中因排序顺序更改需被重建的索引的所有表; 或: select u.name as user_name, o.name as table_name, i.name as index_name,i.status from  sysobjects o,  sysindexes i,  sysusers u where   o.id = i.id   and o.uid = u.uid   –and o.id = object_id('table_name')   and (i.status & -32768) != 0 例子: 1> sp_indsuspect 2> go Suspect indexes in database [...]

曾经写过博文介绍利用代理表统计数据库内所有表占用空间情况,也包括表的行数: 可以参考:ASE15.0中利用代理表实现统计用户表存储空间大小的功能 配置代理表可能有些麻烦,本文提供一个简单的脚本来获得数据库内表的行数。 #!/bin/bash ISQL="isql -Usa -P -SSYBASE -w5000" database_name="tpchdb" $ISQL  <<EOF  | sed -e '1,2d' -e 's/^ *//;s/ *$//' -e '/^$/d' > tablename.list use ${database_name} go set nocount on go select name from sysobjects where type='U' order by name go quit EOF while read table_name do         if [ "${table_name}" = "" ]; then [...]

在定义游标时不指定for update 或 for read only,ASE会检查以了解游标是否可更新;

如果游标查询语句中包含order by子句,则ASE会将游标定义为只读;其它情况下定义为可更新游标;

如果不涉及更新或删除表数据的话,建议在游标定义中加上for read only选项,这样ASE将游标定义为只读;

 

表customer在c_custkey列上建有唯一索引,查询表的前10行内容(所有字段拼接成一个字符串),

如果定义游标为for read only:

    declare cur_hash cursor for select top 10 convert(varchar,c_custkey)+coalesce( nullif(isnull(c_name,''), '') , ' ')+coalesce( nullif(isnull(c_address,''),'') , ' ')+convert(varchar,c_nationkey)+coalesce( nullif(isnull(c_phone,''),'') , ' ')+convert(varchar,c_acctbal)+coalesce( nullif(isnull(c_mktsegment,''),'') , ' ')+coalesce( nullif(isnull(c_comment,''),'' ) , ' ') from customer for read only

则使用表扫描返回表的前10行数据;