当启动服务器时,如果有任何请求,它都将打开日志文件,然后通过对网络连接的监听向数据目录展现网络接口。为了访问数据,客户机建立一个到服务器的连接,然后传达作为SQL 查询的请求,以完成所期望的操作(例如,创建表、选择记录、更新记录)。服务器执行每个操作并将结果发送回客户机。服务器是多线程的,可以服务于多个并发的客户机的连接。但是,由于更新操作一次只能执行一个,因此实际上这些请求是顺序化的,两个客户机决不可能在同一时刻修改同一个记录。 在正常条件下,使服务器担当数据库访问的唯一仲裁者将提供对防止各种讹误的担保,这些讹误可导致多个进程同时访问数据库的表。然而,管理员应该知道:存在着服务器不具有对数据目录独占控制的时期: 何时在单个数据目录中运行多个服务器。通常情况下是运行一个单个的服务器来管理主机中的所有数据库,但是运行多个服务器也是可能的。如果这样做可以提供对多个独立的数据目录的访问,则不存在交互作用的问题。但是,有可能启动多个服务器并在相同的数据目录中指向它们。这是一个好主意,如果您想试试它,最好应确保系统提供了良好的文件锁定性能,否则服务器之间将不能协调地工作。如果将多个服务器同时写入日志文件,则将会使日志文件成为混乱的来源(而不是有用信息的来源)。 何时运行isamchk 和my i s a m c h k。isamchk 和myisamchk 实用程序用于表的维护、故障排除和修复。正如您所猜测的,由于这些实用程序能改变表的内容,所以如果在服务器运作的同时允许实用程序对表进行操作,将引起表的毁坏。了解怎样限制这种类型的交互作用以避免表毁坏是重要的。有关恰当使用这些程序的说明,请参阅第13章“数据库维护和修复”。
数据库的表示法
由MySQL管理的每个数据库都有自己的数据库目录,它们是数据目录的子目录,与所表示的数据库有相同的名称。例如,数据库my_db 对应于数据库目录DATA D I R/ my _ db。 这个表示法使得几个数据库级的语句的实现几乎是微乎其微的。CREATE DATA B A S E db _ name 使用只允许对MySQL服务器用户(服务器运行的UNIX 用户)进行访问的所有权和方式,并在数据目录中创建一个空目录db _ name。这等价于以服务器主机中的服务器用户的身份通过执行下列命令手工创建数据库: % mkdir DATADIR/db_name 创建数据库目录 % chmod 700 DATADIR/db_name 使它仅对MySQL服务器用户可访问 通过空目录表示新数据库的方法与其他数据库系统完全不同,那些数据库系统甚至要为“空”数据库创建许多控制文件或系统文件。 DROP DATABASE 语句也很容易实现。DROP DATABASE db _ name 删除数据目录中的db _ name 目录以及其中的所有表文件。这个语句类似于下列命令: %rm -rf DATA D I R / db _ name 其区别是,服务器只删除带有表的扩展名的文件。如果已经在该数据库目录中创建了其他的文件,服务器将使它们保持完整,并且不删除该目录本身。 SHOW DATABASE 只不过是对应位于数据目录中的子目录名称的一个列表。有些数据库系统需要保留一个列出所有需要维护的数据库的主表,但是,在MySQL中没有这样的结构。由于数据目录结构的简单性,数据库的列表是隐含在该数据目录的内容中的,像主表这样的 表可能会引起不必要的开销。
数据目录的结构易于理解,因为它使用了文件系统的层次结构的方式。同时,该结构具有特定的性能含义,尤其是关于打开表示数据库表文件的操作。 这种数据目录结构的一个后果是,由于表由多个文件来表示,因此每个打开的表都需要多个文件描述符,而不是一个。服务器智能化地高速缓存这些描述符,但是一个繁忙的服务器可能会很轻易地耗尽描述符资源,如果服务器同时为许多并发的客户机连接服务或运行引 用多个表的复杂查询的话。文件描述符在许多系统中都是匮乏的资源,尤其是将缺省的总进程(per- p r o c e s s)限制设置得相当低的系统。第11章“常规的MySQL管理”将提供有关估计所需描述符数量的信息,以及在需要时重新配置服务器或操作系统的信息。 由表自己的文件表示每个表的另一个后果是,表的打开时间随表的数量而增加。打开表的操作映射成由操作系统提供的文件打开操作,因此将受到系统的目录查找程序( d i r e c t o r y - lookup routine)效率的影响。通常这不是个问题,但是,如果在数据库中需要大量的表时,它则是个要考虑的问题。 例如,如果想要得到10 000 个表,则数据库目录中应该包含30 000 个文件。对于这么多的文件,将会引起由于文件打开操作所花费的时间而使运行速度降低( Linux ext2 和S o l a r i s 文件系统存在这个问题)。如果这个问题涉及到利害关系,则应根据应用程序的需要明智地重新考虑表的结构,从而重新组织这些表。应查看一下是否真的需要这么多的表,因为有时应用程序会不必要地繁殖许多表。为每个用户创建一个单个表的应用程序将导致许多表的产生,其实所有这些表都有相同的结构。如果您想将这些表合并成一个表,可以通过增加另一列以标识每行所使用的用户来达到目的。如果这能使表的数量明显减少,则会相应提高应用程序的性能。 在数据库设计阶段,您必须考虑这个特定的阶段对于一个给定的应用程序是否是值得的。不按上面所描述的方法来合并表的原因如下: 增大的磁盘空间的需求。合并表是为了减少所需表的数量(减少表打开的时间),但增加了另一列内容(增加磁盘空间的需求)。这是典型的空间与时间的折衷,您需要决定哪个因素更重要。如果认为速度极为重要,您或许愿意牺牲一点额外的磁盘空间。如果空间太紧张,则只能忍受使用多个表的时间。 安全性考虑。这些可能会约束您的能力或对表合并的愿望。每个用户分别使用单独的表的一个原因是:使只有拥有表级权限的用户才能对每个表进行访问。如果合并了表,则所有用户数据都将在同一个表中出现。 MySQL没有限制一个已知用户对特定行的访问的规定,因此,如果没有泄密访问控制就不能合并表。另一方面,如果所有的数据访问都由应用程序控制(用户不可能直接连接到服务器),则可以合并表并使用应用程序的逻辑强制合并后的行级访问。 MySQL对于表的大小有其自己内部的限制,但是,由于它将表表示为文件, MySQL还将受到文件尺寸最大值的限制,该最大值是由操作系统给出的。因此,有效的表尺寸最大值要小于MySQL的内部限制和系统文件尺寸的限制。 通常,随着时间的推移,对尺寸大小的约束将有所缓和。例如, IBM AIX4.1有2GB 文件大小的限制,但是在AIX4.2 中该限制值大约为6 4 G B。在MySQL中内部的表大小限制值也随着最新版本的出现而增加。在3.23 系列之前,内部的限制值为4 G B。从3 . 2 3系列起,该限制值大约为9 000 000太字节。表10-2 说明了MySQL内部的表大小限制和AIX 文件大小限制怎样相互作用来确定有效的表大小的最大值。类似的相互作用也可应用于其他的操作系统。
MySQL的状态文件
除数据库目录外,MySQL数据目录还包含许多状态文件。表10-3 概括介绍了这些文件。大多数状态文件的缺省名称从服务器主机名字中生成,在此表中表示为H O S T N A M E。 表10-3 MySQL状态文件