PostgreSQL的神秘现象
今天进行了一个小实验,发现一个奇怪的现象:
我当前有这样的数据:
postgres=# select * from tab01;
id | val ----+----- 1 | 100 2 | 200 3 | 300 (3 rows) postgres=#
并且通过查询数据字典,知道 tab01 对应的文件名是:
/usr/local/pgsql/data/base/12788/16385
然后重新启动数据库。开启两个psql 客户端
第一个客户端执行:
postgres=# select * from tab01 where id=1; id | val ----+----- 1 | 100 (1 row)
然后对 16385文件进行改名: mv 16385 16385.bak
此时在第二个客户端执行:
postgres=# select * from tab01 where val=300;
得到提示:
ERROR: could not open file "base/12788/16385": No such file or directory
这倒也很是正常,表所对应的文件已经不存在了。
然后奇怪的事情发生在这里:
我在第一个客户端对表 tab01继续执行查询会怎么样:
postgres=# select * from tab01 where val=200; id | val ----+----- 2 | 200 (1 row)
postgres=# select * from tab01 where val=300;
id | val
----+-----
3 | 300
(1 row)
查询完全没有问题。
难道是第一个客户端记录了缓存?
我们再来看下面实验:
把前面的16385.bak 文件再次改回 16385。
开第三个psql客户端,写入新数据:
postgres=# insert into tab01 values(5,500); INSERT 0 1 postgres=#
这是,我再把 16385改名为 16385.bak,那么第一个客户端还能查到这条新数据吗?
居然毫无问题,可以查询到新增的数据!
postgres=# select * from tab01 where val=500; id | val ----+----- 5 | 500 (1 row) postgres=#
这个现象应该是和PostgreSQL的查询实现方式有关,具体原因需要进一步分析。
询问了Linux方面的牛人,据说是由于OS级别,对文件也提供了类似数据库的多用户视图。就是我们rm或mv一个文件,之前打开此文件的程序仍然能够持续地看到内容。只有rm/mv 动作之后再打开此文件的程序和用户才会受到影响。