注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

PostgreSQL 中文网

 
 
 

日志

 
 

关于PG MVCC原理的一点思考  

2010-12-09 13:31:56|  分类: Postgres基础 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

         今天早上骑电屏车上班时突然想到了一个问题,昨天看了些PG的有关MVCC的资料,PG在处理
UPDATE,DELETE语句时,不会立即删除掉旧的记录,而是将旧的记录保存一段时间,直到VACCUM之后才
会真正删除旧的记录,我在想,当DELETE语句时PG保留原有的记录这很好理解,但是当UPDATE时,PG是
保留UPDATE的整行记录,还是仅保留那条记录被UPDATE的字段,带着这个疑问,做了以下测试。
        
--创建测试表并插入100万数据
mydb=> create table test_7 (id integer, remark varchar(32));
CREATE TABLE

mydb=> insert into test_7 select generate_series(1,1000000),'aaaaaa';
INSERT 0 1000000

--查看表大小
mydb=>  select pg_size_pretty(pg_relation_size('test_7'));
 pg_size_pretty
----------------
 38 MB
(1 row)
 
     这里看出表 test_7 为 38 M

--查看表的page数
mydb=> \d pg_class
       Table "pg_catalog.pg_class"
     Column      |   Type    | Modifiers
-----------------+-----------+-----------
 relname         | name      | not null
 relnamespace    | oid       | not null
 reltype         | oid       | not null
 reloftype       | oid       | not null
 relowner        | oid       | not null
 relam           | oid       | not null
 relfilenode     | oid       | not null
 reltablespace   | oid       | not null
 relpages        | integer   | not null
 reltuples       | real      | not null
 reltoastrelid   | oid       | not null
 reltoastidxid   | oid       | not null
 relhasindex     | boolean   | not null
 relisshared     | boolean   | not null
 relistemp       | boolean   | not null
 relkind         | "char"    | not null
 relnatts        | smallint  | not null
 relchecks       | smallint  | not null
 relhasoids      | boolean   | not null
 relhaspkey      | boolean   | not null
 relhasexclusion | boolean   | not null
 relhasrules     | boolean   | not null
 relhastriggers  | boolean   | not null
 relhassubclass  | boolean   | not null
 relfrozenxid    | xid       | not null
 relacl          | aclitem[] |
 reloptions      | text[]    |
Indexes:
    "pg_class_oid_index" UNIQUE, btree (oid)
    "pg_class_relname_nsp_index" UNIQUE, btree (relname, relnamespace)

mydb=> analyze test_7;
ANALYZE

mydb=> select relname,relpages,reltuples from pg_class where relname='test_7';
 relname | relpages | reltuples
---------+----------+-----------
 test_7  |     4902 |     1e+06
(1 row)

     这里可以看出表 test_7 有4902 page。

--测试UPDATE, 并再次查看表大小和占用 page数
mydb=>  update test_7 set remark='bbbbbb';
UPDATE 1000000

mydb=> select relname,relpages,reltuples from pg_class where relname='test_7';
 relname | relpages | reltuples
---------+----------+-----------
 test_7  |     4902 |     1e+06
(1 row)

mydb=> analyze test_7;
ANALYZE

mydb=> select relname,relpages,reltuples from pg_class where relname='test_7';
 relname | relpages | reltuples
---------+----------+-----------
 test_7  |     9804 |     1e+06
(1 row)

mydb=> select pg_size_pretty(pg_relation_size('test_7'));
 pg_size_pretty
----------------
 77 MB
(1 row)

     从上面看出,表的PAGE数为9804,刚好增加了一倍,这也说明,PG处理UPDATE语句时,也是保留了原有
记录的一份,只是在存储上标记为不可读而已,同时也说明,保留的是原有的记录整行,而不只是更新的字段值。

  评论这张
 
阅读(26136)| 评论(2)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016