Greenplum企业应用实战(笔记):第九章 数据库管理

第九章 数据库管理

[TOC]

9.1 用户及权限管理

9.1.1 Greenplum 数据库逻辑结构

图9-1

在 gp/pgsql 中,角色(Role)、模式(Schema)、数据库(DataBase)是三个不同的概念,不同于 Mysql 的 DataBase 等同于 Schema,Oracle 的 Role 等同于 Schema。

在 gp 中:

  1. 一个 database 下可以有多个 schema。schema在 gp 中也叫做 namespace。
  2. Language 在使用前必须创建,一个语言只属于一个 database
  3. table、view、sequence、function 必须只属于一个 schema
  4. 一个 filespace 可以有多个 tablespace,一个 tablespace 只属于一个 filespace,fielspace 与 role 没有关系
  5. tablespace 与 table 是一对多的关系,一个 schema 下的表可以分布在多个 tablespace 下
  6. 在图9-1 中,除了 filespace 之外,其他的权限管理都是通过 role 来实现,在这些层次结构中,用户必须对上一层有访问权限,才能够访问该层的内容
  7. group 与 role 是一样的概念,group的语法还能用,但实际上已被废弃了

9.1.2 Grant 语法(赋权)

创建数据库语法为:

CREATE ROLE name [[WITH] option [ ... ]]
where option can be:
    SUPERUSER | NOSUPERUSER 
    | CREATEDB | NOCREATEDB 
    | CREATEROLE | NOCREATEROLE 
    | CREATEEXTTABLE | NOCREATEEXTTABLE
    [ ( attribute='value'[, ...]) ] 
    where attribute and values are:
    type='readable'|'writable'
    protocol='gpfdist'|'http'|'gphdfs'
    | INHERIT | NOINHERIT
    | LOGIN | NOLOGIN
    | CONNECTION LIMIT connlimit
    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
    | VALID UNTIL 'timestamp'
    | IN ROLE rolename [, ...]
    | ROLE rolename [,...]
    | ADMIN rolename [,...]
    | RESOURCE QUEUE queue_name

从语法上看,参数配置主要有:

  1. 超级用户(SUPERUSER):最高用户权限,不受资源队列控制,拥有所有的权限,可以对数据库进行任何操作,一般只有 DBA 可以拥有这个权限
  2. 创建数据库权限(CREATEDB)
  3. 创建用户权限(CREATEUSER)
  4. 登录权限(LOGING):可以指定该用户登录的连接数控制
  5. 创建外部表权限(CREATEEXTTABLE):属性配置中也可以对外部表有更细的权限控制,如只读、可写外部表权限等
  6. 用户继承(INHERIT):子用户可以拥有父用户的所有权限
  7. 资源队列控制(RESOURCE QUEUE)
  8. 密码控制(ENCRYPTED):还可以指定密码以及失效时间

赋权命令 Grant:

GRANT 权限类型 ON Relation(如表、视图、函数、schema等) TO 用户或用户组

9.2 登录权限控制

客户端认证是由一个配置文件(通常名为 pg_hba.conf)控制的,它存放在数据库集群的数据目录中。HBA 是 “Host-Based Authentication”的缩写,即基于主机的认证,可以限制登录机器的 IP 段。

9.3 资源队列即并发控制

资源负载管理是为了限制系统中活动的 sql 对使用资源的消耗,避免由于 sql 将系统资源(如 CPU、I/O、内存)耗尽而造成系统缓慢或崩溃。资源队列可以限制活动 sql 的个数,以及 sql 各种消耗的大小。每一个用户会对应到一个资源队列中。通过对用户消耗资源的控制,dba 可以尽量避免系统出现过负载。

资源队列在 gp 中是如何工作的?

资源调度在系统安装的时候已经默认打开了,所有的数据库用户都必须对应了一个资源对象,如果配置具体的资源队列,默认的资源队列是 pg_default。

在 gp 中,资源队列可以实现如下的限制:

  • 活动的 sql 数,在这个资源队列下最多能够运行的 sql 数
  • 能够消耗的最大内存
  • sql 优先级,与其他队列的比较,主要限制在 cpu 的资源上
  • sql 的cost 值
图9-3

(1)内存

如果一个资源队列中限制了最大使用内存是 2000 MB,同时设置了同时执行的sql 数为 10 个,那么每一个 sql 最多使用的内存是 200 MB,同时每个 sql 消耗的内存,不能大于 statement_mem 参数中设置的内存大小。当一个 sql 运行时,这个内存大小就会被分配出来,直到 sql 执行结束后才释放

(2)CPU

cpu 优先级管理,每一个资源队列中,都有一个对应的 cpu 优先级。cpu 的优先级有三个登记:

  • abhoc,低优先级
  • reportin,高优先级
  • executive,最高优先级

当系统中有新的 sql 进入的时候,各个 sql 消耗 cpu 的资源会根据其优先级重新评估,如图9-4:

图9-4

当 executive 优先级的 sql 进入时,系统会将大部分的资源分配给它,如图9-5:

图9-5

(3)语法介绍

并不是所有的 sql 都会被限制在资源队列中,在默认情况下,select、select into、create table as select 和 declare cursor 会被限制在队列中。如果将参数 resource_select_only 设置为 off,那么 insert、update、delete 语句也会被限制在队列中。

下面介绍如何创建资源队列,以及如何使用资源队列,语法如下:

CREATE RESOURCE QUEUE name WITH (queue_attribute=value [, ...])
where queue_attribute is:
    ACTIVE_STATEMENTS=integer
        [ MAX_COST=float [COST_OVERCOMMIT={TRUE|FALSE}]]
        [ MIN_COST=float]
        [ PRIORITY={MIN|LOW|MEDIUM|HIGH|MAX}]
        [ MEMORY='memory_units']| MAX_COST=float [COST_OVERCOMMIT={TRUE|FLASE}]
        [ ACTIVE_STATEMENTS=integer]
        [ MIN_COST=float]
        [ PRIORITY={MIN|LOW|MEDIUM|HIGH|MAX}]
        [ MEMORY_LIMIT='memory_units']

(1)创建一个队列只有限制最大的活动sql数:

CREATE RESOURCE QUEUE abhoc WITH (ACTIVE_STATEMENTS=3);

(2)创建一个队列加上内存限制:

CREATE RESOURCE QUEUE myqueue WITH (ACTIVE_STATEMENTS=20, MEMORY_LIMIT='200MB');

如果想对一个sql进行特殊处理,增加其运行时的内存,那么可以设置 statement_mem 参数,将它调大:

SET statement_mem='2GB';
select * from my_big_table where column='value' order by id;
RESER statement_mem;

(3)设置最大的cost值:

CREATE RESOURCE QUEUE webuser WITH (MAX_COST=10000.0);

(4)设置 CPU 优先级:

CPU优先级有5个级别:MIN|LOW|MEDIUM|HIGH|MAX,可以根据不同的需求选择:

ALTER RESOURCE QUEUE ABHOC WITH (PRIORITY=HIGH);

查看配置情况:

SELECT * FROM pg_resqueue_attributes;

查看现有的资源队列使用情况:

SELECT * FROM pg_resqueue_status;

在 gp_toolkit 中,还有几个视图可用于查看资源队列的使用情况:

\dv gp_toolkit.gp_resq*

创建/修改用户指定资源队列:

CREATE ROLE aquery RESOURCE QUEUE abhoc;
ALTER ROLE etl RESOURCE QUEUE abhoc;

修改资源队列的语法如下,只有超级用户才可以修改资源组:

ALTER RESOURCE QUEUE name WITH (queue_attribute=value [, ...] )
where queue_attribute is:
    ACTIVE_STATEMENTS=integer
    MEMORY_LIMIT='memory_units'
    MAX_COST=float
    COST_OVERCOMMIT={TRUE|FALSE}
    MIN_COST=float
    PRIORITY={MIN|LOW|MEDIUM|HIGH|MAX}

9.4 Greenplum 锁机制

gp 的锁基本上与 postgresSQL 的锁是一样的,但 gp 的锁机制还不够完善,在某些场景上可能会出现一些问题。

表9-1
表9-1-2

这集中锁的冲突如表9-2所示:

表9-2
图9-7

locktype表示锁住的内容,主要是transactionid 和 relation。在gp中,master到segment的连接就是一个 transaction,只要一连接就会有这个锁信息。

relation对应pg_class的oid字段。

gpid不等于-1就是代表每一个segment的锁信息。

通过 lock 命令可以显式地将表锁住,语法如下:

Command: LOCK
Description: lock a table
Syntax:
LOCK [ TABLE ] name  [, ...] [ IN lockmode MODE] [ NOWAIT]
where lockmode is one of :
    ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

9.5 数据目录结构

图9-8是gp主节点(master)的数据目录结构:

图9-8
  • base是数据目录,每个数据库在这个目录下,会有一个对应的文件夹
  • global是每一个数据库公用的数据目录
  • gpperfmon监控数据库性能时,存放监控数据的地方
  • pg_changetracking 是 segment 之间主备同步用到的一些原数据信息保存的地方
  • pg_clog 是记录数据库事务信息的地方,保存每一个事务id的状态,这个非常重要,不能丢失,一旦丢失,整个数据库就基本上不可用了
  • pg_log 是数据库的日志信息
  • pg_twophase 是二阶段提交的事务信息(二阶段提交参阅第7章)
  • pg_xlog 是数据库重写日志保存的地方,其中每个文件固定大小为64MB,并不断重复使用
  • gp_dbid 记录这个数据库的dbid 以及它对应的 mirror节点的dbid
  • pg_hba.conf 是访问权限控制文件
  • pg_ident.conf 是 Ident 映射文件
  • PG_VERSION 是 PostgreSQL 的版本号
  • postgresql.conf 是参数配置文件
  • postmaster.opts 是启动该数据库的 pg_ctl 命令
  • postmaster.pid 是该数据库的进程号和数据目录信息

