Upgrading Postgres from 10 to 12 -- problem with encodings - postgresql

I'm trying to upgrade a postgres server from 10 12, and am having problems with the encodings. I'm following what I believe to be established recipes.
Behold:
postgres#serverbot:~$ psql -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-------------+----------+-----------+---------+-------+-----------------------
postgres | postgres | SQL_ASCII | C | C |
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | postgres=CTc/postgres+
| | | | | =c/postgres
thingsboard | postgres | SQL_ASCII | C | C | =Tc/postgres +
| | | | | postgres=CTc/postgres+
| | | | | nagios=c/postgres
(4 rows)
Notice the encodings on the 10 database. Time to create the database for 12.
postgres#serverbot:~$ sudo service postgresql stop
postgres#serverbot:~$ /usr/lib/postgresql/12/bin/initdb -E SQL_ASCII --locale=C -D /var/lib/postgresql/12/data
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "C".
The default text search configuration will be set to "english".
Data page checksums are disabled.
creating directory /var/lib/postgresql/12/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... America/New_York
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
Success. You can now start the database server using:
/usr/lib/postgresql/12/bin/pg_ctl -D /var/lib/postgresql/12/data -l logfile start
Excellent! Let's fire up the new server.
postgres#serverbot:~$ /usr/lib/postgresql/12/bin/pg_ctl -D /var/lib/postgresql/12/data -l logfile start
waiting for server to start.... done
server started
And verify the encodings...
postgres#serverbot:~$ psql -l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+-----------+---------+-------+-----------------------
postgres | postgres | SQL_ASCII | C | C |
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
Everything matches... time to upgrade!
postgres#serverbot:~$ /usr/lib/postgresql/12/bin/pg_upgrade \
--old-datadir=/var/lib/postgresql/10/main \
--new-datadir=/var/lib/postgresql/12/main \
--old-bindir=/usr/lib/postgresql/10/bin \
--new-bindir=/usr/lib/postgresql/12/bin \
--old-options '-c config_file=/etc/postgresql/10/main/postgresql.conf' \
--new-options '-c config_file=/etc/postgresql/12/main/postgresql.conf' \
--link --check
Performing Consistency Checks
-----------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for reg* data types in user tables ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for tables WITH OIDS ok
Checking for invalid "sql_identifier" user columns ok
encodings for database "postgres" do not match: old "SQL_ASCII", new "UTF8"
Failure, exiting
postgres#serverbot:~$
Doh!
What is wrong here? I assert that the encodings do match, and I'm stuck.
Can anyone offer any advice?

What I see is:
postgres#serverbot:~$ /usr/lib/postgresql/12/bin/pg_ctl -D /var/lib/postgresql/12/data -l logfile start
waiting for server to start.... done
server started
and then:
postgres#serverbot:~$ /usr/lib/postgresql/12/bin/pg_upgrade \
--old-datadir=/var/lib/postgresql/10/main \
--new-datadir=/var/lib/postgresql/12/main \
[...]
Note the $PGDATA directories. The database cluster you did the initdb for is different from the one you are doing the pg_upgrade to.
UPDATE. Since you seem to be using a Debian based OS and it's Postgres packaging, it might work better to stick with the packaging tools:
sudo pg_createcluster --locale=C 12 ascii
Creating new PostgreSQL cluster 12/ascii ...
/usr/lib/postgresql/12/bin/initdb -D /var/lib/postgresql/12/ascii --auth-local peer --auth-host md5 --locale C
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "C".
The default database encoding has accordingly been set to "SQL_ASCII".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/12/ascii ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... America/Los_Angeles
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Success. You can now start the database server using:
pg_ctlcluster 12 ascii start
Ver Cluster Port Status Owner Data directory Log file
12 ascii 5434 down postgres /var/lib/postgresql/12/ascii /var/log/postgresql/postgresql-12-ascii.log
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+-----------+---------+-------+-----------------------
postgres | postgres | SQL_ASCII | C | C |
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
Also I would use pg_upgradecluster, see here for more information. This keeps everything in the same system.

Related

Postgresql error database does not exist however it exists when listing the databases

When I drop the database I have an error that it doesn't exist however when I list the databases I can see it.
Here are the steps I am following:
sudo -u postgres psql
postgres=# \l
postgres=# DROP DATABASE IF EXISTS mydbname;
NOTICE: database "mydbname" does not exist, skipping
DROP DATABASE
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
--------------------+---------------+----------+---------+---------+----------------------------
mydbname | postgres | UTF8 | C.UTF-8 | C.UTF-8 | =Tc/postgres +
| | | | | postgres=CTc/postgres +
| | | | | cryptouser=CTc/postgres

Can not connect to a postgres database in a docker container from my local machine

I have a strange problem with docker and postgres. I can not connect from my local machine to psql inside the docker container.
First of all I created my container with this command:
docker run -d -p 5432:5432 --name my-postgres -e POSTGRES_PASSWORD=mysecretpassword postgres
After that I executed the container with following command:
docker exec -it my-postgres bash
Inside the container I started psql with the postgres user:
psql -U postgres
And I created a new database:
CREATE DATABASE mytestdb;
Everything works inside the container, but if I want to connect to it from my machine it does only show the database from my machine. I tried this to connect to postgres:
psql -h localhost -p 5432 -U postgres
Which should me show something like this:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
mytestdb | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
But instead I get this:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------------+-----------------+----------+---------+---------+----------------------------------
user | user | UTF8 | C | C |
postgres | user | UTF8 | C | C |
template0 | user | UTF8 | C | C | =c/user +
| | | | | user =CTc/user
template1 | user | UTF8 | C | C | =c/user +
| | | | | user =CTc/user
(4 rows)
(END)
In every tutorial, I saw they did it, but for me, it doesn't work. So please help me.
The problem is when you creating the db.
CREATE DATABASE mytestdb you forgot to add ; the command should be like CREATE DATABASE mytestdb;
And then you have your db and you can access it from inside the container or your host with these commands

