快速深入地掌握和管理数据库系统-第七章

 
2009-01-13 来源:chinaunix.net
 

第七章 数据库日志

数据库系统的任何更新操作,都需要记录操作日志。数据库日志是更新操作的记录序列,记录了数据库系统中的所有更新活动,是系统正常运行、保持数据一致性、维护数据库安全和可靠的重要手段。通过了解系统对日志的使用和管理,用户可以采取合理措施,更好地保障数据的安全、可靠;可以在系统需要恢复时,选取正确的恢复手段,尽可能避免数据的丢失。

本章首先介绍数据库日志的概念以及日志所包含的内容,讲解了日志文件的使用以及数据库的日志归档方式。以此为基础,就系统对长事务的处理进行了探讨。本章在最后介绍了常用数据库系统的日志管理以及长事务处理。

7.1 数据库日志概述

7.1.1 什么是数据库日志

在数据库系统中,对数据的任何更新操作(如:增加、修改、删除),都要把相关操作的命令、执行时间、数据的更新等信息保存下来。这些被保存的信息就是数据库日志。也就是说,数据库日志是数据库系统中所有更新活动的操作序列。

数据库日志是系统正常运行、保持数据一致性的重要手段。我们知道,事务具有原子性、一致性、隔离性、持久性四大特性。事务的原子性要求事务中的所有操作,要么全都执行,要么全不执行。在事务失败时,系统就使用数据库日志信息,反向执行所有已经执行的操作,从而使数据库恢复到事务执行前的状态,实现了事务的原子性,保证了数据的一致性。

数据库系统的所有数据处理都是在内存中完成,被更新后的数据不会被马上写入磁盘。一旦系统失败,这些更新就要丢失。通过在事务提交时将日志信息写入磁盘,系统在失败而重新启动后,根据日志信息重新执行已提交事务,可以保证已经提交事务的更新不会丢失。

数据库日志的使用模式决定着数据库的备份和恢复方式。备份数据库时,在有一个完整数据库备份的基础上,用户可以只备份数据库日志,从而减少备份时间以及所需的存储空间。如果数据库系统遭到破坏,在恢复时就必须使用数据库日志使系统处于一致性状态。有关数据库备份和恢复的详细信息,可以参看第8章。

这里,我们需要对一些概念进行区分。管理员在数据库系统的日常维护过程中,需要定期地检查系统的运行状况,其任务之一就是查看系统运行日志。这些运行日志,记录数据库系统运行过程中产生的各种事件、错误代码、错误描述以及解释等。管理员通过对这些信息的检查,可以发现系统中潜在的问题,可以排除已经发生的故障。这些系统运行日志存放在不同的文件中(如:DB2系统的诊断信息日志文件、ORACLE系统的警报与跟踪文件、INFORMIX系统的信息日志文件、SYBASE系统的错误日志文件),供管理员管理和维护系统所用,与我们这里所讲的数据库日志有着本质上的区别。

7.1.2 数据库日志的内容

数据库系统根据事务处理来记录日志信息。对一个事务的执行,数据库系统需要为它记录以下的日志内容:

(1)事务开始标记。

(2)事务标识:在整个数据库内唯一标识该事务。

(3)数据项标识:是所操作数据项的唯一标识,通常是数据项在磁盘上的位置。

(4)旧值:数据项的写前值。(数据插入操作不包含该项)

(5)新值:数据项的写后值。(数据删除操作不包含该项)

(6)事务提交或者终止标记。

数据库系统在出现故障、重新启动后,首先要检查日志记录,看那些事务需要重新执行,那些事务需要回退。需要重新执行的事务,在日志中包含事务开始和事务提交标记;而仅仅包含事务开始标记的事务,则需要进行回退。

7.1.3 日志信息的缓冲和落实

数据库系统在事务处理过程中,所产生的日志信息最初存放在内存的日志缓冲区中。在事务提交或者日志缓冲区满等情况下,才由日志写进程落实到磁盘文件中。存放日志信息的磁盘文件被称为日志文件。有关日志写进程和日志缓冲区的讨论,可见第2.2.5、3.2.5两节。

7.1.4 先写日志原则

任何数据库系统都遵循先写日志的原则。在内存中被更新数据写入磁盘之前,要保证对应日志信息已经写入磁盘,存入日志文件。

日志是数据库要发生操作的记录。将日志信息写入磁盘,是对数据库将要发生处理的确认;而将内存中已更新数据写入磁盘,则表明实际上已经发生某些更新动作。如果先将被更新数据写入磁盘,在写入过程中系统崩溃,那么可能只是部分更新反映到数据库中,内存中的日志信息和其它更新全部丢失。在这种情况下,数据库中数据就处于不一致状态,而且由于不知道那些更新已经写入磁盘,因此无法对数据库进行恢复,数据库就遭到破坏。

