# su – postgres #切换至postgres用户@H_301_3@
# psql #直接访问,默认进入本地postgres数据库@H_301_3@
# su – postgres #切换至postgres用户@H_301_3@
# psql huangxifeng #直接访问本地huangxifeng数据库@H_301_3@
# psql -h 172.16.254.21 -p 5432 -U postgres –d huangxifeng@H_301_3@
以第一种方式为例,当以postgres用户访问数据库时,postgresql产生一个服务进程来接受客户端传过来的请求,并代理客户端执行数据库的各种操作。@H_301_3@
# psql #直接访问,默认进入本地postgres数据库@H_301_3@
查看数据库字典表pg_stat_activity可以知道有什么用户在访问,访 问什么库以及访问的进程@H_301_3@
postgres=# select datid,datname,procpid,usename,xact_start from pg_stat_activity;@H_301_3@
datid | datname | procpid | usename | xact_start @H_301_3@
-------+------------------+---------+----------+-------------------------------@H_301_3@
11511 | postgres | 14190 | postgres | 2010-11-22 17:26:20.022066-05@H_301_3@
11511 | postgres | 14145 | postgres |@H_301_3@
从查询结果可以看到,数据库名为postgres,有一个进程ID为14190的在访问,开始活动的时间为2010-11-22 17:26:20.022066-05。@H_301_3@
进程ID为14190正是服务器产生的进程,代理客户端来执行数据库的各种操作。在linux中通过ps可以看到此进程。@H_301_3@
# ps aux|grep postgres|grep 14190@H_301_3@
postgres 14190 0.0 1.1 102232 4348 ? Ss 17:21 0:00 postgres: postgres postgres [local] idle @H_301_3@
因此,当某一数据库进程异常操作数据库时,要进行中断该进程可通过服务器进程进行@H_301_3@
#kill -9 14190;@H_301_3@
执行该操作时要谨慎小心,一旦杀掉进程,该客户端已经发送但未执行的sql和正在执行的sql都将会失败而丢失。@H_301_3@
安全的操作可以通过pg_cancel_backend取消一个后端的当前查询:@H_301_3@
postgres=# select pg_cancel_backend(14190);@H_301_3@
pg_cancel_backend @H_301_3@
-------------------@H_301_3@
t@H_301_3@
(1 row)@H_301_3@
Psql创建一个数据库的方式主要是两 种:@H_301_3@
1、 linux命令行创建:@H_301_3@
$ createdb huangxifeng #创建一个数据库名为:huangxifeng的数据库@H_301_3@
postgres=# \l #查看所有数据库@H_301_3@
List of databases@H_301_3@
Name | Owner | Encoding @H_301_3@
------------------+----------+----------@H_301_3@
huangxifeng | postgres | UTF8@H_301_3@
postgres | postgres | UTF8@H_301_3@
template0 | postgres | UTF8@H_301_3@
template1 | postgres | UTF8@H_301_3@
(4 rows)@H_301_3@
可以看到name为huangxifeng的数据库已经创建成功,owner为postgres,编码为utf8.@H_301_3@
实际中为了控制权限,可以新建 一个用户为huangxifeng,并把数据库的owner权限赋予该用户,然后再创建数据库。@H_301_3@
postgres=# create role huangxifeng password 'hxf' login;@H_301_3@
CREATE ROLE@H_301_3@
$createdb -O huangxifeng huangxifeng #-O指定用户名为huangxifeng@H_301_3@
postgres=# \l #查看所有数据库@H_301_3@
@H_301_3@
List of databases@H_301_3@
Name | Owner | Encoding @H_301_3@
------------------+----------+----------@H_301_3@
huangxifeng | huangxifeng | UTF8@H_301_3@
postgres | postgres | UTF8@H_301_3@
template0 | postgres | UTF8@H_301_3@
template1 | postgres | UTF8@H_301_3@
(4 rows)@H_301_3@
数据库名为huangxifeng,数据库的所有者是huangxifeng.@H_301_3@
postgres=# create database hxf owner huangxifeng;@H_301_3@
CREATE DATABASE@H_301_3@
postgres=# \l@H_301_3@
List of databases@H_301_3@
Name | Owner | Encoding @H_301_3@
------------------+-------------+----------@H_301_3@
huangxifeng | huangxifeng | UTF8@H_301_3@
hxf | huangxifeng | UTF8@H_301_3@
postgres | postgres | UTF8@H_301_3@
template0 | postgres | UTF8@H_301_3@
template1 | postgres | UTF8@H_301_3@
(5 rows)@H_301_3@
(1) 创建一个数据库时,在公共的global存储目录下写入新库的公共信息,如数据名和数据库所在的目录等@H_301_3@
(2) 以创建名为huangxifeng的数据库为例@H_301_3@
postgres@test21:~$ pg_lsclusters @H_301_3@
Version Cluster Port Status Owner Data directory Log file@H_301_3@
8.3 5shen_db 5432 online postgres /var/lib/postgresql/8.3/5shen_db custom@H_301_3@
实例的目录在/var/lib/postgresql/8.3/5shen_db下,cd到该目录下@H_301_3@
$cd /var/lib/postgresql/8.3/5shen_db@H_301_3@
@H_301_3@
$ ls @H_301_3@
base pg_clog pg_multixact pg_tblspc PG_VERSION postmaster.opts root.crt server.key@H_301_3@
global pg_log pg_subtrans pg_twophase pg_xlog postmaster.pid server.crt@H_301_3@
以上显示的所有文件中,目录global包含实例(集群)范围的表的子目录,主要是公共的信息。@H_301_3@
$cd global@H_301_3@
$ ls@H_301_3@
1136 1213 1232 1260 1262 2397 2672 2677 2695 2698 2843 2845 2847 pg_control pgstat.stat@H_301_3@
1137 1214 1233 1261 2396 2671 2676 2694 2697 2842 2844 2846 pg_auth pg_database@H_301_3@
$ file pg_control @H_301_3@
pg_control: data @H_301_3@
$ strings pg_control @H_301_3@
en_US.UTF-8@H_301_3@
en_US.UTF-8@H_301_3@
所 以,pg_control为公共访问环境信息,包括编码信息,@H_301_3@
$ strings pgstat.stat #数据库统计信息(空)@H_301_3@
即创建新数据库的过程不会向这两 个文件中写入信息,是系统公共的信息。但会向文件pg_auth认证(新建用户),pg_database数据库信息写入信息,这两个文件为文本文件,我们可以直接查看其中的内容。@H_301_3@
$ cat pg_auth @H_301_3@
"huangxifeng" "md57190d79abe15401d107f59f5e7150cc2" ""@H_301_3@
"menu" "md5759bfe7475b04240e12607ef3baba822" ""@H_301_3@
"postgres" "md5fbf3e4ff242ffe9dc60e3c9dc4d3c831" ""@H_301_3@
由以上内容可见,创建一个用户名 为:huangxifeng,向pg_auth文件插入一条记录,说明认证是通过md5加密来访问的,md5后面是密码的加密串。@H_301_3@
那么 pg_database保存什么内容呢?@H_301_3@
$ cat pg_database @H_301_3@
"template1" 1 1663 378@H_301_3@
"template0" 11510 1663 378@H_301_3@
"postgres" 11511 1663 378@H_301_3@
"menu" 32437 1663 378@H_301_3@
"huangxifeng" 52205 1663 378@H_301_3@
"hxf" 52206 1663 378@H_301_3@
由以上内容可见,创建一个新的数 据库huangxifeng,向pg_database文件中插入一条记录,第一列为数据库名,数据库名后面有三个数字,这三个数字各代表什么意思呢?@H_301_3@
现在我们来看数据库字典中是如何 记录数据库信息的,它与pg_database文件,与base目录又有什么样的关联?@H_301_3@
huangxifeng=# select a.datid,a.datname,b.datfrozenxid,b.dattablespace from pg_stat_database a inner join pg_database b on a.datname=b.datname;@H_301_3@
datid | datname | datfrozenxid | dattablespace @H_301_3@
-------+-------------+--------------+---------------@H_301_3@
1 | template1 | 378 | 1663@H_301_3@
11510 | template0 | 378 | 1663@H_301_3@
11511 | postgres | 378 | 1663@H_301_3@
32437 | menu | 378 | 1663@H_301_3@
52205 | huangxifeng | 378 | 1663@H_301_3@
52206 | hxf | 378 | 1663@H_301_3@
(6 rows)@H_301_3@
从以上查询可以知道,pg_database文件中数据库名后面的三个数字代表的涵义,如@H_301_3@
"huangxifeng" 52205 1663 378@H_301_3@
52205是数据库的ID,1663是数据库使用的表空间(默认系 统表空间),378是数据库初始化后冻结的事务ID。@H_301_3@
数据库字典表Pg_stat_database记录了实例中所有数据库名和数据 库的ID及其它相关信息:@H_301_3@
postgres=# select datid,datname from pg_stat_database ;@H_301_3@
datid | datname @H_301_3@
-------+-------------@H_301_3@
1 | template1@H_301_3@
11510 | template0@H_301_3@
11511 | postgres@H_301_3@
32437 | menu@H_301_3@
52205 | huangxifeng@H_301_3@
52206 | hxf@H_301_3@
(6 rows)@H_301_3@
再来看系统base目录下的子目录@H_301_3@
$ ls /var/lib/postgresql/8.3/5shen_db/base/@H_301_3@
1 11510 11511 32437 52205 52206 pgsql_tmp@H_301_3@
我们发现用数据库的ID为名称在base目录下创建相应的目录,每一个目录对应一个数据库。@H_301_3@
现在我们进入数据库huangxifeng的目录52205,发现在一共有129个由数字命名的文件,@H_301_3@
$ file 11429@H_301_3@
11429: data@H_301_3@
这个文件是数据库文件,由postgresql读取的,它实际上是huangxifeng数据库的一个对象,这些对象可以是表,索引及系统的其它对象。在数据库字典中,从下面查询可以看到11429这个对象是一个表:@H_301_3@
huangxifeng=# select relid,schemaname,relname from pg_stat_all_tables where relid=11429;@H_301_3@
relid | schemaname | relname @H_301_3@
-------+--------------------+--------------@H_301_3@
11429 | information_schema | sql_features@H_301_3@
(1 row)@H_301_3@
现在huangxifeng库是空的数据库,也就是没有任何一个用户自己建的数据表,那么现在新建一个表,base目录有什么变化?@H_301_3@
huangxifeng=# create table hxf_member(uid int,uname varchar(50));@H_301_3@
CREATE TABLE@H_301_3@
huangxifeng=# select relid from pg_stat_all_tables where relname='hxf_member';@H_301_3@
relid @H_301_3@
-------@H_301_3@
52207@H_301_3@
(1 row)@H_301_3@
postgres@test21:~/8.3/5shen_db/base/52205$ ls -lh 52207@H_301_3@
-rw------- 1 postgres postgres 0 2010-11-23 10:26 52207@H_301_3@
由上面可以看到在数据库huangxifeng的目录52205的目录下新建了一个以表id 52207命名的文件。注意到新建数据库huangxifeng的数据库id为52205,接着新建数据库hxf的数据库id为52206,现在新建一个表的对象id为52207,证明数据库对象的id统一使用系统的序列。@H_301_3@
相关的系统字典表如下:@H_301_3@
pg_stat_activity 数据库活动进程视图
@H_301_3@
Pg_stat_database系统统计数据库字典视图@H_301_3@
Pg_stat_sys_tables 系统字典表@H_301_3@
Pg_stat_sys_indexes系统字典表索引@H_301_3@
Pg_stat_user_tables用户表@H_301_3@
Pg_stat_user_indexes 用户表索引@H_301_3@