2.2 数据集簇
PostgreSQL安装完成后,在做任何其他事情之前,必须先使用initdb程序初始化磁盘上的数据存储区,即数据集簇,由PostgreSQL管理的用户数据库以及系统数据库总称为数据集簇。在PostgreSQL的实现中,数据库就是磁盘上一些文件的集合,只不过这些文件有特定的文件名、存储位置等,并且有些文件之间会相互关联。默认情况下,PostgreSQL的所有数据都存储在其数据目录里,这个数据目录通常会用环境变量PGDATA来引用,后文中将会用PGDATA来指代数据目录。
在PostgreSQL中,对象标识符(OID)用来在整个数据集簇中唯一地标识一个数据库对象,这个对象可以是数据库、表、索引、视图、元组、类型等。PostgreSQL提供了Oid数据类型来表示OID,它实际上是一个无符号整数。
OID——对象标识符
OID通常是从1开始分配,但在初始化数据集簇时,会先将一部分OID分配给系统表、系统表元组、系统表上的索引等数据库对象,这一部分OID可以在系统表所对应的头文件中找到。同时,为了给后续版本留下扩展的余地,初始化数据集簇时还会预留一部分OID资源。这样,在系统运行时可分配的OID资源实际是从16384开始的。在PostgreSQL源代码src/include/catalog子目录下有一个shell脚本unused_oids用来输出当前版本中预分配和预留的OID的使用情况。
数据集簇中的每一个数据库都对应于系统表pg_database中的一个元组,该元组OID属性中记录的就是分配给该数据库的OID。同样,对于数据库中的对象如表、索引、视图、类型等,也对应于系统表pg_class中的一个元组(包括pg_class本身),这个元组的OID属性中记录的OID也就是该对象所分配的OID。
对于用户表的元组,是可以在创建用户表时选择是否具有OID属性的。如果在CREATE TABLE语句中使用了WITH OIDS选项,则该用户表中插入的每一个元组都将被分配一个OID。否则,默认状态下用户表的元组是没有OID属性的。
OID的分配由系统中的一个全局OID计数器来实现,每次需要分配新的OID时,就从该计数器中取出当前的OID,然后该计数器将会加1。OID分配时会采用互斥锁加以锁定以避免多个要求分配OID的请求获得同一个OID。
初始化数据集簇包括创建包含数据库系统所有数据的数据目录、创建共享的系统表、创建其他的配置文件和控制文件,并创建三个数据库:模板数据库template1和template0、默认的用户数据库postgres。以后用户创建一个新数据库时,template1数据库里的所有内容(包括系统表文件)都会拷贝过来,因此,任何在template1里面安装的内容都自动拷贝到之后创建的数据库中。template0和postgres都是通过拷贝template1创建的。
对于某个具体的数据库,在PGDATA/base里都对应有一个子目录,子目录的名字是该数据库在系统表pg_database里的OID。
每个表和索引都存储在其所属数据库目录下的独立文件里,以该表或者该索引的filenode号命名,该号码记录在该表或索引在系统表pg_class中对应元组的relfilenode属性中。
在表或者索引超过1GB之后,它就被分裂成多个1GB大小的段。第一个段的文件名和filenode相同,随后的段命名为filenode.1,filenode.2……这样的策略避免了在某些有文件大小限制的平台上可能出现的问题。
如果一个表的有些属性要存储相当大的数据,那么就会有个与之相关联的TOAST表,用于存储无法在数据行中放置的超大外置数据。表对应的pg_class元组的reltoastrelid属性记录了它的TOAST表OID。
在PostgreSQL中,默认情况下会将数据文件存放在PGDATA指定的目录下,但如果PGDATA所在磁盘空间不足或者用户出于磁盘性能的考虑,需要为系统增加新的物理存储位置(比如在另外一个磁盘上的目录),则可以使用“表空间”来进行扩展。表空间从物理意义上来说就是一个新的磁盘目录(当然这个目录可以和PGDATA同处一个磁盘或者不同磁盘),指定放在表空间中的数据库对象的物理文件都存放在表空间对应的目录中。如果某个数据库中的数据库对象被指定放在一个表空间中,那么在表空间的目录中会以该数据库的OID为名称创建一个目录,该数据库中属于该表空间的对象的物理文件都放在这个目录中。每个用户定义的表空间在PGDATA/pg_tblspc目录里面都有一个符号链接,它指向表空间的物理目录,该符号链接用表空间的OID命名。系统默认创建的表空间pg_default和pg_global并没有通过符号链接的方式指向其物理目录,而是直接对应PGDATA/base和PGDATA/global。
PGDATA中还保存有数据集簇的配置文件和其他子目录,各子目录及文件的用途说明可以参见表2-9。
表2-9 PGDATA中的子文件和目录
【责任编辑:云霞 TEL:(010)68476606】