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