A good way to think about it is that any operation for which Postgres needs to inspect the existing data can block for a long time if there's a lot of data. For example, adding a unique constraint has to block. There is, however, a workaround with "NOT VALID".
Same with adding a NOT NULL constraint without a default value. If there is a (constant) default value, then postgres can do that without blocking, which is pretty cool. That works because it only needs to modify metadata.
Same with changing column types, they need to go over the existing data.
Same with adding a NOT NULL constraint without a default value. If there is a (constant) default value, then postgres can do that without blocking, which is pretty cool. That works because it only needs to modify metadata.
Same with changing column types, they need to go over the existing data.