使用先写日志的方式,在日志写的过程中,也会出现系统的崩溃,造成内存中数据的丢失。系统在重新启动后,通过检查日志记录,决定数据库将要发生那些动作,判断那些事务的操作全部完成,可以重新执行;那些事务的操作没有全部完成,需要进行回退,从而保证了数据库中数据的一致性。

7.1.5 不生成数据库日志

数据库日志非常重要。缺省情况下,数据库系统生成所有更新操作的日志信息并进行保存。然而,日志信息的生成和保存,不可避免需要消耗CPU、内存资源,需要磁盘I/O操作以及存放日志信息的磁盘空间。这要对系统的运行性能产生明显影响。

有时候,我们可能只关注数据库系统的处理速度,例如:将其它数据源中的大批量数据插入数据库、删除数据库中的历史数据等等。在这些情况,可以考虑关闭数据库日志,使数据库系统不生成更新处理的操作日志,从而大大地提高系统的执行速度。这可以通过以下的方式来实现:

(1)使整个数据库处于不记日志模式。这时,对数据库中所有表的更新处理都不产生日志信息。

(2)使要处理的表处于不记日志模式。这时,对该表的任何更新处理都不产生日志信息。

(3)使用系统提供的数据导入和导出工具。为了加快数据的导入和导出速度,这些工具对数据库中数据的处理,不会产生日志信息。

如果不生成数据库日志,任何事务的失败都将导致数据库的不一致。在这种情况下,用户必须执行整个数据库系统的恢复,使数据库处于一致状态。由于很容易造成数据库系统的损坏,因此我们一般不建议用户关闭数据库日志进行数据的处理。如果一定要使用这种方式,就必须要做到:

(1)充分了解这种处理方式的后果,并采取有关预防措施,例如:在处理前对整个数据库系统进行完整备份。

(2)在处理时,要防止其他用户在系统中运行更新事务,以避免这些事务的失败而引起整个系统的损坏。

7.2 日志文件

数据库日志最终要写入磁盘,以便永久性保存。存放日志信息的磁盘文件被称为日志文件。日志文件很关键的,一旦它遭到破坏,系统可能无法启动,数据库可能无法恢复。

7.2.1 日志文件的状态

日志写进程负责将内存中的日志信息写入日志文件。一个日志文件可能包含很多事务的操作记录,这些事务可能已经提交,也可能仍旧在执行。根据日志文件中所包含事务的执行情况,日志文件可以处于活动状态和不活动状态。

1. 日志文件的活动状态

处于活动状态下的日志文件,当前系统的运行仍旧可能需要读取该日志文件中的日志信息,因而日志文件不能被删除或者覆盖。

一个日志文件不管是否被写满,只要满足下面的两个条件之一,就处于活动状态:

(1)日志文件中包含尚未提交或者回退的事务

数据库日志是数据一致性的有效保障。一个被执行的事务,最终可能正常完成,也可能由于错误、条件不满足等原因而失败、要求回退。如果出现事务回退,并且事务的日志信息已经存入日志文件,数据库系统就需要从日志文件中获取事务已经执行的更新操作,反方向执行这些操作以完成事务回退。

(2)日志文件中所包含事务的更新尚未从内存中写到硬盘上

数据库系统为多个用户提供服务。基于性能的考虑,内存中的数据被更新后,并不是马上写入磁盘,而是仍旧存放在内存缓冲区中。如果系统出现故障,内存中的数据更新没能写入硬盘,系统再次启动后就要读取日志文件中的日志信息,重新执行该事务。

2. 日志文件的不活动状态

处于不活动状态下的日志文件,当前系统的运行不再需要读取该日志文件中的日志信息,因而日志文件可以被删除或者覆盖。

一个日志文件被写满之后,只有同时满足下面的两个条件,才处于不活动状态:

(1)所包含事务已经全部提交或者回退

(2)所包含事务的更新已经全部从内存中写到磁盘上

7.2.2 日志文件的使用方式

存放日志文件的磁盘空间是有限的。在日志文件被写满并处于不活动状态之后,数据库系统可以使用以下两种方式,处理日志文件中不再需要的日志信息:

(1)归档模式。也即数据库的归档日志模式,需要另外的介质空间保存日志文件中的日志信息。

(2)非归档模式。也即数据库的非归档日志模式,不要求保存日志文件中的日志信息。

在此之后,这些不活动状态下的日志文件可以直接删除,以释放磁盘空间;也可以直接被覆盖,由系统写入新的日志信息。对日志文件不同使用方式的选用,将影响到数据库的备份和恢复方式,其具体内容可以参看第8章。

7.2.3 数据库的非归档日志模式

在数据库的非归档模式下,日志文件被循环使用。一个日志文件被写满并处于不活动状态之后,不需要归档保存其中的日志信息。系统对该日志文件的再次使用,将覆盖其中的原有数据。