其中base 下面的文件夹结构为:

# ls
1 10890 10891 16992 285346

其中一个文件夹代表一个数据库,文件夹的名字就是数据库的oid,可以通过 pg_databse查询其对应关系

9.6 数据文件存储分布

下面分别介绍表、索引、序列的文件存储分布(外部表和视图没有实际的数据,没有数据文件生成),每一种类型对应数据库里面哪些文件

(1)表

一般的堆表只有一个数据文件,如果表中有大字段,会多两个数据文件:toast表、toast表索引。

大字段:text字段、varchar的大小大于2036的字段。

select oid,relname,reltoastrelid from pg_class where relname='表名';

默认 toast表的名字为 pg_toast_ + 原表的 relfilenode,索引为 pg_toast_ + 原表的 relfilenode + _index,例如316696是原表的oid:

# select oid, relname from pg_class where relname ~ '316696';

 oid    |  relname
 -----------------
 316698 | pg_toast_316696
 316699 | pg_toast_316696_index

如果是 Appendonly 表,那么会多4个文件:pg_aoseg、pg_aovisimap表及其索引对应的数据文件(参阅第6章)

(2)索引

索引文件只有一个,可以通过索引名在pg_class中查找。索引在创建时就分配了32KB 的存储控件,等到这32 KB用完才开始扩大。

(3)序列

序列(Sequence)与索引一样,也只有一个数据文件,在pg_class中对应一条记录,relfilenode 字段就是文件名。

如果一个表中有字段是 serial 类型的,即一个递增序列,那么这个表会自动创建一个序列,也就会多一个数据文件。

9.7 表空间管理

在 gp4.0 之后的版本中,gp加入了文件空间(Filespace)和表空间(Tablespace)的概念。

在系统初始化的时候,只有两个表空间 pg_default 和 pg_global,这两个表空间都在 pg_system 这个文件系统下:

select a.spcname, b.fsname from pg_tablespace a ,pg_filespace b where spcfsoid=b.oid;

 spcname    | fsname
 ------------------------
 pg_default | pg_system
 pg_global  | pg_system

pg_global 表空间保存的是各个数据库之间的通用信息,在 data_directory/global 目录下,pg_default 表空间保存的是每个数据库特有的数据,包括数据字典及用户数据。其中,每一个数据库都会有一个对应的数据目录,如果数据库中的表比较多,或者表分区比较多(每一个分区都相当于一张表),那么在一个目录下就会有非常多的文件,文件数太多会给文件系统带来非常大的压力。因此,当文件数增长到一定程度的时候,就必须使用表空间,将数据存放到多个目录下。

在 gp 中,表空间必须创建在文件空间上,默认只有 pg_system 一个文件空间,在这个文件空间上不能再创建其他的表空间。

下面介绍如何创建多一个文件空间:

  1. 为每一个表空间创建系统目录,在master 和每一个 segment 上都要创建:

    MASTER:/home/gpadmin/gpdata/master_fspc
    Primary Segment:/home/gpadmin/gpdata/primary_fspc
    Mirror Segment:/home/gpadmin/gpdata/mirror_fspc
    
  2. 运行 gpfilespace 脚本,根据提示输入文件系统的名字和每个segment的目录

    $ gpfilespace
    ...
    > fs_test
    ...
    
  3. 之后,会生成一个 gp_filespace_config 文件,这个文件中保存了每个 segment 对应的数据目录(也可以手动编辑这个文件):

    cat /home/gpadmin/gpdata/gpfilespace_config_20120603_210559
    fielspace:fs_test
    mdw:1:/home/gpadmin/gpdata/master_fspc?gpseg-1
    ...
    

    运行 gpfilespace 创建文件系统:

    $ gpfilespace --config /home/gpadmin/gpdata/gpfilespace_config_20120603_210559
    

    创建好文件系统之后,就可以在上面创建表空间了:

    testDB#= create tablespace tbs_test1 filespace fs_test;
    CREATE TABLESPACE
    

    在表空间创建成功之后,在建表时就可以使用参数,指定表建在哪个表空间下面:

    create table test_01 (id int ,name varchar(200))
    tablespace tbs_test1 distributed by (id);
    

    在filespace 的目录下,就可以看到刚刚创建的表的数据文件了:

    9-5

    默认都是在 default_tablespace(参数)下面建表,这个参数默认是 pg_default 表空间,可以在配置文件 postgresql.conf 中修改这个参数,或者以下命令:

    set default_tablespace='tbs_test1';
    

    这样,建的表就在这个表空间下。还可以为每一个用户设置不同的表空间,同时必须给表空间赋权:

    testDB=# alter role etl set default_tablespace='tbs_test2';
    ALTER ROLE
    testDB=# grant ALL on tablespace tbs_test2 to etl;
    

    更换表空间,将表 hello1 从表空间tbs_test2 更换到 tbs_test3:

    testDB=# alter table hello1 set tablespace tbs_test3;
    

9.8 小结

本章介绍了数据库管理的相关内容,以及一些基本的数据库管理工具。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345