Setting up production postgres (createdb permissions)

I'm setting up postgres on DigitalOcean. I've set PG envs. The 9s are obviously redacted data. To facilitate the ssl connection, ~/.postgresql/root.crt exists.
# env | grep PG
PGPORT=99999
PGPASSWORD=9999999999999
PGSSLMODE=require
PGUSER=doadmin
PGDATABASE=auth_service_prod
PGHOST=private-db-postgresql-sfo9-99999-do-user-9999999-9.a.db.ondigitalocean.com
When calling createdb, it fails:
# createdb
createdb: could not connect to database template1: FATAL: pg_hba.conf rejects connection for host "10.999.9.99", user "doadmin", database "template1", SSL on
I can connect to psql, though. I don't know enough about configuring postgres to allow doadmin to create a db, but hopefully here is some useful info:
# psql
psql (11.7 (Debian 11.7-0+deb10u1), server 11.8)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
auth_service_prod=> \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
_dodb | Superuser, Replication | {}
doadmin | Create role, Create DB, Replication, Bypass RLS | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
auth_service_prod=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-------------------+----------+----------+-------------+-------------+-----------------------
_dodb | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
auth_service_prod | doadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
defaultdb | doadmin | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
DigitalOcean doesn't allow createdb from postgres, apparently. I removed the code creating databases, and created them "manually" from their GUI. The app is now only responsible for managing the schema, not the database(s).

PostgreSQL can't create user [duplicate]

This question already has answers here:
In psql, why do some commands have no effect?
(2 answers)
Closed 3 years ago.
Issue: I can create users or databases from the shell (bash, OSX) but not postgres cli. From bash I get no confirmation if successful.
If I try to CREATE ROLE in psql then I get no response and it doesn't generate any error. If I try to createuser from bash then if successful it reports back nothing, if unsuccessful then it does generate the error: "role username already exists".
Example:
Yunti-# CREATE ROLE testuser
Yunti-# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
Yunti | Superuser, Create role, Create DB, Replication | {}
anything | | {}
monkey | | {}
Yunti-# CREATE DATABASE testdb
Yunti-# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+-------------+-------------+-------------------
Yunti | Yunti | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | Yunti | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | Yunti | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/Yunti +
| | | | | Yunti=CTc/Yunti
template1 | Yunti | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/Yunti +
| | | | | Yunti=CTc/Yunti
test | Yunti | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
test5 | Yunti | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
(6 rows)
Yunti-#
A similar thing happens when using createdb.
How can I create users and databases in postgres cli?
And is this normal to get no response to most postgres commands in bash?
Info: users and their privileges:
Yunti-# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
Yunti | Superuser, Create role, Create DB, Replication | {}
anything | | {}
monkey | | {}
Your statements are not executed, because you don't terminate them properly using a ;.
Quote from the manual:
A command is composed of a sequence of tokens, terminated by a semicolon (";").
And in the manual for psql:
At the prompt, the user can type in SQL commands. Ordinarily, input lines are sent to the server when a command-terminating semicolon is reached. An end of line does not terminate a command. Thus commands can be spread over several lines for clarity. If the command was sent and executed without error, the results of the command are displayed on the screen.
If you do that, you get an output like this:
psql (9.4.4)
Type "help" for help.
postgres=# CREATE ROLE testuser;
CREATE ROLE ---<<<< this tells you the statement was executed
postgres=#
I dont know if the postgres client is using other commands in OSX as it is in Linux but I assume it is the same.
This docs link shows some options for the postgres client:
It seems like "\l" lists the databases while the option you would like to see is roles and their access which is "\du".
When creating a database from within the client you should get a response in the form of "CREATING DATABASE". Maybe you are having some sort of syntax error?
I don't think users is created elsewhere.
I hope this solves some of your problems.

How to import database to PostgreSQL as root?

I want to import a database of mine to a database of my server. So, I copied my database dump file to my server's root directory and logged in and did this:
root#iWidgetServer1:~# sudo -u postgres psql -U iwidget -d iwidget -f iwidget_dump2.sql
could not change directory to "/root"
psql: FATAL: Peer authentication failed for user "iwidget"
However, iwidget is a role and has granted all priviliges for this database:
root#iWidgetServer1:~# sudo -u postgres psql -l
could not change directory to "/root"
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
------------------+----------+----------+-------------+-------------+-----------------------
iwidget | iwidget | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | =Tc/iwidget +
| | | | | iwidget=CTc/iwidget
postgres | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 |
sample_db | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 |
template0 | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template_postgis | postgres | UTF8 | en_GB.UTF-8 | en_GB.UTF-8 |
(6 rows)
What am I doing wrong?
From the docs:
The peer authentication method works by obtaining the client's operating system user name from the kernel and using it as the allowed database user name (with optional user name mapping). This method is only supported on local connections.
You're doing sudo -u postgres, but are trying to connect as iwidget.
You need to create a user named iwidget and login as this user.
This seems to be more a problem with the File permissions of the dump instead of Postgres. Have you tried moving the dump to a folder not owned by root?