数据库系统在最初运行时,从第一个日志文件开始写入日志信息。在这个日志文件写满后,就开始往第二个日志文件中写入日志信息。以此类推,一直到最后一个日志文件被写满。在最后一个日志文件写满后,数据库就返回到第一个日志文件,往第一个日志文件中写入日志,该文件中原有的数据被覆盖。数据库非归档模式下对日志文件的使用,可见图7-1。

在非归档模式下,日志文件能否再次被使用,也就是说日志文件中的原有数据能否被覆盖,这决定于日志文件的状态。只有不活动状态下的日志文件,才能被系统再次使用。如果要被再次使用的日志文件处于活动状态,系统就由于无法写入日志信息而被迫挂起,暂停所有的事务处理。较少的日志文件个数、较小的日志文件磁盘空间以及大数据量的事务处理,都可能引起这种情况的发生,这是管理员要力求避免的事情。

数据库处于非归档模式,其安全、可靠性会受到一定的影响。我们知道,对数据库进行备份,是保证数据库系统安全、可靠的重要前提。一旦数据库遭到破坏,就可以使用备份恢复整个系统。由于日志文件循环使用、不需要归档保存,因此从数据库备份以后的所有事务日志信息全部丢失。使用数据库备份恢复时,只能将系统恢复到备份操作执行的那一时刻,在备份之后执行的所有事务将全部丢失。又由于无法使用日志文件,要保证恢复后的数据库在数据上一致,就要求数据库备份是数据一致的,即在备份时不允许其它事务更新数据库中的数据。

数据库的非归档日志模式,具有以下特性:

(1)管理简单。在设置完成后,不需要管理员再去维护日志文件。

(2)备份时需要中断业务处理,无法满足不间断业务处理的需要。

(3)要求数据库备份是数据一致的。数据库恢复时不需要日志文件,但可能会造成数据的丢失。

7.2.4 数据库的归档日志模式

在数据库的归档模式下,一个日志文件被写满并处于不活动状态之后,需要归档保存其中的日志信息。在这种模式下,系统可以循环使用日志文件,也可以生成新的日志文件。

(1)循环使用日志文件

如同数据库的非归档日志模式。日志文件的位置、空间大小、个数已经固定下来,数据库循环地使用这些日志文件。所不同的是,系统在覆盖这些日志文件之前,要求归档保存日志文件中的日志信息。因此在此模式下,日志文件能够再次被使用,必须满足以下两个条件:

① 处于不活动状态

② 已经被归档备份

如果系统要覆盖一个日志文件,由于以上条件不满足而无法进行,系统就被迫挂起,暂停事务的处理。

(2)生成新的日志文件

在当前日志文件被写满之后,系统就重新生成一个新的日志文件。对被写满、处于不活动状态的日志文件,需要归档并从当前目录中删除,以释放磁盘空间。否则,在当前目录下没有可用磁盘空间、无法生成新的日志文件时,系统就被迫挂起,暂停事务的处理。

(3)归档日志模式的特点

由于不再需要的日志信息被归档保存,保证系统恢复时从数据库备份以后的所有事务处理都不会丢失。

用户执行系统恢复时,首先使用数据库备份,将系统恢复到备份操作执行的那一时刻,然后再使用归档、未归档的日志文件信息,重新执行已经提交的事务,回滚未完成的事务,从而可以将系统恢复到故障发生的那一时刻,避免了数据的丢失。也由于恢复时要使用日志文件,就不要求数据库备份是数据一致的,即在备份时允许其它事务更新数据库中的数据。

对日志文件的归档,可以由管理员定期手工执行;也可以设置脚本程序,由数据库系统自动完成。数据库的归档日志模式,具有以下特性:

① 在设置完成后,需要自动或者手工归档日志文件。

② 对数据库备份,不需要中断业务的处理。

③ 数据库备份可以是数据不一致的。数据库恢复时需要读取日志文件,不会造成数据的丢失。

7.2.5 日志归档模式的选择

数据库的归档和非归档日志模式,各有优缺点。归档日志模式防止了数据的丢失,增强了数据库的可靠性、可操作性;而非归档日志模式管理简单,操作容易。

用户对数据库日志模式的选择,就决定了可用的数据库备份和恢复方式。因此,在应用系统投入使用前,用户应当根据自身业务处理的特点,选择合理的数据库日志归档模式。

大多数数据库系统都应使用日志的归档模式。具体来说,下列情况下应当选用归档日志模式:

(1)业务需要24小时不间断运行。

(2)应用系统中有大量的更新操作,数据的丢失是不可接受的。

在下列情况下,可以使用非归档日志模式:

(1)在正常工作时间之外,没有业务的处理。

(2)应用系统中的更新操作很少,主要是进行查询处理。

(3)数据丢失可以接受,用户能够方便地把丢失的数据找回来。

7.3 长事务的处理

一个管理员在日常的数据库系统维护过程中,不可避免会遇到大批量的数据更新处理。有时候,这种事务处理涉及的记录数可能高达上百万、甚至上千万条记录。我们把这样的事务称为长事务。

