Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commited1cde3

Browse files
committed
Merge branch 'main' into 'main'
Day 55See merge request postgres-ai/postgresql-consulting/postgres-howtos!21
2 parentsd649454 +0aeee07 commited1cde3

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

‎0055_how_to_drop_a_column.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Originally from:[tweet](https://twitter.com/samokhvalov/status/1726596564712571006),[LinkedIn post]().
2+
3+
---
4+
5+
#How to drop a column
6+
7+
>I post a new PostgreSQL "howto" article every day. Join me in this
8+
>journey –[subscribe](https://twitter.com/samokhvalov/), provide feedback, share!
9+
10+
Dropping a column is easy:
11+
12+
```sql
13+
altertable t1 drop column c1;
14+
```
15+
16+
However, it is important to keep in mind a few complications that might occur in various situations.
17+
18+
##Risk 1: application code not ready
19+
20+
Application code needs to stop using this column. It means that it needs to be deployed first.
21+
22+
##Risk 2: partial downtime
23+
24+
Under heavy load, issuing such an alter without a low`lock_timeout` and retries is a bad idea because this statement
25+
need to acquire AccessExclusiveLock on the table, and if an attempt to acquire it lasts a significant time (e.g. because
26+
of existing transaction that holds any lock on this table - it can be a transaction that read a single row from this
27+
table, or autovacuum processing this table to prevent transaction ID wraparound), then this attempt can be harmful for
28+
all current queries to this table, since it will be blocking them. This causes partial downtime in projects under load.
29+
Solution: low`lock_timeout` and retries. An example (more about this and a more advanced example can be found
30+
in[zero-downtime Postgres schema migrations need this: lock_timeout and retries](https://postgres.ai/blog/20210923-zero-downtime-postgres-schema-migrations-lock-timeout-and-retries)):
31+
32+
```sql
33+
do $do$
34+
declare
35+
lock_timeout constanttext :='50ms';
36+
max_attempts constantint :=1000;
37+
ddl_completedboolean := false;
38+
begin
39+
40+
perform set_config('lock_timeout', lock_timeout, false);
41+
42+
for iin1..max_attempts loop
43+
begin
44+
execute'alter table t1 drop column c1';
45+
ddl_completed := true;
46+
exit;
47+
exception
48+
when lock_not_available then
49+
null;
50+
end;
51+
end loop;
52+
53+
if ddl_completed then
54+
raise info'DDL successfully executed';
55+
else
56+
raise exception'DDL execution failed';
57+
end if;
58+
end $do$;
59+
```
60+
61+
Note that in this particular example, subtransactions are implicitly used (the`BEGIN/EXCEPTION WHEN/END` block). Which
62+
can be a problem in case of very high`XID` growth rate (e.g., many writing transactions) and a long-running
63+
transaction – this can trigger`SubtransSLRU` contention on standbys (see:
64+
[PostgreSQL Subtransactions Considered Harmful](https://postgres.ai/blog/20210831-postgresql-subtransactions-considered-harmful)).
65+
In this case, implement the retry logic at transaction level.
66+
67+
##Risk 3: false expectations that the data is deleted
68+
69+
Finally, when copying data between various environments and removing sensitive data, remember that
70+
`ALTER TABLE ... DROP COLUMN ...` is not secure, it doesn't remove the data. After column`c1` is dropped, there is
71+
still information about it in metadata:
72+
73+
```sql
74+
nik=# select attname from pg_attribute where attrelid = 't1'::regclass::oid order by attnum;
75+
attname
76+
------------------------------
77+
tableoid
78+
cmax
79+
xmax
80+
cmin
81+
xmin
82+
ctid
83+
id
84+
........pg.dropped.2........
85+
(8 rows)
86+
```
87+
88+
A superuser can easily recover it:
89+
90+
```sql
91+
nik=# update pg_attribute
92+
set attname='c1', atttypid=20, attisdropped= false
93+
where attname='........pg.dropped.2........';
94+
UPDATE1
95+
nik=# \d t1
96+
Table"public.t1"
97+
Column | Type | Collation | Nullable | Default
98+
--------+---------+-----------+----------+---------
99+
id |bigint | | |
100+
c1 |bigint | | |
101+
```
102+
103+
Some solutions to this problem:
104+
105+
-`VACUUM FULL` to rebuild the table after dropping columns. In this case, though a restoration attempt will succeed,
106+
the data will not be there.
107+
- Consider using restricted users and column-level privileges instead of dropping columns. The columns and data will
108+
remain, but users will not be able to read it. Of course, this approach wouldn't suit if there is a strict requirement
109+
to remove data.
110+
- Dump/restore after the column has already been dropped.

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ As an example, first 2 rows:
8181
- 0052[How to reduce WAL generation rates](./0052_how_to_reduce_wal_generation_rates.md)
8282
- 0053[Index maintenance](./0053_index_maintenance.md)
8383
- 0054[How to check btree indexes for corruption (pg_amcheck)](./0054_how_to_check_btree_indexes_for_corruption.md)
84+
- 0055[How to drop a column](./0055_how_to_drop_a_column.md)
8485
- ...
8586

8687
##Contributors

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp