DB2 database directory shows DB that does not exist - db2

I have an old test database showing when I run db2 list database directory
Database 8 entry:
Database alias = TEST_AN
Database name = TEST_AN
Local database directory = /home/users/db2inst
Database release level = d.00
Comment =
Directory entry type = Indirect
Catalog database partition number = 0
Alternate server hostname =
Alternate server port number =
But it is not there when I run db2 list database directory on /home/users/db2inst
I can't connect to it:
> db2 connect to TEST_AN
SQL1013N The database alias name or database name "TEST_AN" could not be
found. SQLSTATE=42705
or drop it:
> db2 drop db TEST_AN
SQL1013N The database alias name or database name "TEST_AN " could not be
found. SQLSTATE=42705
And I can't create a new DB using that name:
> db2 create database TEST_AN
SQL1005N The database alias "TEST_AN" already exists in either the local
database directory or system database directory.
Does anyone know what the problem is, how can I get rid of this db that does and does not exist?

It would seem your local catalog is out of sync.
You may want to try UNCATALOG DATABASE TEST_AN, which will manually remove the database registration from the local catalog.

for what its worth I couldn't drop a database no matter what I tried, then I figured out that if I recatalog it I could drop it.
so running
CATALOG DBNAME
DROP DB DBNAME
worked for me

Related

Use PostgreSQL database in SQL script

I'm creating 3 databases from a single file:
CREATE DATABASE "products"
WITH
OWNER = postgres
ENCODING = "UTF8"
CONNECTION LIMIT = -1
IS_TEMPLATE = False;
CREATE DATABASE "accounts"
WITH
OWNER = postgres
ENCODING = "UTF8"
CONNECTION LIMIT = -1
IS_TEMPLATE = False;
CREATE TYPE role as ENUM ('employee', 'admin', 'customer');
Now I would like the type role to be created in the accounts database. The current script just creates the role in the 'default' postgres DB. I am used to MySQL syntax where I could use the 'use ' command. Any idea how I can use a similar command for a PostgreSQL script?
For additional context: this SQL file is executed in a PostgreSQL docker container upon initialisation.
I tried the following:
use the 'use' command. -> not recognised.
use the 'select' command. -> invalid.
In PostgreSQL you have to specify the database when you open a connection to the server. You can not switch to a different database using SQL.
From the documentation of the low-level API for opening connections:
An application program can have several backend connections open at one time. (One reason to do that is to access more than one database.)
But as #a_horse_with_no_name already pointed out if you are using psql you can use the command \connect to open a new connection to a different database.

PostgreSQL 13: create empty copy of database

I have a AWS RDS PostgreSQL 13 server with some databases. I have to create an empty copy of one database (empty means schema (tables, views, functions) + security (users, roles)).
Is pg_dump -s what I am looking for?
Thanks!
pg_dump -d db_name -s. You will also need to do pg_dumpall -g to get the global data e.g. roles. This will get all global data for the Postgres cluster, so you may have more then you need for the particular database.
Postgres allows the use of any existing database on the server as a template when creating a new database. I'm not sure whether pgAdmin gives you the option on the create database dialog but you should be able to execute the following in a query window if it doesn't:
CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;
Still, you may get:
ERROR: source database "originaldb" is being accessed by other users
To disconnect all other users from the database, you can use this query:
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'originaldb' AND pid <> pg_backend_pid();

Amazon RDS postgres Data wiped and can't connect to database?

I created an RDS Postgres instance. I'm new to RDS.
db host:
demodb.xxxuxxvxxxxx.us-east-2.rds.amazonaws.com
db identifier:
demodb
Every tutorial says to connect with this URL:
jdbc:postgresql://demodb.xxxuxxvxxxxx.us-east-2.rds.amazonaws.com:5432/demodb
but every time I do I get this error-
FATAl: database "demodb" does not exist.
I am able to connect using this:
jdbc:postgresql://demodb.xxxuxxvxxxxx.us-east-2.rds.amazonaws.com:5432/postgres
Now, while I was excited to connect after I used SQL workbench to create tables and insert data into those tables, a few hours later all my tables and data were deleted/wiped/dropped. Why would this happen? and How can I prevent it from happening in the future?
FATAl: database "demodb" does not exist.
demodb is db instance identifier. It is NOT the name of your database inside of PostgreSQL.
By default RDS PostgreSQL does not create a database for you. It seems to me that you haven't created an actual database when you setup your RDS PostgreSQL.
To create a database at RDS creation there is an option called Initial database name where you should specify the name of the database you want. Otherwise, no database is created, which is a default behavior:

How to shut down one database in a db2 instance?

I want to shut down one database in a db2 instance with multiple dbs.
I don't want to deactivate the db as it will reconnect when I try to connect. It should be completely shut down so I get a connection error when trying to connect to the db.
This is not a programming question so it can be viewed as off topic.
There are different techniques, each has advantages/disadvantages.
You can quiesce the database and later unquiesce it.
or you can revoke connect rights, and later grant them, but this depends on how well your role separation is done.
or you force off existing applications and then connect in exclusive mode as the instance owner (provided that your applications NEVER connect with instance-owner credentials).
One trick you could use is to temporarily recatalog the database you want to deactivate under a different name; this will prevent applications from connecting to it using the original name, regardless of the authority they use.
First, determine the database path by looking at its catalog entry:
db2 list db directory
The value of the "Local database directory" property is what you need.
Now you can recatalog the database:
db2 uncatalog db orig_db
db2 catalog db orig_db as foobar on <path>
where <path> is the local database directory determined previously.
Once you force all applications currently connected to the database in question you will be able to deactivate the database:
db2 list applications
db2 "force application (<app id 1>, <app id 2>,...)
db2 deactivate db foobar
Later on you can restore the catalog entry to its original value:
db2 uncatalog db foobar
db2 catalog db orig_db on <path>

Trying to rename a database in Redshift cluster

I'm trying to rename a database in my Redshift cluster.
You cannot rename the database when you're connected to it so I've created a temporary database, reconnected with SQL Workbench to the temporary db and issued:
ALTER DATABASE olddb RENAME to newdb;
I get an error stating ERROR: database "olddb" is being accessed by other users [SQL State=55006]
I've checked who is connected and there appear to be some connections from user rdsdb to the database. I assume this is a service account that AWS Redshift use to perform maintenance tasks etc.
How can I rename the database when this superuser is connected?
Many thanks.
You cannot alter the name of (or delete!) the database that is created during the initial cluster creation. I don't believe this is mentioned in the docs but I've confirmed it with them.
We can change the database name which is already created.
Detailed steps on how to do
Connect to the old database and create a new database if you do not have another one already.
create database databasebasename
In this example, I will call the databasename as 'newdb'.
Connect to newdb using connecting string as, jdbc:redshift://.us-east-1.redshift.amazonaws.com:8192/newdb, with the same password and username of your superuser (or the other eligible users as mentioned above).
Now you can alter the database name. Substitute 'database_name_new' with the desired databasename.
alter database old-db-name rename to database_name_new;
If there are any active sessions, you'll have to kill them. To find the pid of active sessions:
select * from STV_SESSIONS where user_name='rdsdb';
Then to kill a session:
SELECT
pg_terminate_backend(<pid>)
FROM
pg_stat_activity
WHERE
-- don't kill my own connection!
procpid <> pg_backend_pid()
-- don't kill the connections to other databases
AND datname = '<old-db-name>';
Once complete, you can connect back to that new database using the new name in the connection string as
jdbc:redshift://<cluser-id>.us-east-1.redshift.amazonaws.com:8192/database_name_new
You can delete the temporary 'newdb'.
drop database databasebasename
That's possible now -- I just renamed the database that was created during the initial cluster creation.
We had a similar situation.
Step 1: Connect to the database which is not the one you are trying to rename. Check the same by executing SELECT CURRENT_DATABASE();.
Step 2: Execute the query below -
SELECT
ss.*, 'select pg_terminate_backend('||process||');'
FROM
stv_sessions ss
ORDER BY
db_name;
The output of the query will have a column at the end with the select statements. Execute those to kill the sessions.
Step 3(Optional): If you are not the owner of the database try to modify the ownership of the database -
ALTER DATABASE <database to be renamed>
OWNER TO <user which is going to do the rename>;
Step 4: Rename the database