长事务只是一个相对的概念,大多情况下用来维护数据库中的历史数据,一般不会出现在日常的业务处理过程中。和一般的事务相比,它具有以下特点:

(1)需要更新的记录数很多

(2)整个处理需要较长的一段时间

虽然长事务被运行的几率较低,但它的执行会对整个数据库系统产生比较大的影响,而且不正确的使用可能造成整个数据库系统的破坏。因此用户在处理长事务时,需要仔细地规划和考虑。如果很随意地开始长事务的处理,往往会带来以下的结果:

(1)事务运行时间远远超过预期。事务已经运行了好几个小时,还远没有结束。由于影响到正常的业务处理,管理员被迫中止事务的运行。事务的异常中止又引起事务回滚,系统需要反向执行所有已经执行的操作,这又需要很长的一段时间。

(2)数据库系统被挂起。事务在执行时要产生日志信息,长事务所需要的日志空间是非常可观的。在所有的日志文件被写满之后,由于事务没有提交,系统不能够覆盖最早的日志文件,新的日志信息无处存放,于是系统就被挂起。

事务的异常中止、系统的挂起,都会造成数据库中数据的不一致。如果处理不当,就可能破坏数据库,进而需要对整个数据库系统进行恢复,日常的业务处理被迫中断。

为了降低长事务执行对系统产生的影响,我们可以考虑采取以下措施:

(1)保证系统日志文件有足够空间。在系统中创建更多的日志文件,或者使系统在需要时能够自动创建新的日志文件,从而保证长事务的运行有足够的可用日志空间,进而避免事务的挂起。

(2)将长事务分成多个小事务。使用条件限制或者其他手段,将一个长事务划分成很多个小事务,这样对数据的处理就可以分批、多次进行。由于每次执行所需时间、日志空间都较小,从而减少了对系统的影响。

(3)不生成数据库日志。就是通过设置,使长事务的处理不产生日志信息,避免对日志文件的写入。在加快事务处理的同时,又可以避免系统被挂起。然而其具体实现存在一些限制和注意事项,详细可见第7.1.5一节。

(4)使用表的分区。将数据量大的表分区,例如:根据日期、年份,将数据存放在表的不同分区中。在维护数据库时,如果需要移走历史数据,就可以直接将单个的分区移走。倘若需要查询历史数据,又可以方便地将被保存的分区直接加入表中。这种数据维护方法,需要在应用系统设计时就进行考虑。

尽可能缩短长事务的处理时间,是用户比较关心的问题。除了对表分区、不生成日志信息之外,用户还可以考虑采取以下措施:

(1)利用系统空闲时间,执行长事务的处理。例如:夜晚、非工作时间等。

(2)删除表上索引。在长事务处理完成后,重新创建。这样可以避免对表的每一个更新处理,都连带要引起索引的更新处理。

(3)使用表锁或者数据库锁。这样可以减少锁的使用,防止锁资源不足,同时也避免每次处理都要申请锁,减缓事务处理速度。

做好数据库备份是长事务处理前必须要完成的工作。在长事务处理完成后,用户有必要重新收集表、索引的统计信息,以保证优化器能够生成合理、正确的执行计划。如果需要,用户还可以重新组织表、索引的存储结构,以加快系统的I/O处理。

7.4 常用系统数据库的日志管理

日志信息是保证系统安全、可靠的重要手段, 用户应当根据自身需要,合理地管理和使用数据库日志。常用数据库系统:DB2、ORACLE、INFORMIX、SYBASE,在数据库日志的使用和配置上各不相同,对长事务的处理也各有特色。

对长事务的处理,关键是要采取一些合理的执行措施。从数据库系统的角度来看,可以通过设置,使长事务的处理有足够的日志存放空间,避免系统被挂起。在以下对各数据库系统的长事务处理讨论中,我们仅仅着重于讲解如何保证系统有足够的日志存放空间。

有关常用数据库系统日志信息的缓冲和落实,可以参看第2.6、3.5两节。

7.4.1 DB2数据库系统

DB2系统中,有两种类型的日志文件:主日志文件(primary log file)和辅助日志文件(secondary log file)。通常情况下,事务的日志信息存放在主日志文件中。在系统中存在大数据量处理的事务时,系统才会用到辅助日志文件,有关辅助日志文件的使用以及长事务的实现,可以参见下面的长事务处理。下列数据库配置参数和数据库日志有关:

LOGRETAIN:设定数据库日志的归档模式。

USEREXIT:设定是否启用用户出口标志。

LOGPRIMARY:设定主日志文件的数目。

LOGSECOND:设定辅助日志文件的数目。

LOGFILSIZ:设定一个日志文件的磁盘空间大小。

LOGBUFSZ:设定内存中日志缓冲区的大小。

