对于PostgreSQL的 "create index concurrently". 我个人认为其中存在一个bug。
我的验证过程如下:
我有两个表,tab01和 tab02,这两个表之间没有任何关联。
我认为 对 tab02执行 "create index concurrently" 不会对 访问tab01的事务有任何影响,然而事实并非尽然。
我第一程序的表现: 通过ecpg执行事务,再通过 "create index concurrently" 给tab02建立索引,成功。
我第二程序的表现:通过ecpg执行事务,再通过 "create index concurrently" 给tab02建立索引,被阻塞。
我第三个测试: 通过psql发起事务, 另一个psql客户端执行 "create index concurrently" 成功。
我第四个测试: 通过psql发起事务 另一个psql客户端执行 "create index concurrently",被阻塞。
无论 PostgreSQL9.1.2,还是PostgreSQL9.2.4,结果是一样的。
数据准备:
[postgres@server bin]$ ./psql -U tester -d tester psql (9.1.2) Type "help" for help. tester=> d tab01; Table "public.tab01" Column | Type | Modifiers --------+----------------------+----------- id | integer | cd | character varying(4) | tester=> d tab02; Table "public.tab02" Column | Type | Modifiers --------+---------+----------- id | integer | value | integer | tester=> select * from tab01; id | cd ----+---- 1 | 14 2 | 15 3 | 14 (3 rows) tester=> select * from tab02; id | value ----+------- 1 | 100 2 | 200 3 | 300 (3 rows) tester=>
我的测试方法:
对第一个程序和第二个程序:
当我的eccp程序正在睡眠的时候,我另外开一个终端,执行:
"create index concurrently idx_tab02_id_new on tab02(id)"
结果是:
第一个程序执行中,我可成功建立索引。
第二个程序执行中,我无法建立索引,会被阻塞
而我的tab01和tab02之间,没有任何关联。而且我也不认为我的ecpg程序会有潜在的可能去使用tab02的索引。
事实上,如果我去看ecpg预编译后得到的c程序,我可以看到:
{ ECPGdo(__LINE__, 0, 1, "db_conn", 0, ECPGst_normal, "select count ( * ) from tab01 where cd = $1 ", ECPGt_char,(vcd),(long)4 + 1,(long)1,(4 + 1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(vCount),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
当我给$1加入引号后,我就可以成功地建立索引了。
{ ECPGdo(__LINE__, 0, 1, "db_conn", 0, ECPGst_normal, "select count ( * ) from tab01 where cd = '$1' ", ECPGt_char,(vcd),(long)4 + 1,(long)1,(4 + 1)*sizeof(char), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_int,&(vCount),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
下面是我测试程序的源代码:
第一个:
[root@server soft]# cat ./test01/test01.pc int main() { EXEC SQL BEGIN DECLARE SECTION; int vCount; char vcd[4+1]; EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO 'tester@127.0.0.1:5432' AS db_conn USER tester IDENTIFIED BY tester; EXEC SQL AT db_conn SELECT COUNT(*) INTO :vCount FROM tab01; fprintf(stderr,"count is:%d ",vCount); fprintf(stderr,"Before disconnect,sleep for 500 seconds "); sleep(500); EXEC SQL DISCONNECT db_conn; fprintf(stderr,"After disconnect,sleep for 600 seconds "); sleep(600); return 0; } [root@server soft]#
第二个:
[root@server soft]# cat ./test02/test02.pc int main() { EXEC SQL BEGIN DECLARE SECTION; int vCount; char vcd[4+1]; EXEC SQL END DECLARE SECTION; EXEC SQL CONNECT TO 'tester@127.0.0.1:5432' AS db_conn USER tester IDENTIFIED BY tester; char *pCd="14"; memset(vcd,'