前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >进阶数据库系列(二十五):PostgreSQL 数据库日常运维管理

进阶数据库系列(二十五):PostgreSQL 数据库日常运维管理

作者头像
民工哥
发布2023-08-22 14:08:43
1.1K0
发布2023-08-22 14:08:43
举报
文章被收录于专栏:民工哥技术之路

版本升级

小版本升级pg_upgrade
代码语言:javascript
复制
su - postgres

#将旧的数据库目录重命名
mkdir /usr/local/pgsql.old
chown -R postgres.postgres /usr/local/pgsql.old
mv /usr/local/pgsql/* /usr/local/pgsql.old/

exit #切回root
cd /opt
rz #上传源码包
tar -zxvf postgresql-11.16.tar.gz #解压
cd postgresql-11.16/ #进入到源码目录
./configure --prefix=/usr/local/pgsql --with-openssl --with-pgport=5432 --with-tcl --with-perl --with-python --with-libxml --with-libxslt --with-ossp-uuid --with-pam --with-ldap
gmake world #gmake包括第三方插件全部编译
gmake install-world #包括第三方插件全部安装
mkdir /usr/local/pgsql/data #创建数据目录
chown -R postgres.postgres /usr/local/pgsql
chown -R postgres.postgres /usr/local/pgsql/data #授权数据目录
su - postgres

#初始化数据库
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data --encoding=UTF8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8 #初始化数据库

#如果有外部extension插件则在这安装插件

#关闭旧数据库
/usr/local/pgsql.old/bin/pg_ctl -D /usr/local/pgsql.old/data/ stop -m fast

#环境变量临时赋值本地ip
export PGHOST=127.0.0.1

#升级前检查
/usr/local/pgsql/bin/pg_upgrade -d /usr/local/pgsql.old/data/ -D /usr/local/pgsql/data/ -b /usr/local/pgsql.old/bin/ -B /usr/local/pgsql/bin/ -c

#升级
/usr/local/pgsql/bin/pg_upgrade -d /usr/local/pgsql.old/data/ -D /usr/local/pgsql/data/ -b /usr/local/pgsql.old/bin/ -B /usr/local/pgsql/bin/ 

#收集表的统计信息
./analyze_new_cluster.sh

cd $PGDATA
rm -f pg_hba.conf #删除新的pg_hba.conf
rm -f postgresql.conf #删除新的postgresql.conf

#拷贝旧的pg_hba.conf和postgresql.conf到升级的库
cp /usr/local/pgsql.old/data/pg_hba.conf $PGDATA/
cp /usr/local/pgsql.old/data/postgresql.conf $PGDATA/

#启动数据库
pg_ctl -D $PGDATA start

这是个bug,版本升级后,pg_config改变了,会导致后面装外部extension时没有装到指定目录。

代码语言:javascript
复制
#旧版本
/database/postgres11.old/psql/bin/pg_config
BINDIR = /database/postgres11.old/psql/bin
DOCDIR = /database/postgres11.old/psql/share/doc
HTMLDIR = /database/postgres11.old/psql/share/doc
INCLUDEDIR = /database/postgres11.old/psql/include
PKGINCLUDEDIR = /database/postgres11.old/psql/include
INCLUDEDIR-SERVER = /database/postgres11.old/psql/include/server
LIBDIR = /database/postgres11.old/psql/lib
PKGLIBDIR = /database/postgres11.old/psql/lib
LOCALEDIR = /database/postgres11.old/psql/share/locale
MANDIR = /database/postgres11.old/psql/share/man
SHAREDIR = /database/postgres11.old/psql/share
SYSCONFDIR = /database/postgres11.old/psql/etc
PGXS = /database/postgres11.old/psql/lib/pgxs/src/makefiles/pgxs.mk
CONFIGURE = '--prefix=/database/postgres11/psql/' '--with-perl' '--with-python'
CC = gcc
CPPFLAGS = -D_GNU_SOURCE
CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2
CFLAGS_SL = -fPIC
LDFLAGS = -Wl,--as-needed -Wl,-rpath,'/database/postgres11/psql/lib',--enable-new-dtags
LDFLAGS_EX = 
LDFLAGS_SL = 
LIBS = -lpgcommon -lpgport -lpthread -lz -lreadline -lrt -lcrypt -ldl -lm 
VERSION = PostgreSQL 11.6

代码语言:javascript
复制
#新版本
/database/postgres11/psql/bin/pg_config
BINDIR = /database/postgres11/psql/bin
DOCDIR = /database/postgres11/psql/share/doc/postgresql
HTMLDIR = /database/postgres11/psql/share/doc/postgresql
INCLUDEDIR = /database/postgres11/psql/include
PKGINCLUDEDIR = /database/postgres11/psql/include/postgresql
INCLUDEDIR-SERVER = /database/postgres11/psql/include/postgresql/server
LIBDIR = /database/postgres11/psql/lib
PKGLIBDIR = /database/postgres11/psql/lib/postgresql
LOCALEDIR = /database/postgres11/psql/share/locale
MANDIR = /database/postgres11/psql/share/man
SHAREDIR = /database/postgres11/psql/share/postgresql
SYSCONFDIR = /database/postgres11/psql/etc/postgresql
PGXS = /database/postgres11/psql/lib/postgresql/pgxs/src/makefiles/pgxs.mk
CONFIGURE = '--prefix='
CC = gcc
CPPFLAGS = -D_GNU_SOURCE
CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2
CFLAGS_SL = -fPIC
LDFLAGS = -Wl,--as-needed -Wl,-rpath,'/lib',--enable-new-dtags
LDFLAGS_EX = 
LDFLAGS_SL = 
LIBS = -lpgcommon -lpgport -lpthread -lz -lreadline -lrt -lcrypt -ldl -lm 
VERSION = PostgreSQL 11.16

大版本升级
逻辑备份旧数据库

安装新版本数据库

然后创建对应的role和schema和database并且grant。

在新版本库中进行逻辑恢复

数据库管理

简单的psql命令
代码语言:javascript
复制
[postgres@pg_master ~]$ psql -h 192.168.233.30 -p 5432 -U postgres -d pgtest -E
# -h 主机名 默认读取环境变量 PGHOST  PGHOST默认为当前主机
# -p 端口号 默认读取环境变量 PGPORT  PGPORT默认为5432
# -U 用户名 默认读取环境变量 PGUSER  PGUSER默认为postgres
# -d 数据库名 默认读取环境变量 PGDATABASE PGDATABASE默认为postgres
# -W 强制输入密码 当有配值环境变量 PGPASSWORD 时,无需输入密码,加入该参数后,强制用户登录时输入密码
# -E 回显命令对应的sql语句
创建数据库
代码语言:javascript
复制
CREATE DATABASE name [ [WITH] [OWNER [=] user_name]
               [TEMPLATE [=] template]
               [ENCODING [=] encoding]
               [LC_COLLATE [=] lc_collate]
               [LC_CTYPE [=] lc_ctype]
               [TABLESPACE [=] tablespace]
               [CONNECTION LIMIT [=] connlimit ] ]
  • name:要创建的数据库的名称。
  • user_name:拥有新数据库的⽤户的名称,或者使⽤默认所有者(执⾏命令的⽤户)DEFAULT。
  • template:创建新数据库的模板的名称,或者DEFAULT使⽤默认模板的模板(template1)。
  • encoding:在新数据库中使⽤的字符集编码。指定字符串常量(例如’SQL_ASCII’),整数编码数字或
  • DEFAULT以使⽤默认编码。 有关更多信息,请参⻅字符集⽀持。
  • lc_collate:在新数据库中使⽤的排序规则(LC_COLLATE)。这会影响应⽤于字符串的排序顺序,例如在使⽤ORDER BY的查询中,以及在⽂本列的索引中使⽤的顺序。 默认设置是使⽤模板数据库的排序规则。有关其他限制,请参⻅“注释”部分。
  • lc_ctype:在新数据库中使⽤的字符分类(LC_CTYPE)。 这会影响字符的分类,例如下,上和数字。 默认值是使⽤模板数据库的字符分类。有关其他限制,请参⻅下⽂。
  • tablespace:将与新数据库关联的表空间的名称,或者为DEFAULT以使⽤模板数据库的表空间。该表空间将是⽤于在此数据库中创建的对象的默认表空间。
  • connlimit:可能的最⼤并发连接数。 默认值-1表示没有限制。
代码语言:javascript
复制
create database etl;  --创建一个etl数据库,其他参数不用配置,直接用模板数据库的即可
drop database etl;  --删除数据库

用户管理

创建用户组
代码语言:javascript
复制
--创建管理员组 admin
create role admin;
--创建开发人员用户组 developer
create role developer;
--创建数据装载用户组 dataload
create role dataload;
--创建外部接口用户组 interface
create role interface;
创建用户
代码语言:javascript
复制
--创建管理员 pgadmin
create role pgadmin with superuser login password 'pgadminAa123456';
--创建开发用户
create role yuzhenchao with login password 'yzc+Aa123456' connection limit 10 valid until '2023-01-16 00:00:00';
--创建数据装载用户
create role copyload with login password 'copy+Aa123456' connection limit 60 valid until '2023-01-16 00:00:00';
--创建外部接口用户
create role finebi with login password 'finebi+Aa123456' connection limit 20 valid until '2023-01-16 00:00:00';
用户加入到指定的用户组
代码语言:javascript
复制
--将pgadmin加入到admin组
alter group admin add user pgadmin;
--将yuzhenchao加入到developer组
alter group developer add user yuzhenchao;
--将copyload加入到dataload组
alter group dataload add user copyload;
--将finebi加入到interface用户组
alter group interface add user finebi;
创建用户名对应的模式名
代码语言:javascript
复制
--创建pgadmin对应的模式名pgadmin
create schema pgadmin;
--创建yuzhenchao对应的模式名yuzhenchao
create schema yuzhenchao;
--创建copyload对应的模式名copyload
create schema copyload;
--一般外部接口都只有只读权限,所以不需要给他建单独的模式

授权管理

用户模式映射
代码语言:javascript
复制
--将pgadmin模式的所有权限授权给pgadmin
grant create,usage on schema pgadmin to pgadmin;
--将yuzhenchao模式的所有权限授权给yuzhenchao
grant create,usage on schema yuzhenchao to yuzhenchao;
--将copyload模式的所有权限授权给copyload
grant create,usage on schema copyload to copyload;
所有模式公开usage权限
代码语言:javascript
复制
--将pgadmin模式的usage权限授权给public
grant usage on schema pgadmin to public;
--将yuzhenchao模式的usage权限授权给public
grant usage on schema yuzhenchao to public;
--将copyload模式的usage权限授权给public
grant usage on schema copyload to public;
回收public模式的create权限
代码语言:javascript
复制
--任何用户都拥有public模式的所有权限
--出于安全,回收任何用户在public的create权限
revoke create on schema public from public;
收回函数的执行权限
代码语言:javascript
复制
/*
 * pg中函数默认公开execute权限
 * 通过pg的基于schema和基于role的默认权限实现
 */

