Chinaunix首页 | 论坛 | 博客
  • 博客访问: 86923
  • 博文数量: 31
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 350
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-16 20:38
文章分类
文章存档

2009年(12)

2008年(19)

我的朋友

分类:

2009-06-06 00:09:06

症状: 在db shcema中我们制定uuid column上面有一个unique的constraint,但是在某些failure case中我们可以看到uuid中出现两个相同的value
 id |                 uuid                 |    hostname    
  1 | 44454C4C-3600-104E-8047-C3C04F364A31 | etc003478a-001
  2 | 44454C4C-3800-1039-8037-B9C04F364A31 | etc003478a-002
  3 | 44454C4C-4E00-104B-8037-C3C04F364A31 | etc003478a-003
  4 | 44454C4C-4D00-104B-8037-C3C04F364A31 | etc003478a-004
  5 | 44454C4C-3200-1047-8037-B8C04F364A31 | etc003478a-005
  6 | 44454C4C-4300-1039-804C-C7C04F334831 | etc003478a-006
  7 | 44454C4C-3100-104C-804C-C4C04F334831 | etc003478a-007
  8 | 44454C4C-3000-1042-8039-B5C04F4B4831 | etc003478a-008    <------------------
 11 | 44454C4C-3000-1042-8039-B5C04F4B4831 | etc003478a-008    <------------------

模拟这种failure case的步骤
[1] 因为uuid申明为unique,所以postgresql会把它当成是index一样的列来单独存储在一个单独的文件里,所以我们首先要定位这个文件
select relname, relfilenode from pg_class where relname like 'nodes%';
    relname     | relfilenode
 nodes          |       16999
 nodes_id_seq   |       17015
 nodes_pkey     |       40965
 nodes_uuid_key |       40966         <----------- this value is often not equivalent on different system.
[2] 接着要定位你的数据库在文件系统里面所处的目录,这个在$PG_DATA/pg_database里面有记录
[3] 有了以上这两个信息,我们就找到了那个存储index的文件,比如说数据库的目录是16384,index文件名诗40966,那么index文件的绝对路径就是$PG_DATA/base/16384/40966,打开以后会看到如下东西:
  0@(^@^@^@44454C4C-3000-1042-8039-B5C04F4B4831^@^@^@^@^L^@0@(^@^@^@44454C4C-3000-1042-8039
  B5C04F4B4831^@^@^@^@^C^@0@(^@^@^@44454C4C-4E00-104B-8037-C3C04F364A31^@^@^@^@^B^@0@(^@^@^@44454C4C-4D00-104B
  8037-C3C04F364A31^@^@^@^@^E^@0@(^@^@^@44454C4C-4300-1039-804C-C7C04F334831^@^@^@^@^F^@0@(^@^@^@44454C4C-3800-1039-8037
  B9C04F364A31^@^@^@^@^H^@0@(^@^@^@44454C4C-3600-104E-8047-C3C04F364A31^@^@^@^@^G^@0@(^@^@^@44454C4C-3200-1042-8037
  B8C04F364A31^@^@^@^@^D^@0@(^@^@^@44454C4C-3100-104C-804C-C4C04F334831^@^@^@^@        ^@0@(^@^@^@44454C4C-3000-1045-8039
  B5C04F4B4831^@^@^@^@^@^@^@^@^@^@^@^@C^@^@^@
显然这些就是uuid字段的值,我们可以把"44454C4C-3200-1042-8037B8C04F364A31"改成"44454C4C-3200-2334-8037B8C04F364A31",保存退出
[4] 别忘了重启postgresql
[5] 在我们hack之前,先看一下table里面的东西,方便后面作一个比较
  SELECT id, uuid, hostname from nodes order by id;
 id |                 uuid                 |    hostname    
  1 | 44454C4C-3600-104E-8047-C3C04F364A31 | etc003478a-001
  2 | 44454C4C-3800-1039-8037-B9C04F364A31 | etc003478a-002
  3 | 44454C4C-4E00-104B-8037-C3C04F364A31 | etc003478a-003
  4 | 44454C4C-4D00-104B-8037-C3C04F364A31 | etc003478a-004
  5 | 44454C4C-3200-1047-8037-B8C04F364A31 | etc003478a-005
  6 | 44454C4C-4300-1039-804C-C7C04F334831 | etc003478a-006
  7 | 44454C4C-3100-104C-804C-C4C04F334831 | etc003478a-007
  8 | 44454C4C-3000-1042-8039-B5C04F4B4831 | etc003478a-008
[6] 我们在插入一个记录,这个记录的uuid 是已经存在的"44454C4C-3100-1042-804C-C4C04F334831".
INSERT INTO nodes(uuid, hostname) values('44454C4C-3000-1042-8039-B5C04F4B4831', 'etc003478a-008');
[7] "SELECT id, uuid, hostname from nodes order by id;"
 id |                 uuid                 |    hostname    
  1 | 44454C4C-3600-104E-8047-C3C04F364A31 | etc003478a-001
  2 | 44454C4C-3800-1039-8037-B9C04F364A31 | etc003478a-002
  3 | 44454C4C-4E00-104B-8037-C3C04F364A31 | etc003478a-003
  4 | 44454C4C-4D00-104B-8037-C3C04F364A31 | etc003478a-004
  5 | 44454C4C-3200-1047-8037-B8C04F364A31 | etc003478a-005
  6 | 44454C4C-4300-1039-804C-C7C04F334831 | etc003478a-006
  7 | 44454C4C-3100-104C-804C-C4C04F334831 | etc003478a-007
  8 | 44454C4C-3000-1042-8039-B5C04F4B4831 | etc003478a-008
 11 | 44454C4C-3000-1042-8039-B5C04F4B4831 | etc003478a-008  <--------------------
[8] 我们看到我们成功模拟了postgresql的index corruption现象。但是,别忘了,我们还不知道情况中这种现象是由什么导致的,还要继续学习 ...

阅读(487) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~