Setting autovacuum on partitioned tables in Postgres 11 - postgresql

I'm trying to adjust autovacuum settings on a partitioned table, on PostgreSQL 11.
e.g:
# create table test (ts timestamp) partition by range (ts);
CREATE TABLE
# alter table test set (autovacuum_analyze_scale_factor = 0.1);
ERROR: unrecognized parameter "autovacuum_analyze_scale_factor"
Is it possible to alter such settings on partitioned tables?

It seems that you can only set parameters on table partitions rather than on parent table.
postgres=# create table test (ts timestamp) partition by range (ts);
CREATE TABLE
postgres=# create table test_2018 partition of test for values from ('2018-01-01 00:00:00') to ('2018-12-31 23:59:59');
CREATE TABLE
postgres=# alter table test_2018 set (autovacuum_analyze_scale_factor = 0.1);
ALTER TABLE
postgres=# alter table test set (autovacuum_analyze_scale_factor = 0.1);
ERROR: unrecognized parameter "autovacuum_analyze_scale_factor"
postgres=#

Related

bigint id changed back to int during table rename

I hit the int limit on a large table I use.
The table is in single user mode and has no FK constraints.
CREATE TABLE my_table_bigint (LIKE my_table INCLUDING ALL);
ALTER TABLE my_table_bigint ALTER id DROP DEFAULT;
ALTER TABLE my_table_bigint alter column id set data type bigint;
CREATE SEQUENCE my_table_bigint_id_seq;
INSERT INTO my_table_bigint SELECT * FROM my_table;
ALTER TABLE my_table_bigint ALTER id SET DEFAULT nextval('my_table_bigint_id_seq');
ALTER SEQUENCE my_table_bigint_id_seq OWNED BY my_table_bigint.id;
SELECT setval('my_table_bigint_id_seq', (SELECT max(id) FROM my_table_bigint), true);
At this point I tested that I could insert new rows without any problems. Success, I thought.
I went about renaming the tables.
alter table my_table rename my_table_old
alter table my_table_bigint rename my_table
ALTER INDEX post_comments_pkey RENAME TO post_comments_old_pkey
ALTER INDEX post_comments_pkey_bigint RENAME TO post_comments_pkey
Now, when I checked the schema.... the table ID type had changed BACK to integer, instead of bigint.
Copying took about 3 days - so I am really, really hoping that I don't need to do this again. This is postgres10 on RDS.
EDIT
I'm going to take care of this problem like this:
Create a new table - call it my_table_bigint2.
Do this:
CREATE TABLE my_table_bigint2 (LIKE my_table INCLUDING ALL);
ALTER TABLE my_table_bigint2 ALTER id DROP DEFAULT;
ALTER TABLE my_table_bigint2 alter column id set data type bigint;
CREATE SEQUENCE my_table_bigint2_id_seq;
ALTER TABLE my_table_bigint2 ALTER id SET DEFAULT nextval('my_table_bigint2_id_seq');
ALTER SEQUENCE my_table_bigint2_id_seq OWNED BY my_table_bigint2.id;
And start populating that table with the new data. (This is fine given the usecase.)
In the meantime, I'm going to run
ALTER TABLE post_comments alter column id set data type bigint;
And finally, once that's done, I'm going to
INSERT INTO my_table SELECT * FROM my_table_bigint2;
My follow-up question - is this allowed? Will this create some interaction between the sequences? Should I use a new sequence?

PostgreSQL add auto increment to empty ID column

I create table in PostgreSQL but I forgot to add auto increment.
How to alter empty Id column in Postgres to add auto increment?
Starting with Postgres 10 it's recommended to use identity columns for this.
You can turn an existing column into an identity column using an ALTER TABLE:
alter table the_table
alter id add generated always as identity;
If you already have data in the table, you will need to sync the sequence:
select setval(pg_get_serial_sequence('the_table', 'id'), (select max(id) from the_table));
You will need to create a sequence owned by that column and set that as the default value.
e.g.
CREATE TABLE mytable (id int);
CREATE SEQUENCE mytable_id_seq OWNED BY mytable.id;
ALTER TABLE mytable ALTER COLUMN id SET DEFAULT nextval('mytable_id_seq');

Altering tablespace for partitioned table in Postgres

In my database i have a partitioned table with name 'record_partitioned' on PostgreSQL 11.2.
i want to change its tablespace to a new tablespace 'fast_ssd' so all new dervied tables from this table be in 'fast_ssd' tablespace.
when i try to alter tablespace to 'fast_ssd'.
alter table record_partitioned set tablespace fast_ssd;
i see:
ALTER TABLE
but it seems nothing happened! i check tablespace like this:
SELECT tablespace,tablename FROM pg_tables where tablename='record_partitioned';
and output is:
tablespace | tablename
------------+--------------------
| record_partitioned
tablespace does not change.
There is no way to do this for a partitioned table. You'll have to add an explicit TABLESPACE clause whenever you create a partition.
An alternative is to set the default_tablespace parameter, but that would affect all other tables too.

Postgres alter field type from float4 to float8 on huge table

I want to alter column data type from float4 to float8 on a table with huge rows count. If I do it in usual path it takes much time and my table blocked for this time.
IS any hack to do it without rewrite the table content?
ALTER TABLE ... ALTER COLUMN ... TYPE ... USING ... (or related things like ALTER TABLE ... ADD COLUMN ... DEFAULT ... NOT NULL) requires a full table rewrite with an exclusive lock.
You can, with a bit of effort, work around this in steps:
ALTER TABLE thetable ADD COLUMN thecol_tmp newtype without NOT NULL.
Create a trigger on the table that, for every write to thecol, updates thecol_tmp as well, so new rows that're created, and rows that're updated, get a value for newcol_tmp as well as newcol.
In batches by ID range, UPDATE thetable SET thecol_tmp = CAST(thecol AS newtype) WHERE id BETWEEN .. AND ..
once all values are populated in thecol_tmp, ALTER TABLE thetable ALTER COLUMN thecol_tmp SET NOT NULL;.
Now swap the columns and drop the trigger in a single tx:
BEGIN;
ALTER TABLE thetable DROP COLUMN thecol;
ALTER TABLE thetable RENAME COLUMN thecol_tmp TO thecol;
DROP TRIGGER whatever_trigger_name ON thetable;
COMMIT;
Ideally we'd have an ALTER TABLE ... ALTER COLUMN ... CONCURRENTLY that did this within PostgreSQL, but nobody's implemented that. Yet.

Postgres: Reduce varchar size and truncate

I currently have a Postgres 8.4 database that contains a varchar(10000) column. I'd like to change this into a varchar(255) and truncate any data that happens to be too long. How can I do this?
Something like ALTER TABLE t ALTER COLUMN c TYPE VARCHAR(255) USING SUBSTR(c, 1, 255)
1) Update the column data using a substring method to truncate it
update t set col = substring(col from 1 for 255)
2) Then alter the table column
alter table t alter column col type varchar(255)
Docs here http://www.postgresql.org/docs/8.4/static/sql-altertable.html
BEGIN;
UPDATE table SET column = CAST(column as varchar(255));
ALTER TABLE table ALTER COLUMN column TYPE varchar(255); --not sure on this line. my memory is a bit sketchy
COMMIT;