Postgresql学习笔记

概述

postgresql是一个开源的关系型数据库,可以作为mysql的替代品。
本篇意在让读者快速的了解postgresql的基本概念,使用的版本是postgresql9.6本,如有错误欢迎指正。

参考书籍

《PostgreSQL 9 Administration Cookbook》第二版。

本篇省略的东西

有些内容比较冗长,或者使用场景较少,或者过于复杂,建议参考具体的手册,本篇将会省略。

  • 选择postgresql的理由。
  • 常用的用于操作的语法、语句。
  • 数据库函数的编写与执行。
  • 不同数据库、模式、表空间之间的数据移动。
  • 访问其他postgres数据库或者其他类型的数据库。
  • 自动数据库维护的定制化配置。
  • 数据库的复制配置。
  • 数据库的升级操作。

postgres服务使用

发音

post-gres-q-l。

下载、安装、启动

基本上主流unix操作系统的库里都有制作好的安装包,直接安装即可,然后用相应的系统服务启动。
也可以使用命令行工具启动或者停止。
-m参数可以指定关闭方式,fast会等待所有操作完毕后再关闭,immediate则会强行关闭。

pg_ctl -D Datadir start
pg_ctl -D Datadir -m fast stop
pg_ctl -D Datadir -m immediate stop

每个服务在初始化的时候都会被分配一个系统标识符,很多系统操作需要使用到,可以通过如下命令获得。

pg_controldata Datadir | grep “system identifier”

版本号

postgreql的版本号组成为:主版本号.次版本号.维护版本号,它的特性和兼容性是由主版本号和次版本号共同决定的。

psql --version

连接

初始管理员用户:postgres,密码:postgres,数据库:postgres。

psql postgres://user:password@host:port/db
psql -U user -W password -h host -p port -d db

变量 默认值
user 当前用户
password
host localhost
port 5432
db postgres

每个连接在同一时刻只允许有一个活跃的事务,并且在任何时刻只允许有一个完全活跃的语句。

数据库

psql -l

template0和template1是两个数据库模板,template1是可以修改的,用来自定义。

命令行执行语句和脚本

psql -c "SELECT current_time"
psql -f test.sql

postgres客户端

帮助

postgres=# help
postgres=# ?
postgres=# \h

注释

-- 单行注释
/*
* 多行注释
*/

退出

postgres=# \q

开关一行显示一列数据

postgres=# \x

运行操作系统的命令

postgres=# \! cat test.sql

命令从文件中定向输入

postgres=# \i test.sql

临时数据库配置,LOCAL表示仅对当前事务生效

postgres=# SET work_mem = '16MB';
postgres=# SET LOCAL work_mem = '16MB';
postgres=# RESET work_mem;
postgres=# SHOW work_mem;

管理数据库插件

postgres=# CREATE EXTENSION myext;
postgres=# ALTER EXTENSION myext UPDATE;
postgres=# DROP EXTENSION myext;

更新所有表大小和数据分布的统计信息

postgres=# ANALYZE;

垃圾回收

postgres=# VACUUM;

postgres数据管理

服务(server)

  • 一个操作系统中可以启动多个postgres服务。
  • 每个服务由多个进程组成,为首的进程名为postmaster。
  • 每个服务要占用一个端口,多个服务不能共享端口。
  • 每个服务都有一个data目录用于存放数据,目录不允许修改,否则会破坏数据库,并且无法修复。
  • 服务使用4字节长的内部事务标识符,即时发生重叠后仍然继续使用,这会导致问题,所以需要定期进行VACUUM操作。

数据库(database)

  • 一个服务中可以拥有多个数据库。
  • 数据库默认是任何用户可连接的,创建好后需要修改相应的权限。
  • 数据库之间的数据是隔离的,不能进行联表。
  • 数据库默认的数据块大小为8192。

模式(schema)

  • 一个数据库中可以有多个模式,模式相当于表的命名空间,类似于mysql中的database,可以使用带模式的完整名称来访问或者创建对象。
  • 不同模式之间的表是可以联表查询的。
  • 可以通过对用户设置search_path参数来指定默认搜索的模式。

表(table)

  • 一个模式中可以有多张表。
  • 表是由多个关系元素组成的,大字段数据放在另一个名为TOAST的表中,每张表都有一个TOAST表和TOAST索引。
  • 用双引号括起来的表和没用双引号括起来的表是不一样的,即使名字一样。
  • 双引号括起来的表区分大小写,没用双引号括起来的表不区分大小写。

列(column)

  • 每张表都由许多列组成,每一列有一个列名、类型、默认值等属性,用来存储每一条记录中的各种值。
  • 文本类型统一由一种数据类型存储,支持长度从1B到1G,经过优化,存储少的时候很高效,存储多的时候会自动管理和压缩。
  • 自增类型serial本质上就是整数,通过创建并关联到一个SEQUENCE类型的对象来记录自增值。

