`
被触发
  • 浏览: 34508 次
文章分类
社区版块
存档分类
最新评论

sybase问题整理

阅读更多

1) 关于定时备份

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1233&show=390

crontab 中可以这样写:

00 23 * * * /sybase/ASE-12_0/bin/DUMPDB.sh >>/sybase/ASE-12_0/install/DUMPDB.out

放那里都无所谓,一个dumpdb.sh的例子:

#SUN Solaris 8

#!/bin/ksh

export SYBASE=/sybase

export SYBASE_FTS=FTS-12_0

export PATH=/sybase/ASE-12_0/bin:/sybase/OCS-12_0/bin:$PATH:/sybase/ASE-12_0/install:/usr/sbin

export SYBASE_OCS=OCS-12_0

export SYBASE_ASE=ASE-12_0

export LM_LICENSE_FILE=/sybase/SYSAM-1_0/licenses/license.dat:$LM_LICENSE_FILE

export LD_LIBRARY_PATH=/sybase/ASE-12_0/lib:/usr/local/openwin/lib:/sybase/FTS-12_0/lib:/sybase/OCS-12_0/lib:/usr/local/openwin/lib:/usr/lib:/sybase/SQLRemote/lib:$LD_LIBRARY_PATH

export SYBASE_SYSAM=SYSAM-1_0

export HOME=$SYBASE

$SYBASE_OCS/bin/isql -Usa -SSYBASE -P <dump database YOURDBNAME to "/sybdump/dump.01"

                stripe on "/sybdump/dump.02"

                stripe on "/sybdump/dump.03"

                stripe on "/sybdump/dump.04"

                stripe on "/sybdump/dump.05"

go

!

这里是一个典型的脚本,用于实现full备份!

#!/usr/bin/sh

# *************************************************************************

#for full backup after excuted dbcc operation

# *************************************************************************

SHLIB_PATH=/opt/sybase/ASE-12_0/lib:/opt/sybase/FTS-12_0/lib:/opt/sybase/OCS-12_0/lib:/usr/lib:/lib:/usr/lib/Motif1.2:/opt/sybase/SQLRemote/

lib

export SHLIB_PATH

SYBASE_OCS=OCS-12_0

export SYBASE_OCS

SYBASE=/opt/sybase

export SYBASE

ISQL="/opt/sybase/OCS-12_0/bin"

ymd=`date +%y%m%d`

bk_user="unb"

bk_pwd="******"

bk_db="SYB_HP"

cd /sybase/backup

mkdir $ymd

LOG="/sybase/backup/$ymd"

echo $ymd >$LOG/backup.log

echo "\n11*************************" >>$LOG/backup.log

echo "Check database $bk_db..." >>$LOG/backup.log

d1=`date`

su - sybase -c "isql -SSYB_HP -Usa -P****** <$LOG/dbcc-$ymd.log 2>&1

dbcc traceon(3604)

go

dbcc checkdb($bk_db)

go

dbcc traceoff(3604)

go

DBCC

echo $d1,`date` >>$LOG/backup.log

echo "\n22*************************" >>$LOG/backup.log

d1=`date`

dump_file="/sybase/backup/$dump-unb-full-$ymd.dat"

echo "Dump database $bk_db to " $dump_file >>$LOG/backup.log

su - sybase -c "isql -SSYB_HP -Usa -P****** <$LOG/dump-$ymd.log 2>&1

dump database $bk_db to "$dump_file"

go

DUMP

echo $d1,`date` >>$LOG/backup.log

echo "\n33*************************" >>$LOG/backup.log

请根据自身系统,调试后再使用!

至于备份日志的脚本与此类似,自己根据sybase的相关语法,稍加变动即可!

2) 有个关于游标的问题,请教各位大虾

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=429&show=390

在sybase数据库中用游标操作完表a的记录后,关闭close游标,在free游标。但接着想drop此表a,结果失败,显示的错误信息是"游标在使用"(记得不是很清楚了,大概是这个意思)。

请碰到过这类问题的大虾支持支持。在informix和oracle中释放游标是用free,在sybase也是用free吗?

sybase 中正确操作游标的顺序是:

1、DECLARE CUR_ACCTINFO CURSOR FOR SELECT .....    (定义)

2、OPEN CUR_ACCTINFO                               (打开)

 

3、WHILE @@SQLSTATUS = 0                            (判断是否成功)

 BEGIN

 

4、         FETCH CUR_ACCTINFO INTO  .......     (取数据)

          IF @@SQLSTATUS  <> 0

 begin

                    ......

 end

           ...........

5、 CLOSE CUR_ACCTINFO               (关闭)

6、 DEALLOCATE  CURSOR CUR_ACCTINFO  (释放)

3) 在sybase中有没有进行数据类型转换的函数

  http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1346&show=330

四舍五入用round,如round(123.4567,1)=123.5或round(123.4567,0)=123或round(123.67,0)=124

去尾用floor,如floor(123.4567)=123

进尾用ceiling,如ceiling(123.4567)=124

 

4) 新手问题:为什么我的SYBASE的RUN_BACKUP老是自己DOWN啊!?

  http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1335&show=330

 为什么我的SYBASE的RUN_BACKUP老是自己DOWN啊!?

我用NetTerm登陆运行,但只要一退出NetTerm,BACKUP就自己DOWN了

加&运行也不行,怎么办啊?

 

命令前加nohup 试试

那是因为你的backup进程是以你的登录用户起动的,所以当该用户退出unix时,

进程也跟着退出操作系统了

5) 什么是BYPASS RECOVERY mode?

  http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1371&show=300

 

在客户端出现提示:

Attempt to BEGIN TRANsaction in database "****" failed because database is in BYPASS RECOVERY mode.

请问如何解决?

select name,status from master..sysdatabases where db_name="你所说的数据库"

看status是否是-32768 ,若是,sysdatabases系统表相应记录的status字段改为0,reboot数据库服务器就可以了。

谢谢各位,问题已解决。中午去SYBASE网站查找到有关这个问题的详细信息,包括问题成因及解决办法:

Error 3908

Severity

16

Error Message

Attempt to BEGIN TRANsaction in database '%.*s' failed because database is in BYPASS RECOVERY mode.

Explanation

Adaptive Server can start various types of transactions such as local (in response to a local command), internal (for the server's own use), external (started by an external client like a TP Monitor) and subordinate (child transactions started by a parent transaction in parallel).

Bypass recovery starts Adaptive Server without recovering one or more databases. A database in this mode can be accessed even though it is not recovered. You use this mode to allow access to the database for problem analysis, to copy out data, and so on.

Error 3908 is raised when a transaction is attempted while the database is in bypass recovery. Although certain commands are permissible in this mode, no transactions - regardless of type - can be started when the database is in bypass recovery.

Error 3908 is raised in the following states:

 

State Meaning

1 Attempted to start a transaction when the database is not available for update. Applies to all possible transaction types.

2 Attempted to start a subordinate transaction when the database is not available for update.

Action

Do not attempt to start a transaction while the database is in bypass recovery. Check if any automated jobs may have submitted a batch job that attempted such a transaction. First restore the database to the original working status it had (prior to bypass status) before attempting any transactions.

Use the following steps to reset the database status:

Note Although a status of zero is usually appropriate, it is not the only possible status value you can use. Reset the database to the actual, normal status it had prior to entering bypass recovery status.

1. Reset the database status to 0:

1> sp_configure "allow updates", 1

2> go

1> begin tran

2> go

1> use master

2> go

1> update sysdatabases set status=0 where name=

2> go

Check that the above update command affected only one row (if more than one row was affected, issue a rollback transaction.) Then commit the transaction and shut down Adaptive Server as follows:

1>commit tran

2>go

1>shutdown with nowait

2>go

2. Restart Adaptive Server. Run dbcc checkdb and dbcc checkalloc on the affected database to make sure there are no errors.

Version in Which This Error is Raised

All versions.

再次谢谢aladdin,freebob,changing。

6) 数据库表BCP出来报错

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1326&show=300

数据库表BCP出来报错

DB-LIBRARY error

 I/O error while writing bcp data-file

bcp出来的文件正好2GB,实际应该更大。

操作系统SCO OpenServer5.0.4, SYBASE 11.0.3

请问是何原因?谢谢。

当在后备数据量大于2GB的数据库时,可能会遇到以下错误:

I/Oerror:

operating system error,server device /backup/data. code 27 messages

file too large.

  这是由于后备文件的大小超出了操作系统的用户最大文件限制。而有些操作系统不支持大于2GB的文件,这时可以使用Backup Server将一个数据库后备到多个文件中。

  1>dump database pubs2 to "/usr/sybase/pubs2_dump.1"

  2>stripe on "/usr/sybase/pubs2_dump.2"

  3>stripe on "/usr/sybase/pubs2_dump.3"

  4>go

  这种方法还可以提高后备及恢复的速度,但注意恢复也必须用相应多的设备。例如:

  1>load database pubs2 from "/usr/sybase/pubs2_dump.1"

  2>stripe on "/usr/sybase/pubs2_dump.2"

  3>stripe on "/usr/sybase/pubs2_dump.3"

  4>go

7) sybase的sa口令丢失怎样恢复?

  http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1239&show=270

在RUN-SERVER文件中加入一行-psa,重起dataserver,在控制台上可以看见新的口令

http://www.powerba.com/develop/database/sybase/article/20010505001.htm

8) sybase表中如何删掉多条相同的记录?

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1438&start=0&show=180

sybase表中如何删掉多条相同的记录?

由于表出问题,将没有进行处理的*.txt文件bcp到表中,其中含有大量的重复记录。

请问有没有办法将表中重复的记录删掉呢?

那好办,那你就可以使用下面语句将唯一的记录先插入到临时表中:

select distinct a ,b,c,d ... into tempdb..tempdb_table from tablename

然后清空原表,把临时表中的数据插入正式表中!

试试看

可以参考这种经典方法:

1---select * into tmp_tab from your_dup_tab where 1=2

2---若表无唯一性索引则建一个唯一性索引(一定能找到一个唯一性的索引建(复合索引))create unique index(列名1,列名2...) on tmp_tab with ignore_dup_key.

3----insert into tmp_tab from your_dup_tab

这样在新表中将自动删出重复记录。但数据量过大请留意日志空间(sp_spaceused syslogs).

很使用的方法.try it!

9) 关于阀值

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1231&show=180

发告警或者水自动溢出,以保护系统不至于达到危险境界。对于数据库而言,我们使用的存储设备毕竟有限,如果任由数据或日志增长,数据或日志日久天长终将占用所有存储设备,如果到了没有空间的时候,系统将挂起,这样业务将暂停。所以对于一些要求数据库可用性很高的系统,必须保证在可预见的情况下数据段或者日志段不至于没有空间!为做到这一点,传统的数据库一般都需要系统维护人员经常的定期的进行数据库检查,若数据段不够了,转储一部分数据或者增加一些设备,若日志空间不够了,转储日志!但这样系统管理员就有点累了!

为减轻系统管理员的负担,提高系统的自动化程度,sybase提出了用阀值进行自动管理的这样一种模式,只要在开始定义好各段的阀值,以及达到阀值后的处理存储过程,就可以实现自动管理了!

不过,我先前也想这样做,也研究了一阵子,但是后来还是放弃了这种懒惰的办法。因为使用阀值管理可能出现一些意想不到的问题,什么问题现在还没想到,只是sybase不推荐在大系统中这样做!再加上本身系统有omni back备份软件,何必自找麻烦呢!

10) 什么SYBASE安装完后要增加TEMPDB的空间?

 http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1444&show=180

扩展后sp_helpdb tempdb看应改master设备上是data/log的

你use tempdb

sp_dropsegment 'default',tempdb,master

sp_dropsegment system,tempdb,master

sp_dropsegment logsegment,tempdb,master

后,

sp_helpdb tempdb

select db_name(dbid),segmap,lstart,size,vstart,pad,unreservedpgs

from sysusages

where dbid=2

贴出来

如果第一行中segmap为0,就ok

 

你们回答的什么,驴唇不对马嘴(呵呵,开玩笑)

一般情况下数据库装好之后,都要给tempdb增加空间,因为在用户数据库中的很多插入,删除等操作需要用到tempdb数据库作为临时存储空间,所以要增大他的空间,否则可能你的事务不能执行

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=185&show=120

sybase 临时数据库

缺省情况下,tempdb数据库是放置在master设备上,容量为2M,而临时数据库是活动最为平凡的数据库常常被用来排序、创建临时表、重格式化等操作,所以tempdb的优化应该受到特别的关注。本篇文章目的在于使你掌握临时数据库的优化策略以及临时表的优化使用。本文中,你将以调整临时库的位置开始,有步骤的完成临时数据库的优化,并在此过程中了解到优化临时数据库和临时表的一些方法和规则。

实验环境的要求:你应具有系统管理员的权限,系统中有auths和article表。

步骤:

第一步:调整临时库的位置

  tempdb数据库缺省放在master设备上,将临时数据库发在分离的设备上是更可取的。

1)  初始化一个用来存放临时数据库的设备

disk init

name="tempdb_dev",

physname="d:\sybase\example\tempdb.dat",

vdevno=13,

size=15360

(注意:如果将tempdb数据库放在多个设备上,需初始化多个数据库设备)

2)将临时数据库扩展到该一个设备上

  alter database tempdb on tempdb_dev=30

3)打开tempdb数据库,从段上删除master设备

sp_dropsegment "default",tempdb,master

sp_dropsegment logsegment,tempdb,master

4)发出如下命令,检查default段中是否不再包含master设备

     select dbid,name,segmap from sysusages,sysdevices

where sysdevices.low<=syusages.size+vstart

and sysdevices.high>=sysusages.size+vstart-1

and dbid=2

and(status=2 or status=3)

说明:若将临时数据库放在多个磁盘设备上,可以更好的利用并行查询特性来提高查询性能。

第二步:将临时数据库与高速缓冲进行绑定。

  由于临时表的创建、使用,临时数据库会频繁地使用数据缓存,所以应为临时数据库创建高速缓存,从而可以使其常驻内存并有助于分散I/O:

1、创建命名高速缓存

sp_cacheconfig “tempdb_cache","10m","mixed"

2、重新启动server

3、捆绑临时数据库到tempdb_cache高速缓存

sp_bindcache “tempdb_cache", tempdb

4、若有大的I/O,配置内存池

第三步:优化临时表

   大多数临时表的使用是简单的,很少需要优化。但需要对临时表进行复杂的访问则

应通过使用多个过程或批处理来把表的创建和索引分开。以下两种技术可以改善临时表的优化

slash;         在临时表上创建索引

1)  临时表必须存在

2)  统计页必须存在(即不能在空表上创建索引)

slash;         把对临时表的复杂的使用分散到多个批处理或过程中,以便为优化器提供信息

下面的这个过程需要进行优化:

create proc base_proc

as

select * into #huge_result from auths

select * from article, #huge_result where article.author_code=

#huge_result.author_code and sex="0"

使用两个过程可以得到更好的性能

1)create proc base_proc

as

select *

into #huge_result

from auths

exec select_proc

2)  create proc select_proc

     as

select *       from article,#huge_result

where  article.author_code=#huge_result.author_code and sex="0"

说明:在同一个存储过程或批处理中,创建并使用一个表时,查询优化器无法决定这个表的大小。

结论:通过本实验我们知道,临时数据库经过优化可以极大的提高系统性能。实际工作中,必须考虑具体应用的情况,需长时间经验的积累。

11) 怎样利用脚本自动关闭sybase数据库

 http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1484&show=180

不知你什么平台,如果是unix,ksh

#!/bin/ksh

LOGIN="`whoami`"

if [ "${LOGIN}" != "sybase" ]; then

 echo "`basename $0`: You should login as 'sybase'\n"

 exit 0

fi

echo "\n\n"

{

isql -Usa -P -Syourservername > /dev/null 2>&1 <use master

go

shutdown SYB_BACKUP

go

shutdown

go

ISQL

}

12) 请教存储过程动态使用表

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1488&show=180

你指动态sql

要12.0版本以上才支持

CREATE PROCEDURE dbo.mytt

(@c varchar(25))

AS

  BEGIN

declare @cc varchar(25)

select @cc = "select * from " + @c

exec (@cc)

  END

13) sybase中的跨库操作

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1489&show=150

假如本机server为loc_server,远程server为re_server

在这两个server 各自的interface文件里都必须有定义

sp_configure "allow remote access"是否为1;

在本机server上:

sp_addserver re_server

sp_addserver loc_server,LOCAL --->这样你select @@servername就有东西

在remote server 上:

sp_addserver loc_server

sp_addserver re_server,LOCAL

在2个server 上

sp_addremotelogin ......

检查这两个参数

number of remote sites

number of remote connections .

然后:

如果isql从loc_server 到rs_server

connect to rs_server

disconnect

rs_server...sp_who在loc_server上执行rs_server 上的sp_who

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1560&start=15&show=90

这里给你提供一篇这方面的资料:

如何实现两个Sybase Adaptive Server之间的数据通信

 在进行以Sybase作为后台数据库的MIS系统开发时,经常会碰到需要在两个Sybase Adaptive Server之间进行数据通信的问题。要解决这一问题通常由两类方法:其一便是在前台来做;这种方法一般是通过建立多个事务,分别连接到不同的Server,在应用程序中通过编程实现数据的交换。这种方法的缺点在于可维护性差,还有一点是由于需要多个事务肯定也会影响效率。另外一类方法就是利用Sybase 的Transact SQL在后台来做。这类方法把数据的通信工作交给了SQL服务器自己去做。这种方法显而易见的一种有点便是可维护性好,当业务发生变化或服务器设置改变时可以很少修改大部分情况是不用修改应用程序。下面举一个简单的例子来介绍一下如何利用Transact SQL在后台实现SQL服务器之间的数据通信。

---- 假设有两台操作系统都是Windows NT的Sybase SQL服务器LocalServer、RemoteServer,两者能够相互访问即应是通过网络相连的;在LocalServer和RemoteServer上分别有数据库LS_database和RS_database;在数据库LS_database和RS_database里分别有表LS_table和RS_table。

---- 假设现在业务规则是当LS_table更新时需要更新RS_table。

---- 要实现这种业务逻辑首先需要在RemoteServer的RS_database里建立至少一个带参数的存储过程设为pro_upd_rst,用来更新RS_table;其次需要在表LS_table上建立三个触发器:设为update_rst、delete_rst和insert_rst,在这些触发器中调用RS_database中的存储过程。即采用触发器传递参数进行远程存储过程调用(Remote Procedure Calls)的技术来实现。当LS_table发生更新时触发器update_rst、delete_rst和insert_rst中有一个会被触发,通过临时表inserted和deleted能够得到更新的信息,赋给相应变量,传递参数给pro_upd_rst并调用之。

---- 需要提到的一点是Sybase数据库的缺省安装并没有设置RPC,所以还要对LocalServer进行一些设置工作,这一点比较有必要强调尤其是对于初学者来说。这些设置工作主要有以下几点:

运行LocalServer接口程序管理器Dsedit添加一个Server,Server Name设置为"RemoteServer"(可以是其他字符串),编辑Server Address,添加网络协议和端口号,通常选择TCP/IP协议,Network Address 设为"RemoteServer,5000",其中RemoteServer(这里指的是该服务器在网络中的机器名)可以用其IP地址来代替。试一试能否Ping通RemoteServer。Ping通后进行下面的工作。

在LocalServer添加一个远程服务器,可以通过运行LocalServer的Sybase Central,打开LocalServer的"remote servers"文件夹,双击"Add Remote Server",在编辑框内输入一个字符串设为"Remote_Local"(注意区分大小写),在下面的下拉列表框中选择"RemoteServer"(这是第1步中的Server Name),点击下一步后在列表框中选择"sql_server"完成。

重新设置LocalServer一些与RPC有关的参数,也可以通过Sybase Central。右键点击LocalServer,单击谈出菜单的"configure",在下拉列表框种选择"Component Integration Services",注意下面的两个参数"cis rpc handling" 和 "enable cis",这两个参数的缺省值都是"0",应该把它们都改为"1"。由于"enable cis"是静态参数所以修改后需要重起数据库才能生效。最后最好检查一下RemoteServer的"enable remote access"参数的值是否为"1"(缺省情况应该是"1")否则改为"1"。

---- 其中第1步可以通过编辑接口文件sql.ini(在Sybase根目录的"ini"子目录下)来代替,打开sql.ini在最后加入如下三行:

[RemoteServer] master=TCP,RemoteServer,5000 query= TCP,RemoteServer,5000

        保存并关闭。

---- 第2、3步可以通过系统存储过程"sp_configure"来代替,在SQL Advantage或isql中执行下列语句:

sp_addserver Remote_Local,null,RemoteServer

        go sp_configure "enable cis",1 go sp_configure "cis rpc handling",1

        go

---- LocalServer配置号以后应该测试一下,运行SQL Advantage或isql连接LocalServer执行下列语句"exec Remote_Local.master.dbo.sp_help",再次强调一点其中的Remote_Local区分大小写。

---- 上面所举的只是一个简单的例子,只能在LocalServer上调用RemoteServer上的存储过程,若要在RemoteServer调用上LocalServer上的存储过程则要在RemoteServer进行同样的设置(添加Remote Server、重新配置RemoteServer的参数等),并且要保证LocalServer的"enable remote access"的值为"1"。

14) ASE在windows xp/2000上安装的二个注意的问题

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1522&show=150

本人近日在Windows xp上安装Sybase ASE12.5开发版作学习之用。遇到了一点麻烦,现将解决办法介绍给大家参考,如有还有类似的问题可联系我:email: learun@hotmail.com

一、ASE12.4 在XP下中文乱码解决办法:

  查看注册表,在键:key_local_machine\software\microsoft\windows NT\CurrentVersion\CurrentVerison中,可知当前系统版本为5.1

  进入Sybase源安装目录,查看run.bat文件,找到一行:set JAVA_HOME=.\shared-1_0\jre1.2.2,

然后进入: .\shared-1_0\jre1.2.2\lib目录,将文件font.properties.zh.NT4.0的名称改为font.properties.zh.NT5.1即可。如果源目录在光

盘上,将jre1.2.2目录、run.bat文件拷到硬盘上,修改run.bat中的JAVA_HOME项,然后运行run.bat.

 安装后,基于中文的管理工具依然会出现乱吗,按上面的方法更改%sybase%\shared-1_0\jre1.2.2\lib中的font.properties.zh.NT4.0文件

名。

 一些windows操作系统的版本号:

 windows9898

 windows nt4nt4.0

 windwos 2000nt5.0

 windows xpnt5.1

二、网络地址

 安装过程中,需要配置sql server和sybase xp server的网络地址。在安装界面上,对网络地址没有什么说明,如果输入错了,也没什么提

示。它其实与协议类型有关,如果是TCP协议,它的构成为:机器名(或IP地址), 端口号。例如:myserver,9001 。在安装后也可以用

“Dsedit"来编辑。网络地址很重要,如果错了,服务器无法启动。

 另:当启动信息中含有:in module 'e:\rel12501\porttree\svr\sql\generic\ksource\strmio\n_winsock.c' 。不必为这句话迷惑,这是

Sybase程序的硬编码输出,与你的E盘有无此文件无关。

15) 关于数据库锁

http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1118&show=120

SYBASE 11.9以上的版本提供行级锁。

锁类型选择的确是sybase数据库设计的一个需要重要考虑的问题!见大家讨论的如此火热,特上点干材支持一把,来点关于lock的借介绍性资料!

所支持的加锁机制

2.1 全页加锁

  全页加锁既是一个新术语,它又是由ASE(Adaptive Server Enterprise)在过去所支持的一种加锁类型。这种类型有下列特性:

对所有可被访问的页面在页面级加锁

当各种类型的页面以任何方式发生改变时,对这些排它性的页面进行加锁;而且这种加锁机制一直保持到该事务终止;

当下一个所需的页面已经成功地获得,对那些已经释放的的当前访问页进行共享页面加锁(如果采用了第三层ANSI隔离,则把这种加锁机制保持到该事务终止为止)

采用页级时间印记(timestamp)以确定是否发生改变,详细信息记录在事务日志中,以便在系统恢复时以向前或向后方式使用。

  这种加锁方式常常提供性能最高的解决方案,特别是当应用设计时已经考虑了这些特性时更是如此。但是,有一些应用系统,当发生某些活动时,这种对整个页面进行加锁的方式就可能会对系统性能产生有重大意义的影响。对于那些面对诸如文件系统或其它已经支持更细小尺度加锁机制的数据库厂家产品的一般环境而设计的应用系统而言,这种情况尤其如此。

  此外,还存在一系列问题,它们要围绕着更加困难的条件进行工作。它们通常要采用更加具有Sybase特性的解决方案。对于商用的应用软件制造厂商而言,对他们是一个挑战,因为这将要求他们必须跨越他们所支持的数据库平台,去完成维护其原代码的工作,而这个工作有相当工作量。在这个领域的基本问题如下:

对已经按照升序值创建的非群聚性索引的最末端叶型页面存在着争议

对非群聚性索引的表进行插入和查询时可能发生死锁;

在按照群聚性的索引值进行更新和对非群聚性索引的表进行查询访问之间可能发生死锁;

在没有作索引的表的最后一行可能发生冲突(尽管对最后的特定地址可以使用分区) ;

有可能使行数很少的表之间发生潜在的冲突(尽管对特定的地址可以使用填充因子[ fillfactors]和每页最大行数[ max_rows_per_page]这两个参数)

对每个页面两边进行加锁的需要常常被分割开来;

如果一个表特别小,以致在一个单一页面中进行驻留,那么对单一行的访问实际上将破坏对整个表的加锁机制。

2.2 仅对数据加锁

  仅对数据加锁机制试图去解决本文前一节所关注的主要问题(其他的议题将在其它功能领域中加以解决)。这种加锁方式支持两类不同的工作方式: 数据行加锁和数据页加锁。在这两种情况中,对于它们所支持的加锁方式,都与以前的加锁机制有所不同。仅对数据加锁具有下列特性:

在索引页面中不会破坏事务加锁。相反,而是采用了一种称之为锁存的机制。锁存是一种类似于旋转锁(spinlocks)的同步方法,它们与事务无关并且只保留很短的周期(一般而言,当一个任务在数据库中物理上改变一小片数据时,这个周期相当于在共享存贮区中在一个2K的页面改变某些字节数据的时间)一旦完成之后,这个任务将直接打开这个锁存。当这种情况还可能临时同其它组块时 ,因为这种锁存不能对服务器任务进行有上下文的切换,也不能涉及死锁,并且只能保持主要的一小段时间,所以它们不能产生有显著意义的争用。

采用一个RID对单一行进行数据行加锁(行标识[RID----Row ID]是逻辑页号与所在页面上该行号的组合);

支持固定的行标识 RIDs, 它可以是向前的,允许不进行其RID的改变,就完成数据行的移动。当一行变大超过了它的可用空间时,采用上述结果对非群聚索引不需要进行任何改变。

不需要进行任何争用就可以在表的尾部进行插入操作,这一功能已经增加进来。.

支持采用范围加锁、下一个关键字加锁和无限大加锁等方式对逻辑范围值进行加锁

支持由最顶层操作所导致的页面分割。这些情况直接加以提交,"系统"事务可以导致在更短一点的时间周期里保持分裂的页面处于锁定状态。

  为了支持这些变化,需要对采用的存贮表结构进行一系列改善。这些改进的主要效果如下:

群聚索引现在被存贮为象许多人所熟悉的IBM DB2产品所采用的"放置索引"("placement indexes.")方式。这种结构类似于非群聚性的索引,需要类似的空间总量。这种修正的结构导致了在数据初始存贮时可以按照顺序跨数据页进行存储,但是当发生插入时,它们就要尽可能紧密存放以便在正确的逻辑页面中不存在页面分割。此外,在数据页中的数据顺序在新行增加时是不进行维护整理的。这种索引的应用使每个群聚化的索引周游增加了一次I/O操作。

行位移表已经增加到索引页和数据页中。这种增加和新的行索引行存贮格式具有使每个索引页面所存贮的索引条目个数减少的潜在能力。

固定行标识(RIDS)。当一行移动时,对于分配新行位置的向前地址被放在用于驻留该行的位置上。当这种移动需要改变非群聚性索引时,对该行的访问需要增加一次I/O操作以得到'向前'的位置。

一般而言,索引将更小和更短,这是因为如下原因:

从每个叶级页面中采用双重键限制机制来限制双重键(Duplicate key)例如,如果值"绿"("GREEN")在下列行标识(RIDs)值等于123-1,234-2,和345-3的行中, 就分别存贮值“绿”("GREEN"),123-1,234-2,345-3,而不是存贮值"绿"("GREEN,")三次。在每个索引页中每个值只存贮一次。

在非群聚性索引树的非叶型结点中将后缀实行压缩(例如,如果键值是"GREEN"和"HAMILTON",而在这两个值之间发生分裂,那么就在非页级索引页面中存储"G"和"H")。

2.3 数据页和数据行加锁

  只对数据加锁机制支持两种方式:数据页加锁和数据行加锁。这些与它们的工作方式和所提供的功能相类似。这两种方式仅在对数据访问产生阻碍作用时,在加锁的尺度上有所区别。在数据页加锁方式下再采用数据行加锁方式具有两种作用(一种起正向作用,另一种起反向作用)。首先,较小尺度加锁机制的使用可能导致减少争用与冲突,然而当大量数据发生变化时,就有可能对加锁产生大量阻碍的情况发生。

2.4 特定使用的加锁类型

  除非对配置参数加以特定,对所有的表都予置了隐含的全页面加锁机制。

sp_configure 'lock scheme', [allpages | datapages | datarows]

  当数据库从原先版本的服务器中转储出来重新加载时,所有的表都被定义为全页面加锁的表。当建立一个新表时,可以不使用这个缺省值,可采用如下的句法格式:

create table … lock [allpages | datapages | datarows]

  为了在使用的一个表中改变加锁类型,可以采用如下的句法格式:

alter table lock [allpages | datapages | datarows]

  在一个现存的表中改变加锁方式,将引起下列三种行动后果发生:

首先,如果一张表从全页加锁转变为仅对数据加锁,或者从仅对数据加锁转变为全页加锁,在这两种类型之间就要对表进行选择以允许进行存贮格式改变。如果这是一个分区表,就要同时假定必要的并行级别和工作线程已经配置好的情况下,才能执行。

其次, 对表中的群聚性索引必须重新创建。因为我们能保证数据,所以如果从全页加锁方式转换为只对数据加锁时,这种重新创建可以通过"with sorted_data"来完成。然而,当从仅对数据加锁机制转换为全页加锁方式时,就要进行并行的索引创建操作。(请注意:如果这是一个分区表时,那么并行等级和工作线程的数目必须加以配置才能允许进行这种改变,否则这种迁移将会失败)

最后,非群聚性的索引将被重建,如果服务器已经为并行处理所加以配置,当进行本步骤时将加以采用。

  由于这些活动同潜在的工作量有关,从全页加锁机制改变为仅对数据加锁或从仅对数据加锁改变为全页加锁机制都可能是耗费时间的活动。为了标注这一点,有以下一些选择:

如果可能的话,应该配置使用并行方式。这至少对执行非群聚性索引的哈斯(杂凑,即hashed)创建方法是必须的,但是如果可能的话,采用分区表和分区扫描将使系统得到更大的改进。

在选择进入和创建群聚性的索引之后,该任务将被设置检查点(checkpointed )所以,如果有充分的硬件资源,通过允许在任何一个时间点上,检查点任务可以具有多于10个(系统缺省值)的异步I/O请求,利用dbcc进行调谐将能够带来有益的效果。('maxwritedes', number)

进一步作为降低使用检查点成本的一种方法,在相关的高速缓冲池(cache pool)、大数据量的I/O操作中,采用对高淘汰程度进行标记的方法,并允许清洁程序(好象家庭主妇一样)保持特别活跃的状态,将为那些检查点需要从高速缓冲池中刷新较"脏"的页面的而增加的I/O操作次数,并因此花费了在检查点上的时间,都能够大大减少作出贡献。

如果预先进行了配置,则可以对并行的选择进入可以使用预先分配的盘区。所以,通过将sp_configure number of pre-allocated extents设置为16也将对系统性能有明显的积极的效果。

  备注:在仅对数据加锁类型之间进行改变不需要对数据进行备份, 而且执行起来只需很短的一段时间。

[以上为摘自sybase公司站点上的资料]

据我个人使用经验,我觉得对于并行性较高的应用要充分考虑使用行级锁,这样对于提高并发性能至关重要!当然,事务都存在利弊两方面,使用行级锁,也会带来一些相应的弊端,比如使用的锁越多,占用的内存也越多,在使用行级锁的表上频繁的进行数据删除、插入操作久而久之会造成数据库碎片的大量生成,数据库性能会下降,这就需要定时进行reorg操作,但该操作比较耗时,且影响业务!

16) 请问!怎样设置自动清log,和temp的阀值?

  http://www.chinaunix.net/cgi-bin/bbs/topic.cgi?forum=10&topic=1507&show=120

一般我们可以为某段设置多个阀值,但只需在达到最后机会阀值时作些空间清理的操作.

第一步,在你的数据库中设置阀值,并指定达到阀值后的处理过程:

查看当前数据库某段的最后机会阀值:

sp_helpthreshold "default"

或者察看其他段的信息。

修改某段的最后机会阀值:

sp_modifythreshold 数据库名,段名,自由空间名,[新过程名[,新自由空间名[,新段名]]]

sp_modifythreshold mydb,"default",200,NULL,175

将最后机会阀值由200页调整到175页。

具体其他操作,可以参考相关手册!

第二步,编写阀值处理过程:

create procedure sp_thresholdaction

               @dbname varchar(30),

               @segmentname varchar(30),

        @space_left int,

    @status int

as

       declare @SpaceLeft varchar(20),

               @Status varchar(20)

       select @SpaceLeft=str(@space_left,6,0)

       select @Status=str(@status,6,0)

       print "Log is dumpped('%1!' for '%2!',SpaceLeft:'%3!',Status:'%4)',

       and is dumped.",@segmentname,@dbname,@SpaceLeft,@Status

       dump transaction tempdb to with truncate_only

return

不过,我还是不建议用最后机会阀值来进行自动维护。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics