普段あまり意識する事はありませんが、PostgreSQLにはデータふぃある初期化(initdb実行時)に3つのDBが作成されます。
・ template0
・ template1
・ postgres
この上2つのtemplateXというDBは、全てのDBのテンプレートとなるDBという特殊な意味を持っています。
これについては、マニュアルの中にも触れられて(@ PostgreSQL 8.3.3文書) いますが、もう少し詳しくみていってみます。
どういうことかは、具体的に動かしてみればはっきり分かります。
例)
$ psql template1 template1=# create table master (id integer, name text); CREATE TABLE template1=# \z Access privileges for database "template1" Schema | Name | Type | Access privileges --------+------ +-----+------------------- public | master | table | (1 row) template1=# \q $ createdb testdb CREATE DATABASE $ psql testdb testdb=# \z Access privileges for database "testdb" Schema | Name | Type | Access privileges --------+------+------+------------------- public | master | table | (1 row)
どうでしょう。
template1で作成したテーブル(master)が、その後に作ったDBであるtestdb上でも勝手に作られています。
このように、template1は全てのDBのテンプレートとなる役割を果たしています。
template1がこういう用途のDBとなっているため、template1内にオブジェクトを作ってはならないとなっています。
作ってしまった場合、その後作る全DBにそのオブジェクトがコピーされて作られてしまうためです。
※ 全DBで共通のテーブルを作成したい場合(本番DBとテストDBの用途分けなど)などに意味を持ったりしますが、
それほど大きな用途としてはなさそうな気もします。
では、次にtemplate0の役割です。
こちらも、同じテンプレートDBですがtemplate0へは接続する事もできません。
$ psql template0 psql: FATAL: database "template0" is not currently accepting connections
こちらは、マニュアルに書いてあるとおりで、データファイル初期化時(initidb実行時)の状態のテンプレートDBとなっています。(純粋な状態のテンプレートDB)
template1のDBへは接続や変更を加える事はできますが、template0へは(通常のままだと)変更を加える事や接続する事はできません。
template0はtemplate1のテンプレートにもなっています。(言い方が紛らわしいですが)
予断となりますが、残り一つのpostgresというDBですが、こちらもinitdb実行時に自動的に作成されるDBです。
$ initdb (snip) copying template1 to template0 ... ok copying template1 to postgres ... ok
次に、マニュアルをよく読むとtemplate1は削除する事ができると書いていますが、実際に削除してみるとエラーが出てしまいます。
$ dropdb template1 dropdb: database removal failed: ERROR: cannot drop a template database
誤ってtemplate1内にオブジェクトを作ってしまった場合、一つ一つのオブジェクトを削除するのも面倒なので、ばっさりとDBごとを削除してしまいたいと考えるかもしれません。
(template1は削除してもよいものと、マニュアルにも記載されています)
具体的にtemplate1のDBを削除するには、下記の方法を取れば可能です。
$ psql template1 template1=# UPDATE pg_database SET datistemplate = FALSE where datname = 'template1'; UPDATE 1 template1=# \q $ dropdb template1 DROP DATABASE
まず、pg_database というシステムカタログ(Oracleのデータディクショナリのようなもの)内にある、「datistemplate」というカラムをFALSEにセットします。
このカラムは、テンプレートに指定ができるかどうかを表すもので、template1ではデフォルトTRUEになっています。
datistemplateカラムがTRUEとなっている場合、DBの削除は行えません。
template1を再作成したい場合、引き続き下記の操作を行います。
$ createdb template1 --template=template0; CREATE DATABASE $ psql -l List of databases Name | Owner | Encoding -----------+----------+---------- postgres | postgres | UTF8 template0 | postgres | UTF8 template1 | postgres | UTF8 (3 rows) $ psql template1 template1=# UPDATE pg_database SET datistemplate = TRUE where datname = 'template1'; UPDATE 1
template1は、全DBのテンプレートとなる特殊なDBという意味からも、勝手に削除をされないように、再度UPDATEをかけて元の状態に戻しています。
ただ、このような回りくどいやり方をせずとも、バックアップを取るべきDBをpg_dumpコマンドでバックアップし、initdbでデータファイルを初期化後に、リストアするという方法もあります。
ただし、pg_dumpallで取得したバックアップファイルからリストアする場合、template1も対象となっているので気をつけましょう。