21.3. 临时库

CREATE DATABASE实际上是通过拷贝一个现有的数据库进行工作的。 缺省时,它拷贝名为template1的标准系统数据库。所以该数据库是创建新数据库的"模板"。 如果你给template1数据库增加对象,这些对象将被拷贝到随后用户创建的数据库中。 这样的行为允许节点对数据库中的标准套件进行修改。比如,如果你把过程语言PL/Perl安装到 template1里,那么你在创建用户数据库的时候它们就会自动可得,而不需要额外的动作。

系统里还有名为template0的第二个标准系统数据库, 这个数据库包含和template1初始时一样的数据内容,也就是说, 只包含标准的PostgreSQL对象。在initdb之后,我们不应该对template0做任何修改。 通过告诉CREATE DATABASE使用template0而不是template1进行拷贝, 你可以创建一个"纯净"的用户数据库,它不会包含任何 template1里所特有的东西。 这一点在恢复pg_dump转储的时候是非常方便的:转储脚本应该在一个纯净的数据库 中恢复以确保我们正确创建了被转储出的数据库内容, 而不和任何现在可能已经存在于template1中的附加物相冲突。

另一个复制 template0中而不是template1的常见原因是, 可以在复制template0时声明新的编码和区域设置,而如果复制template1时, 必须使用与它相同的设置。这是因为的template1可能包含特定编码 或区域特定的数据,而 template0中不需要。

要通过拷贝 template0 的方法创建一个数据库,可使用下列方法之一:

CREATE DATABASE dbname TEMPLATE template0;

;

createdb -T template0 dbname

前者用于 SQL 环境,后者用于 shell 环境。

我们可以创建额外的模板数据库,而且实际上我们可以在一个集群中通 过将CREATE DATABASE 的模板声明为相应的数据库名拷贝任何数据库。 不过,我们必需明白,这个功能并非一般性的"COPY DATABASE"工具。实际上, 在拷贝操作的过程中,源数据库必需是空闲状态(没有正在处理的数据修改事务)。 如果在 CREATEDATABASE 开始的时候存在其它连接,那么操作将会失败, 否则在 CREATEDATABASE的执行过程中新连接都将被锁定,直到拷贝完成。

pg_database里有两个有用的标志可以用于每个数据库: datistemplatedatallowconn 字段。 datistemplate 表示该数据库是可以用作 CREATE DATABASE时的模板。如果设置了这个标志, 那么该数据库可以由任何有 CREATEDB权限的用户克隆;如果没有设置, 那么只有超级用户和该数据库的所有者可以克隆它。如果 datallowconn 为假, 那么将不允许与该数据库发生任何新的连接(不过现有的会话不会因为把该标志设置为假而被杀死)。 template0数据库通常被标记为 datallowconn = false 以避免对它的修改。 template0template1都应该总是标记为 datistemplate = true

Note: 除了 template1CREATE DATABASE.的缺省源数据库名之外, template1template0没有任何特殊的状态。比如, 我们可以删除 template1 然后从 template0 中创建它而不会有任何不良效果。 如果我们不小心在 template1 里加了一堆垃圾,那么我们就会建议做这样的操作。template1必须得是 pg_database.datistemplate = false才能被删除。

在初始化数据库集群的时候,也会创建 postgres 数据库。这个数据库用于 做为用户和应用连接的缺省数据库。它只是 template1的一个简单拷贝 ,需要的时候可以删除或者重建。