--在schema为pgadmin上创建的任何函数,除定义者外,其他人调用需要显式授权
alter default privileges for role pgadmin revoke execute on functions from public;
--由pgadmin用户创建的任何函数,除定义者外,其他人调用需要显式授权
alter default privileges in schema pgadmin revoke execute on functions from public;

--在schema为yuzhenchao上创建的任何函数,除定义者外,其他人调用需要显式授权
alter default privileges for role yuzhenchao revoke execute on functions from public;
--由yuzhenchao用户创建的任何函数,除定义者外,其他人调用需要显式授权
alter default privileges in schema yuzhenchao revoke execute on functions from public;

--在schema为copyload上创建的任何函数,除定义者外,其他人调用需要显式授权
alter default privileges for role copyload revoke execute on functions from public;
--由copyload用户创建的任何函数,除定义者外,其他人调用需要显式授权
alter default privileges in schema copyload revoke execute on functions from public;
公开表的select权限(视情况而定)
代码语言:javascript
复制
/*
 * pg与oracle不同,没有select any table的权限
 * 但是pg有默认权限
 * 通过pg的基于schema和基于role的默认权限实现
 */

--在schema为pgadmin上创建的任何表默认公开select权限
alter default privileges in schema pgadmin grant select on tables to public;
--由pgadmin用户创建的任何表默认公开select权限
alter default privileges for role pgadmin grant select on tables to public;

