• 世界上最先进的开源数据库
• 设计灵活(extensibility ) ,可定制(customization)
• 支持ANSI/ISO 兼容的 SQL
• 已有30多年的发展历史
– University POSTGRES (1986-1993)
– Postgres95 (1994-1995)
– PostgreSQL (1996-2019)
• 有活跃在全球范围内的社区支持
– Support Mailing Lists
• http://www.postgresql.org/community/lists/
• 中文社区
– http://www.postgres.cn
安装 :4种安装方式(1)
• 在Linux安装PostgreSQL
① 二进制安装包安装
• EDB不再为PostgreSQL 11及更高版本提供Linux安装程序(windows版本继续提供),推荐用户使用源码编译安装
• 更早版本可参照 https://www.enterprislnxdb.com/downloads/postgres-postgresql-downloads
② 通过yum安装
• 1)安装指南:https://www.postgresql.org/download/linux/redhat/
• 2) 安装RPM仓库
1 | yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm |
• 3)安装PG
yum search postgresql – 得到相关列表
yum install -y postgresql14-14.4 postgresql14-contrib-14.4 postgresql14-libs-14.4 postgresql14-server-14.4
yum install -y postgresql14 postgresql14-contrib postgresql14-libs postgresql14-server (安装 14的最新子版本)
• 干净卸载 yum -y remove postgresql;rpm -e –nodeps rpm -qa | grep postgresql (一键删除所有的包)
③ RPM安装
下载位置https://yum.postgresql.org/rpmchart/
或者:https://download.postgresql.org/pub/repos/yum/14/redhat/rhel-7-x86_64/
postgresql14 - PostgreSQL client programs and libraries
postgresql14-contrib - Contributed source and binaries distributed with PostgreSQL
postgresql14-libs - The shared libraries required for any PostgreSQL clients
postgresql14-server - The programs needed to create and run a PostgreSQL server
rpm -ivh postgresql13*
安装 :4种安装方式(2)
④ 通过源码编译安装
• 重要的依赖:readline,flex,bison
• 三部曲:./configure && make && make install | install-world
• 源码安装的优势
安装:初始化数据库
– 修改 postgresql.conf 中的监听和端口,确保为每个实例分配了唯一端口
• listen_addresses = ‘*’ # what IP address(es) to listen on;
• port = 5436 # (change requires restart)
– 重启数据库
数据库启动与关闭
• 启停
– 使用 pg_ctl ( 推荐 )
• Start $PGHOME/pg_ctl –D $PGDATA start
• Reload $PGHOME/pg_ctl –D $PGDATA reload
• Stop $PGHOME/pg_ctl –D $PGDATA –m smart | fast | immediate stop
• Restart $PGHOME/pg_ctl –D $PGDATA –m smart | fast | immediate restart
– -m smart 等待客户端断开连接
– -m fast 回滚未完成的事务,断开客户端连接 (默认方式 )
– -m immediate 强行终止进程,数据库没有干净的关闭
– 使用Service方式 (el7)
• /etc/init.d/postgresql-14.x start | stop | restart | reload
• Service postgresql-14.x start | stop | restart | reload
– 使用systemctl (el7)
• systemctl start | stop | restart | relaod postgresql-14.x.service
• 启停注意事项
– 启动和停止时,尽量一边观察日志一边操作 (eg. $ tailf logfile.csv)
– 可以通过预先设置环境变量,减少出错及方便日常操作
• PATH 必须指向正确的 bin 目录.
• PGDATA 必须指向正确的数据库实例目录.
• PGPORT 必须指向正确的数据库实例运行的端口.
• 修改 .bash_profile或/etc/profile文件设置变量
• 前台启动
– postgres -D $PGDATA
• 前台变后台启动
– postgres -d $PGDATA >logfile 2>&1 &
为什么要配置变量?
Postgres,pg_ctl都会读取$PGDATA变量,所以要设置好这个变量
安装与运行:注意事项
OS 用户不能是root或具有操作系统管理权限的帐号
进行容量估算和规划
• 存储空间及读写能力
• 内存、CPU、网卡带宽
– 安装集群需要确认OS用户uid和gid
• 检查uid和gid
1 | id postgres |
• 通过usermod,groupmod修改OS用户uid和gid
1 | groupmod -g 1000 postgres |
– 配置NTP服务器(now,current_date,current_time使用的都是系统data时间)
• 方法1)配置NTP服务器 : server cn.pool.ntp.org iburst | server time1.aliyun.com iburst
• 方法2)从NTP服务器更新系统时间:ntpdate cn.pool.ntp.org
http://www.pool.ntp.org/zone/cn
– 在Linux上作为一个后台进程 ,在Windows上作为一个服务
• Linux中查看postgres进程
– ps -aux | grep postgres
– netstat -natp|grep post (查看进程占用的端口号)
– netstat -anpl|grep post (查看进程占用的端口号)
– netstat -ano | grep PGSQL (查看进程占用的端口号)
– ss -tnlp | grep post(查看进程占用的端口号)
• 查看进程相关信息的命令:
– lsof –p pid
– strace -o output.txt -T -tt -e trace=all -p 28979 (strace能帮助你追踪到一个程序所执行的系统调用)
– 所有的PostgreSQL 的进程以及数据文件属于一个OS的用户
• 修改目录或文件属主:chown
– OS 用户和数据库用户没有关系 (un-related )
• OS 用户不能是root或具有操作系统管理权限的帐号
• 在 Windows 上只支持NTFS(只有NTFS下才支持建立表空间) .
– 环境变量说明
• $PGHOME 指向PG可执行程序的路径(安装路径)
• $PGDATA 指向数据库目录
登录数据库
• psql
1 | su - postgres |
• -U :以哪个用户登录
• -W:强制输入密码
• -h :主机名(IP地址)
• -p :端口号
• -d :登录哪个数据库
参数配置: 配置基础
• 配置文件的位置
– $PGDATA/postgresql.conf
• 开启参数include_dir = ‘conf.d’可使用$PGDATA/.conf.d/custom.conf
• 开启参数include_if_exists = ‘exists.conf’并存在可使用$PGDATA/exists.conf
• 开启参数#include = ‘special.conf’可使用$PGDATA/special.conf
• 数据库启动时,会读取该文件
• 可手工编辑
– $PGDATA/postgresql.auto.conf
• 保存ALTER SYSTEM修改后的参数( ALTER SYSTEM writes the given parameter setting to the postgresql.auto.conf file, Values
set with ALTER SYSTEM will be effective after the next server configuration reload)
• 不要手动修改它
• postgresql.auto.conf 的值覆盖postgresql.conf 的值(Settings in postgresql.auto.conf override those in postgresql.conf. )
– $PGDATA/recovery.conf(pg12已经不存在这个文件,recovery.conf 配置文件中的参数合并到 postgresql.conf)
– $PGDATA/pg_hba.conf
– $PGDATA/pg_ident.conf(记录操作系统用户和数据库用户映射关系)
• postgresql.conf 配置文件结构
– #注释
– key = value
• 支持的参数值类型
– 布尔、整数、浮点数、字符串、枚举
– include指令(允许嵌套)
Oracle配置文件与PG配置文件对应关系
pfile: 初始化参数文件(Initialization Parameters Files),
pfile 默认的名称为“init+例程名.ora”文件路径: /data/app/oracle/product/。
该文件可以使用任何文本编辑工具打开。
spfile: 服务器参数文件(Server Parameter Files),从Oracle 9i版本开始,Oracle 引入了服务器参数文件(spfile)。它的默认名称为“spfile+例程名.ora”文件路径: /data/app/oracle/product/。
与 pfile 不同,spfile 不能直接通过文本编辑器编辑,其中的参数进行修改时,只能通过 SQL 命令在线修改。
全局参数修改
• 修改参数的方法
– 通过linux命令修改配置文件vim,echo,sed
– 通过ALTER SYSTEM命令修改全局配置:
– 启动时设置(不推荐,除非进入单用户模式)
• postgres -c configparameter=newvalue
• 如何查看参数
– 查询pg_settings系统表:SELECT name,setting FROM pg_settings where name ~ ‘xxx’;
– select name,setting,unit,short_desc from pg_settings where name like ‘work_mem%’;
– SELECT current_setting(name);
– SELECT current_setting(‘work_mem’);
– 通过show (show all)命令查看
• 使参数生效的几种方法
– SELECT pg_reload_conf();
– pg_ctl -D $PGDATA reload;
– /etc/init.d/postgresql-14.x reload; (el6)
– systemctl reload service.postgresql-14.x (el7)
非全局参数
• 设置和重置Database级别的配置
– ALTER DATABASE name SET configparameter { TO | = } { value | DEFAULT }
– ALTER DATABASE name RESET configuration
• 设置和重置Session级别的配置
– 通过SET命令设置当前Session的配置
• SET configparameter { TO | = } { value | ‘value’ | DEFAULT }
• SET configparameter TO DEFAULT;
– 更新pg_settings视图
• UPDATE pg_settings SET setting = new_value WHERE name = ‘configparameter’;
• UPDATE pg_settings SET setting = reset_val WHERE name = ‘configparameter’;
– 使用set_config函数更新会话配置
• SELECT set_config(‘configparameter’,new_value,false);
• Role级别的配置
– ALTER ROLE name IN DATABASE database_name SET configparameter { TO | = } { value | DEFAULT }
– ALTER ROLE name IN DATABASE database_name RESET configparameter
PG防火墙
pg_hba格式
• 由pg_hba.conf决定
– 哪些主机可以连接数据库实例
– 客户端使用什么连接方式和认证方式
• 连接方式(TYPE):local,host,hostssl,hostnossl
• 认证方式:trust, reject, md5, password, scram, gss, sspi, ident, peer, pam, ldap, radius or cert
– 哪个数据库用户可以使用它
– 允许这个用户使用哪些数据库
– find / -name “postgresql.conf”
• 七种格式
– # TYPE DATABASE USER ADDRESS METHOD
– local database user auth-method [auth-options]
– host database user address auth-method [auth-options]
– hostssl database user address auth-method [auth-options]
– hostnossl database user address auth-method [auth-options]
– host database user IP-address IP-mask auth-method [auth-options]
– hostssl database user IP-address IP-mask auth-method [auth-options]
– hostnossl database user IP-address IP-mask auth-method [auth-options]
连接方式
• local匹配使用Unix域套接字的连接。
– 如果没有TYPE为local的条目则不允许通过Unix域套接字连接
• host匹配使用 TCP/IP建立的连接,同时匹配SSL和非SSL连接
– 缺省安装只监听本地环回地址localhost的连接,不允许使用TCP/IP远程连接,启用远程连接需要修改postgresql.conf中的listen_addresses参数。
• hostssl匹配必须是使用SSL的TCP/IP连接
– 客户端和服务器端都安装OpenSSL
– 编译PostgreSQL的时候指定configure参数–with-openssl打开SSL支持
– 在postgresql.conf中配置ssl = on
• hostnossl只匹配使用非SSL的TCP/IP连接
认证方法 (1)
• trust
– 无条件地允许连接。这种方法允许任何可以与PostgreSQL数据库服务器连接的用户以他们期望的任意PostgreSQL数据库用户身份登入,而不需要口令或者其他任何认证。
• reject
– 无条件拒绝连接。常用于从一个组中“过滤出”特定主机,例如一个reject行可以阻塞一个特定的主机连接,而后面一行允许一个特定网络中的其余主机进行连。
• md5
– md5认证方式为双重md5加密
认证方法(2)
• password口令认证
– password指明文密码,所以不能在非信任网络使用password方式(Require the client to supply an unencrypted password for authentication. Since the password is sent in clear text over the network, this should not be used on untrusted networks)。
• peer
– 从操作系统获得客户端的操作系统用户,并且检查它是否匹配被请求的数据库用户名。这只对本地连接可用。
• scram-sha-256
– Perform SCRAM-SHA-256 authentication to verify the user’s password.。
– 其它认证方式
– https://www.postgresql.org/docs/current/static/auth-methods.html
认证方法 (3)
如果要使所有可提供有效密码的用户均能从以 100 开头的地址连接到 PostgreSQL 实例中的任何数据库,则需要向 pg_hba.conf 文件
添加与与下面的行内容类似的行:
host all all 100.0.0.0/8 md5
上述示例针对 IPV4 地址。如果需要配置数据库群集以接受具有 IPV6 地址的计算机的连接,那么格式应如下所示:
host all all fe60::61f9:1253:c522:9b92%10/128 md5
要允许所有具有以 fe60 开始的地址的计算机进行连接,应向 pg_hba.conf 文件添加以下行:
host all all fe60::0000:0000:0000:0000%10/8 md5
如果您的 PostgreSQL 数据库集群安装在具有 IPV6 地址的计算机上,而您想要使具有 IPV4 地址的计算机与其连接,则需要在
pg_hba.conf 文件中取消以下行的注释:
host all all ::1/128 md5
允许IP地址为10.10.56.17的所有用户可以通过MD5的密码验证方式连接主机上所有的数据库
TYPE DATABASE USER ADDRESS METHOD
host all all 10.10.56.17/32 md5
即表示允许地址为 10.10.56.17 的用户 pgtest通过 MD5方式 加密的密码方式连接主机上的 test 数据库
TYPE DATABASE USER ADDRESS METHOD
host test pgtest 10.10.56.17/32 md5
即表示允许 任意iP 通过用户名为 pgtest 和md5的 密码 验证方式连接主机上 test 的数据库
TYPE DATABASE USER ADDRESS METHOD
host test pgtest 0.0.0.0/0 md5
用最安全的认证(A)
查看没有用SCRAM加密口令的用户
1 | create user foo password 'foopassword'; |
MD5破解网站:https://cmd5.com/default.aspx?hashtype=md5&answer=mtu5mdu3oty1mdi%3d
查看现在的加密方法
1 | postgres=# show password_encryption; |
修改加密方法
1 | postgres=# alter system set password_encryption = 'scram-sha-256'; |
用最安全的认证(B)
修改密码
1 | postgres=# alter user foo password 'Xzzp20088'; |
The password_encryption parameter decides how the ALTER USER statement will encrypt the password
修改pg_hba.conf 本地连接的method方法为scram-sha-256
TYPE DATABASE USER ADDRESS METHOD
“local” is for Unix domain socket connections only
host all all 0.0.0.0/0 scram-sha-256
1 | postgres=# select pg_reload_conf(); |
远程登录
1 | psql -h 10.0.0.61 -p 5433 -d postgres -U foo -W |
有一个插件,可以用于加强口令复杂度管理
passwordcheck
http://www.postgresql.org/docs/current/static/passwordcheck.html
客户端工具
pgAdmin 4
– https://www.pgadmin.org
– yum / apt install pgadmin
• other
– Navicat , DBeaver ….
• psql - 最好的客户端工具
– 连接数据库:psql -h localhost -p 5432 database_name
– 获得psql的帮助:?
– 获得语法的帮助:\h STATEMENT
– 在shell中执行命令:psql -c “STATEMENT”
– 通过psql执行sql文件:psql < f.sql
psql的使用
\l 查看有哪些数据库
\c 用于切换数据库
\d 显示每个匹配关系(表,视图,索引,序列)的信息
\d [ pattern ] +
\d 后面跟一个表名,表示显示表结构定义
\d 后跟一个索引名,显示索引的信息
\d 后面跟一个视图名,显示视图信息
\timing on 显示SQL执行的时间
\timing off 关闭计时功能
\dn 列出所有的schema
\db 显示所有的表空间
\du\dg 列出所有的角色或者用户
\dp 显示权限分配情况
\x 行列互换显示
\set AUTOCOMMIT off将自动提交功能关闭
数据库管理
• 创建数据库(2种方法)
- Using CREATE DATABASE, an SQL command.
postgres=# CREATE DATABASE LNXDB; - Using creatlnxdb a command-line executable.
[postgres@tar1 pgdata]$ createdb LNXDB
• 登录数据库
psql LNXDB
• 删除数据库
- Using CREATE DATABASE, an SQL command.
postgres=# DROP DATABASE LNXDB;
(可能有错,试分析并解决) - Using creatlnxdb a command-line executable.
[postgres@tar1 pgdata]$ dropdb LNXDB
体系结构初探
数据库集群
( Database Cluster )的概念*
• 一个数据库集群(database cluster)=一个数据库实例(简称“实例”)
• 通过两种方式访问集群:
– 数据目录的位置
– 端口号
• 一个服务器可以管理多个数据库实例
• PostgreSQL多实例和MySQL多实例
• 进程树(pstree -p 13524)
• 进程查看
ps -ef |grep postgres
| Table: background processes. | ||
|---|---|---|
| process description reference | ||
| background writer 进程将shared buffer pool中的脏数据写到磁盘,检查点总能触发这个进程 | ||
| checkpointer 检查点会触发产生这个进程 | ||
| autovacuum launcher 为vacuum process周期性的调用autovacuum work processes | ||
| WAL writer 周期性的从wal buffer刷新数据到磁盘 | ||
| statistics collector 收集统计信息进程,比如pg_stat_activity 和pg_stat_database的数据 | ||
| logging collector (logger) 将错误信息写入到日志 | ||
| archiver 将日志归档的进程 |
故障排查
• 查看操作系统错误日志
/var/log/message 系统启动后的信息和错误日志,是Linux中最常用的日志之一
• 查看数据库错误日志
查看文件$PGDATA/log
常见故障
1、Initdb Failed Due to Directory ‘Invalid Permission’
$ initdb -D data running bootstrap script …
FATAL: data directory “data” has invalid permissions [1885]
DETAIL: Permissions should be u=rwx (0700) or u=rwx,g=rx (0750).
child process exited with exit code 1 initdb: removing data directory “data”
2、Is the PostgreSQL Server Running Locally and Accepting?
$ psql postgres
psql:
error: could not connect to server: could not connect to server: No such file or directory
Is the server running locally and accepting connections on Unix domain socket
“/var/run/postgresql/.s.PGSQL.5432”?
3、FATAL: no pg_hba.conf entry for host
4、no space left on device
以下是针对您提供的 PostgreSQL 常见故障的解析及解决方案:
- Initdb Failed Due to Directory ‘Invalid Permission’
错误信息:
1 | $ initdb -D data |
错误原因:
PostgreSQL 数据目录的权限设置不正确,initdb 需要确保目录具有特定的权限(0700 或 0750)。这个错误通常发生在您设置 PostgreSQL 数据目录时权限不正确。
解决方案:
检查并修改数据目录权限。使用以下命令:
1
chmod 700 /path/to/data # 或者 chmod 750
确保 PostgreSQL 用户拥有访问和写入数据目录的权限:
1
chown -R postgres:postgres /path/to/data
然后重新运行
initdb命令。
- Is the PostgreSQL Server Running Locally and Accepting Connections?
错误信息:
1 | $ psql postgres |
错误原因:
此错误通常表示 PostgreSQL 服务器没有运行,或者没有在正确的 Unix 域套接字上监听。
解决方案:
检查 PostgreSQL 服务是否正在运行。运行以下命令:
1
systemctl status postgresql
或者:
1
service postgresql status
如果服务没有运行,可以通过以下命令启动:
1
systemctl start postgresql
或者:
1
service postgresql start
确保 PostgreSQL 配置文件
postgresql.conf中的unix_socket_directories参数指向正确的目录。如果没有设置或者设置不正确,可以在配置文件中调整它:1
unix_socket_directories = '/var/run/postgresql'
- FATAL: no pg_hba.conf entry for host
错误信息:
1 | FATAL: no pg_hba.conf entry for host |
错误原因:
PostgreSQL 的 pg_hba.conf 文件用于控制哪些主机可以连接到数据库以及如何进行身份验证。如果没有正确配置该文件,客户端会收到此错误。
解决方案:
编辑
pg_hba.conf文件(通常位于 PostgreSQL 数据目录中):1
sudo nano /var/lib/pgsql/data/pg_hba.conf
确保在文件中添加了适当的条目以允许客户端连接。例如,允许本地连接:
1
2
3# 允许所有本地用户连接到所有数据库
host all all 127.0.0.1/32 md5
host all all ::1/128 md5修改后保存并重新加载 PostgreSQL 配置:
1
sudo systemctl reload postgresql
- no space left on device
错误信息:
1 | no space left on device |
错误原因:
此错误通常意味着 PostgreSQL 数据目录所在的磁盘已经没有剩余空间。由于 PostgreSQL 要写入日志文件、事务日志等,这会导致数据库无法正常运行。
解决方案:
检查磁盘空间:
1
df -h
确保数据存储目录所在的磁盘有足够的空间。如果空间不足,您可以采取以下措施:
- 清理不必要的日志文件,临时文件等。
- 将 PostgreSQL 数据目录移动到空间较大的磁盘。
如果是数据库日志占用大量空间,您可以考虑调整日志文件的保留策略或手动清理旧的日志文件。
SQL快速上手
SQL Basic(1) SQL
• 语法
– 标识符、关键字、常量的转义
• 在系统表中查询所有关键字
– select word from pg_get_keywords();
• 用单引号标示字符串常量
– 例如:’foo’
• 在字符串前写字母E (大写或者小写)的方法声明C风格的转义字符串常量
– 例如:SELECT E’\tfoo’;将返回“__foo”
– 例如:SELECT E‘\’;将返回“\”,请问:SELECT ‘\’;返回什么?
• Dollar-quoted字符串常量
– $$这里\有个’单引号$$
– $tag$这里是一’个标\签的内容$tag$(标签大小写敏感)
• 位串常量
– 以B开头加单引号包括的0和1组成位串常量,例如:SELECT B‘1001’::int;返回9
– 以X开头加十六进制数组成,请问:SELECT X‘0B’::int;返回什么?
• 值表达式
– 字段引用,例如:correlation.columnname
– 位置参数,例如:$1表示函数的第一个参数
– 下标,例如:mytable.arraycolumn[4]
– 字段选择,例如:mytable.mycolumn
– 函数调用,例如:abs(x);
SQL Basic(2) CREATE TABLE
• 语法
CREATE TABLE table_name (
col_1 data_type,
col_2 data_type, …
col_n data_type
);
• 示例
CREATE TABLE departments(
department_idinteger,
name varchar(50)
);
SQL Basic(3) DROP TABLE
• 使用 DROP 命令
• 删除一个表:
– 语法:
DROP TABLE [ IF EXISTS ] name [, …] [ CASCADE]
SQL Basic(4) Insert
• 语法
INSERT INTO table [ ( column [, …] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT }
[, …] ) | query }
• 示例
INSERT INTO departments (department_id, name)
VALUES (1, ‘Development’);
SQL Basic(5) Multi Value INSERT
• 语法
INSERT INTO table [ ( column [, …] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT }
[, …] ) | query }
• 示例
INSERT INTO emp (empno, ename, job) VALUES
(2,’JOHN’, ‘MANAGER’),
(3, ‘MARY’, ‘CLERK’),
(4, ‘HARRY’, ‘MANAGER’);
SQL Basic(6) Simple SELECT
• 语法
SELECT column_1, column_2 , … column_n
FROM table
WHERE condition
ORDER BY column_list
• 示例
SELECT department_id, name
FROM departments
WHERE department_id = 1
ORDER BY name;
SQL Basic(7) 列和表别名(Aliases)
• 可以提高复杂SQL的可读性
• 可以减少输入量
• 示例:
SELECT ename, dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;
SQL Basic(8) UPDATE
• 语法
UPDATE [ ONLY ] table SET column = {expression | DEFAULT}
[,…]
[ FROM fromlist ]
[ WHERE condition ]
• 示例
UPDATE departments SET name=’DEVELOPMENT’
WHERE department_id=1;
SQL Basic(9) DELETE
• 语法
DELETE FROM [ ONLY ] table [ WHERE condition ]
• 示例
DELETE FROM departments
WHERE department_id = 2;
TRUNCATE 快速清空表中数据
SQL Basic(10) 使用SQL Functions
• 可以在 SELECT 语句以及WHERE 中使用
• 包括
– String Functions
– Format Functions
– Date & Time Fuctions
– Aggregate Functions
• 示例
SELECT lower(name)
FROM departments;
SELECT * FROM departments
WHERE lower(name) = ‘development’;
数据类型
数据类型分类
PostgreSQL 拥有大量的内置的数据类型用来存储不同类型的数据。
• 标准类型(Standard)
– Boolean and Logic
– Strings - char(n), varchar(n), varchar2(n) and text
– Numbers - integer, floating point, numeric, number
– Date/time - timestamp(), date, time(), interval(), datetime
• 扩展类型(Extended)
– Geometric - point, line, box, etc
– Network - inet, cidr, macaddr
– Bit - bit, bit varying
• 数组和符合类型(Arrays and Composite types)
• 系统类型(System types)
Boolean
• Postgres 提供了标准的SQL类型boolean。 boolean 只能有如下两种状态中的一种: “true” or “false”. 第三种, “unknown”, 可以用SQL null 值表示.
• TRUE, ‘t’, ‘true’, ‘y’, ‘yes’, ‘1’
• FALSE, ‘f’, ‘false’, ‘n’, ‘no’, ‘0’
• 使用关键字 TRUE 和 FALSE 是首选的(它是SQL兼容的( SQL-compliant)).
逻辑和比较操作符
• AND, OR, 和 NOT
• <, >, <=, >=, =,和<> 或者 != 所有都返回boolean值.
• BETWEEN和NOT BETWEEN
• IS NULL 是唯一标准的方式查看是否为空. IS NOT NULL 是相反的操作符。
• NULL != NULL ! NULL = anything 将返回 NULL
• 将 transform_null_equals 设置为 on
就会使得
x = NULL 转换为 x IS NULL
a IS DISTINCT FROM b 等价于 a != b,除非 a 或 b 有一个为空,那就返回TRUE。如果a和b
都是 null, 他将返回FALSE. 这将使null的比较变的更简单。
IS TRUE, IS NOT TRUE, 等等…
条件表达式
• SQL中的 CASE 表达式是一种常见的条件表达式,同其他语言的
if/else语句很相似:
• CASE WHEN condition THEN result
CASE expression
WHEN value THEN result
[WHEN …]
[ELSE result]
END
• COALESCE() – 返回第一个非空值(non-null)
COALESCE(desc, short_desc, ‘(none)’)
• NULLIF(a, b) – 与 coalesce 相反,
如果 a = b 则返回NULL,否则返回 a
NULLIF(a, ‘(none)’)
Strings
• Postgres中有3中主要的文本类型: char(n), varchar(n) 和text.
• char(n) 和 varchar(n) 大多遵循 ANSI 标准
– 如果给定的一个string比 n characters (not bytes)长,将会报错,除非超出的全部为空格,或者你显式地标注(casting),在这种情况下这个字符串将会被截断(truncated) (感谢, ANSI SQL)
– char(n)末尾的空格,在两个 char(n) 比较时将被忽略掉,在转换为其他string类型时也会被去掉。
– 和其他许多数据库不一样, 在Postgres中,char(n)不存储为fixed-sized。对它的处理和
varchar(n)很像,只是需要被填补(being padded) 。
• char(n) 和 varchar(n) - cont’d
– char() 或者 char 等同于 char(1) ,和 “char”不同
– varchar()或者 varchar等同于 一个没有长度限制的varchar. 这是 Postgres 的扩展(extension)。
– 所有的存储为 “变长 (varlena)”类型 – 后面详述
模式匹配
(Pattern Matching) - LIKE
1 | • string [NOT] LIKE pattern [ESCAPE escape-character] (also ~~ and !~~) |
• “_” – 单字符通配符 (思考“?”)
• “%” – 多字符通配符 (思考 “*”)
• 匹配整个字符串; 使用 ‘%abc%’ 来查询字符串中任何位置的’abc’
• 使用 escape-character (通常用“\”)来将一个字面上的(不作为通配符)_或%加入到 pattern中
(Pattern Matching) - RegEx
• 正则表达式(Regular Expression (或者 regex)) 是一个模式匹配(pattern
matching)/文本处理(text processing)的语言
• string ~ regex – 如果 string 匹配上 regex则返回TRUE, 大小写敏感
• “*” -大小写不敏感” 和 “!~*” 如果 string 没有匹配上 regex则返回TRUE
• “!
• 不匹配上整个字符串
1 | SELECT 'PostgreSQL' ~ 'gre'; |
(Pattern Matching) - SIMILAR TO
• string [NOT] SIMILAR TO pattern [ESCAPE escape-character]
• 和 LIKE 操作相同, 只不过 pattern 是 ANSI SQL regex
• “_” and “%” instead of “.” and “.”
• “.” 不是一个特殊的字符
• “|”, “”, “+”, “()”, 和 “[]” 在正则表达式中操作
• “{}” 不支持
字符串函数
•ascii
•bit_length
•btrim
•char_length or character_length
•chr
•concat
•convert
•decode
•encode
•initcap
•length
•rpad
•rtrim
•split_part
•strpos
•substr
•substring
•to_ascii
•to_hex
•translate
•trim
•upper
•lower
•lpad,
•ltrim
•md5,
•octet_length
•overlay
•pg_client_encoding
•position
•quote_ident
•quote_literal
•repeat
•replace
General
• ||连接两个字符串
• greatest(value[, …]), least(value[, …]) – 返回最大最小值
• lower(), upper() – 将字符串变为小写或大写
• length() – 返回字符串中字符的个数. 参见 char_length(), character_length(), octet_length() 和 bit_length()
Pad
• lpad, rpad(string, length[, fill])
使用填充字符串 “fill”,在左边或右边填充一个字符串到
固定的长度”length” (填充字符串fill缺省为空格).如果填
充后的字符串比”length”约束的长,则会截断。1
2
3
4
5
6- SELECT rpad('pad', 8, 'xyz');
rpad
----------
padxyzxyTrim
• ltrim, rtrim, btrim(string[, characters])
删除字符串左边或右边或两边的characters字符
(默认是空格)1
2
3
4SELECT btrim('xyxtrimyyx', 'xy');
btrim
-------
trimPosition
• position(substring in string)
substring 在 string中的位置。参见 strpos().
1 | SELECT position('DB' in |
Substring
• substring(string[ from start][ for run])
• substring(string from pattern)
• substring(string from pattern for escape)
根据指定位置返回子串, POSIX regex pattern, or SQL regex pattern. 参
见 substr().1
2
3
4
5
6- SELECT substring('EnterpriseDB' from 11 for 2);
substring
-----------
DB数值类型(Numbers)
• Integers
– int/integer/int4, smallint/int2, bigint/int8
– bigint 依赖于编译器的支持,因此不一定能在所有的平台上运行。
– bigint, int2, int4 and int8 是 Postgres扩展
• Serial
– 不是一个真正的类型 - 只不过为创建一个 sequence并把它作为列的默认类型提供方便
– 可以定义列 NOT NULL
– serial, bigserial, serial4, serial8CREATE TABLE s(s serial);
NOTICE: CREATE TABLE will create implicit sequence “s_s_seq” for serial
column “s.s”
\d s
…
s | integer | not null default nextval(‘s_s_seq’::regclass)
数值类型(Numbers)
• Floating point
– real, double precision
– 它依赖于编译器,CPU, 和 OS 支持, 在不同的安装中细节会有不同
– real 通常有 6 位精度,范围至少在 1E-37 和 1E+37之间
– double通常有 15 位精度,范围至少在 1E-307 和 1E+308之间
– 特殊值 : Infinity, -Infinity, NaN
–SQL标准表示法float(p)用于声明一个的数值类型,它以P(二进制位表示的最低可接受精度,在7.4以前,P是一个十进制的位)。P取值在1到24之间表示一个real的精度,在25到53之间表示double的精度。如果有其他值将会返回错误。
– 如果没有定义float的precision,等价于 double的precision
数值类型(Numbers)
• Numeric
– 允许是任意 precision (所有位的个数) 和 scale (小数位数)
– 可以存储多达1000位的数值,但非常慢
– numeric(p, s) 定义了最大的 precision (须 > 0) 和最大的 scale (须 >= 0)
– numeric(p)是一个scale为0的 numeric
– 如果在numeric中没有定义任何的 precision 或者 scale,那他将允许存储任意precision 和 scale的数值。这种形式不会将输入数值强制转化成任何特定精度的值
– 如果一个要存储的数值的scale比声明的scale大, 那么系统将尝试四舍五入该数值到指定的scale。如果小数点左边的数据位数超过了声明的precision减去scale , 那么抛出一个错误。
– 数据在物理存储时其前后不带任何的0
– 允许 NaN
数值类型操作符 - DON’T EVER DO THIS
• +, -, *, /, % (also mod()), ^ (also power())
• |/ (prefix) square root (also sqrt())
• ||/ (prefix) cube root (also cbrt())
• !! (prefix), ! – factorial
• @ (prefix) - absolute value (also abs())
1 | SELECT |/ 25, 5 !, @ -5; |
数值函数
• ceil/ceiling, floor
• exp (exponential), ln, log
• greatest, least
• random, setseed
• round, truncate
• sign
• to_number
• degrees(radians), radians(degrees)
• cos, acos, sin, asin
• cot (cotangent), tan, atan
• atan2(x, y) = atan(x/y)
日期/时间(Date/Time)
• 可能会以 integers 或者 double 的精度存储
• timestamp[(p)] with time zone (timestamptz)
• timestamp[(p)] without time zone (timestamp)
– p - 0 to 6 digits of fractional seconds
– + interval
– interval, timestamp
• 特殊值
– now – 当前事务开始时间
– today, tomorrow, yesterday - 那天的midnight
– epoch - unix epoch (midnight, Jan. 1, 1970)
• Date
– 当添加了 timestamp,即假设 midnight
– 特殊值: now, today/tomorrow/yesterday, epoch
– + int (days), interval, time (returns timestamp)
– - int (days), interval, date (returns int)
• time[(p)] with time zone (timetz)
• time[(p)] without time zone (time)
– p - 0 to 6 for 如果使用integer存储,p为0-6;如果使用double存储,p为0-10
– 特殊值: now, allballs (00:00:00.00 UTC)
– + interval, date (returns timestamp)
– - interval, time
• interval[(p)]
– 接受输入中的单位(Units)(如day,minutes)
‘1 day 3 minutes’ = ‘1 00:03:00‘
– 单位(Units)和ago共同使用代表负数
‘1 day ago’ = ‘-1 days -00:03:00‘
– “冒号” 默认为 hour:minute
‘1 1:30’ = ‘1 day 01:30:00‘
– 没有单位就默认为秒
‘12345’::interval = ‘03:25:45‘
– 在内部存储为月,日,秒的形式,因为一个月内的天数是变化的。
– +/- timestamp, date, time, interval
– 可以乘以或除以某个数
5 * ‘2 minutes’::interval = 00:10:00
‘10 minutes’::interval / 3 = 00:03:20
• Time zones
– timestamp with time zone 内部存储为 UTC, 没有原来的时区
(original time zone)
– time with time zone存储中带有原来的时区(original time zone)
– 没有日期的时区转换没有什么意义,使用带时区的time是不推荐的,最好使用 timestamp 来代替。
– 时区信息 (尤其是 daylight savings time) 变化频繁,因此保持当前的时间更新是最重要的。
日期/时间函数
• age - 减去参数,生成一个使用年、月、天的”符号化”的结果
1 | SELECT age('1/1/2006'::timestamp), |
• date_part or extract - get subfield(day, month, week, etc)
• date_trunc -截断成指定的精度
• greatest, least
• isfinite - timestamp/interval 不是 +/- infinity
• justify_days – 调整间隔为 years, months, days的形式
• justify_hours -调整间隔为 days, hours的形式
• current_date, current_time[(p)], current_timestamp[(p)]
• now() – 事务开始的 date/time/timestamp with timezone
• localtime[(p)], localtimestamp[(p)] - 事务开始的 time/timestamp without timezone
• timeofday() – 当前时间 (不是事务开始时间). 返回text.
1 | CREATE TABLE a(a int[][5]); |
1 | CREATE TABLE a(a int ARRAY[5]); |
1 | INSERT INTO a VALUES('{{1,2},{4,5,6}}'); |
域(Domains)和组合类型(Composite types)
• 域(Domains)
– 是已存在的数据类型的别名,虽然可以额外定义约束
CREATE DOMAIN name [AS] type [DEFAULT expression]
[constraint …]
– 支持性不太好; plpgsql 不检查约束, 不能被使用到一些系统中…
• 组合类型(Composite types)
– 类似C语言的结构体(struct)
1 | CREATE TYPE complex AS ( |
• 注意 AS 是必须的,否则数据库会认为你将创建一个新的数据类型。
聚集函数
• 从一系列的输入值中计算出某个单一的值
• 忽略 NULLs (如果所有的输入是NULL则返回 NULL)
• avg, count, max, min, stddev, sum, variance
• bit_and, bit_or – 所有非空输入值按位”与/或”
• bool_and, every -如果所有输入值都是真,则为真,否则为假
• bool_or -如果至少有一个输入值为真,则为真,否则为假
设置返回集合函数
• 返回多行的函数;使用时和表类似
• generate_series(start, stop[, step]) -生成一个数值序列,从 start 到 stop,步长
为 step (默认为1)
1 | SELECT * FROM generate_series(1,3) a; |
对象标识符类型Object Identifier Types (OID)
• 内部使用,用来标识对象
• 可以在用户定义的表中使用,但不推荐
• 别名类型对查找一个对象的OID非常方便。
– reg* ,其中 *可以是class, type, oper, operator, proc 或者procedure
– regoperator 和 regprocedure 接收参数类型
1 | SELECT 'pg_catalog.abs'::regproc; |
约束(Constraints)
• 条件约束
(Check Constraints)
• 非空约束
(Not-Null Constraints)
• 唯一性约束
(Unique Constraints)
• 主键(Primary Keys)
• 外键(Foreign Keys)
1 | CREATE TABLE emp |
建立数据库用户
• 数据库用户和操作系统用户不同
• 用户可以通过SQL命令 “CREATE USER”或 “createuser” 工具创建
例如:
1 | CREATE USER scott PASSWORD ‘tiger’; |
用户与角色有什么区别?
这张截图展示的是关于 PostgreSQL 数据库中 CREATE USER 和 CREATE ROLE 命令的说明。它的核心意思如下:
解释:
CREATE USER现在是CREATE ROLE的别名。也就是说,CREATE USER实际上是CREATE ROLE的简写。- 这两者的唯一区别在于:
- 当命令是
CREATE USER时,默认假定该用户可以登录(LOGIN),即用户会拥有登录权限。 - 而当命令是
CREATE ROLE时,默认假定该角色不能登录(NOLOGIN)。
- 当命令是
主要内容:
CREATE USER和CREATE ROLE都用于创建数据库角色。- 在使用
CREATE USER时,创建的角色默认是可以登录的。 - 在使用
CREATE ROLE时,创建的角色默认是不能登录的,除非显式指定LOGIN选项。
总结:
CREATE USER只是CREATE ROLE的一种语法简化,二者的功能相同,但默认行为有所不同。
操作权限赋予
对表的访问权限通过 GRANT 和 REVOKE SQL 命令赋予和回收。
例如:
1 | GRANT UPDATE DELETE ON emp TO scott_temp; |
索引(Indexes)
• 索引是提高性能的常用的方法
• Postgres 支持多种索引类型:
– B-tree (default)
– Hash – 只有当 WHERE 语句包含一个简单的等号(”=”)时使用 (缺点: 需要创建的时间长, 不如B-tree好)
– Index on Expressions – 当某个表达式(expression)经常被使用以提高查询速度的时候使用。插入和更新操作
会变慢。
– Partial Index – 只对满足WHERE条件的行进行索引 (WHERE语句不能包含索引列)。 查询也必须使用partial
1 | index 使用的那个WHERE 语句。 |
流复制维护生产案例
主备切换
1.备库执行pg_ctl promote 提升成主库
2.原主库执行pg_rewind拉齐和新主库之间的时间线
3.如果主库中wal日志被超时清理,就需要使用pg_basebackup重做备库
流复制经验谈 1
需求1:一个数据库中一部分表要求同步复制,一部分表要求异步复制。
当主库已配置参数synchronous_standby_names = standby01 或 * 时
会话执行:set synchronous_commit = off;
当前会话可以取消同步复制,改为异步复制。
流复制经验谈 2
延迟备库需求
多个备库情况下可以将其中某一个或者几个设置成延迟备库,预防数据在主
库被删除后,可以在延迟备库中找回。
recovery_min_apply_delay = 1min #延迟1分钟
流复制经验谈 3
同步备库模式,可用性与一致性兼顾。
synchronous_standby_names=’ANY 2 (s1,s2,s3)’
流复制经验谈 4
主库上创建表空间,备库宕机
流复制经验谈 5
主库上的WAL被覆盖,导致备库不可用。
1.复制槽
2.wal_keep_segment
流复制经验谈 6
pg_basebackup卡住
在备份的开始时,需要向从中拿去备份的服务器写一个检查点。尤其在没
有使用选项–checkpoint=fast时,这可能需要一点时间,在其间
pg_basebackup看起来处于闲置状态。
有可能是checkpoint的阶段卡住了
想要不等待checkpoint直接开始备份,可以加上参数 -c, –
checkpoint=fast|spread