Does Rollback automatically end transaction in Postgres - postgresql

Using PostgreSQL 9.1
In this code:
BEGIN TRANSACTION
// Do something
If error then
ROLLBACK //<--Does this automatically End Transaction
Else
COMMIT //<--Automatically Ends Transaction
End if
Is an END TRANSACTION command necessary after the ROLLBACK command?

Rollback has end Your transaction, no need another command.
Here some example :
test_general=# begin;
BEGIN
test_general=# lock TABLE t1 ;
LOCK TABLE
test_general=# select locktype, relname, mode from pg_locks l inner join pg_class c on c.oid = l.relation;
locktype | relname | mode
----------+----------------------------+---------------------
relation | pg_namespace_oid_index | AccessShareLock
relation | pg_class_relname_nsp_index | AccessShareLock
relation | t1 | AccessExclusiveLock
test_general=# rollback;
ROLLBACK
test_general=# select locktype, relname, mode from pg_locks l inner join pg_class c on c.oid = l.relation;
locktype | relname | mode
----------+----------------------------+-----------------
relation | pg_class_relname_nsp_index | AccessShareLock
relation | pg_class_oid_index | AccessShareLock
relation | pg_class | AccessShareLock
relation | pg_locks | AccessShareLock
(4 rows)
Lock released means that the transaction is over.

Related

Get table options from query

Is there a way to query the options (specifically the autovacuum_vacuum_scale_factor) set for a specific table?
Right now I'm doing \d+ <table_name> in the CLI to get them, but I'd like to do it from a query.
Thanks :)
CREATE TABLE a_a (
a int
)
WITH (
autovacuum_vacuum_scale_factor = 20
);
SELECT
relname,
relnamespace,
reloptions
FROM
pg_class
WHERE
relname = 'a_a';
you will get:
+---------+--------------+-------------------------------------+
| relname | relnamespace | reloptions |
+---------+--------------+-------------------------------------+
| a_a | 16466 | {autovacuum_vacuum_scale_factor=20} |
+---------+--------------+-------------------------------------+

Check a materialized view exists?

How do I check if a materialized view exists?
I have created one and checked in information_schema.tables and information_schema.viewsbut I cannot see it.
Where should I be looking?
Use the system catalog pg_class, e.g.:
create materialized view my_view as select 1;
select relname, relkind
from pg_class
where relname = 'my_view'
and relkind = 'm';
relname | relkind
---------+---------
my_view | m
(1 row)
or the system view pg_matviews:
select *
from pg_matviews
where matviewname = 'my_view';
schemaname | matviewname | matviewowner | tablespace | hasindexes | ispopulated | definition
------------+-------------+--------------+------------+------------+-------------+------------
public | my_view | postgres | | f | t | SELECT 1;
(1 row)

Size of temp tables created in a particular session

I created a temp table using below query
Drop table if exists tmp_a;
Create temp table tmp_a
(
id int
);
Insert into tmp_a select generate_series(1,10000);
When I queried pg_stat_activity, it is showing as "IDLE" in current_query column for the above session.
I will get the size of all temp table from pg_class table using this query.
But I want the list of temp tables created for a particular session and the size of those temp tables i.e if I created two temp tables from two different sessions then the result should be like below
procpid | temp table name | size | username
12345 | tmp_a | 20 | gpadmin
12346 | tmp_b | 30 | gpadmin
Please share the query if anyone has it
It's actually simpler than you think --
The temporary schema namesapce is the same as the session id --
So...
SELECT
a.procpid as ProcessID,
a.sess_id as SessionID,
n.nspname as SchemaName,
c.relname as RelationName,
CASE c.relkind
WHEN 'r' THEN 'table'
WHEN 'v' THEN 'view'
WHEN 'i' THEN 'index'
WHEN 'S' THEN 'sequence'
WHEN 's' THEN 'special'
END as RelationType,
pg_catalog.pg_get_userbyid(c.relowner) as RelationOwner,
pg_size_pretty(pg_relation_size(n.nspname ||'.'|| c.relname)) as RelationSize
FROM
pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_catalog.pg_stat_activity a ON 'pg_temp_' || a.sess_id::varchar = n.nspname
WHERE c.relkind IN ('r','s')
AND (n.nspname !~ '^pg_toast' and nspname like 'pg_temp%')
ORDER BY pg_relation_size(n.nspname ||'.'|| c.relname) DESC;
And you get --
processid | sessionid | schemaname | relationname | relationtype | relationowner | relationsize
-----------+-----------+------------+--------------+--------------+---------------+--------------
5006 | 9 | pg_temp_9 | tmp_a | table | gpadmin | 384 kB
5006 | 9 | pg_temp_9 | tmp_b | table | gpadmin | 384 kB
(2 rows)
Let's put that process to sleep -- and startup another....
gpadmin=#
[1]+ Stopped psql
[gpadmin#gpdb-sandbox ~]$ psql
psql (8.2.15)
Type "help" for help.
gpadmin=# SELECT nspname
FROM pg_namespace
WHERE oid = pg_my_temp_schema();
nspname
---------
(0 rows)
gpadmin=# Create temp table tmp_a( id int );
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
CREATE TABLE
gpadmin=# SELECT nspname
FROM pg_namespace
WHERE oid = pg_my_temp_schema();
nspname
---------
pg_temp_10
(1 row)
... run the same query ...
processid | sessionid | schemaname | relationname | relationtype | relationowner | relationsize
-----------+-----------+------------+--------------+--------------+---------------+--------------
5006 | 9 | pg_temp_9 | tmp_a | table | gpadmin | 384 kB
5006 | 9 | pg_temp_9 | tmp_b | table | gpadmin | 384 kB
27365 | 10 | pg_temp_10 | tmp_a | table | gpadmin | 384 kB
(3 rows)

Amazon Redshift get list of identity columns for a table

How can I get a list of identity columns for a table in Amazon Redshift? (using system's tables)
Thank you.
For those who might be interested to know about how to get all identity columns in a Redshift DB. The following query was posted by Neil#AWS to AWS Redshift Forum:
select
c.relname,
a.attname
from pg_class c, pg_attribute a, pg_attrdef d
where c.oid = a.attrelid
and c.relkind = 'r'
and a.attrelid = d.adrelid
and a.attnum = d.adnum
and d.adsrc like '%identity%'
order by 1;
The PG_TABLE_DEF table contains information about tables and columns:
select * from pg_table_def where tablename = 't2';
schemaname|tablename|column| type | encoding | distkey |sortkey| notnull
----------+---------+------+---------+----------+---------+-------+---------
public | t2 | c1 | bigint | none | t | 0 | f
public | t2 | c2 | integer | mostly16 | f | 0 | f
public | t2 | c3 | integer | none | f | 1 | t
public | t2 | c4 | integer | none | f | 2 | f
(4 rows)
Also, the standard PostgreSQL catalog tables are accessible to Amazon Redshift users. For more information about PostgreSQL system catalogs, see PostgreSQL System Tables.

select table from AccessExclusiveLock locked table

I'm testing postgresql lock mechanism on my pgsql-9.1 on centos-5.8.
What I'm wondering is how can I select from table which is exclusively locked caused by <IDLE> in transaction uncommited.
The case is below...
In session1
postgres=# create table test_table(col1 char);
CREATE TABLE
postgres=# begin;
BEGIN
postgres=# insert into test_table values('1');
INSERT 0 1
--uncommited
In session2
postgres=# alter table test_table add column c2 char;
-- It has been locked....
in session3
postgres=# select t.relname, l.locktype,page,pid,virtualtransaction,mode,granted from pg_locks l, pg_stat_all_tables t where l.relation=t.relid order by relation asc;
relname | locktype | page | pid | virtualtransaction | mode | granted
--------------+----------+------+------+--------------------+---------------------+---------
pg_class | relation | | 9940 | 2/715754 | AccessShareLock | t
pg_index | relation | | 9940 | 2/715754 | AccessShareLock | t
pg_namespace | relation | | 9940 | 2/715754 | AccessShareLock | t
test_table | relation | | 9660 | 9/671042 | RowExclusiveLock | t
test_table | relation | | 9639 | 7/707191 | AccessExclusiveLock | f
(5 rows)
postgres=# select col1 from test_table;
--It's not possible to select from exclusively locked table
What I need is to get size of the relation regardless of locking happened.
I'm bushing around set transaction isolation level but I didn't catch any solutions till now.
Any advice would be very appreciated.
Thanks in advance.
Your table is not access exclusively locked, it has an AccessExclusiveLock pending but not granted, behind a granted AccessShareLock. Although it does have about the same effect, new AccessShareLock queue up behind it. They could in theory jump the queue and be granted, but that risks the starvation of AccessExclusiveLock requests so it is not done.
If an estimate is good enough, you could do
select reltuples from pg_class where oid='test_table'::regclass;
Otherwise, about the only options is to kill one of the two processes that is holding the table lock hostage, either the one holding the AccessShare or the one wanting the AccessExclusive. (Or hack the PostgreSQL source code.)