--在schema为yuzhenchao上创建的任何表默认公开select权限
alter default privileges in schema yuzhenchao grant select on tables to public;
--由yuzhenchao用户创建的任何表默认公开select权限
alter default privileges for role yuzhenchao grant select on tables to public;

--在schema为copyload上创建的任何表默认公开select权限
alter default privileges in schema copyload grant select on tables to public;
--由copyload用户创建的任何表默认公开select权限
alter default privileges for role copyload grant select on tables to public;

动态sql函数

代码语言:javascript
复制
/*
 * 为了方便各用户的管理
 * 需要用定义者权限创建动态sql函数
 * 最终由pgadmin用户集中管理
 */

--为pgadmin用户创建sp_exec函数
create or replace function pgadmin.sp_exec(vsql varchar)
 returns void  --返回空
 language plpgsql
 security definer  --定义者权限
as $function$ 
begin
    execute vsql;
end;
$function$
;
--将对应模式的对应模式的函数给对应的模式的拥有者
alter function pgadmin.sp_exec(varchar) owner to pgadmin;
--将对应模式的sp_exec函数授权给定义者和集中用户execute权限
grant execute on function pgadmin.sp_exec(varchar) to pgadmin;

--为yuzhenchao用户创建sp_exec函数
create or replace function yuzhenchao.sp_exec(vsql varchar)
 returns void  --返回空
 language plpgsql
 security definer  --定义者权限
as $function$ 
begin
    execute vsql;
end;
$function$
;
--将对应模式的对应模式的函数给对应的模式的拥有者
alter function yuzhenchao.sp_exec(varchar) owner to yuzhenchao;
--将对应模式的sp_exec函数授权给定义者和集中用户execute权限
grant execute on function yuzhenchao.sp_exec(varchar) to yuzhenchao,pgadmin;