表空间(tablespace)

  • 默认情况下,所有的数据都会放在postgres指定的data目录下,通过定义表空间,可以让postgres将数据存放在不同的设备上。
  • 表空间是通过软链接来实现的。
  • 建议为每个数据库设立一个单独的表空间,尤其是不同数据库中有同名的模式或者表的时候。

postgres=# CREATE TABLESPACE tbs LOCATION '/usr/local/tbs';

视图(view)

  • 视图本质上是预定义好的一个sql查询,以一张表的形式给出,在每次调用时都会执行相应的sql查询。

postgres=# CREATE VIEW view AS SELECT * FROM tb;

  • 当视图足够简单的时候,postgres是支持视图更新的,相应的更新会传递到相应的表中。
    还可以使用INSTEAD OF触发器或者规则来实现视图更新,请参考具体的操作手册。
  • 物化视图可以预先将数据查询出来,这样调用的时候就不必反复查询了,更新需要手动更新。

postgres=# CREATE MATERIALIZED VIEW view AS SELECT * FROM tb;
postgres=# REFRESH MATERIALIZED VIEW view;

行(row)

  • 行即表中的一条数据。
  • postgres中每个行都有一个行版本,而且还有两个系统列xmin和xmax,分别标示这个行被创建和删除的事务。
    删除时,设置xmax为删除事务号,不会实际执行删除。
  • UPDATE操作被认为是紧跟INSERT操作后的DELETE操作。

索引(index)

  • 索引可以用来给表添加约束或者提高查询速度。
  • 在涉及高比例插入\删除的表中,会造成索引膨胀,这时候可以重建索引。

reindexdb

  • 创建CONCURRENTLY索引时不会持有全表锁,这条指令分成两个步骤,第一部分创建索引并标记为不可用,这时候INSERT、UPDATE、DELETE操作已经开始维护索引了,但是查询不能使用索引。建立完毕后才会被标记为可用。

postgres=# CREATE CONCURRENTLY INDEX index ON tb(id);

  • 可以手工设置索引的可用性。

UPDATE pg_index SET indisvalid = false WHERE indexrelid = index::regclass;

postgres目录结构

子目录 用途
base 主数据目录。此目录中每个数据库都有自己的目录,以oid号命名,其中包含用于每张表和索引的文件
global 数据库中的系统表,在所有的数据库中共享
pg_clog 事务状态文件
pg_dynshmem 动态共享内存信息
pg_multixact 行锁状态文件
pg_notify 监听和通知的状态文件
pg_replslot 复制槽位的信息
pg_serial 已提交的序列化事务信息
pg_snapshot 输出的快照文件
pg_stat 服务活动统计以及持久文件
pg_stat_tmp 服务活动统计以及临时文件
pg_subtrans 子事务状态文件
pg_tblspc 连接到外部的表空间
pg_twophase “两阶段提交”事务状态
pg_xlog 事务日志WAL

postgres权限控制

连接权限

首先要修改数据目录下的postgresql.conf文件来允许它监听所有地址。修改完后需要重启服务。

listen_addresses = '*'

postgres连接的权限在数据目录下的pg_hba.conf文件中按照指定格式进行定义,每次连接会按照顺序检查每条规则,直到匹配到通过策略或者拒绝策略。

#TYPE DATABASE USER ADDRESS METHOD
host all all 127.0.0.1/32 password

每条策略的参数如下:

  • type:连接类型,local表示允许本地socket连接、host表示允许ip连接、hostssl表示允许ssl连接。
  • database:连接的数据库,all表示所有、sameuser表示用户名和数据库名相同、其他表示数据库名称。
  • user:连接的用户,all表示所有用户、其他表示连接的数据库用户。
  • address:允许连接的子网和子网掩码。
  • method:认证方式,trust表示允许、password表示密码、md5表示加密密码、cert表示证书、ldap表示ldap认证,对于证书认证之后还会有一个参数来配置证书。

权限模型

  • postgres采用角色(ROLE)-权限(PRIVILEGE)模型。
  • 权限主要有USAGE、SELECT、INSERT、UPDATE、DELETE五种。
  • 角色分两种,可以登录的用户(USER)与不可以登录的组(GROUP)。
  • 角色可以继承。

postgres=# CREATE USER user;
postgres=# CREATE ROLE role NOLOGIN;
postgres=# GRANT role1 TO role2;

特殊权限

  • postgres中有一些特殊权限,不能被授予,也不会被继承,分别是SUPERUSER、CREATEDB和CREATEUSER;
  • 特殊权限单独对用户进行授予或者回收。

角色切换与权限继承

  • 用户可以切换到自己拥有的角色。

postgres=# SET ROLE TO role;

  • 可以通过NOINHERIT参数来创建不会继承角色的用户,这样用户只有切换角色才能获得相应的权限。

postgres=# CREATE USER user NOINGERIT;