MINCOMMIT:设定系统提交的事务数。在达到此设定后,日志写进程被激活,将日志缓冲区中的日志信息写入磁盘。

1. 不生成数据库日志

在特殊情况下,要提高数据库系统的处理速度,可以使事务的更新处理不产生日志信息。在DB2系统中,不能对整个数据库进行设置,使针对该数据库中所有表的更新处理都不产生日志信息。可以在一个事务中,改变表的属性,使该事务对表的更新操作不生成日志。这种属性更改,仅仅局限于当前事务,只对当前事务起作用。其他事务对该表的更新处理仍旧要产生日志信息。

另外,向表中插入数据时,可以使用load工具代替import工具。import工具对数据的插入,就好像是用一条条的SQL插入语句,要产生日志信息。而load工具,不但避免了日志信息的生成,而且限制表间参照、触发器等的检查和执行,因而加快了处理速度。

2. 日志文件的归档

DB2数据库系统支持归档日志和非归档日志(DB2资料中称作循环日志)两种模式,确省情况下,数据库处于非归档日志模式。

要使数据库处于归档日志模式,设置LOGRETAIN和USEREXIT这两个参数中的任何一个,或者两个参数都设置。

在归档日志模式下,当前日志文件被写满后,系统就重新生成一个新的日志文件。对日志文件的归档,可以采用自动和手工两种方式。

(1)自动归档。设置USEREXIT数据库参数,数据库就自动归档日志。但在设置该参数前,还需要其他一些操作。

(2)手工归档。定期手工归档、删除日志目录下不再被系统需要的日志文件,从而保证日志目录下有足够的空间,以便系统能够在需要时,产生新的日志文件。

对日志文件自动或者手工归档方式的具体实现,可参看第9章。

3. 长事务的处理

要使DB2系统有足够的日志存放空间,以保证长事务的顺利完成,我们必须要明了主日志文件和辅助日志文件的使用方式。通常情况下,事务的日志信息存放在主日志文件中。配置参数LOGPRIMARY、LOGSECOND设定系统分别创建的主日志文件、辅助日志文件的个数。

在非归档日志模式下,日志文件被循环使用。在处理长事务时,如果所有主日志文件中均包含该长事务的日志信息,也就是所有的主日志文件都处于活动状态,系统就不能覆盖最前面的主日志文件。这时,系统开始循环使用辅助日志文件。在所有辅助日志文件也都写满长事务的日志信息、处于活动状态而长事务仍旧没有结束时,由于没有可用的日志信息存放空间,系统就被迫挂起。

在归档日志模式下,当前日志文件被写满后,系统就重新生成一个新的日志文件。配置参数LOGPRIMARY、LOGSECOND实际上设定可处于活动状态的主日志文件、辅助日志文件的个数。对长事务的处理,类似于上面的非归档日志模式。

要避免系统被挂起,需要有足够的日志存放空间,也就是保证有无限个可被循环使用、或者可被创建的辅助日志文件。将配置参数LOGSECOND设为-1,只要有足够磁盘空间,数据库系统就可以创建无限个辅助日志文件。

7.4.2 ORACLE数据库系统

ORACLE系统使用日志文件组存放数据库日志。之所以被称为组,是因为每个日志文件组中可以包含多个日志文件,这些日志文件被称为组的成员。一个日志文件组中的所有成员具有同样的空间尺寸,包含相同的日志信息。由于一个组中包含多个成员,因此即使一个成员文件遭到破坏,该日志文件组仍旧可以被使用。下列配置参数和数据库日志有关:

LOGFILE:设定日志文件组及其成员的存放位置和空间大小。

MAXLOGFILES:设定系统可使用日志文件组的最大个数。

MAXLOGMEMBERS:设定每个日志文件组中所包含成员的最大个数。

LOG_ARCHIVE_START:设定是否自动进行日志文件组的归档。

LOG_ARCHIVE_MAX_PROCESSES:设定用来归档日志文件组的最大进程个数。

LOG_ARCHIVE_DEST:设定被归档日志文件组的存放位置。

LOG_ARCHIVE_FORMAT:设定被归档日志文件组的命名格式。

1. 不生成数据库日志

在特殊情况下,要提高数据库系统的处理速度,可以使事务的更新处理不产生日志信息。在ORACLE系统中,不能对整个数据库进行设置,使针对该数据库中所有表的更新处理都不产生日志信息。我们可以改变表、索引、实体化视图的属性,使它们处于不记日志模式,从而对这些对象的更新操作,都不会产生日志信息。如果一个表空间的属性被改变为不记日志模式,则在该表空间中新创建的对象,都拥有不记日志的属性。

另外,向表中插入数据时,使用SQL *LOADER工具的直接路径装入,可以减少日志信息的生成。要删除一个表中的所有记录数据,可以首先移走整个表,然后重新创建该表。更好的方法是使用truncate table命令,该命令删除表中的所有记录,不会生成日志信息,在保留表结构的同时回收表所拥有的磁盘空间。

