Will changing column from timestamp to timestamptz lock the table?

半腔热情 提交于 2019-12-12 20:06:30

问题


I want to migrate a column from timestamp (no timezone) to timestamptz type.

I'm on Postgres 9.3.9.

I need to know if this operation will cause a table rewrite (lock the table) as my table is large and the db is live.

I found this in the 9.2 release notes:

Increasing the length limit for a varchar or varbit column, or removing the limit altogether, no longer requires a table rewrite. Similarly, increasing the allowable precision of a numeric column, or changing a column from constrained numeric to unconstrained numeric, no longer requires a table rewrite. Table rewrites are also avoided in similar cases involving the interval, timestamp, and timestamptz types.

It sounds promising but doesn't actually detail what 'similar cases' might be.

If this operation is going to lock the table I'd appreciate suggestions for how to work around this on a live db without interrupting service.


回答1:


First of all, you seem to be confusing locks and table rewrites. The note in the release notes talks about table rewrites - which always take an ACCESS EXCLUSIVE lock on the table. But here are many other operations that also take locks.

You would need:

ALTER TABLE tbl ALTER ts_col TYPE timestamptz;

Unless you want to set a specific time zone in the conversion, not the current time zone of your session:

ALTER TABLE tbl ALTER ts_col TYPE timestamptz USING ts_col AT TIME ZONE 'Europe/London';

Be sure to use a time zone name in this case, not a simple offset nor an abbreviation. Details:

  • Time zone names with identical properties yield different result when applied to timestamp
  • Ignoring timezones altogether in Rails and PostgreSQL

The documentation:

ALTER TABLE changes the definition of an existing table. There are several subforms described below. Note that the lock level required may differ for each subform. An ACCESS EXCLUSIVE lock is held unless explicitly noted.

ALTER column_name TYPE data_type takes such an ACCESS EXCLUSIVE lock. While the internal storage format of timestamp and timestamptz are identical, the internal value is typically changed by the conversion (depending on the time zone setting of the session!). Postgres has to write a new version of every row in the table, so this requires a table rewrite as well. Since the operation took an ACCESS EXCLUSIVE lock there is no need to keep old row versions and you will see no dead tuples after the conversion.

SQL Fiddle demonstrating the role of the time zone setting on the conversion. I also added an example converting varchar to text, which does not require a table rewrite - unless you move to a shorter length modifier.
Note how I cast the output to text (ts_col::text) to keep the JDBC layer in sqlfiddle from adding some more (generally unwanted!) representation magic.

Concurrent transactions trying to access the table after your transaction has started will wait until this transaction has finished.

You could try to keep the lock time short by preparing a new table in the background, delete the old table and rename the new, but this will make concurrent transactions fail with an error like:

ERROR: could not open relation with OID 123456

Details:

  • Best way to populate a new column in a large table?

"Similar cases" for timestamp / timestamptz

Like varchar or numeric timestamp, time and interval types allow modifiers. For example, timestamps store up to 6 digits for fractional seconds per default, but you can modify that: timestamp(0) does not store fractional seconds.

The conversion from varchar(10) -> varchar(20) does not requires a table rewrite because values in the source type are guaranteed to fit (binary compatible) in the target type as well.

The same is true for timestamp (0) -> timestamp or timestamptz(3) -> timestamptz(5). That's what the manual refers to in the quoted passage in the release notes:

Table rewrites are also avoided in similar cases involving the interval, timestamp, and timestamptz types.



来源:https://stackoverflow.com/questions/32480700/will-changing-column-from-timestamp-to-timestamptz-lock-the-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!