--为copyload用户创建sp_exec函数
create or replace function copyload.sp_exec(vsql varchar)
 returns void  --返回空
 language plpgsql
 security definer  --定义者权限
as $function$ 
begin
    execute vsql;
end;
$function$
;
--将对应模式的对应模式的函数给对应的模式的拥有者
alter function copyload.sp_exec(varchar) owner to copyload;
--将对应模式的sp_exec函数授权给定义者和集中用户execute权限
grant execute on function copyload.sp_exec(varchar) to copyload,pgadmin;

集中管理函数

代码语言:javascript
复制
create or replace function pgadmin.sp_execsql(exec_sql character varying,exec_user character varying)
 returns void
 language plpgsql
 security definer
as $function$ 
/* 作者 : v-yuzhenc
 * 功能 : 集中处理程序,以某用户的权限执行某条sql语句
 * exec_sql : 需要执行的sql语句
 * exec_user : 需要以哪个用户的权限执行该sql语句
 * */
declare 
    p_user varchar := exec_user;
    o_search_path varchar;
begin
    --记录原来的模式搜索路径
    execute 'show search_path;' into o_search_path;
    --临时切换模式搜索路径
    execute 'SET search_path TO '||p_user||',public,oracle';
    case p_user 
        when 'pgadmin' then perform pgadmin.sp_exec(exec_sql);
        when 'yuzhenchao' then perform yuzhenchao.sp_exec(exec_sql);
        when 'copyload' then perform copyload.sp_exec(exec_sql);
        else raise exception '未配置该用户:%',p_user;
    end case;
    --恢复模式搜索路径
    execute 'SET search_path TO '||o_search_path;

    exception when others then
        --恢复模式搜索路径
        execute 'SET search_path TO '||o_search_path;
        raise exception '%',sqlerrm;
end;
$function$
;

--将对应模式的对应模式的函数给对应的模式的拥有者
alter function pgadmin.sp_execsql(varchar,varchar) owner to pgadmin;
--将对应模式的sp_exec函数授权给定义者和集中用户execute权限
grant execute on function pgadmin.sp_execsql(varchar,varchar) to pgadmin;

备份与恢复

逻辑备份
代码语言:javascript
复制
su - postgres
#先备份全局对象
pg_dumpall -f backup.sql --globals-only
#再备份数据库
pg_dump hy_observe -Fc > hy_observe.dump
逻辑恢复
代码语言:javascript
复制
su - postgres
#先恢复全局对象
psql
\i backup.sql
--创建对应的数据库
create database hy_observe;
\q

#pg_restore进行恢复
pg_restore -d hy_observe hy_observe.dump -v
物理备份
代码语言:javascript
复制
# 开启归档日志
vi $PGDATA/postgresql.conf
wal_level = replica  # 或者更高级别
archive_mode = on
# backup_in_progress文件用来辅助wal日志备份,通过删除配合test指令控制wal日志备份
archive_command = 'test ! -f /usr/local/pgsql/backup_in_progress || (test ! -f /usr/local/pgsql/data/pg_archive/%f && cp %p /usr/local/pgsql/data/pg_archive/%f)'

# 重启数据库
pg_ctl restart -mf

touch /usr/local/pgsql/backup_in_progress
# 开始基础备份,可以在代码里连接数据库执行
psql -c "select pg_start_backup('hot_backup');"
# 将数据库文件进行备份
BACKUPDATE=`date '+%Y%m%d%H%m%S'`
tar -cf /data/pg_backup/pgbackup_${BACKUPDATE}.tar $PGDATA
# 结束备份,可以在代码里连接数据库执行
psql -c "select pg_stop_backup();"
# 停止wal日志备份
rm /usr/local/pgsql/backup_in_progress
# 将wal日志和基础备份打包在一起
tar -rf /data/pg_backup/pgbackup_${BACKUPDATE}.tar /usr/local/pgsql/data/pg_archive
物理恢复
代码语言:javascript
复制
pg_ctl stop -mf
mv $PGDATA ${PGDATA}.old
tar -xf /data/pg_backup/pgbackup_${BACKUPDATE}.tar -C $PGDATA
vi $PGDATA/recovery.conf
restore_command = 'cp /usr/local/pgsql/data/pg_archive/%f %p'
# 指定要恢复的时间点,也可以不指定,直接恢复所有数据
recovery_target_time = '2022-09-01 10:00:00'
pg_ctl start

开启ssl

代码语言:javascript
复制
su - postgres

#进入到数据目录
cd $PGDATA

#创建证书
openssl req -new -x509 -days 365 -nodes -text -out server.crt -keyout server.key -subj "/CN=pg_master"

#只读权限
chmod 400 server.{crt,key}

#修改pg_hba.conf
vi $PGDATA/pg_hba.conf
#所有远程连接都通过ssl连接
hostssl    all             postgres        0.0.0.0/0               md5
hostssl    all             repl            192.168.233.0/24        trust
hostssl    replication     repl            192.168.233.0/24        md5
hostssl    all             all             0.0.0.0/0               md5 
代码语言:javascript
复制
#开启ssl
alter system set ssl=on;

#重新加载数据库配置
select pg_reload_conf();

#重新登录
\q
psql

#查看当前连接信息
\conninfo

#查看所有连接信息
select 
     pg_ssl.pid
    ,pg_ssl.ssl
    ,pg_ssl.version
    ,pg_sa.backend_type
    ,pg_sa.usename
    ,pg_sa.client_addr
from pg_stat_ssl pg_ssl
inner join pg_stat_activity pg_sa
on (pg_ssl.pid = pg_sa.pid);

密码安全策略

密码加密存储
代码语言:javascript
复制
show password_encryption;--md5
select * from pg_shadow where usename='yuzhenchao';
密码有效期
代码语言:javascript
复制
alter role yuzhenchao valid until '2022-12-31 23:59:59';
select * from pg_user where usename='yuzhenchao';

注意:

  • pg密码有效期仅针对客户端有效,服务器端不受限制。
  • 网络访问控制文件中不能配置为trust认证方式
密码复杂度策略
代码语言:javascript
复制
ls -atl $LD_LIBRARY_PATH/passwordcheck*
代码语言:javascript
复制
alter system set shared_preload_libraries=pg_stat_statements,passwordcheck;
代码语言:javascript
复制
pg_ctl restart -mf
密码验证失败延迟
代码语言:javascript
复制
ls -atl $LD_LIBRARY_PATH/auth_delay*
代码语言:javascript
复制
--重启生效
alter system set shared_preload_libraries=pg_stat_statements,passwordcheck,auth_delay;
代码语言:javascript
复制
pg_ctl restart -mf
代码语言:javascript
复制
--重新加载生效
alter system set auth_delay.milliseconds=5000;
--重新加载
select pg_reload_conf();
代码语言:javascript
复制
pg_ctl reload
防止密码记录到数据库日志
  • 使用createuser命令加上-W选项创建用户
开启服务器日志

postgresql扩展组件

oracle兼容性函数
代码语言:javascript
复制
su - postgres

cd /opt
wget https://api.pgxn.org/dist/orafce/3.21.0/orafce-3.21.0.zip --no-check-certificate
unzip orafce-3.21.0.zip #解压

cd orafce-3.21.0/ #进入orafce-3.21.0目录
make clean 
make #编译
make install #安装

psql -d pgtest -U pgadmin -W
create extension orafce;  --创建orafce扩展
\q
postgis模块
安装cmake3.x版本
代码语言:javascript
复制
cd /opt
wget https://github.com/Kitware/CMake/releases/download/v3.16.2/cmake-3.16.2.tar.gz
tar -zxvf cmake-3.16.2.tar.gz
cd cmake-3.16.2
./configure --prefix=/usr/local/cmake-3.16.2
make -j 4
make install

vi /etc/profile
export CMAKE_HOME=/usr/local/cmake-3.16.2
export PATH=$CMAKE_HOME/bin:$PATH
source /etc/profile
安装geos
代码语言:javascript
复制
cd /opt
wget https://download.osgeo.org/geos/geos-3.11.0.tar.bz2 --no-check-certificate
tar -jxvf geos-3.11.0.tar.bz2
cd geos-3.11.0/
./configure --prefix=/usr/local/geos-3.11.0
make -j 4
make install
安装sqlite3.11以上版本
代码语言:javascript
复制
cd /opt
wget https://www.sqlite.org/2022/sqlite-autoconf-3390100.tar.gz --no-check-certificate
tar -zxvf sqlite-autoconf-3390100.tar.gz
cd sqlite-autoconf-3390100

vi ./sqlite3.c
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif
#define SQLITE_ENABLE_COLUMN_METADATA 1 //增加这句

./configure --prefix=/usr/local/sqlite
make -j 4
make install

mv /usr/bin/sqlite3  /usr/bin/sqlite3_old
ln -s /usr/local/sqlite/bin/sqlite3   /usr/bin/sqlite3

sqlite3 --version

export PKG_CONFIG_PATH=/usr/local/sqlite/lib/pkgconfig:$PKG_CONFIG_PATH
安装proj
代码语言:javascript
复制
cd /opt 
wget http://download.osgeo.org/proj/proj-6.3.2.tar.gz
tar -zxvf proj-6.3.2.tar.gz
cd proj-6.3.2/
./configure  --prefix=/usr/local/proj-6.3.2
make -j 4
make install
安装gdal
代码语言:javascript
复制
cd /opt
wget https://download.osgeo.org/gdal/3.2.1/gdal-3.2.1.tar.gz --no-check-certificate
tar -zxvf gdal-3.2.1.tar.gz 

