gpadmin=# drop database template0; ERROR: cannot drop a template database gpadmin=# drop database template1; ERROR: cannot drop a template database gpadmin=# drop database postgres; ERROR: cannot drop a template database缺省时不能连接template0,但可以连接template1:
gpadmin=# \c template0 FATAL: database "template0" is not currently accepting connections Previous connection kept gpadmin=# \c template1 You are now connected to database "template1" as user "gpadmin".每一个新创建的数据库都基于一个模板,建库时如果不指定 TEMPLATE属性,默认用的是template1模板库。除非希望某些对象在每一个新创建的数据库中都存在,不要在template1中创建任何对象。
template1=# create table t1 (a int); CREATE TABLE template1=# insert into t1 values (1); INSERT 0 1 template1=# create database db1; CREATE DATABASE template1=# \dt List of relations Schema | Name | Type | Owner | Storage --------+------+-------+---------+------------- public | t1 | table | gpadmin | append only (1 row) template1=# select * from t1; a --- 1 (1 row)HAWQ还有一个模板库postgres。不要修改template0或postgres,HAWQ内部需要使用它们。以template0为模板可以创建一个完全干净的数据库,其中只包含HAWQ在初始化时预定义的标准对象。如果修改了template1,可能就需要这么做。
template1=# create database db2 with template template0; CREATE DATABASE通过配置,也可以连接template0:
template1=# set allow_system_table_mods='DML'; SET template1=# update pg_database set datallowconn='t' where datname='template0'; UPDATE 1 template1=# \c template0 You are now connected to database "template0" as user "gpadmin". template0=# update pg_database set datallowconn='f' where datname='template0'; ERROR: permission denied: "pg_database" is a system catalog template0=# set allow_system_table_mods='DML'; SET template0=# update pg_database set datallowconn='f' where datname='template0'; UPDATE 1 template0=# \q [gpadmin@hdp3 ~]$ psql -d template0 psql: FATAL: database "template0" is not currently accepting connections
[gpadmin@hdp4 ~]$ createdb -h hdp3 -p 5432 db3 [gpadmin@hdp4 ~]$ psql -h hdp3 psql (8.2.15) Type "help" for help. gpadmin=# \l List of databases Name | Owner | Encoding | Access privileges -----------+---------+----------+------------------- db1 | gpadmin | UTF8 | db2 | gpadmin | UTF8 | db3 | gpadmin | UTF8 | gpadmin | gpadmin | UTF8 | postgres | gpadmin | UTF8 | template0 | gpadmin | UTF8 | template1 | gpadmin | UTF8 | (7 rows)某些对象,如角色(用户),是被HAWQ中的所有数据库所共享的。而另外一些对象,如表,则只有它所在的数据库能感知它的存在。
gpadmin=# \l List of databases Name | Owner | Encoding | Access privileges -----------+---------+----------+------------------- db1 | gpadmin | UTF8 | db2 | gpadmin | UTF8 | db3 | gpadmin | UTF8 | gpadmin | gpadmin | UTF8 | postgres | gpadmin | UTF8 | template0 | gpadmin | UTF8 | template1 | gpadmin | UTF8 | (7 rows) gpadmin=# select datname from pg_database; datname ----------- hcatalog template1 postgres gpadmin template0 db1 db2 db3 (8 rows)可以看到,从pg_database查询出的结果比\l命令多返回一个库名为hcatalog。此库仅HAWQ系统使用,并且不允许连接。
gpadmin=# \c hcatalog FATAL: "hcatalog" database is only for system use Previous connection kept
gpadmin=# alter database db1 set search_path to myschema, public, pg_catalog; NOTICE: schema "myschema" does not exist ALTER DATABASEHAWQ不支持修改数据库改名。
gpadmin=# alter database db1 rename to db11; ERROR: Cannot support rename database statement yet
gpadmin=# \c template1 You are now connected to database "template1" as user "gpadmin". template1=# drop database db1; DROP DATABASE也可以使用客户端程序dropdb删除一个数据库。
[gpadmin@hdp4 ~]$ dropdb -h hdp3 -p 5432 db2一个数据库有连接时是不允许删除的,必须先终止所有连接,在没有连接之后再删除数据库。
gpadmin=# drop database db3; ERROR: database "db3" is being accessed by other users gpadmin=# select procpid,current_query from pg_stat_activity where datname='db3'; procpid | current_query ---------+--------------- 790583 | <IDLE> (1 row) gpadmin=# select pg_terminate_backend(790583); pg_terminate_backend ---------------------- t (1 row) gpadmin=# drop database db3; DROP DATABASE注意,删除数据库操作是不可回滚的。
[root@hdp4 ~]# su - hdfs [hdfs@hdp4 ~]$ hdfs dfs -mkdir /hawq_data1 [hdfs@hdp4 ~]$ hdfs dfs -chown -R gpadmin:gpadmin /hawq_data1(2)用gpadmin用户登录HAWQ master
$ su - gpadmin(3)创建一个文件空间配置文件:
$ hawq filespace -o hawqfilespace_config(4)在提示符下,输入文件空间的名字、master文件系统位置和segment文件系统位置。
[gpadmin@hdp3 ~]$ hawq filespace -o hawqfilespace_config Enter a name for this filespace > testfs Enter replica num for filespace. If 0, default replica num is used (default=3) > Please specify the DFS location for the filespace (for example: localhost:9000/fs) location> mycluster/hawq_data1 20170306:11:24:52:352152 hawqfilespace:hdp3:gpadmin-[INFO]:-[created] 20170306:11:24:52:352152 hawqfilespace:hdp3:gpadmin-[INFO]:- To add this filespace to the database please run the command: hawqfilespace --config /home/gpadmin/hawqfilespace_config [gpadmin@hdp3 ~]$ more /home/gpadmin/hawqfilespace_config filespace:testfs fsreplica:3 dfs_url::mycluster/hawq_data1 [gpadmin@hdp3 ~]$ hawq filespace --config /home/gpadmin/hawqfilespace_config Reading Configuration file: '/home/gpadmin/hawqfilespace_config' CREATE FILESPACE testfs ON hdfs ('mycluster/hawq_data1/testfs') WITH (NUMREPLICA = 3); 20170306:11:25:50:352658 hawqfilespace:hdp3:gpadmin-[INFO]:-Connecting to database 20170306:11:25:50:352658 hawqfilespace:hdp3:gpadmin-[INFO]:-Filespace "testfs" successfully created此时HDFS上会看到建立了/hawq_data1/testfs目录。
[hdfs@hdp2 ~]$ hdfs dfs -ls /hawq_data1 Found 1 items drwx------ - gpadmin gpadmin 0 2017-03-07 14:32 /hawq_data1/testfs
gpadmin=# create tablespace testts filespace testfs; CREATE TABLESPACE目前HAWQ只允许数据库超级用户定义表空间,并且不支持向其他用户GRANT/REVOKE表空间上的CREATION权限。
gpadmin=# create user wxy with superuser login password 'mypassword'; CREATE ROLE gpadmin=# grant create on tablespace testts to wxy; ERROR: Cannot support GRANT/REVOKE on TABLESPACE statement相关信息参见 https://issues.apache.org/jira/browse/HAWQ-24。
[gpadmin@hdp3 ~]$ psql -d template1 -U wxy -h hdp3 template1=# create database db1 tablespace testts; CREATE DATABASE template1=# \c db1 You are now connected to database "db1" as user "wxy". db1=# create table t1 (a int); CREATE TABLE db1=# create table t2 (a int) tablespace testts; CREATE TABLE db1=# set default_tablespace = testts; SET db1=# create table t3 (a int); CREATE TABLE db1=# set default_tablespace = dfs_default; SET db1=# create table t4 (a int); CREATE TABLE db1=# select relname,reltablespace from pg_catalog.pg_class where relname in ('t1','t2','t3','t4'); relname | reltablespace ---------+--------------- t1 | 0 t2 | 0 t3 | 0 t4 | 16385 (4 rows)pg_class.reltablespace为0,说明表保存在从数据库继承的缺省表空间testts里。特别要指出的是,所有非共享的系统表也都存放在这里。
db1=# select spcname as tblspc, fsname as filespc, db1-# fsedbid as seg_dbid, fselocation as datadir db1-# from pg_tablespace pgts, pg_filespace pgfs, db1-# pg_filespace_entry pgfse db1-# where pgts.spcfsoid=pgfse.fsefsoid db1-# and pgfse.fsefsoid=pgfs.oid db1-# order by tblspc, seg_dbid; tblspc | filespc | seg_dbid | datadir -------------+------------+----------+----------------------------------------------- dfs_default | dfs_system | 0 | hdfs://mycluster/hawq_data testts | testfs | 0 | hdfs://{replica=3}mycluster/hawq_data1/testfs (2 rows)
postgres=# drop tablespace testts; ERROR: tablespace "testts" is not empty: existing database. postgres=# drop filespace testfs; ERROR: filespace "testfs" is not empty postgres=# drop database db1; DROP DATABASE postgres=# drop filespace testfs; ERROR: filespace "testfs" is not empty postgres=# drop tablespace testts; DROP TABLESPACE postgres=# drop filespace testfs; DROP FILESPACE postgres=#此时HDFS上的/hawq_data1/testfs目录已经删除。
[hdfs@hdp2 ~]$ hdfs dfs -ls /hawq_data1/testfs ls: `/hawq_data1/testfs': No such file or directory [hdfs@hdp2 ~]$
ALTER DATABASE db1 SET search_path TO u1,public, pg_catalog;(2)查看当前模式
SELECT current_schema();使用SHOW命令查看当前查找路径。
SHOW search_path;set search_path to my_schema;只能改变当前session,如果需要长久生效可以为用户创建一个变量:
alter role etl set search_path=trade;官方建议是这样的:在管理员创建一个具体数据库后,应该为所有可以连接到该数据库的用户分别创建一个与用户名相同的模式,然后,将search_path设置为"$user",即默认的模式是与用户名相同的模式。
DROP SCHEMA myschema;缺省时,模式必须为空后才能删除它。为了删除一个非空的模式,可以使用:DROP SCHEMA <schemaname> CASCADE;
gpadmin=# \dn List of schemas Name | Owner --------------------+--------- hawq_toolkit | gpadmin information_schema | gpadmin pg_aoseg | gpadmin pg_bitmapindex | gpadmin pg_catalog | gpadmin pg_toast | gpadmin public | gpadmin (7 rows)以下是每个数据库中系统级别的模式:
# 修改master的pg_hba.conf文件,增加三个用户u1、u2、u3的认证 [gpadmin@hdp3 ~]$ vi /data/hawq/master/pg_hba.conf ... host all u1 172.16.1.0/24 md5 host all u2 172.16.1.0/24 md5 host all u3 172.16.1.0/24 md5 # 使认证文件生效 [gpadmin@hdp3 ~]$ more /data/hawq/master/pg_hba.conf # 创建数据库db1 [gpadmin@hdp3 ~]$ createdb db1 # 使用gpadmin创建两个用户u1、u2,授予超级用户权限, [gpadmin@hdp3 ~]$ psql -c "create role u1 with superuser password 'mypassword' login;create role u2 with superuser password 'mypassword' login;" # 使用gpadmin在db1数据库中创建两个与用户u1、u2同名的schema,并指定对应的属主。此情况模拟Oracle的用户模式。 [gpadmin@hdp3 ~]$ psql -d db1 -c "create schema u1 authorization u1; create schema u2 authorization u2;" # 用u1用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u1 -h hdp3 -c "create table t1 (a int); insert into t1 values(1);" # 用u2用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u2 -h hdp3 -c "create table t1 (a int); insert into t1 values(2);" # 用u1用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u1 -h hdp3 -c "select *,current_schema() from t1;" Password for user u1: a | current_schema ---+---------------- 1 | u1 (1 row) # 用u2用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u2 -h hdp3 -c "select *,current_schema() from t1;" Password for user u2: a | current_schema ---+---------------- 2 | u2 (1 row) # 用gpadmin用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -h hdp3 -c "create table t1(a int);insert into t1 values(3);" INSERT 0 1 [gpadmin@hdp3 ~]$ psql -d db1 -h hdp3 -c "select * from pg_tables where tablename='t1';" schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastriggers ------------+-----------+------------+------------+------------+----------+------------- u1 | t1 | u1 | | f | f | f u2 | t1 | u2 | | f | f | f public | t1 | gpadmin | | f | f | f (3 rows) [gpadmin@hdp3 ~]$ psql -d db1 psql (8.2.15) Type "help" for help. db1=# show search_path; search_path ---------------- "$user",public (1 row) db1=# select * from t1; a --- 3 (1 row) db1=# set search_path='u1'; SET db1=# select * from t1; a --- 1 (1 row) db1=# set search_path='u2'; SET db1=# select * from t1; a --- 2 (1 row) # 建立只有login权限的用户u3 [gpadmin@hdp3 ~]$ psql -c "create role u3 with password 'mypassword' login;" NOTICE: resource queue required -- using default resource queue "pg_default" CREATE ROLE # 用u3用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u3 -h hdp3 Password for user u3: psql: FATAL: password authentication failed for user "u3" [gpadmin@hdp3 ~]$ psql -d db1 -U u3 -h hdp3 Password for user u3: psql (8.2.15) Type "help" for help. db1=> set search_path='u1'; SET db1=> db1=> \dt No relations found. db1-> # 可以看到,u3看不到表u1.t1。 # 赋予usage权限 [gpadmin@hdp3 ~]$ psql -d db1 -c "grant usage on schema u1 to u3;" GRANT # 用u3用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u3 -h hdp3 Password for user u3: psql (8.2.15) Type "help" for help. db1=> set search_path='u1'; SET db1=> \dt List of relations Schema | Name | Type | Owner | Storage --------+------+-------+-------+------------- u1 | t1 | table | u1 | append only (1 row) db1=> select * from t1; ERROR: permission denied for relation t1 db1=> # 可以看到,u3可以看到表u1.t1,但不能查询。 # 赋予select权限 [gpadmin@hdp3 ~]$ psql -d db1 -c "grant select on u1.t1 to u3;" GRANT # 用u3用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u3 -h hdp3 -c "set search_path='u1';select *,current_schema(),current_schemas(true) from t1;" Password for user u3: a | current_schema | current_schemas ---+----------------+----------------- 1 | u1 | {pg_catalog,u1} (1 row) # u3现在可以查询u1.t1。 # 用u3用户执行 [gpadmin@hdp3 ~]$ psql -d db1 -U u3 -h hdp3 -c "create table t2(a int);" Password for user u3: CREATE TABLE # 删除模式 [gpadmin@hdp4 ~]$ psql -h hdp3 -d db1 psql (8.2.15) Type "help" for help. db1=# drop schema u1; NOTICE: append only table u1.t1 depends on schema u1 ERROR: cannot drop schema u1 because other objects depend on it HINT: Use DROP ... CASCADE to drop the dependent objects too. db1=# drop schema u1 cascade; NOTICE: drop cascades to append only table u1.t1 DROP SCHEMA db1=# drop schema u2 cascade; NOTICE: drop cascades to append only table u2.t1 DROP SCHEMA说明:
db1=# create table products ( product_no integer, name text, price numeric check (price > 0) ); db1=# insert into products values (1,'a',10); INSERT 0 1 db1=# insert into products values (1,'a',10.5); INSERT 0 1 db1=# insert into products values (1,'a',10.5111); INSERT 0 1 db1=# insert into products values (1,'a',-10.5111); ERROR: One or more assertions failed (seg0 hdp3:40000 pid=731975) DETAIL: Check constraint products_price_check for table products was violated db1=# insert into products values (1,'a',0); ERROR: One or more assertions failed (seg0 hdp3:40000 pid=731988) DETAIL: Check constraint products_price_check for table products was violated db1=# select * from products; product_no | name | price ------------+------+--------- 1 | a | 10 1 | a | 10.5 1 | a | 10.5111 (3 rows)
db1=# create table products ( product_no integer not null, name text not null, price numeric ); db1=# insert into products values(1,'a',10.51); INSERT 0 1 db1=# insert into products (price) values(10.51); ERROR: null value in column "product_no" violates not-null constraint (CTranslatorUtils.cpp:2726) db1=#
db1=# create table t2(a int); CREATE TABLE db1=# create table t3(a int primary key); ERROR: Cannot support create index statement yet
db1=# create table t1 (a int); CREATE TABLE db1=# insert into t1 values (1); INSERT 0 1 db1=# create view v1 as select * from t1; CREATE VIEW db1=# select * from v1; a --- 1 (1 row) db1=# drop table t1; NOTICE: rule _RETURN on view v1 depends on append only table t1 NOTICE: view v1 depends on rule _RETURN on view v1 ERROR: cannot drop append only table t1 because other objects depend on it HINT: Use DROP ... CASCADE to drop the dependent objects too. db1=# drop table t1 cascade; NOTICE: drop cascades to rule _RETURN on view v1 NOTICE: drop cascades to view v1 DROP TABLE如果要清空表中的数据,但保留表定义,使用TRUNCATE <tablename>。
3. 查看表对应的HDFS文件
db1=# select * from pg_filespace_entry; fsefsoid | fsedbid | fselocation ----------+---------+---------------------------- 16384 | 0 | hdfs://mycluster/hawq_data (1 row)可以看到,HAWQ在HDFS上的根目录/hawq_data。我的Hadoop集群配置了HA,所以文件位置字段中的值使用Nameservice ID(mycluster)代替了NameNode FQDN(Fully Qualified Domain Name)。
db1=# select d.dat2tablespace tablespace_id, d.oid database_id, c.relfilenode table_id db1-# from pg_database d, pg_class c, pg_namespace n db1-# where c.relnamespace = n.oid db1-# and d.datname = current_database() db1-# and n.nspname = 'public' db1-# and c.relname = 't2'; tablespace_id | database_id | table_id ---------------+-------------+---------- 16385 | 25270 | 156634 (1 row)一个数据库中不同schema下的表可能重名,但对应的表ID不同,因此需要关联pg_namespace系统表。d.oid是一个系统的隐藏列,表示行的对象标识符(对象ID)。该列只有在创建表的时候使用了WITH OIDS ,或者是设置了default_with_oids配置参数时出现。用\d pg_database命令是看不到oid列的。系统表pg_class的relhasoids列是布尔类型,true表示对象具有OID。
[gpadmin@hdp3 ~]$ hdfs dfs -ls /hawq_data/16385/25270/156634 Found 1 items -rw------- 3 gpadmin gpadmin 0 2017-03-30 11:05 /hawq_data/16385/25270/156634/1
db1=# create table t1 (a int); CREATE TABLE db1=# insert into t1 values (10); INSERT 0 1 db1=# insert into t1 values (1); INSERT 0 1 db1=# select * from t1; a ---- 10 1 (2 rows) db1=# create view v1 as select * from t1 order by a; CREATE VIEW db1=# select * from v1; a ---- 1 10 (2 rows) db1=# drop view v1; DROP VIEW db1=# create view v1 as select * from t1 order by a desc; CREATE VIEW db1=# select * from v1; a ---- 10 1 (2 rows) db1=# select * from v1; a ---- 10 1 (2 rows) db1=# select * from v1 order by a; a ---- 1 10 (2 rows)
db1=# \d v1 View "public.v1" Column | Type | Modifiers --------+---------+----------- a | integer | View definition: SELECT t1.a FROM t1 ORDER BY t1.a DESC;
db1=# drop view v1;
gpadmin=# \c db1 You are now connected to database "db1" as user "gpadmin". db1=# create type compfoo as (f1 int, f2 text); CREATE TYPE db1=# create table big_objs ( db1(# id integer, db1(# obj compfoo db1(# ); CREATE TABLE db1=# insert into big_objs values (1,(1,'a')); INSERT 0 1更多自定义数据类型信息参见 http://hawq.incubator.apache.org/docs/userguide/2.1.0.0-incubating/reference/sql/CREATE-TYPE.html。
db1=# create sequence myseq start 101; CREATE SEQUENCE db1=# select currval('myseq'), nextval('myseq'); ERROR: currval() not supported db1=# select nextval('myseq'); nextval --------- 101 (1 row) db1=# select nextval('myseq'); nextval --------- 102 (1 row)更多序列信息参见 http://hawq.incubator.apache.org/docs/userguide/2.1.0.0-incubating/reference/sql/CREATE-SEQUENCE.html。