2. 日志文件的归档

ORACLE数据库系统支持归档日志和非归档日志两种模式,确省情况下,数据库处于非归档日志模式。要使数据库处于日志归档模式,可以使用命令:alter database archivelog改变。

在归档日志模式下,系统循环地使用所有的日志文件组。对日志文件组的归档,可以采用自动和手工两种方式。

(1)自动归档。设置数据库参数LOG_ARCHIVE_START=TRUE。

(2)手工归档。设置数据库参数LOG_ARCHIVE_START=FALSE,定期手工归档日志文件组。

对日志文件组自动或者手工归档方式的具体实现,可参看第9章。

3. 长事务的处理

ORACLE系统日志文件组的个数以及组中成员的空间尺寸,都不能够自动扩充。因此无法保证系统总是有足够日志空间,使长事务顺利完成。管理员可以根据需要,建立更多的日志文件组,使组中成员有更大的磁盘空间。

回退表空间在更新事务的处理过程中,存放数据被更新前的映像。事务处理的数据量越大,需要的空间就越多。因此,管理员在处理长事务时,还要保证回退表空间有足够可用空间。

7.4.3 INFORMIX数据库系统

INFORMIX系统使用了两类日志文件:逻辑日志文件(logical log file)和物理日志文件(physical log file)。逻辑日志文件用来存放数据库系统中所有更新事务的日志信息,就是我们这一章所讲的数据库日志;物理日志文件并不存放日志信息,它被用来保存数据被更新前的原有映像。任何事务在更新数据前,都需要将这些数据备份到物理日志文件中。

INFORMIX系统在下列两种情况下,需要用到物理日志文件:

(1)如果当前事务需要回退,INFORMIX系统直接使用物理日志文件中的原有数据映像,覆盖当前事务所做的修改,使数据恢复到事务处理之前的状态。

(2)INFORMIX系统在恢复时使用物理日志文件,将数据库恢复到一个物理上的一致点,然后再根据逻辑日志文件中的日志信息,进行事务的前滚和回退。

INFORMIX系统中物理日志文件的使用,总给人“蛇足”的感觉。如果没有物理日志文件,数据库系统照样可以从逻辑日志文件中读出当前事务所有已经执行的更新操作,反方向执行以回退事务,照样可以完成数据库系统的恢复。DB2和SYBASE系统就是这样实现的。物理日志文件的使用,虽说提高了事务回退的效率,但事务处理之前的原有数据保存,既影响事务的处理速度,又要消耗系统资源。在ORACLE系统中,也存在类似于物理日志文件的回退表空间。但ORACLE系统的回退表空间,除了用做事务的回退之外,还和数据库系统的并发控制——多版本两阶段锁机制的实现,有着密切的关系,是数据库系统不可或缺的一个组成部分。

在INFORMIX系统中,每一个逻辑日志文件、物理日志文件并不是对应到一个操作系统文件或者裸设备上。所有的逻辑日志文件、物理日志文件可以放置在一个表空间中,系统根据每个日志文件的大小,在这个表空间上进行空间的分配。下列配置参数和数据库日志有关:

LOGBUFF:设定逻辑日志缓冲区的内存空间。

LOGFILES:设定逻辑日志文件的数目。

LOGSIZE:设定单个逻辑日志文件的空间大小。

PHYSBUFF:设定物理日志缓冲区的内存空间。

PHYSDBS:设定物理日志文件使用的表空间。

PHYSFILE:设定单个物理日志文件的空间大小。

LTAPEDEV:设定对逻辑日志文件备份时所使用的备份设备。可以是磁带机、操作系统文件。

LTAPEBLK:设定对逻辑日志文件备份时所使用的块大小。

LTAPESIZE:设定进行逻辑日志文件备份的备份设备所使用介质的空间大小。

1. 不生成数据库日志

在特殊情况下,要提高数据库系统的处理速度,可以使事务的更新处理不产生日志信息。在INFORMIX系统中,可以设置整个数据库,使它处于不记日志模式,从而对数据库中所有表的更新处理都不产生日志信息。也可以改变单个表的属性为不记日志模式,从而只是对该表的更新操作,不会产生日志信息。

另外,向表中插入数据时,可以使用ONLOAD工具。使用该工具装入数据时,要求数据库处于不记日志模式,不会产生日志信息。在数据装入完成后,再使用命令改变数据库的日志模式。要删除一个表中的所有记录数据,可以首先移走整个表,然后重新创建该表。更好的方法是使用truncate table命令,该命令删除表中的所有记录,不会生成日志信息,在保留表结构的同时回收表所拥有的磁盘空间。

2. 日志文件的归档