cd gdal-3.2.1 
./configure  --prefix=/usr/local/gdal-3.2.1 --with-proj=/usr/local/proj-6.3.2
make -j 4
make install 
安装json-c
代码语言:javascript
复制
cd /opt
wget https://github.com/json-c/json-c/archive/json-c-0.13.1-20180305.tar.gz
tar -zxvf json-c-0.13.1-20180305.tar.gz

cd json-c-json-c-0.13.1-20180305
./configure  --prefix=/usr/local/json-c-0.13.1
make -j 4
make install
安装libxml
代码语言:javascript
复制
cd /opt
wget https://mirror.ossplanet.net/gnome/sources/libxml2/2.9/libxml2-2.9.14.tar.xz --no-check-certificate
tar -xvf libxml2-2.9.14.tar.xz

cd libxml2-2.9.14
chmod +x configure
./configure --prefix=/usr/local/libxml2-2.9.14
make -j 4
make install
安装protobuf
代码语言:javascript
复制
cd /opt
wget https://github.com/protocolbuffers/protobuf/archive/v3.10.1.tar.gz
tar -zxvf v3.10.1.tar.gz
cd protobuf-3.10.1/
./autogen.sh #自动生成configure配置文件
./configure  --prefix=/usr/local/protobuf-3.10.1
make -j 4
make install

vi /etc/profile
export PROTOBUF_HOME=/usr/local/protobuf-3.10.1
export PATH=$PROTOBUF_HOME/bin:$PATH
source /etc/profile

protoc --version
libprotoc 3.10.1
安装protobuf-c
代码语言:javascript
复制
cd /opt
wget https://github.com/protobuf-c/protobuf-c/releases/download/v1.3.2/protobuf-c-1.3.2.tar.gz
tar -zxvf protobuf-c-1.3.2.tar.gz 
cd protobuf-c-1.3.2/
#导入protobuf的pkgconfig,否则"--No package 'protobuf' found"

export PKG_CONFIG_PATH=/usr/local/protobuf-3.10.1/lib/pkgconfig

./configure  --prefix=/usr/local/protobuf-c-1.3.2
make -j 4
make install

vi /etc/profile
export PROTOBUFC_HOME=/usr/local/protobuf-c-1.3.2
export PATH=$PROTOBUFC_HOME/bin:$PATH
source /etc/profile
安装boost-devel
代码语言:javascript
复制
yum -y install boost-devel
安装cgal
代码语言:javascript
复制
cd /opt
wget https://github.com/CGAL/cgal/archive/releases/CGAL-4.13.tar.gz
tar -zxvf CGAL-4.13.tar.gz 
cd cgal-releases-CGAL-4.13/

mkdir build && cd build
cmake ..
make
make install
安装sfcgal
代码语言:javascript
复制
cd /opt
wget https://github.com/Oslandia/SFCGAL/archive/v1.3.7.tar.gz
tar -zxvf v1.3.7.tar.gz
cd SFCGAL-1.3.7
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/sfcgal-1.3.7 ..
make -j 4
make install
安装postgis
代码语言:javascript
复制
vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/local/pgsql/lib
/usr/local/proj-6.3.2/lib
/usr/local/gdal-3.2.1/lib
/usr/local/geos-3.11.0/lib64
/usr/local/sfcgal-1.3.7/lib64
/usr/local/json-c-0.13.1/lib
/usr/local/libxml2-2.9.14/lib
/usr/local/protobuf-3.10.1/lib
/usr/local/protobuf-c-1.3.2/lib

ldconfig -v #重启生效

su - postgres
cd /usr/local/pgsql/contrib
wget http://download.osgeo.org/postgis/source/postgis-3.2.1.tar.gz
tar -zxvf postgis-3.2.1.tar.gz
cd postgis-3.2.1/
./configure --prefix=/usr/local/pgsql --with-gdalconfig=/usr/local/gdal-3.2.1/bin/gdal-config --with-pgconfig=/usr/local/pgsql/bin/pg_config --with-geosconfig=/usr/local/geos-3.11.0/bin/geos-config --with-projdir=/usr/local/proj-6.3.2 --with-xml2config=/usr/local/libxml2-2.9.14/bin/xml2-config --with-jsondir=/usr/local/json-c-0.13.1 --with-protobufdir=/usr/local/protobuf-c-1.3.2 --with-sfcgal=/usr/local/sfcgal-1.3.7/bin/sfcgal-config
make -j 4
make install
创建extension
代码语言:javascript
复制
psql -d pgtest -U pgadmin -W

--postgis扩展
create extension postgis;

--验证栅格类数据需要的raster扩展
create extension postgis_raster;

--如果安装带有sfcgal,验证下三维sfcgal扩展
create extension postgis_sfcgal;

