--当pg开启
一个事务,执行dml操作时,如果另
一个事务要
修改表结构,其不得不等待 --session1 中执行dml postgres=# begin; BEGIN postgres=# select pg_backend_pid(); pg_backend_pid ---------------- 4144 (1 row) postgres=# insert into t values(2,'rudy2'); INSERT 0 1 postgres=# --在session2 中执行ddl语句,发现其要等待 postgres=# begin; BEGIN postgres=# select pg_backend_pid(); pg_backend_pid ---------------- 3128 (1 row) postgres=# alter table t add password1 varchar(50); --在session3中可以发现session2发等待session 1 postgres=# SELECT locktype,postgres-# pg_locks.pid,postgres-# virtualtransaction,postgres-# transactionid,postgres-# nspname,postgres-# relname,postgres-# mode,postgres-# granted,postgres-# CASE postgres-# WHEN granted='f' THEN postgres-# 'get_lock' postgres-# WHEN granted='t' THEN postgres-# 'wait_lock' postgres-# END lock_satus,postgres-# CASE postgres-# WHEN waiting='f' THEN postgres-# 'waiting' postgres-# WHEN waiting='t' THEN postgres-# 'executing' postgres-# END lock_satus,cast(date_t
runc('second',query_start) AS timestamp) AS query_start,substr(query,1,25) AS query postgres-# FROM pg_locks LEFT OUTER postgres-# JOIN pg_class postgres-# ON (pg_locks.relation = pg_class.oid) LEFT OUTER postgres-# JOIN pg_namespace postgres-# ON (pg_namespace.oid = pg_class.relnamespace),pg_stat_activity postgres-# WHERE NOT pg_locks.pid=pg_backend_pid() postgres-# AND pg_locks.pid=pg_stat_activity.pid postgres-# AND transactionid is NOT null postgres-# ORDER BY query_start; locktype | pid | virtualtransaction | transactionid | nspname | relname | mode | granted | lock_satus | lock_satus | query_start | query ---------------+------+--------------------+---------------+---------+---------+---------------+---------+------------+------------+---------------------+--------------------------- transactionid | 4144 | 8/3137 | 4638456 | | | ExclusiveLock | t | wait_lock | waiting | 2015-10-21 20:29:58 | insert into t values(2,'r' transactionid | 3128 | 2/14315 | 4638461 | | | ExclusiveLock | t | wait_lock | executing | 2015-10-21 20:30:32 | alter table t add passwor --在
修改表结构时,如果把ddl放在
一个事务中,如果事务没有提交,则其它的事务必须等待,
包括查询 --在session2事务中执行
一个ddl postgres=# begin; BEGIN postgres=# select pg_backend_pid(); pg_backend_pid ---------------- 3128 (1 row) postgres=# alter table t add password2 varchar(50); ALTER TABLE --在session1事务中执行dml发生等待 postgres=# begin; BEGIN postgres=# insert into t values(2,'rudy2'); --在session3中可以发现session1在等待session2 locktype | pid | virtualtransaction | transactionid | nspname | relname | mode | granted | lock_satus | lock_satus | query_start | query ---------------+------+--------------------+---------------+---------+---------+---------------+---------+------------+------------+---------------------+--------------------------- transactionid | 3128 | 2/14316 | 4638466 | | | ExclusiveLock | t | wait_lock | waiting | 2015-10-21 20:37:38 | alter table t add passwor --在session4中的
查询也发生了等待 postgres=# select * from t limit 1; --故最好不要把ddl语句放在
一个事务中,如果该事务没有提交,否则其会造成后续的
查询与
修改都等待 --如果
一个session中有
一个大的
查询在执行,此时最好不要在另
一个session中
修改表结构,因为
查询会阻塞ddl语句 --在session1中执行
一个大的
查询 postgres=# select count(*) from t,t t1; --在session2中的ddl语句不得不等待 postgres=# alter table t add password3 varchar(50); --在session3中可以查看到等待的锁 locktype | pid | virtualtransaction | transactionid | nspname | relname | mode | granted | lock_satus | lock_satus | query_start | query ---------------+------+--------------------+---------------+---------+---------+---------------+---------+------------+------------+---------------------+--------------------------- transactionid | 3128 | 2/14317 | 4638470 | | | ExclusiveLock | t | wait_lock | executing | 2015-10-21 20:46:09 | alter table t add passwor --此时如果有其它session的dml操作,又不得不等待session2的ddl语句执行结束,也不得不等待,进而造成排对等待 --由此展开,在主从复制过程中,如果从库再进行类似报表的
查询,主库有
一个修改表结构的动作,wal日志复制到从库,但其却不得不等待从库
查询语句执行完成,才能应用日志,进而造成主从之
间的延迟 --故最好在
修改表结构时观察下是否有大的
查询在发生
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。