# 修改防火墙设置,打开5432端口
vi /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 5432 -j ACCEPT
# 重启防火墙使新设置生效
service iptables restart
# 新增用户组
groupadd postgres
# 新增用户
useradd postgres -M -g postgres
# 新建数据库执行文件目录
mkdir -p /usr/local/pgsql
# 新建数据库数据文件目录
mkdir -p /data/pgsql/data
# 修改目录拥有者
chown -R postgres /usr/local/pgsql/.
chown -R postgres /data/pgsql/data
chown -R postgres /data/pgsql/data/.
# 编辑PATH搜索路径
vi /etc/profile
Append these 2 lines to the end of the file:
PATH=/usr/local/pgsql/bin:$PATH
export PATH
# 生效PATH搜索路径
source /etc/profile
# 安装编译源码所需的工具和库
yum -y install wget gcc readline-devel zlib-devel make
# 进入源码压缩包下载目录
cd /usr/src
# 下载源码压缩包
wget http://ftp.postgresql.org/pub/source/v9.2.2/postgresql-9.2.2.tar.bz2
# 解压缩源码包
tar jxvf ./postgresql-9.2.2.tar.bz2
# 进入解压缩源码目录
cd ./postgresql-9.2.2
# 执行源码编译配置脚本
./configure
# 编译源码
make
# 安装
make install
# 变更登录用户
su - postgres
# 执行数据库初始化脚本
/usr/local/pgsql/bin/initdb --encoding=utf8 -D /data/pgsql/data
# 退出变更登录
exit
# 复制PostgreSQL执行脚本
cp /usr/src/postgresql-9.2.2/contrib/start-scripts/linux /etc/init.d/postgresql
# 增加执行权限
chmod +x /etc/init.d/postgresql
# 编辑PostgreSQL执行脚本,指定数据库文件目录
vi /etc/init.d/postgresql
PGDATA="/data/pgsql/data"
# 编辑配置文件,配置可访问数据库的网络地址
vi /data/pgsql/data/postgresql.conf
listen_addresses = '*'
# 启动PostgreSQL服务
service postgresql start
# 以postgres用户登录数据库,修改postgres用户的数据库密码
psql -U postgres
postgres=# ALTER USER postgres PASSWORD '123456';
postgres=# \q
# 编辑配置文件,设置密码md5验证
vi /data/pgsql/data/pg_hba.conf
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
#host all all 127.0.0.1/32 trust
host all all all md5
# 重启数据库服务
service postgresql restart
# 设置开机自动启动服务
chkconfig postgresql on
>>>>>>>>>>>>>>>完成
本文链接
全表扫先读段头块,而后在段头块里面找到HWM
下面用实验由内而外来理解Oracle的HWM
--t表有一条数据 hr@ORCL> select * from t; ID NAME ---------- ---------- 1 AAAAA --找t段的段头块 hr@ORCL> select header_file,header_block from dba_segments where segment_name='T' and owner='HR'; HEADER_FILE HEADER_BLOCK ----------- ------------ 4 387 --另开一个session,dump段头块 sys@ORCL> alter session set tracefile_identifier='sys_dump_t_01'; Session altered. sys@ORCL> alter system dump datafile 4 block 387; System altered.
dump的部分trc内容摘入
Extent Control Header ----------------------------------------------------------------- Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 8 last map 0x00000000 #maps: 0 offset: 2716 Highwater:: 0x01000189 ext#: 0 blk#: 8 ext size: 8 --Highwater就是高水位,0x01000189这个是HWM的地址 #blocks in seg. hdr's freelists: 0 #blocks below: 5 mapblk 0x00000000 offset: 0 Unlocked -------------------------------------------------------- Low HighWater Mark : Highwater:: 0x01000189 ext#: 0 blk#: 8 ext size: 8 #blocks in seg. hdr's freelists: 0 #blocks below: 5 mapblk 0x00000000 offset: 0 Level 1 BMB for High HWM block: 0x01000181 Level 1 BMB for Low HWM block: 0x01000181 -------------------------------------------------------- Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0 L2 Array start offset: 0x00001434 First Level 3 BMB: 0x00000000 L2 Hint for inserts: 0x01000182 Last Level 1 BMB: 0x01000181 Last Level II BMB: 0x01000182 Last Level III BMB: 0x00000000 Map Header:: next 0x00000000 #extents: 1 obj#: 52713 flag: 0x10000000 Inc # 0 Extent Map ----------------------------------------------------------------- 0x01000181 length: 8 Auxillary Map -------------------------------------------------------- Extent 0 : L1 dba: 0x01000181 Data dba: 0x01000184 -------------------------------------------------------- Second Level Bitmap block DBAs -------------------------------------------------------- DBA 1: 0x01000182 End dump data blocks tsn: 4 file#: 4 minblk 387 maxblk 387
--对t表做一次全表扫 hr@ORCL> set autot traceonly hr@ORCL> select * from t; Execution Plan ---------------------------------------------------------- Plan hash value: 1601196873 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 20 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| T | 1 | 20 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- Note ----- - dynamic sampling used for this statement Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 7 consistent gets --全表扫读了6个块 0 physical reads 0 redo size 469 bytes sent via SQL*Net to client 385 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
这6个块是如何算出来的呢?
hr@ORCL> select file_id,block_id,blocks from dba_extents where segment_name='T'; FILE_ID BLOCK_ID BLOCKS ---------- ---------- ---------- 4 385 8
这t段一共用了8个块,分别是385 386 387 388 389 390 391 392 393
Highwater:: 0x01000189 即:4号文件的393号块
这个可由下面dbms_utility包算出
sys@ORCL> select to_number('01000189','xxxxxxxx') from dual; TO_NUMBER('01000189','XXXXXXXX') -------------------------------- 16777609 sys@ORCL> select dbms_utility.data_block_address_file(16777609) from dual; DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(16777609) ---------------------------------------------- 4 sys@ORCL> select dbms_utility.data_block_address_block(16777609) from dual; DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(16777609) ----------------------------------------------- 393
读了一次段头块:4号文件387号块
读了高水位之下的388 389 390 391 392 等5个块
这样一共就读了6个块
注:
385是FIRST LEVEL BITMAP BLOCK
386是SECOND LEVEL BITMAP BLOCK
接着分析我们所dump的内容:
Low HighWater Mark : Highwater:: 0x01000189 ext#: 0 blk#: 8 ext size: 8
接下来谈谈highwater mark 和 low highwater mark
low high water mark与high water mark 之间可能存在formated block也可以可能存在unformatted block
先来理清dba_tables里面的字段blocks的含义
dba_tables.blocks记录的是分析得到的 formatted block 的总数
而 low hwm 和 high hwm之间可能同时存在 formatted block 和 unfomatted block
所以准确地说 blocks 不能代表 low hwm 或high hwm
如果 low hwm 和 high hwm之间正好没有formatted block时,dba_tables.blocks和low hwm下的blocks一致
那么什么是Oracle中未格式化的块呢?
未格式化,意思就是这个块,已经是属于这个段了,但是还保留着原来的样子没动
格式化就是把块中的数据清除掉,并把块头改为这个对象的
MSSM表空间中的段,只有一个高水位,高水位下的块都是格式化了的
但是ASSM表空间中的段,有两个高水位:低高水位和高高水位
即上文trc里的:Highwater:: 0x01000189和Low HighWater Mark Highwater:: 0x01000189
低高水位下的块全部是格式化了的
但是低高水位和高高水位之间的块,则可能是格式化了的,也可能是没有
现在的t的高高水位是file 4,block 393;其低高水位是file 4,block 393
我们现在再来看一下t现在data_object_id是多少:
hr@ORCL> select object_id,data_object_id from dba_objects where object_name='T'; OBJECT_ID DATA_OBJECT_ID ---------- -------------- 52713 52714
这里很明显t的data_object_id大于object_id
也就是说,在t上曾经发生过move或truncate操作
注意,对于truncate操作而言,truncate后其data_object_id不一定就是在原先的data_object_id上加1
sys@ORCL> select to_char('52714','XXXXXXXX') from dual; TO_CHAR(' --------- CDEA
换句话说,t中现在在其低高水位和其高高水位之间的block,只要这个block上记录的data_object_id不等于CDEA
我们可以通过dump里面的Block header dump部分中的seg/obj来判断其data_object_id是否与段编号相等
那么这个block 就是一个未格式化的块
也就是说,可以通过data_object_id来确定块是在HWM和LHWM的位置
那么Oracle为什么要增加低高水位设置?出于什么目的?全表扫描时,是到低高水位,还是到高高水位?
&nb
Oracle PL/SQL中判断两个两个字段相等或者不相等的时候,常常出现:字段值明明不相等(一个空,一个不空),但是判断不相等的时候就是得不到TRUE。
例如以下代码:
...
a1 VARCHAR2(50);
a2 VARCHAR2(50);
b1 VARCHAR2(50);
b2 VARCHAR2(50);
...
IF ( a1 <> a2 OR b1<>b2 ) THEN
My_Modify(a2,b2);
END IF;
...
IF ( a1 = a2 AND b1=b2 ) THEN
--do something not useful
a1:=a1;
ELSE
My_Modify(a2,b2);
END IF;
当a1等于a2, b1不等于b2时:
经常会出现 My_Modify(a2,b2); 不执行的情况,但不知道为什么会这样,难道是<>符号不稳定?
2012-8-27回答:不是不稳定,而是没有考虑字段空值问题,详细见后面分析。
2012-8-27添加说明:
经过测试和分析,发现,并不是<>不稳定,而是字段值为NULL是,不能使用=或者<>比较值,应该使用IS NULL判断是否为空。
当字段a1,a2,b1,b2中有一个或多个为空时,下面两个语句都会失效:
1. IF ( a1 <> a2 OR b1<>b2 ) THEN
2. IF ( a1 = a2 AND b1=b2 ) THEN
例如,如果a1为空,a2, b1,b2不空时,语句应该这么写
1. IF ( (a1 IS NULL AND a2 IS NOT NULL) OR b1<>b2 ) THEN
2. IF ( (a1 IS NULL AND a2 IS NULL) AND b1=b2 ) THEN
为了解决NULL带来的“无法判断相等或不等”的问题,我们可以使用NVL函数解决,语句如下:
1. IF ( NVL(a1,0) <> NVL(a2,0) OR NVL(b1,0) <> NVL(b2,0) ) THEN
2. IF ( NVL(a1,0) = NVL(a2,0) AND NVL(b1,0) = NVL(b2,0) ) THEN
注:NVL(args, deafultValue),args为变量,deafultValue为当args为空时,设置的默认值(一般为0)。
其中:NVL(a1, 0) 和 NVL(a1, '0') 效果样,最后 a1 的值都是字符串: '0' (不是字符!).
来一段测试代码:
-- Created on 2012/8/27
DECLEAR
a1 VARCHAR2(50);
a2 VARCHAR2(50);
b1 VARCHAR2(50);
b2 VARCHAR2(50);
BEGIN
a1 := 'a';
a2 := 'a';
b1 := 'b';
b2 := NULL;
IF ( a1 <> a2 OR b1<>b2 )