create extension fuzzystrmatch;

create extension postgis_tiger_geocoder;

create extension postgis_topology;

\q
  • 创建extension时遇到问题
代码语言:javascript
复制
could not load library "/usr/local/pgsql/lib/postgis-3.so": /usr/local/pgsql/lib/postgis-3.so: undefined symbol: GEOSLargestEmpt
  • 查找原因,是geos存在多个版本
代码语言:javascript
复制
ldconfig -p | grep libgeos_c.so.1
libgeos_c.so.1 (libc6,x86-64) => /usr/geos39/lib64/libgeos_c.so.1
libgeos_c.so.1 (libc6,x86-64) => /usr/local/geos-3.11.0/lib64/libgeos_c.so.1
#查找geos39
rpm -qa geos39
geos39-3.9.2-1.rhel7.x86_64
  • 解决方案:卸载geos39-3.9.2-1.rhel7.x86_64
  • 再次校验,发现只剩一个了
代码语言:javascript
复制
ldconfig -p | grep libgeos_c.so.1
libgeos_c.so.1 (libc6,x86-64) => /usr/local/geos-3.11.0/lib64/libgeos_c.so.1
  • 最后 create extension postgis; 成功了

数据库开发规范

命名规范
  • 标识符总长度不超过63,由于oracle标识符长度不超过30,原则上,为了兼容oracle,标识符长度最好不要超过30;
  • 对象名(表名、列名、函数名、视图名、序列名、等对象名称)规范,对象名务必只使用小写字母,下划线,数字。不要以pg开头,不要以数字开头,不要使用保留字;
  • 查询中的别名不要使用 “小写字母,下划线,数字” 以外的字符,例如中文;
  • 主键索引应以 pk_ 开头, 唯一索引要以 uk_ 开头,普通索引要以 idx_ 打头
  • 临时表以 tmp_ 开头,子表以规则结尾,例如按年分区的主表如果为tbl, 则子表为tbl_2016,tbl_2017等;
  • 库名最好以部门名字开头 + 功能,如 xxx_yyy,xxx_zzz,便于辨识;
  • 禁用public schema,应该为每个应用分配对应的schema,schema_name最好与user name一致。
设计规范
  • 多表中的相同列,必须保证列名一致,数据类型一致;
  • btree索引字段不建议超过2000字节,如果有超过2000字节的字段需要建索引,建议使用函数索引(例如哈希值索引),或者使用分词索引;
  • 对于频繁更新的表,建议建表时指定表的fillfactor=85,每页预留15%的空间给HOT更新使用;(create table test123(id int, info text) with(fillfactor=85); CREATE TABLE)
  • 表结构中字段定义的数据类型与应用程序中的定义保持一致,表之间字段校对规则一致,避免报错或无法使用索引的情况发生;
  • 建议有定期历史数据删除需求的业务,表按时间分区,删除时不要使用DELETE操作,而是DROP或者TRUNCATE对应的表;
  • 为了全球化的需求,所有的字符存储与表示,均以UTF-8编码;
  • 对于值与堆表的存储顺序线性相关的数据,如果通常的查询为范围查询,建议使用BRIN索引。例如流式数据,时间字段或自增字段,可以使用BRIN索引,减少索引的大小,加快数据插入速度。(create index idx on tbl using brin(id); )
  • 设计时应尽可能选择合适的数据类型,能用数字的坚决不用字符串,使用好的数据类型,可以使用数据库的索引,操作符,函数,提高数据的查询效率;
  • 应该尽量避免全表扫描(除了大数据量扫描的数据分析),PostgreSQL支持几乎所有数据类型的索引;
  • 应该尽量避免使用数据库触发器,这会使得数据处理逻辑复杂,不便于调试;
  • 未使用的大对象,一定要同时删除数据部分,否则大对象数据会一直存在数据库中,与内存泄露类似;
  • 对于固定条件的查询,可以使用部分索引,减少索引的大小,同时提升查询效率;(create index idx on tbl (col) where id=1;)
  • 对于经常使用表达式作为查询条件的语句,可以使用表达式或函数索引加速查询;(create index idx on tbl ( exp ); )
  • 如果需要调试较为复杂的逻辑时,不建议写成函数进行调试,可以使用plpgsql的匿名代码块;
  • 当用户有prefix或者 suffix的模糊查询需求时,可以使用索引,或反转索引达到提速的需求;(select * from tbl where reverse(col) ~ ‘^def’; – 后缀查询使用反转函数索引)
  • 用户应该对频繁访问的大表(通常指超过8GB的表,或者超过1000万记录的表)进行分区,从而提升查询的效率、更新的效率、备份与恢复的效率、建索引的效率等等;
  • 设计表结构时必须加上字段数据的入库时间inputed_time和数据的更新时间updated_time;
