http://blog.osdba.net/?post=90 PostgreSQL中刷shared buffer的试验

全文:

PostgreSQL中刷shared buffer的试验

作者:osdba 发布于:2012-5-14 16:07 Monday 分类:PostgreSQL

在Oracle数据库中,使用alter system flush buffer_cache;就可以把cache住的数据块从内存中刷出去,于是想在PostgreSQL库中如何实现这个功能呢。查看源代码,发现了两个函数 DropRelFileNodeBuffers和DropDatabaseBuffers的类似的功能。于是照葫芦画瓢用写了一个模块flushbuffer(源码见附件),实现了这个功能,下面演示一下:

 

postgres=# CREATE EXTENSION flushbuffer;

CREATE EXTENSION

postgres=# 

 

建两个测试表tang01、tang02:

postgres=# create table tang01(id int,name text);

CREATE TABLE

postgres=# create table tang02(id int,name text);

CREATE TABLE

postgres=# insert into tang01 select generate_series(1,1000),'aaaaaaaaaaaaaaaa';

INSERT 0 1000

postgres=# insert into tang02 select generate_series(1,1000),'bbbbbbbbbbbbbbbb';

INSERT 0 1000

 

使用checkpoint把脏数据都保存到数据文件中:

postgres=# checkpoint;

CHECKPOINT

postgres=# select oid,relname,relfilenode from pg_class where relname like 'tang0%';\

  oid  | relname | relfilenode 

-------+---------+-------------

 16409 | tang01  |       16409

 16415 | tang02  |       16415

查询两个表:
postgres=# select * from tang01 limit 10;
 id |       name       
----+------------------
  1 | aaaaaaaaaaaaaaaa
  2 | aaaaaaaaaaaaaaaa
  3 | aaaaaaaaaaaaaaaa
  4 | aaaaaaaaaaaaaaaa
  5 | aaaaaaaaaaaaaaaa
  6 | aaaaaaaaaaaaaaaa
  7 | aaaaaaaaaaaaaaaa
  8 | aaaaaaaaaaaaaaaa
  9 | aaaaaaaaaaaaaaaa
 10 | aaaaaaaaaaaaaaaa
(10 rows)
 
postgres=# select * from tang02 limit 10;
 id |       name       
----+------------------
  1 | bbbbbbbbbbbbbbbb
  2 | bbbbbbbbbbbbbbbb
  3 | bbbbbbbbbbbbbbbb
  4 | bbbbbbbbbbbbbbbb
  5 | bbbbbbbbbbbbbbbb
  6 | bbbbbbbbbbbbbbbb
  7 | bbbbbbbbbbbbbbbb
  8 | bbbbbbbbbbbbbbbb
  9 | bbbbbbbbbbbbbbbb
 10 | bbbbbbbbbbbbbbbb
(10 rows)
 
这时把tang02的数据文件直接覆盖tang01的数据文件:
osdba@osdba-laptop:/data/pgdata/base/11955$ ls -l 16415
-rw------- 1 osdba osdba 57344  5月 14 16:18 16415
osdba@osdba-laptop:/data/pgdata/base/11955$ ls -l 16409
-rw------- 1 osdba osdba 57344  5月 14 16:18 16409
osdba@osdba-laptop:/data/pgdata/base/11955$ cp 16415 16409
 
继续查询tang01:
postgres=# select * from tang01 limit 10;
 id |       name       
----+------------------
  1 | aaaaaaaaaaaaaaaa
  2 | aaaaaaaaaaaaaaaa
  3 | aaaaaaaaaaaaaaaa
  4 | aaaaaaaaaaaaaaaa
  5 | aaaaaaaaaaaaaaaa
  6 | aaaaaaaaaaaaaaaa
  7 | aaaaaaaaaaaaaaaa
  8 | aaaaaaaaaaaaaaaa
  9 | aaaaaaaaaaaaaaaa
 10 | aaaaaaaaaaaaaaaa
发现看到的还是旧数据,原因是在内存中cache了表tang01的数据块,虽然tang01的底层的数据文件16409的内容变成了16415,但内存中的内容还没有变过来。
 
使用我写的flushtable函数把share buffer刷出去:
postgres=# select oid,* from pg_tablespace;
 oid  |  spcname   | spcowner | spclocation | spcacl | spcoptions 
------+------------+----------+-------------+--------+------------
 1663 | pg_default |       10 |             |        | 
 1664 | pg_global  |       10 |             |        | 
(2 rows)
 
postgres=# select oid,datname from pg_database;
  oid  |  datname  
-------+-----------
     1 | template1
 11947 | template0
 11955 | postgres
(3 rows)
 
postgres=# select flushtable(1663,11955,16409);
 flushtable 
------------
          9
(1 row)
 
再查询tang01,发现内容已经变成与tang02一样的:
postgres=# select * from tang01 limit 10;
 id |       name       
----+------------------
  1 | bbbbbbbbbbbbbbbb
  2 | bbbbbbbbbbbbbbbb
  3 | bbbbbbbbbbbbbbbb
  4 | bbbbbbbbbbbbbbbb
  5 | bbbbbbbbbbbbbbbb
  6 | bbbbbbbbbbbbbbbb
  7 | bbbbbbbbbbbbbbbb
  8 | bbbbbbbbbbbbbbbb
  9 | bbbbbbbbbbbbbbbb
 10 | bbbbbbbbbbbbbbbb
 
 
注意:
我写的这个flushtable函数,只是简单把内存中的数据块丢弃掉,如果数据块是脏块,就会造成数据丢失,请大家不要在生产库使用这个模块,这个模块仅做为研究PostgreSQL源代码使用。

此包的使用方法:

把此包解压下PostgreSQL9.1.3源代码中的contrib目录下,进个flushbuffer目录下:

make && make install即可

flushbuffer下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值