Informix是一种大型的数据库管理系统,具有先进的技术、性能与可靠性,在全球范围的各种应用中使用十分广泛,包括政府、金融保险、邮政电信、制造及零售等重要行业或领域。本文根据笔者在SCO
Unix/Xenix上使用
Informix-4GL与Informix-SQL的经验,简要介绍Informix系统维护中的几个较为特殊的问题及其处理方法。
表文件的修复:
Informix的数据库是指由若干张表所构成的集合,其中每一张表对应着两个文件,即数据文件(后缀为.dat)与索引文件(后缀为.idx)。当系统出现异常、死机、掉电或非正常关闭时,有时会使一些使用中的表文件未能正常关闭而出现毁损,当系统再次对这些表进行相关操作时,就会报告“不能检索下一条记录”、“不能删除记录”等错误信息。
通常,数据文件是很少发生问题的。要判别数据文件是否正常,只需执行select * from 〈table—name〉语句或类似的语句即可,但不能使用where、order by等子句,以免利用到索引文件,目的就是纯粹从数据文件中依次读取数据。如果数据读取顺利且记录个数正确,表明该文件完好无损;反之,则有问题,通常只能用其数据备份来恢复。
如果数据文件正确无误,那么就该检查相应的索引文件。Informix提供有一个实用程序bcheck,专门用来检查与修复索引文件,即依次比较数据文件与索引文件,倘若不一致,就询问是否删除和重建有问题的索引。bcheck有许多选项可供选用,其中-n和-y用于对所有的提问都回答“no”或“yes”,让系统自动进行一系列的操作。其语法如下:
bcheck
[选项] 〈表文件名〉
要检查表的索引文件,应先运行bcheck
-n命令。如果一切正常,
说明索引没有问题。一旦发现有错误报告(如有多少个错误数据记录指针、丢失了多少个数据记录指针或索引结点指针等),则再执行bcheck
-y 命令即可将其修复。
Informix-SQL中的语句check
table 〈表名〉与repair
table 〈表名〉在运行时分别以选项-n与-y调用bcheck命令,功能一样,不同的只是使用表名而不是表文件名。
如果索引文件没有相应的读写权限,
或者没有正确指明其路径,
在bcheck时会出现“无法打开索引文件”的信息。如果索引文件被删除或格式被破坏了,也有同样的信息。此时可从数据备份中将对应的索引文件拷贝回来,也可暂时创建一个字段与索引均与原表完全一致的新表并将其索引文件拷贝给原表,再运行bcheck
-y命令修复。
表空间的回收
Informix对数据表的管理方式较为特殊,当数据量增加时,表所占用的磁盘空间随之增加;但数据记录被删除时,原先所占用的空间暂不释放,依然由该表所控制,作为日后增加记录时使用。为提高系统的性能及有关各表的查询速度,应及时回收这种“空闲”的磁盘空间。
使用bcheck -s命令可回收索引文件的空间,其中-s 选项的作用是重新估算索引文件的大小。要同时回收数据文件与索引文件的空间,可让DBMS(数据库管理系统)去做表结构的修改工作,但修改前后的表结构及有关权限要保证一样。可利用Informix-SQL达此目的,最为保险的做法是先给相应的表增加一个字段,再将该字段删除。也可利用alter
table 命令“欺骗”DBMS去修改表的结构,如alter
table aa modify(bb smallint),其中aa表的字段bb的类型本来就是smallint。
表的迁移
任何一个Informix数据库都有九个系统表,用于记录数据库的有关信息,其中系统表systables(用于描述数据库中的各表)中的字段dirpath指明各表文件的绝对路径或相对路径。
Informix数据库的搜索路径一般由环境变量DBPATH来设定,系统根据DBPATH的正确设定即可找到相应的数据库及其各表。迁移Informix数据库表时(比如从Unix/Xenix的根文件系统迁移到分离的文件系统/u),只要重新设定DBPATH,通常系统即可正常运行。如果报告某些表找不到了(实际上这些表文件还在,且有关权限也对),问题就在于systables
表中的dirpath字段值采用了绝对路径,
此时要用update命令修正其值,最好改用相对路径,即直接改为表文件名。
系统查询的优化
Informix在执行查询(特别是多表查询)指令前,会利用其所提供的优化器(cost-based
optimizer,基于成本的优化器),依据当时系统所记载的有关各表的相关信息,按照一定的判断法则进行分析并选择出一条最有效率的途径来执行。系统必须掌握各表的正确数据,才不至于做出错误的选择。但出于系统效率上的考虑,不可能随时修改记录各表最新状况的相关文件,否则会增加许多额外的输入/输出负担。因此,
应定期执行这种信息的更新操作。
在Informix数据库的系统表systables中有一字段nrows,专门用来记录各表的记录个数。优化器在运行法则判断时,各表的nrows
值具有很高的参考价值。nrows的更新可通过如下命令来完成,即:
update
statistics [for table 〈table—name〉]
其中,方括号[]中的子句是可选的,用于指定表名,以对该表进行更新;否则,将对数据库中的各表进行全部更新。
一一 Informix数据库安全性
informix动态服务器提供两个级别的访问特权,来保证数据库的安全性。数据库特权控制对数据库的访问和在数据库上创建表和索索引的权力。表的特权指定用户在特定的表上所能进行的操作。
informix动态服务器支持表级的修改,插入和删除的安全性,同时增强了列级的更新和查询的安全性。分离特权语句用于向用户授予适当的访问基级别的特权,或回收特权。由于informx安全性是在用户级别上的,因此,不需要进行分离的数据库登录。
存储过程通过建立他们自己的,有别于数据库的许可权限而提供了附加的安全机制。存储过程的所有者向用户授予执行该存储过程的权限,允许用户执行该存储过程中所有的SQL操作,但对其他的数据库访问加以限制。通过使用存储过程来限制用户执行某些用户执行某些数据库的操作,数据库管理员可以提高系统的安全性
安全审计
INFORMIX动态服务器提供的安全审计功能对用来操作的每一个数据库对象提供跟踪和操作记录。这一功能符合“美国国家计算机安全中心”提出的C2级安全要求模型。
借助于INFORMIX动态服务器,你可以对系统中用户的活动进行选择性监控。安全审计的界面是由命令行驱动的,或是有参数调节控制的,它允许你指定对某一特定用户的特定活动进行监控。
Informix数据一致性
如果说高可用性能保证系统级的完整性,那么数据的一致性是在事务级保证完整性。INFORMIX动态服务器通过事务日志和内部一致性检查、创建和加强封锁过程、隔离级别和业务规则来保证数据的一致性。
事务日志
如果一个操作不能完成,则已经完成的那部分事务必须从数据库中清除,以保持数据的一致性。为了清楚部分完成的事务,INFORMIX动态服务器在逻辑日志中对所有事务的历史记录进行维护,并以这些事务记录作为依据,将数据库恢复到事务之前的状态。
内部一致性检查
内部一致性检查为提醒管理员数据或系统的不一致状态而专门设计。INFORMIX动态服务器包含一个数据级的检查机制,它能够发现由于硬件或操作系统故障而引起的数据不一致。如果发现了不一致,该内部机制就自动向INFORMIX动态服务器消息日志发消息。
为了更好地确定不一致的原因,INFORMIX动态服务器管理员可以指导用户来设置一致性检查环境变量,这些变量产生诊断结果(例如,在不一致发生的共享内存中的内容),来帮助确定不一致发生的原因。
封锁和处理的独立性
为了保持数据的一致性,所需的另一个重要的功能是封锁过程和处理的独立性。这些安全性措施保护当前正在被访问或修改的数据不会被其它用户更改。
封锁
数据库服务器引入封锁机制来防止错误的发生。锁是一个程序加在数据片断上的声明或限制。数据库服务器保证只要数据是被封锁的,其它任何数据库服务器进程都不能对其进行修改。当另一数据库服务器程序要求对该数据库进行修改时,数据库服务器使该程序要么等待,要么返回一个错误。
INFORMIX动态服务器还能防止死锁的发生。死锁是两个用户都封锁着另一个用户所等待得数据。例如,用户A封锁了一个元组,并且在用户A访问B所封锁的数据之前不会将其释放。INFORMIX动态服务器能立即检测到死锁的发生,并向第二个程序发出出错消息,以防止死锁状态的出现。
一个表或事务的吞吐量会受封锁策略的影响。使用排它锁对数据进行访问的应用会发现其它的数据库服务器进程都在花时间等待对数据进行访问。因此,INFORMIX动态服务器提供了几个不同级别的封锁。数据库服务器可以在单个记录、页面、表和数据库的级别上加锁。
在创建表和改变表结构时,可以指定记录和页面级别的封锁。在用户应用中可以指定表和数据库级别的封锁。
隔离级别
隔离级别是读操作独立于其它并发数据库服务进程的程度;其它进程可以对你正在读的记录进行什么修改,以及你可以对其它进程正在读或修改的哪些记录进行读操作。
隔离级别只能影响读操作,它们不作用于其它的语句,如插入,删除,更新等。INFORMIX动态服务器有四个隔离级别:脏读、提交读、游标的稳定性、以及重复读。
脏读是隔离级别中最简单的一个,它实际上根本没有提供任何独立性。当一个程序使用脏读来访问数据时,它不加锁。对于脏读,用户可以读任何数据,包括以提交的未提交的。
提交读保证INFORMIX动态服务器只能读提交给数据库的记录。在对记录进行访问之前,数据库服务器检查是否有更新进程给该记录加了锁。如果没有加锁,数据库服务器就对该数据进行访问。提交读保证数据库服务器不会读未提交的数据,因为在作了修改而又没有提交的记录上加了锁。
下一个隔离级别是游标的稳定性。使用游标的稳定性时,数据库服务器在所读的最新记录上加上锁。每次仅对一个记录加锁;每当读新的记录时,就将原来的锁释放。这个孤立级别保证程序在读的当前的记录不会被改变。
重复读保证在读操作过程中,所得到的结果与在该事务中其它时刻得到的结果是一致的。重复读不仅在所读的记录上加共享锁,而且还阻止其它用户违反数据库的读锁标准向数据库中增加记录或更新记录。
业务规则
业务规则能增强字段级的数据一致性,这些规则指定数据可能的值、列的缺省值,以及列与列之间的关系。
业务规则必须由对数据进行访问和操作的应用来限定。但是,INFORMIX动态服务器不依赖于应用来实现这些规则。实际上,INFORMIX动态服务器可以独立实现这些规则。责任的集中减轻了用户应用的负担,并保证了业务规则的继承性。
INFORMIX动态服务器支持完整性约束、存储过程和触发器,从而保证业务规则。
完整性约束
INFORMIX支持ANSI SQL的完整性约束,保证信息不会被不当地删除,插入的数据满足字段的特殊要求。INFORMIX动态服务器提供两种类型的完整性约束:参照完整性和实体完整性。
参照完整性允许用户定义和保证字段之间的关系。例如,INFORMIX动态服务器的参照完整性可以保证,对于主表中有关的一个实体的信息,如果在子表中存在相应的信息的话,那么主表信息不会被删除。这就保证不会在某客户的订单存在的情况下将该客户删除。
实体完整性为特定字段规定合法取值范围。这样的检查允许DBA对所允许的值的范围作出规定。缺省值允许用户指定符合字段数据类型的任何智值作为缺省值。
存储过程 存储过程是以命名过程的形式存储在数据库中的SQL命令和编程语句,以保证常用操作的一致实现。存储过程在数据库中,而不是在应用程序中对常用的优化过的应用例程进行维护。
存储过程减少数据库操作所需要的网络流量。因为存储过程可在一个命令中处理多个任务(如插入、更新和删除)。在处理请求之后,存储过程仅返回满足条件的结果,而不是每一个查询结果的集合。
触发器
触发器是唤醒存储过程的另一种方法。与应用程序调用存储过程来实现业务规则的方法不同,触发器可以被定义为:在需要进行插入、删除、和更新的时候,启动数据库服务器自动执行存储过程(或SQL语句)。
由于触发器是存储在系统数据字典中的,因此不需要应用程序来完成维护触发器代码。同样,由于无法绕过触发器,所以跨所有事务的完整性约束也得到了保证。
Informix安全审计
什么是安全审计
安全审计可以创建用户在数据库中活动的事件记录,通过这些记录可检查不平常或可疑的数据库活动。
可以记录的事件有:
成功或者失败的操作。你可以只记录成功的操作,或者只记录失败的操作,或者两种都记录。
online系统的连接。你可以记录与online系统建立连接的情况,包括是谁建立了这个连接,在什么时刻
系统和数据库管理事件。任何管理事件例如增加dbspaces和chunks,归档,赋权,回收权限,或者当前的事务日志都可以被审计。
数据库和表的操作。select,insert,update,或者delete语句都可以被审计,但是不允许只对某一个表的操作进行审计。
审计是如何工作的
管理员首先要创建audit masks(审计掩码),一个audit masks就像一个过滤器,检查用户的活动是否应该被审计。audit masks存储在sysmaster数据库的sysaudit表中。
如果执行数据库操作,而这个操作在被审计的范围内,online会自动在审计日志中插入一条记录。审计日志是一个UNIX文件,其中保存有审计的记录。这个文件有可能会变得很大,主要看audit masks中包括的操作的数量和操作的类型。
对每一个数据库用户可以有单独的user mask(用户掩码)。另外,管理员可以设置一个默认掩码,这样没有设置user mask的用户就可以使用这个默认的掩码。
审计掩码
审计掩码告诉online什么事件需要被审计。审计掩码的种类如下:
单独的审计掩码(indiviual masks)。单独审计掩码是为每一个用户创建的掩码,其作用是对每一个用户的活动进行审计的。
默认的用户掩码(_default masks)。默认的用户掩码会被用在任何没有单独设置掩码的用户上。
必须的用户掩码(_require masks)。必须的用户掩码会忽略单独用户掩码和默认用户掩码中的内容。任何在_require用户掩码中设置的事件都会被审计,而不管用户的单独掩码中是否设置了这些事件。
排它用户掩码(_exclusive masks)。排它用户掩码同样会覆盖单独的用户掩码和默认用户掩码。其中包含的事件不会被审计,即使这些事件存在于单独的用户掩码和默认用户掩码中。这些事件不会覆盖_require掩码中的事件。
你也许想要对有经验的用户很少事件进行审计,对没有经验的用户更多的事件进行审计。为了达到这种目的,为有经验的用户创建一个单独审计掩码其中包括较少的事件。为所有的其它用户创建一个默认审计掩码,其中列出更全面的审计事件。
管理员必须创建所有的掩码;_default,_require,_exclude和单独用户掩码。
审计角色
在7.10.UD1之后,审计角色可以在用户之间实现独立的审计功能。
数据库系统安全官员(DBSSO)的责任是维护审计掩码。
审计分析官员(AAO)分析审计记录,发现安全问题。
为了更高的安全性,DBSSO,AAO,和ONLINE管理员应该由不同的人员来担当。
要设置基于角色的存取控制,ONLINE系统管理员应该设置两个环境变量。$DBSSOOWNER环境变量应该在DBSSO的登录脚本之中。$AAOWNER环境变量应该设置在AAO的登录脚本中。如果设置了这两个变量:
只有AAO可以打开或者关闭审计功能。
只有DBSSO可以使用onaudit工具来维护审计掩码。
设置安全审计
设置安全审计的步骤:
1.打开安全审计。
2.设置审计参数。
3.创建审计掩码和审计事件。
打开审计功能:
有两种方法可以打开安全审计:使用onaudit工具,或者通过配置参数。在7.10UD1之前,这些参数是在$ONCONFIG文件中设置,在7.10UD1之后,这些参数在$INFORMIXDIR/aaodir/adtcfg文件中设置。
安全审计在你第一次初始化或者关闭和重新启动online的时候生效。你必须明确地打开审计功能:
作为informix用户,运行以下的命令:
onaudit -1 1
审计功能会立即对任何的新的连接生效。这个命令同时会修改ADTMODE配置参数,这样在下一次online启动的时候会自动生效。
也可以通过修改ADTMODE参数为1来打开安全审计。在修改了这个配置参数之后,你必须重新启动online,让改动生效。在ONLINE7.10.UD1版本之前,这个参数在$ONCONFIG文件中配置,在这个版本之后,这个参数在$INFORMIXDIR/aaodir/adtcfg文件中设置,并增加了更多的功能:
ADTMODE=1 写到informix审计记录中。不自动审计DBSSO和DBSA活动。
ADTMODE=2 写到操作系统的审计记录中。这个选项只在操作系统支持审计的时候才会生效。不自动审计DBSSO和DBSA的活动。
ADTMODE=3 写到INFORMIX审计记录中。自动审计所有的DBSSO活动。
ADTMODE=4 写到操作系统审计记录中。自动审计所有的DBSSO活动。
ADTMODE=5 写到INFORMIX审计记录中。自动审计DBSA活动。
ADTMODE=6 写到操作系统审计记录中。自动审计DBSA活动。
ADTMODE=7 写到INFORMIX审计记录中。自动审计所有DBSSO和DBSA活动
设置审计文件参数:
1.指定审计文件的目录:
onaudit -p /work/audit
或者ADTPATH /work/audit
2.指定审计文件的大小:
onaudit
onaudit -s 50000
或者ADTSIZE 50000
在创建审计掩码之前需要设置其它的两个审计参数,它们是:
审计文件所在的目录。审计文件中存储所有用户的审计记录。首先创建一个目录。确保这个目录的权限为只能被INFORMIX帐号存取。
在online处于启动状态的时候,你可以通过执行如下的命令来修改审计目录:
onaudit -p 路径
其中路径名为将要放置审计文件的路径名。onaudit命令同时会修改ADTPATH配置参数的值。
你可以手工修改ADTPATH参数的值。然尔通过这种方式,你必须关闭和重新启动ONLINE,让改动生效。
默认文件大小。 ONLINE在ADTSIZE配置参数中限制了审计文件的大小。当审计文件的大小到达ADTSIZE的时候,一个新的审计文件会在ADTPATH路径下创建。
你可以通过onaudit工具来修改审计文件的大小,同时会修改ADTSIZE配置参数,这个大小的单位是字节:
onaudit -s 50000
你可以手工修改ADTSIZE参数的值。然尔通过这种方式,你必须关闭和重新启动ONLINE,让改动生效。
通过限制审计文件的大小,你可以周期性地将旧的审计文件归档或者删除。你也可以在当前的审计文件没有满的时候自动启动一个新的审计文件,方法是执行如下命令:
onaudit -n
设置错误参数
最后,你可以指定由于某种原因导致不能写审计文件的情况下,系统执行什么操作:
停止(0)模式-在一个用户会话试图写一个审计文件,但是写文件失败,它会等待,然后每秒重试一次。在审计文件可以写之前,这个会话不能做任何操作。
继续(1)模式-这种模式意味着会话会继续下去,即使不能够写审计日志,online的信息日志中会接到一条错误信息,说日志文件不能存取和更新。
HALT(0)是默认的错误模式。
你可以通过两种办法来修改错误模式。
使用onaudit工具:
onaudit -e error-mode
这个命名执行的同时会修改ADTERR配置参数。
修改在$ONCONFIG文件中的ADTERR参数的值,为了让这个改变生效,你必须重新启动online。
显示审计配置
你可以运行onaudit -c 命令来显示审计的配置:如
onaudit -c
Current audit system configuration:
ADTMODE =1
ADTERR = 0
ADTPATH = /work/tmpaudit
ADTSIZE = 5000
Audit file =1
如果online DBSERVERNAME为online1shm,当前的审计文件名为:
online1shm.1
使用onaudit设置掩码
onaudit工具同时用来维护审计掩码。可以用它来增加,删除,修改或者输出一个掩码。
_default,_require和_exclude掩码
在增加单独的用户掩码之前,你应该首先设置_default,_require和_exclude掩码,因为这些掩码会决定什么审计事件会被放置在单独用户掩码之中,它们应该被先创建。_require和_exclude掩码中的审计事件会覆盖任何单独的用户掩码。
使用-a选项增加一个掩码,。使用-e选项可以增加事件。
增加一个_default掩码:
onaudit -a -u _default -e +ACTB
增加一个_require掩码:
onauit -a -u _require -e +GRTB,GRDB
增加一个_exclude掩码:
onaudit -a -u _exclude -e +RDRW
单独的用户掩码
要为单独用户创建掩码,在-u 选项之后指定一个登录名。
如果你有一组用户有相似的审计事件,你可以创建一个掩码模板,要创建一个模本掩码,使用-u选项指定模本名。模本名必须以下划线(_)开头,并且不能超过8个字符。
要利用这个模本创建一个用户掩码,使用-r选项来执行这个模本名。你还可以使用-e选项来增加或者删除模本中的事件。在下例中,用户eric会接收_advance模本中指定的所有的事件(DRTB,DRDB)。用户lucy会接收_advance模本中的所有事件,然后再加上ALTB事件。
增加一个单独的用户掩码:
onaudit -a -u liz -e +DRTB,DRDB
增加一个掩码模本:
onaudit -a -u _advance -e +DRTB,DRDB
应用一个模本给一个用户:
onaudit -a -u eric -r _advance
onaudit -a -u lucy -r _advance -e +ALTB
显示掩码
你可以使用-o选项来列出一个掩码中的所有事件,如:
onaudit -o -u liz
Onaudit -- Audit Subsystem Configuration Utility
copyrigt (c) Informix Software,Inc.,1993
liz -DRDB,DRTB
如果不使用-u指定某个用户,可以列出所有的掩码。
你可以让online只列出成功或者只列出失败的事件方法是在onaudit命令的事件参数之前加上S和F。如果在事件之前没有S或者F,成功和失败的事件都会被审计。
例子:
仅仅审计成功的事件,在事件的前面加上S。
+SDLRW(只记录成功的记录删除)
+FDLRW(只记录失败的记录删除)
修改一个掩码
onaudit -m -u artdy -e -ADCK
删除一个掩码
onaudit -d -u artdy
可以使用-m选项来增加或者删除一个已经存在的掩码中的事件,使用(+)加号可以增加事件,使用(-)号,可以删除事件。
分析审计文件
分析审计文件可以使用两种方式:
通过onshowaudit工具。onshowaudit工具可以重指定的审计文件中提取审计记录
通过数据库表的方式,使用SQL来进行查询。onshowaudit工具可以产生一个文件,然后利用dbload和sql中的load语句将这个文件装载到一个数据库的表中,然后你就可以使用SQL语句来对这个表进行查询
只有informix用户才能使用onshowaudit工具。
1.使用onshowaudit分析审计记录
你可以使用onshowaudit来提取和列出审计记录。
通过指定审计文件(-f audit_file)。如果使用-f选项,只有指定的审计文件被提取 。如果没有使用-f选项,会自动顺序从最早的文件进行提取。
通过指定用户名(-u login)。只提取指定用户产生的审计记录。一次只能指定一个用户名。
通过数据库服务器名(-s server_name)。只提取指定的主机产生的审计记录。
2.装载审计记录进一个表
你可以使用如下步骤,将审计记录装载如一个表中,然后就可以使用sql语句对其进行分析。
1.创建一个审计数据库,和一个审计表。
2.创建一个可以装载的审计文件:
onshowaudit -1>log_records
3.如果使用dbload,创建一个load命令文件:
FILE log_records delimiter | 17;
INSERT INTO audit_table;
4.如果使用dbload,运行dbload命令:
dbload -d audit -c cmd_file
5.如果使用load,运行以下的SQL语句
load from 'log_records' insert into audit_table
关闭审计功能
要关闭审计,你可以执行onaudit命令,指定-1 0 选项,这会立即关闭审计功能。
你同样也可以修改$ONCONFIG文件中的ADTMODE配置参数,但是审计只会在系统下一次启动的时候才会关闭。
一二 INFORMIX动态服务器表分片策略的计划和调整
“数据分片”允许在表一级对数据存储进行控制。“表分片”是INFORMIX数据库的一个特征。用户可以对表中的记录或索引进行分组,并且存储在不同的位置,这样可以将数据存储到多个磁盘上,从而减少对磁盘I/O的竞争。数据分片的方案以及分片数据所存放的一组dbspace构成了“分片策略”。数据分片有两种基本类型:基于轮转分片和 “基于表达式分片”,对于“基于轮转法分片”,正如其名字一样,数据是根据轮转法方式存入表中的。“基于表达式分片”则根据表中的一个或多个字段对分片的规则进行定义。一般在预知查询条件时采用这种方式,从而避免查询中对某些分片的扫描。
对“表中的数据”和索引进行分片主要是为了提高应程序的效率,由于INFORMIX动态服务器可以并行地扫描多个磁盘上的数据,从而实现内部查询的并行操作,因此采用”分片“技术可以提高查询效率。内部查询的并行化有助于减少对一个复杂查询的响应时间。”表分片“技术与并行数据查询(PDQ)特征联系在一起使用,这样INFORMIX服务器可以分配多条线索。从所有数据分片上并行地选取数据。此外,还可以仅仅对包含“目标数据”的数据分片进行扫描。从而大幅度地提高了整个系统效率。“DATASKIP这一个特征还允许用户跳过那些出现故障或者不包含“目标数据”的数据分片,当某些数据所在的盘出现故障时,就可以体现出高度的“数据可获得性”
我们通过大量的数据分片将数据分布在许多的磁盘上,也实现了外部查询的并行操作。这样在大量用户对同一个表进行访问时,可以减少I/O的竞争,每秒钟完成的事务数(系统吞吐能力)也得到了提高。“表分片”技术还通过对存储在dbspace上的数据分片进行备份/恢复操作。
分片方案
在“创建表”和“创建索引”时候均可以用到分片方案。索引可以附加在与其相关联的数据上,或与数据分离存放。一个索引如果出现在对表数据的分片方案中,就可以认为索引已经附加在数据上。另外一个方面,如果索引的分片方案与数据不同,就称为索引与数据分离。这种情况下,索引存放在指定的dbspace上。
“数据分片”方式主要有两种:“基于轮转法”和“基于表达式”的方案,
轮转法方案
轮转法(PR)所使用的分片规则是系统内部定义的。使用这种方案,新追加的记录被存放在轮转法方式指定的下一个数据分片。记录所插入的第一个数据分片也是随机选定,例如,下列语法用于创建一个名为xyz的表:
CREATE TABLE xyz FRAGMENT BY ROUND ROBIN
IN dbspace1,dbspace2......dbspaceN
INFORMIX不支持用轮转法方式创建索引,因为这样会降低系统性能。轮转法方案的优点在于各数据分片上数据量是比较均匀的,对记录进行更新时,并不需要对记录进行转移。然而轮转法有一个缺陷,在进行一个查询时,要扫描所有的数据分片。因此,轮转法方案不支持DATASKIP,不允许INFORMIX动态服务器越过某个数据分片。如果不支持DATASKIP,同时又有一个数据分片出现错误,那么整个查询将会失败,因为不能确定出现故障的数据分片上是否有符合条件的数据记录存在。轮转法方案适用的情况是:用户需要快速加载数据,用户预先不知道数据访问的方式。用户的数据经常更新,或者是用户对于数据分布方式未知。
“基于表达式”的分片方式
对于“基于表达式的分片方案“,用户可以用下面两种规则对数据进行分片”
范围规则
绝对规则
范围规则
范围规则用SQL的关系或逻辑操作定义表的数据分片的边界。范围规则可以包含关系操作符,比如 >,<,>=,<=,还可以包含一些逻辑操作符,比如AND。范围规则最好根据表的某一个字段进行分片,但也可以根据两个或者多个字段进行分片。下面的分片实例运行效率并不很高,因为向表中插入一行时候需要进行太多的运算。所有不符合表达式条件的记录将放在REMAINDER dbspace中。基于“范围表达式”的分片方案可以确保只对包含目标数据的数据分片进行扫描。
下面是一个采用“基于范围表达式分片方案”创建表的例子:
CREATE TABLE xyz (aa integer....)
FRAGMENT BY EXPRESSION
aa<=100 IN dbspace1
aa>1000 AND aa<2000 IN dbspace2
REMAINDER IN dbspace3
绝对规则
“绝对规则”使用了SQL的关系与逻辑操作符。与“范围规则”不同,“绝对规则”运行用户采用关系操作符与逻辑操作符对规则进行定义。此外,表中可以有多个字段参与分片。
例: FRAGMENT BY EXAMPLE
zipcode=94536 OR zipcode=94538 IN dbspace
zipcode=94025 OR zipcode=92310 IN dbspace
REMAIDER IN dbspace3
对于以上这种分片方案,必须知道每一个邮政编码所联系的数据个数,以确保每个数据分片上的数据量比较平衡,从而使INFORMIX动态服务器减少扫描的数据分片的数目。指定分片方案时,要确保数据分片之间不互相重叠。此外,定义数据分片时可以不包括REMAINDER分片。
分片的基本原则
“数据分片”的表达式必须尽可能简单,因为执行较复杂的表达式将加重CPU的负荷。同时,数据库中并不是每一个表都需要分片,除非能从“数据分片”中得到显著的收益。“分片”的表达式因为能确保磁盘I/O操作均衡,尽管我们没必要制定一个均衡的数据分片方案。如果大量的查询只对表数据中很小的区域进行访问,那么应该用表达式将那些被频繁访问的数据分片到多个盘上,尽管这样的分片也许数据量并不均衡。表达式应该把限制性最强的部分放在前面。对表达式进行修正是为了减少表达式的计算量,减少每次访问的数据量,从而最终减轻CPU的负荷。如果表达式中第一个不等式的结果为假,那么整个表达式的结果也将为假,因此不必计算表达式的其它部分(AND表达式)。比如说,为了插入数值25,下列表达式需要计算6个不等式:
x>=1 and x<=10 in dbspace1
x>10 and x<=20 in dbspace2
x>20 and x<=30 in dbspace3
如果用如下表达式,则只需要计算4个不等式:
x<=10 and x>=1 in dbspace1
x<=20 and x>10 in dbspace2
x<=30 and x>20 in dbspace3
分片的表达式中应该避免数据类型的转换。例如,日期数据类型在表达式中内部转换为整数类型。对于频繁更新的字段进行分片,会带来许多管理上附加工作。例如,如果根据一个日期字段进行分片,而超过保存日期的记录被删除,那么包含”超期数据”的数据分片将最终变空。这样就需要删除旧的数据分片,并为最新日期的记录创建一个新的数据分片。
“分片”策略的设计
一个“分片”策略包含数据分布方案以及数据分片所存放的一组dbspace。制定“数据分片”策略时需要根据分片的目标以及数据库的信息,诸如硬件/软件特性、查询特性、数据分布等作出决策。同时还需要知道一个现存的未分片数据库是否做转换,以及是否需要临时创建相应的应用程序。在前面的例子中,已经预知查询的方式,则可以加以利用。我们还应考虑到查询方式在将来的不断变化,诸如数据库的区域和/或帐户的附加部分,这一点也很重要。
“数据分片”的目标包括最大程度的内部查询并行化、外部查询并行化、提高数据可用性、更细的备份/恢复粒度以及更强的数据加载效率。
数据分片获得“内部查询并行化”:是指INFORMIX动态服务器充分发挥“数据分片”与PDQ功能的优势,并行地处理一个复杂的查询。这是决策支持系统(DSS)一类应用程序的主要目标。DSS查询从一个表中顺序读出大量数据记录。我们推荐使用数据分片。选择“轮转法”分片方案还是“基于表达式”的分片方案取决于查询特征、数据分布等因素,一般来说,当用户不能确定根据表中哪一个字段做“基于表达式”的分片,从而保持数据分片的均衡,或者不知道数据访问的方式时,我们推荐采用“轮转法”方式。“轮转法”方式不支持对索引的分片,因为扫描线索要越过分片的边界去读取索引,这样会导致效率的下降。“分片策略”还应该确保数据均衡的分布在不同的数据分片上,确保并行顺序扫描能均衡地完成。
数据分片获得“外部查询的并行化”:是指在大量用户运行较小的查询、返回少量的数据的条件下,INFORMIX动态服务器最大程度提高性能的能力。一般来讲,对于“存在大量用户,需要实时响应的应用程序,称为联机事务处理(OLTP)。OLTP查询总是在同一时间访问数据的一小部分区域,总是随机地对一些数据行进行更新或者删除操作。这些操作总是和”索引扫描”有关。在这种情况下,应该用表达式将数据表和索引表进行分片,从而允许查询在扫描过程过中某些数据分片。如果不考虑I/O竞争,数据分片和索引分片可以在同一个盘上,并使用同样的“分片”策略。另一方面,在一个大系统中如果额外有空余的盘,并且磁盘I/O可能成为潜在的瓶颈,那么最后将索引单独建在一块盘上。调换一下顺序,当按照某一字段创建索引时候,如果每一个查询都根据同一字段访问数据时,我们也可以使用与“数据分片”不相同的策略对索引进行分片。这种情况下,最好在WHERE子句中使用另外一个字段,“分片”策略的理想化程度取决于数据的分布和对表的查询的分布情况。我们的目标通过数据分布消除I/O瓶颈,尽管每个数据分片上的数据量可能不太均匀。
数据分片增强“数据可获得性”:是指可以在某些数据分片发生故障的时候,数据库仍然能接受应用程序的查询请求。这种能力是有INFORMIX动态服务器的DATASKIP特征提供的。
数据分片“增强数据加载的性能”:尤其适用于”周期性地加载几个G的数据,从而需要快速加载技术”的大型应用程序。将数据 分片到不同的磁盘上,可以使数据自动地进行并行加载,这是通过使用多个I/O流向数据分片所驻留的磁盘上写数据而达到的。轮转法分片方案应该最能保证快速数据加载,因为复杂表达式的计算会加重CPU的负荷,如果采取较简单的表达式并将每个数据分片放在单独的盘上,用“基于表达式”的分片方案同样可以保证快速加载数据。
以下是“确定合理的分片策略”所必须的步骤:
硬件/软件特征
要搞清楚硬件平台,如CPU的速度,数目,磁盘数目,大小,磁盘控制器的数目,以及与每个控制器相连接的磁盘数目,等等。这些信息对于确认表分片的数目以及怎样存放数据分片以减少I/O竞争,都是十分有用的。除了可用的磁盘外,对于每个表的数据分片的数目都有一定的上限,这些限制与分片的目标有关,如果分片的主要目的是增强内部查询的并行程度,那么系统CPU的数目和数据总线的带宽将限制一个表所能得到的并行线索的最大数目。另一个方面,如果分片的主要目标是增强外部查询的并行程度,那么分片的数目可大于CPU的数目,从而保证数据分布在许多磁盘上,在OLTP条件下可以允许用户并发地访问不同的磁盘,然而,当数据分片的容量变小的时候,应用程序会寻找多个数据分片,同时对寻找的结果进行合并。这些都会降低查询的效率。
对于具有高速CPU和低速盘的系统,每个表的分片数目可以超过物理CPU的实际个数。
所选的硬件平台 的操作系统类型和编译器对选择“分片”方案也是一个重要的因素。有的操作系统擅长处理MOD操作以及数据类型转换。
了解查询的特征
要了解一个应用程序到底是OLTP还是DSS类型,还要了解SELECT语句查询用的频繁还是update/delete操作频繁。如果查询多用SELECT语句,还要确定带有 “group by,order by等复杂子句查询的执行频度。对于这些情况的了解有助于平衡I/O,消除瓶颈。检查每个SELECT 查询的选择性以及返回数据的比例。如果一个查询的选择性(selectivity)很大,就需要为查询创建索引。检查有无JOIN操作,并确认JOIN操作的主码是什么。如果在DSS查询中总对某一特定的表进行JOIN操作,那么这个表应该被分片到不同的磁盘上以避免I/O瓶颈。检查每个查询的查询条件。最后将所涉及的表中的字段画一个矩阵。接着将某一查询中用做查询条件的字段填上“+”字符。有了这个矩阵,我们可确认在所有的查询中,哪个查询条件最常用。这一信息与每一查询的执行频度一起,有助于确认对哪个字段做“基于表达式的分片”收益最大。检查数据是怎样被访问的,即数据是通过“顺序读取”还是通过“INDEX SCAN被访问。为每一个查询配备“SET EXPLAIN 子句,加上表的模式信息,可以达到以上目标。
数据分布及特征
确认表中用户查询条件的字段的取值范围。确认表中每一取值范围内符合记录的个数。在许多DSS类应用程序中,结果是从几个GB的数据或几个月,甚至一年的数据中得出来的。在这种条件下,很容易确认某一州,某个城市的记录数,或者是整个月的数据供以后使用。如果大多数查询将某个州和某月作为筛选条件,那么这些字段是参与”基于表达式”的分片方式的最佳选择。此外,还应了解表中数据被修改的速率,诸如增、删、改等。
一二 使用IDS中的SMI表向用户发送“广播信息”
INFORMIX-Online以SQL表的形式向用户提供监控信息。这些被称作系统监控接口(SMI)的表,可以在非并行状态下方便地提供INFORMIX动态服务器的信息。有一个存储过程可借助这些信息,向当前Online例程连接的用户提供广播信息。
SMI表
当INFORMIX动态服务器最初初始化时,在消息日志中出现了提示信息:“sysmaster数据库被创建。这个数据库包括所有SMI表,每个Online例程都有自己的sysmaster数据库。在sysmaster数据库中的表,是基于磁盘的SQL表表或视图在共享内存中的组合,被称为伪表。
对于查询语言来说,SMI表和普通SQL表是一样的,因此SQL语句可以充分发挥其优势,检索当前Online例程的信息。INFORMIX动态服务器依赖于这些SMI表中的信息,认识到这一点很重要。因此,对这些表的信息进行各更新或修正会产生不可预知的后果。用户应该把SMI表中的信息看做是只读信息。SMI表的信息还可以用来监控磁盘的使用、表的状态,chunk的状态、系统的效率、备份(ON_Archive)的状态以及其它信息。
Syssessions表
本文的例子要向当前所有用户发出”广播信息,所以SMI表中”Syssessions”有其重要。该表包含了当前与Online例程相连接的所有用户信息。当用户连接到数据库引擎时,就在该表中加入一条新的记录。当用户与Online例程分离时,这个用户在syssessions表中的记录就被取消。在该表的各个字段中,下面几个字段对于本文的存储过程来说非常重要:
Sid
Session ID:在与其它SMI表连接时非常有用
Usename
Puser ID:用户的UNIX登录名
Hostname
Hostname of Client:用户客户端的主机名
tty
User's of stderrFile:客户端的全路径
syssession表中还可读到许多字段,包括每个用户session的当前状态。但对本文的存储过程而言,不涉及到这些字段。这些字段在《INFORMIX动态服务器管理员指南》中有详细介绍。
本文示例中存储过程所涉及到的具体问题
首先,有必要对存储过程中关于算法和具体语法的一些具体问题做必要的解释。最初,存储过程对终端设备执行一个回应,对远端用户进行写操作。因为在UNIX平台上没有标准的远程“写”命令。所以这种方法只不过是权宜之计。要注意在syssession表中,tty字段只有16个字符的长度。在同一个系统中,这个长度不足以指定一个终端设备或机器名。同时,请注意存储过程中出现的“”语法。这是在“存储过程语言”(SPL)中包含双引号的用法。
一个向全体用户发布“广播信息”的存储过程
create procedure public_address(mesg_str char(80))
define user_name char(10);
define mach_name char(16);
define tty_name char(20);
define cmd_line char(160);
foreach c_user_list_1 for
select unique username,hostsname,tty
into user_name,mach_name,tty_name
from sysmaster:syssessions
where username is not null and username!= and
hostname is not null and hostname != and
tty is not null and tty!=
let cmd_line=rsh ||mach_name|| echo'||meg_str||'>
||tty_name||;
system cmd_line;
end foreach
end procedure -- public address;
运行上例中的存储过程
因为上面例子中的存储过程在运行中用到了sysmaster数据库中的信息,执行起来就相当简明。为了准备并运行下列存储过程,要做以下工作:
1.启动dbaccess,连接到一个常规数据库上(不要选择sysmaster)
2.在“Query Language菜单下运行上述语句
3.Online例程会在屏幕上向用户发”消息“
4.EXECUTE PROCEUDRE public_address(Hi Vern)
确认”Hi Vern被发送给所有用户-不论是本地用户,还是远程用户。
结论:
本文展示了关于SMI的一个表的简单应用,利用SMI表所能提供的信息,以及强有力的SQL工具,以及各种前后端工具,我们能作得更多的工作。SMI表可以提供许多极有帮助的信息,这完全取决于你的具体需求。
| | |