查询规范
  • 统计行数用count(*)或者count(1),count(列名)不会统计列为空的行;
  • count(distinct col) 计算该列的非NULL不重复数量,NULL不被计数;
  • count(distinct (col1,col2,…) ) 计算多列的唯一值时,NULL会被计数,同时NULL与NULL会被认为是想同的;
  • NULL是UNKNOWN的意思,也就是不知道是什么。 因此NULL与任意值的逻辑判断都返回NULL;
  • 除非是ETL程序,否则应该尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理;
  • 尽量不要使用 select * from t ,用具体的字段列表代替*,不要返回用不到的任何字段,另外表结构发生变化也容易出现问题。
管理规范
  • 数据订正时,删除和修改记录时,要先select,避免出现误删除,确认无误才能提交执行;
  • 用户可以使用explain analyze查看实际的执行计划,但是如果需要查看的执行计划设计数据的变更,必须在事务中执行explain analyze,然后回滚;
  • 如何并行创建索引,不堵塞表的DML,创建索引时加CONCURRENTLY关键字,就可以并行创建,不会堵塞DML操作,否则会堵塞DML操作;(create index CONCURRENTLY idx on tbl(id); )
  • 为数据库访问账号设置复杂密码;
  • 业务系统,开发测试账号,不要使用数据库超级用户,非常危险;
  • 应该为每个业务分配不同的数据库账号,禁止多个业务共用一个数据库账号;
  • 大批量数据入库的优化,如果有大批量的数据入库,建议使用copy语法,或者 insert into table values (),(),…(); 的方式,提高写入速度。
稳定性与性能规范
  • 游标使用后要及时关闭;
  • 两阶段提交的事务,要及时提交或回滚,否则可能导致数据库膨胀;
  • 不要使用delete 全表,性能很差,请使用truncate代替;
  • 应用程序一定要开启autocommit,同时避免应用程序自动begin事务,并且不进行任何操作的情况发生,某些框架可能会有这样的问题;
  • 在函数中,或程序中,不要使用count(*)判断是否有数据,很慢。 建议的方法是limit 1;
  • 必须选择合适的事务隔离级别,不要使用越级的隔离级别,例如READ COMMITTED可以满足时,就不要使用repeatable read和serializable隔离级别;
  • 高峰期对大表添加包含默认值的字段,会导致表的rewrite,建议只添加不包含默认值的字段,业务逻辑层面后期处理默认值;
  • 可以预估SQL执行时间的操作,建议设置语句级别的超时,可以防止雪崩,也可以防止长时间持锁;
  • PostgreSQL支持DDL事务,支持回滚DDL,建议将DDL封装在事务中执行,必要时可以回滚,但是需要注意事务的长度,避免长时间堵塞DDL对象的读操作;
  • 如果用户需要在插入数据和,删除数据前,或者修改数据后马上拿到插入或被删除或修改后的数据,建议使用insert into … returning …; delete … returning …或update … returning …; 语法。减少数据库交互次数;
  • 自增字段建议使用序列,序列分为2字节,4字节,8字节几种(serial2,serial4,serial8)。按实际情况选择。 禁止使用触发器产生序列值;
  • 使用窗口查询减少数据库和应用的交互次数;
  • 如何判断两个值是不是不一样(并且将NULL视为一样的值),使用col1 IS DISTINCT FROM col2;
  • 对于经常变更,或者新增,删除记录的表,应该尽量加快这种表的统计信息采样频率,获得较实时的采样,输出较好的执行计划。

参考文章:https://blog.csdn.net/qq_33445829/article /details/126636295

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-07-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 民工哥技术之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 小版本升级pg_upgrade
  • 大版本升级
  • 在新版本库中进行逻辑恢复
  • 数据库管理
    • 简单的psql命令
      • 创建数据库
        • 创建用户组
          • 创建用户
            • 用户加入到指定的用户组
              • 创建用户名对应的模式名
              • 授权管理
                • 用户模式映射
                  • 所有模式公开usage权限
                    • 回收public模式的create权限
                      • 收回函数的执行权限
                        • 公开表的select权限(视情况而定)
                        • 动态sql函数
                        • 备份与恢复
                          • 逻辑备份
                            • 逻辑恢复
                              • 物理备份
                                • 物理恢复
                                • 密码安全策略
                                  • 密码加密存储
                                    • 密码有效期
                                      • 密码复杂度策略
                                        • 密码验证失败延迟
                                          • 防止密码记录到数据库日志
                                            • 开启服务器日志
                                              • oracle兼容性函数
                                                • postgis模块
                                                  • 命名规范
                                                    • 设计规范
                                                      • 查询规范
                                                        • 管理规范
                                                          • 稳定性与性能规范
                                                          相关产品与服务
                                                          数据库
                                                          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                                                          领券
                                                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档