postgres支持的数据类型

  • 整数:smallint、integer、bigint
  • 实数:real、double
  • 自增数:smallserial、serial、bigserial
  • 高精度:decimal、numeric

  • 有限不定长字符串:varchar
  • 有限定长字符串:char
  • 无限不定长字符串:text
  • 位串:bit
  • UUID

几何

  • 点:point
  • 线:line、lseg
  • 矩形:box
  • 圆:circle
  • 路径:path
  • 多边形:polygon

其他

  • 布尔:boolean
  • 枚举:enum
  • 二进制:bytea
  • 时间:date、time、timestamp、interval
  • 货币:money
  • 网络地址:cidr、inet、macaddr
  • 数据格式:json、xml
  • 复合类型:table、type

postgres中一些系统变量、系统函数和系统视图

变量名 含义
current_user 当前用户
current_time 当前时间
current_timestamp 当前时间戳
current_schema 当前所在模式
current_user 当前登录的用户
session_user 当前会话的用户
函数名 功能
current_database0 当前连接的数据库
inet_server_addr() 当前服务的地址
inet_server_port() 当前服务的端口
version() 当前数据库的版本
pg_postmaster_start_time() 服务启动时间
pg_database_size() 当前数据库的大小
pg_size_pretty() 格式化尺寸数字
pg_relation_size(table) 某张表的表大小
pg_total_relation_size(table) 某张表的总大小
pg_reload_conf() 重新加载配置文件
generate_series(a, b) 从a到b顺序生成整数
random() 随机一个0到1之间的数
:: type 强制类型转换
pg_cancel_backend(pid) 取消当前查询
pg_terminate_backend(pid) 杀死后端进程
pg_stat_reset() 重置表的统计信息
pg_stat_statements_reset() 重置查询的统计信息
视图名 内容
pg_database 服务中的数据库信息
pg_catalog 系统信息
pg_extension 扩展插件信息
pg_available_extensions 可用扩展插件信息
pg_constraint 表之间的约束信息
pg_settings 数据库的配置
pg_stat_activity 后台进程的信息
pg_stat_user_tables 当前使用情况统计信息
pg_stat_database 数据库的统计信息
pg_stat_statements 被执行的查询的执行状态
pg_locks 锁信息
pg_prepared_xacts 准备事务的信息
pg_index 索引的信息
pg_class 实体的信息
pg_stat_replication 复制的状态

postgres脚本执行

postgres会按照顺序执行脚本中的每条指令,遇到错误会报错并继续执行接下来的指令。

事务

事务的功能是让一批指令要么同时执行成功,要么同时执行失败。本质上postgres会按照顺序执行指令,一旦遇到错误,就回滚之前的指令。
事务是不能够嵌套的,否则后续的BEGIN会被忽略。

postgres=# BEGIN;
postgres=# command1;
postgres=# command2;
postgres=# COMMIT;

因为事务的特性,使得事务中不能包含以下命令。

  • CREATE/DROP DATABASE/TABLESPACE
  • CREATE INDEX CONCURRENTCY
  • VACUUM
  • REINDEX DATABASE / REINDEX SYSTEM
  • CLUSTER

遇错退出

通过设置开关来实现遇到错误就停止脚本。

psql -f test.sql -v ON_ERROR_STOP=on
postgres=# \set ON_ERROR_STOP

数据导入与导出

postgres提供两个工具来进行数据导入和导出,pg_dump和pg_dumpall。

  • pg_dump工具产生一个默认轻量压缩的自定义格式归档文件,通过pg_restore恢复;pg_dumpall工具产生一个脚本文件,通过psql执行。
  • pg_dump不会导出角色和表空间;pg_dumpall可以导出全局对象,也可以只导出全局对象。
  • pg_dump和gp_restore可以并行,pg_dumpall和psql只能串行。
  • pg_dump也可以通过选项-F p来生成脚本文件。
    postgres还可以进行热物理备份,需要遵循步骤来处理备份中的增量数据,详细信息请参考手册。

复制

postgres提供两种复制方法,物理流复制和逻辑流复制。
之前还有一种基于日志文件传送的复制,主节点将数据库更改记录到事务日志,然后将日志文件从主节点传动到备节点,之后备节点再重演日志。现在它已经被流复制取代了,不推荐使用。

  • 物理流复制获取事务日志WAL并将数据传送到远程节点,WAL包含数据块中发生的改变的精确物理备份,因此远程节点是主节点的精确副本,也无法执行写入到数据库的事务。
  • 逻辑流复制允许远程节点复制数据而不需要保持数据库的完整副本,复制中所有形式的身份验证和安全工作都和普通的连接相同。逻辑流复制可以实现多主复制。
  • 复制槽位功能允许明确定义复制架构,还允许即使在节点连接断开的情况下跟踪节点的细节。逻辑流复制以及任何其他使用逻辑解码功能的工具都需要复制槽位,但对于物理流是可选的。

你可能感兴趣的:(Postgresql学习笔记)