INFORMIX系统只有一种日志模式,即归档日志模式,系统循环地使用所有的逻辑日志文件,任何日志文件被写满之后、再次被使用之前,必须被归档保存。在实际操作时,可以根据需要,设置逻辑日志的备份设备参数:LTAPEDEV = /dev/null,数据库系统会将写满的逻辑日志文件自动标记为已归档,尽管实际的归档操作并没有被执行。另外,物理日志文件不需要被归档。

3. 长事务的处理

要使INFORMIX系统有足够的日志信息存放空间,以保证长事务的顺利完成,我们首先要了解和长事务有关的配置参数。

LTXHWM:设定单个事务能够使用的逻辑日志文件数,占总数目的百分比。一旦达到这个比例,系统就开始回退事务。

LTXEHWM:设定单个事务能够使用的逻辑日志文件数,占总数目的百分比。一旦达到这个比例,该事务就独享剩余的逻辑日志文件空间,其它事务被挂起。

DYNAMIC_LOGS:设定是否允许系统自动增加逻辑日志文件。这些逻辑日志文件在事务完成后被系统删除。

当一个事务所使用的逻辑日志文件达到配置参数LTXHWM的值后,系统就认定此事务为一个长事务。为防止事务占用所有的日志文件空间而引起系统挂起,系统就开始回滚该事务。由于回滚事务仍旧要产生日志、要写入逻辑日志文件,当事务所使用的逻辑日志文件达到配置参数LTXEHWM的值后,系统就暂停其他事务的执行,所有剩余日志文件空间全部用作该事务的回退。

一个逻辑日志文件被写满之后,系统就自动切换到下一个逻辑日志文件,这个日志文件就成为当前日志文件。除此之外,在切换时系统还要检查新的当前日志文件的下一个日志文件。如果它处于活动状态并且配置参数DYNAMIC_LOGS被设置,系统就自动在新的当前日志文件之后增加一个新的逻辑日志文件。

只要设置配置参数DYNAMIC_LOGS,同时将LTXHWM和LTXEHWM的值设为100,系统就会在需要时创建新的逻辑日志文件,一直到事务的完成。通过这种方式,可以保证长事务的处理有足够的日志信息存放空间。

物理日志文件在更新事务的处理过程中,要存放数据被更新前的映像。事务处理的数据量越大,需要的空间就越多。因此,管理员在处理长事务时,还要保证物理日志文件有足够可用空间。

7.4.4 SYBASE数据库系统

相对于DB2、ORACLE、INFORMIX数据库系统,SYBASE系统的数据库日志实现比较独特,日志文件在逻辑上是作为数据库的一个表而存在。创建数据库时,如果没有为日志指定单独的设备,日志将和数据一起存放在相同的设备上。SYBASE公司强烈建议用户将数据库的日志和数据分开存放。

SYBASE系统可用的日志模式属于归档日志模式,尽管它仅仅使用了一个日志表来存放日志记录。数据库系统在最初运行时,从数据库日志表的起始部分开始,依次向下记录事务的更新日志。在达到日志表的结尾时,日志表中没有空间可以用来登记事务的更新日志,数据库的事务处理就被挂起。这时数据库管理员必须备份数据库日志。对日志的备份,就是从日志表的起始部分开始,找到所有不再活动的日志记录,归档这些日志记录并从日志表中删除。在日志的备份操作完成之后,数据库系统就返回到日志表的起始位置,继续记录事务的更新日志,数据库的事务处理就继续进行。在下一次日志表被写满后,这时的日志备份就从上一次备份操作的后面开始,循环在日志表中找出所有不再活动的日志记录进行归档进而释放空间。SYBASE系统就是这样周而复始地使用数据库的日志表。

当然,用户应当定期执行数据库日志备份,不要等到事务处理被挂起时才开始进行。在备份日志时,用户可以根据需要,只是清除不再活动的日志记录,而不将它们归档保存。

SYBASE系统的这种将日志和数据同时存放在数据库中的实现方式,总让人对系统的可靠性产生怀疑,这就好象将保险柜的备用钥匙也锁在保险柜中一样。在现有钥匙丢掉之后,需要使用备用钥匙打开保险柜,却发现备用钥匙取不出来。我们知道,数据库日志保证了数据库的数据一致性。在数据库遭到破坏后,使用数据库备份、加上从备份操作开始一直到故障发生时的所有数据库日志,就可以将数据库恢复到故障发生的那一时刻。但对SYBASE系统来说,数据库被破坏之后,日志表中仍旧处于活动状态的日志记录肯定不会被备份。使用数据库备份进行恢复,自然会将日志表中还没有被备份的日志记录所覆盖。

好在SYBASE公司已经对这个问题提供了解决方法。在数据库失败、恢复数据库之前,用户可以使用带with no_truncate选项的dump transaction命令,备份失败数据库当前的日志记录。该命令使用master系统数据库中的空间分配信息,直接访问已损坏数据库的日志磁盘空间。由于该命令跳过了数据库而直接访问磁盘,因此只能在数据库遭到破坏后使用。对处于正常状态的数据库使用此命令,可能会破坏现有数据库。此外,该命令能否执行成功,还取决于以下的两个条件:

(1)master系统数据库可以正常访问

(2)失败数据库的日志和数据分开存放在不同的设备上

在一些资料中,对已损坏数据库的处理,建议使用bcp命令,将数据库中所有的数据导出来,存放在文本文件中。在数据库重建后,再导入数据。这种做法是一种舍本逐末的方法,同时也存在很大的缺陷。一来导出过程可能要花费很长的时间;二来部分数据可能无法导出。只是将部分数据导入重建后的数据库,无法保证数据库的数据一致性,除非用户有办法手工恢复已经丢失的数据。

1. 不生成数据库日志

在特殊情况下,要提高数据库系统的处理速度,可以使事务的更新处理不产生日志信息。在SYBASE系统中,既不能对整个数据库,也不能对单个表进行设置,使它们处于不记日志模式。SYBASE系统中的更新操作都要产生日志信息。

在向表中装入数据时,可以设置数据库的select into/bulkcopy/pllsort选项,使用bcp工具的快速装入方式,减少日志信息的生成,提高数据插入速度。要删除一个表中的所有记录数据,可以首先移走整个表,然后重新创建该表。更好的方法是使用truncate table命令,该命令删除表中的所有记录,不会生成日志信息,在保留表结构的同时回收表所拥有的磁盘空间。

2. 日志文件的归档

SYBASE系统只有一种日志模式,即归档日志模式,系统循环地使用数据库的日志表。日志表中的空间再次被使用前,日志信息必须被归档。对于数据和日志分开的数据库,可以使用命令dump transaction备份事务日志,并将不活动的部分从系统中删除。而对于数据和日志混合存放的数据库,只能使用命令dump transaction删除事务日志而无法单独归档备份。对关键的用户数据库,一定要将数据和日志分开存放。

对日志信息的归档,可以采用自动和手工两种方式。

(1)手工归档。定期使用dump transaction命令归档数据库日志,可以保存、也可以不保存日志信息。

(2)自动归档。可以设置数据库属性,使数据库在执行检查点操作时,自动清除日志。也可以使用sp_threshold命令,为数据库日志的空间使用设定界限值以及相应的脚本程序。在日志表的空间使用达到设置的界限值后,相应的脚本程序就自动执行,从而达到备份、清除日志的目的。

对日志信息自动或者手工归档方式的具体实现,可以参看第9章。

3. 长事务的处理

SYBASE系统的日志表不能够自动扩充,因此无法保证总是有足够的日志空间,使长事务顺利完成。管理员可以根据需要,为日志表分配更多的磁盘空间。此外,在长事务执行过程中,应不断地归档日志,释放日志空间。比较好的做法是让系统自动归档日志,手工归档方式往往是系统被挂起之后,才会引起用户的注意。

7.5 本章小结

对数据库的任何更新操作,都需要记录操作日志。数据库日志是系统中所有更新活动的操作序列,是系统正常运行、保持数据一致性的重要手段。

任何数据库系统都遵循先写日志的原则。系统在出现故障、重新启动后,首先要检查日志记录,决定那些事务需要重新执行,那些事务需要回退。

为了提高系统的执行速度,可以在大数据量处理时关闭数据库日志。为了防止系统遭到破坏,用户应当充分考虑并采取有关措施,处理过程中还要禁止其他用户更新数据库。

日志文件存放数据库日志信息。如果一个日志文件包含尚未提交、尚未回退的事务,或者所包含事务的更新尚未从内存中写到硬盘上,该日志文件就处于活动状态,不能被删除或者覆盖。除此之外,日志文件就处于不活动状态。

数据库系统可以使用两种日志模式:归档模式和非归档模式。在非归档模式下,日志文件被循环使用,管理简单,操作方便,但系统的安全、可靠性会受到一定的影响。在归档模式下,日志文件被写满后,需要归档保存,大多数系统应使用这种模式。

长事务是指大批量的数据更新处理,不正确的执行可能造成数据库系统的破坏。对它的处理,管理员需要仔细地规划和考虑,并做好必要的预防措施。

DB2系统使用两种类型的日志文件:主日志文件和辅助日志文件,支持归档日志和非归档日志两种模式。确省情况下,数据库处于非归档日志模式。

ORACLE系统使用日志文件组存放数据库日志,一个组中可以包含多个日志文件。支持归档日志和非归档日志两种模式。确省情况下,数据库处于非归档日志模式。

INFORMIX系统使用两类日志文件:逻辑日志文件和物理日志文件。逻辑日志文件用来存放系统中所有更新事务的日志信息,而物理日志文件用来保存数据被更新前的原有映像。系统只支持归档日志模式。

SYBASE系统的日志文件在逻辑上是数据库的一个表,应当将日志和数据分开存放在不同的设备上。系统只支持归档日志模式。


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织