官术网_书友最值得收藏!

Avoiding typical mistakes and explicit locking

In my life as a professional PostgreSQL consultant (http://postgresql-support.de/), I have seen a couple of mistakes that are made again and again. If there are constants in life, these typical mistakes are definitely some of the things that never change.

Here is my favorite:

In this case, there will be either a duplicate key violation or two identical entries. Neither variation of the problem is all that appealing.

One way to fix the problem is to use explicit table locking:

test=# h LOCK 
Command: LOCK
Description: lock a table
Syntax:
LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]

where lockmode is one of:

ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE |
SHARE UPDATE EXCLUSIVE| SHARE |
SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

As you can see, PostgreSQL offers eight types of locks to lock an entire table. In PostgreSQL, a lock can be as light as an ACCESS SHARE lock or as heavy as an ACCESS EXCLUSIVE lock. The following list shows what these locks do:

  • ACCESS SHARE: This type of lock is taken by reads and conflicts only with ACCESS EXCLUSIVE, which is set by DROP TABLE and the like. Practically, this means that a SELECT cannot start if a table is about to be dropped. This also implies that DROP TABLE has to wait until a reading transaction is completed.
  • ROW SHARE: PostgreSQL takes this kind of lock in the case of SELECT FOR UPDATE/SELECT FOR SHARE. It conflicts with EXCLUSIVE and ACCESS EXCLUSIVE.
  • ROW EXCLUSIVE: This lock is taken by INSERT, UPDATE, and DELETE. It conflicts with SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE.
  • SHARE UPDATE EXLUSIVE: This kind of lock is taken by CREATE INDEX CONCURRENTLY, ANALYZE, ALTER TABLEVALIDATE, and some other flavors of ALTER TABLE as well as by VACUUM (not VACUUM FULL). It conflicts with the SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes.
  • SHARE: When an index is created, SHARE locks will be set. It conflicts with ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE.
  • SHARE ROW EXCLUSIVE: This one is set by CREATE TRIGGER and some forms of ALTER TABLE, and conflicts with everything but ACCESS SHARE.
  • EXCLUSIVE: This type of lock is by far the most restrictive one. It protects against reads and writes alike. If this lock is taken by a transaction, nobody else can read or write to the table affected.

Given the PostgreSQL locking infrastructure, one solution to the max-problem outlined previously would be:

BEGIN; 
LOCK TABLE product IN ACCESS EXCLUSIVE MODE;
INSERT INTO product SELECT max(id) + 1, ... FROM product;
COMMIT;

Keep in mind that this is a pretty nasty way of doing this kind of operation because nobody else can read or write to the table during your operation. Therefore, ACCESS EXCLUSIVE should be avoided at all costs.

主站蜘蛛池模板: 梧州市| 河曲县| 扶绥县| 博白县| 普定县| 会泽县| 通海县| 榆中县| 博罗县| 江都市| 治多县| 平塘县| 平顶山市| 武隆县| 万宁市| 中阳县| 连州市| 齐齐哈尔市| 东至县| 永安市| 慈利县| 南宫市| 油尖旺区| 龙川县| 射洪县| 马山县| 莱阳市| 南靖县| 浙江省| 天祝| 嵩明县| 方城县| 宜兴市| 华阴市| 阳谷县| 彩票| 资源县| 吐鲁番市| 凤凰县| 内丘县| 武川县|