Default databases in PostgreSQL - postgresql

What are the default databases in PostgreSQL at the time of installation?

template1: the "default" database, which is copied when you perform "create database foo"
template0: the "minimal default" database, which serves essentially the same purpose, but typically used to create databases when restoring dumps which might already have the extra objects that are in template1, or to create a database that uses a different character encoding to the server default (template0 should only contain ASCII characters in strings)
postgres: an "administrative" database, which clients can assume exists to connect to merely to list which databases are available etc. Also, for example, pgAdmin will install the pg_agent schema in this database.

Apparently there is a database "postgres" that is created by default on each postgresql server installation.
It appears that it does not really have a well-defined purpose. According to the docs:
Creating a database cluster consists of creating the directories in
which the database data will live, generating the shared catalog
tables (tables that belong to the whole cluster rather than to any
particular database), and creating the template1 and postgres
databases. When you later create a new database, everything in the
template1 database is copied. (Therefore, anything installed in
template1 is automatically copied into each database created later.)
The postgres database is a default database meant for use by users,
utilities and third party applications.
(Source: http://www.postgresql.org/docs/8.2/static/app-initdb.html )

Related

How is the Postgres 'system database' attribute set or unset?

One of several databases in a Postgres 10.15 cluster has been set to be a system database. The mechanism that caused this is unknown, though it may have happened at the same time that the database was converted to a template by updating the pg_database table. The pg_database table does not have a setting to control whether or not a database is a system database, however, and I cannot find any documentation describing how to set (or unset, which is what I really want to do) the system database flag.
The idea of a “system database” is foreign to PostgreSQL, it is an artifact of pgAdmin.
PostgreSQL does have the notion of a “template database”, that is a database that is intended to serve s template in CREATE DATABASE. You turn a database to a template database with
ALTER DATABASE some_db IS_TEMPLATE TRUE;
For such a database it is also a good idea to forbid connections, because you can only use a database as template if nobody else is connected to it:
ALTER DATABASE some_db ALLOW_CONNECTIONS FALSE;

Postgres - required databases

I have accidentally deleted the default "postgres" database from my postgres. I've read that:
Most Postgres servers have three databases defined by default: template0 , template1 and postgres . template0 and template1 are skeleton databases that are or can be used by the CREATE DATABASE command. postgres is the default database you will connect to before you have created any other databases.
I have now created again a postgres database by running CREATE DATABASE postgres.
Do I need to do anything else to basically redo deleting the "postgres" database? Or the current one is basically the same?
Thanks
The database postgres is in no way special. You should use the bootstrap superuser (normally postgres) as the database owner, then the database will be just as good as the original postgres database.
The only difference is that the new database will have an OID ≥ 16384, which identifies it as an object created after cluster initialization. However, a quick look through the source code makes me believe that we don't use that anywhere.

Every time I create a new database it's creating a table in that database

Every time I create a new database it's creating a table in that database. I'm finding information about model databases for Microsoft SQL Server, but I can't find anything for Postgres.
You probably created that table in the template1 database.
When you create a database, Postgres doesn't really create it from scratch, it copies an existing one.
Quote from the manual
By default, the new database will be created by cloning the standard system database template1. A different template can be specified by writing TEMPLATE name.
Just connect to the template1 database and drop the table there.

What happens after a "DROP DATABASE postgres"

I have a funny question about PostgreSQL database: What happens if the postgres database is dropped?
dropdb postgres worked.
createdb postgres worked too.
psql worked.
But I thought the users would be lost. Yet the old users are still there.
So where are the users stored for the database and which implications does dropping the postgres database have?
PostgreSQL metadata are stored in catalog tables, which are in the pg_catalog schema. These are accessible like regular views and tables.
There are shared system catalog tables which are shared between all databases. These tables are not affected when databases are dropped.
pg_authid, the table where the users are stored, is one of those shared catalogs. This is because in PostgreSQL, users don't belong to a database, but to the whole database cluster.
You can list all shared catalog tables like this:
SELECT relname FROM pg_class
WHERE relisshared AND relkind = 'r';
In the documentation you can find more information about the system catalogs.
When connecting to a Postgres server, you always need to specify which database you want to connect to.
When you set up a new server, you need something to connect to before you can run your first CREATE DATABASE statement.
That's all the postgres database is: a dummy database to use as a connection target for admin commands. There's no data in there, and you're free to drop it and use a different one instead (though whoever inherits your system will probably not thank you for it...).
As gil.fernandes said in his answer, server-wide objects like users are accessible from every database, but aren't stored inside any database in particular.

What's the difference between initdb /usr/local/var/[db] and createdb [db]

I am starting to use PostgreSQL and I am confused about the two ways to create a database. When I installed it the first time, the instructions said I have to create a default database with initdb /usr/local/var/postgres When I lookup my databases, I can see that I have a database called postgres. Now I am able to create a database with two other commands whereas the former is the command line script and the latter the SQL command. In the case of a "postgres" called database it would be:
createdb postgres
CREATE DATABASE postgres
Both are setting up a database in my list of databases. When I try to create another database with initdb /usr/local/var/[someDbName] though, it doesn't appear in my list of databases. So what's the difference between initdb and createdb then?
initdb is not used to create a "new database".
As documented in the manual you need it to create a "cluster" or "data directory" which then stores databases created with create database.
Quote from the manual:
Before you can do anything, you must initialize a database storage area on disk. We call this a database cluster. (The SQL standard uses the term catalog cluster.) A database cluster is a collection of databases that is managed by a single instance of a running database server
[...]
In file system terms, a database cluster is a single directory under which all data will be stored. We call this the data directory or data area
In short: initdb creates the necessary directory layout on the harddisk to be able to create and manage databases.
It's a necessary part of the installation process of a Postgres server.