postgresql

源码安装

root@server01:~# mkdir /apps/pgsql/

./configure --prefix=/apps/pgsql

make world -j4

make install-world

useradd -s /bin/bash -m -d /home/postgres postgres

echo -e '123456\n123456' | passwd postgres

mkdir -pv /pgsql/data

chown postgres:postgres /pgsql/data/

设置环境变量

bash 复制代码
vim /etc/profile.d/pgsql.sh
export PGHOME=/apps/pgsql
export PATH=$PGHOME/bin/:$PATH
export PGDATA=/pgsql/data
export PGUSER=postgres
export MANPATH=/apps/pgsql/share/man:$MANPATH

初始化

su - postgres

initdb -D /pgsql/data/

pg_ctl -D /pgsql/data/ -l logfile start

连接

psql

Ubuntu 启动脚本实现开机自动PostgreSQL

方法一

root@server02:~/postgresql-14.2/contrib# vim start-scripts/linux #修改安装目录和数据目录

prefix=/apps/pgsql

#Data directory

PGDATA="/pgsql/data"

root@server02:~/postgresql-14.2/contrib# cp start-scripts/linux /etc/init.d/postgresql

root@server02:~/postgresql-14.2/contrib# chmod +x /etc/init.d/postgresql

vi /etc/rc.local

/etc/init.d/postgresql start

方法二

su - postgres -c "/apps/pgsql/bin/pg_ctl -D /pgsql/data/ -l logfile start"

service文件启动

bash 复制代码
root@server02:/apps/pgsql# cat /lib/systemd/system/postgresql.service
[Unit]
Description=PostgreSQL database server
After=network.target
[Service]
User=postgres
Group=postgres
ExecStart=/apps/pgsql/bin/postmaster -D /pgsql/data
ExecReload=/bin/kill -HUP
[Install]
WantedBy=multi-user.target

POSTgresql管理

导入数据:psql -f pg.sql

cat pg.sql

create database luo;

\c luo;

create table test(id int);

配置远程连接

改配置文件,修改监听端口为0.0.0.0

listen_addresses = '0.0.0.0'

psql -h 120.77.146.92 -U postgres

psql: error: connection to server at "120.77.146.92", port 5432 failed: FATAL: no pg_hba.conf entry for host "120.79.60.104", user "postgres", database "postgres", no encryption

配置连接文件,ubuntu yum安装在 /etc/postgresql/14/main/pg_hba.conf

vi pg_hba.conf

host all all 0.0.0.0/0 trust 远程不用密码

host all all 0.0.0.0/0 md5 #要密码,添加此行

重启服务:pg_ctl -D /pgsql/data/ restart

修改用户密码

alter user postgres with password '123456';

远程连接成功

psql -h 120.79.60.104 -U postgres -p 5432

免密连接

cat .pgpass

120.79.60.104:5432:db1:postgres:12345

psql -h 120.79.60.104 db1 postgres

\timing on #显示执行命令时间

\set VERBOSITY VERBOSE ##显示详细的信息,可以打印出报出问题的源代码位置

bash 复制代码
查看数据库存放目录的路径
 select oid,datname from pg_database;
create schema  n80_sch;   #创建schema
db1=# \dn  #查看schema
 create table n80_sch.t1(id int);  #创建 表属于n80_sch
  \dt n80_sch.t1   #查看
  db1=# \dt n80_sch.t1
         List of relations
 Schema  | Name | Type  |  Owner   
---------+------+-------+----------
 n80_sch | t1   | table | postgres
sql 复制代码
b1=#  \c testdb  #切换数据库
testdb=#  insert into tb1 (name) select (md5(random()::text)) from  generate_series (2,10);



 create table tb2 (like tb1); ##复制表结构,不复制数据
\d tb2  查看表结果

select * from pg_tables;  #查看所有的表
 select pg_total_relation_size('tb1');#查看表大小



查看数据库对应的目录
testdb=# select oid,datname from pg_database where datname = 'testdb';
  oid  | datname 
-------+---------
 16409 | testdb
(1 row)
查看表对应的文件
testdb=#  select relid from pg_stat_all_tables where relname='tb1';
 relid 
-------
 16411


root@server02:/pgsql/data/base/16409# ll 16411
-rw------- 1 postgres postgres 8192 Aug 20 12:41 16411

或者
testdb=#  select * from pg_relation_filepath('tb1');
 base/16409/16411


 查看当前库中的所有表的统计信息
 select * from pg_stat_all_tables;

#查看指定表t1的信息
 select * from pg_stat_all_tables where relname='t1';

create table tb1 (id serial,name varchar(10));

批量添加

sql 复制代码
testdb=#  create table tb1 (id serial primary key,name text);
CREATE TABLE
Time: 5.048 ms
testdb=#  insert into tb1 (name) select (md5(random()::text)) from 
generate_series (1,1000000);
INSERT 0 1000000
Time: 3638.546 ms (00:03.639)

100万记录2秒
sql 复制代码
testdb=#  create table tb1(id int,info text,crt_time timestamp);
CREATE TABLE
Time: 3.263 ms
testdb=#  insert into tb1 select 
generate_series(1,100000),md5(random()::text),clock_timestamp();
INSERT 0 100000

显示时间
testdb=# select clock_timestamp();
 2023-08-20 13:09:20.561662+08

#创建索引
testdb=#  create index idx_tb1_id on tb1(id);

#查看索引
select * from pg_indexes where tablename='tb1'; 
#查询条件是索引列
testdb=#  explain analyze select * from tb1 where id = 99999;
 Index Scan using idx_tb1_id on tb1  (cost=0.29..8.31 rows=1 width=45) (actual time=0.020..0.021 rows=1 loops=1)
   Index Cond: (id = 99999)
 Planning Time: 0.198 ms
 Execution Time: 0.041 ms
Time: 0.412 ms


全表扫描
testdb=# explain analyze select * from tb1 where info = 
'fb16d90265f55880ba96b016afe65b51 ';
 Seq Scan on tb1  (cost=0.00..2185.00 rows=1 width=45) (actual time=7.967..7.968 rows=0 loops=1)
   Filter: (info = 'fb16d90265f55880ba96b016afe65b51 '::text)
   Rows Removed by Filter: 100000
 Planning Time: 0.058 ms
 Execution Time: 7.986 ms

Time: 8.359 ms



#关闭索引
testdb=#  set enable_indexscan=off;
SET
 set enable_bitmapscan=off;

删除索引
testdb=# drop index idx_tb1_id;

表空间

存放表的目录

postgres@server02:~$ mkdir ts1

testdb=# create tablespace ts1 location '/home/postgres/ts1/';

CREATE TABLESPACE

Time: 1.256 ms

testdb=# \db

pg_default | postgres |

pg_global | postgres |

ts1 | postgres | /home/postgres/ts1

创建表指定表空间

create table tb3(id int) tablespace ts1;

testdb=# select * from pg_relation_filepath('tb3');

pg_tblspc/16448/PG_14_202107181/16409/16449

删除表空间,要先删除表

drop tablespace ts1;

#查看数据库启动时间

postgres=# select pg_postmaster_start_time();

导入数据

psql < hellodb.sql

#关闭自动提交,可以用rollback取消DML语句

\set AUTOCOMMIT off

\set AUTOCOMMIT on

用户账号管理

python 复制代码
Create user   user1 PASSWORD '123';


CREATE ROLE li WITH LOGIN PASSWORD '123456';

登录

psql -h 120.79.60.104 -U user1 hellodb

创建超级管理员,可以删除库

CREATE ROLE luo WITH SUPERUSER LOGIN PASSWORD '123456' ;

禁止登录

alter user luo with nologin ;

\du 查看用户信息

修改用户有创建数据库权限

postgres=# alter user li with createdb;

授权li用户hellodb数据库查看权限

pinxixi=# \c hellodb

You are now connected to database "hellodb" as user "postgres".

hellodb=# GRANT select ON ALL TABLES IN schema public to li;

GRANT

安装pgadmin

apt list|grep pgadmin

apt install phppgadmin

wal 日志

Online WAL(WRITE-AHEAD LOG)日志功能是为了保证崩溃后的安全,如果系统崩溃,可以"重放"从最

后一次检查点以来的日志项来恢复数据库的一致性。但是也存在日志膨胀的问题,相当于MySQL的事务日

志redo log

#查看当前日志文件lsn位置;

select pg_current_wal_lsn();

查看wal日志位置

root@server02:~# ll /pgsql/data/pg_wal/ -t

#查看事务ID

postgres=# select txid_current();

txid_current

      820

查看 WAL 文件内容

pg_waldump /pgsql/data/pg_wal/000000010000000000000018

rmgr: XLOG len (rec/tot): 114/ 114, tx: 0, lsn: 0/18000328, prev 0/180002F0, desc: CHECKPOINT_ONLINE redo 0/180002F0; tli 1; prev tli 1; fpw true; xid 0:819; oid 16519; multi 1; offset 0; oldest xid 726 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 819; online

rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/180003A0, prev 0/18000328, desc: RUNNING_XACTS nextXid 819 latestCompletedXid 818 oldestRunningXid 819

rmgr: Transaction len (rec/tot): 34/ 34, tx: 819, lsn: 0/180003D8, prev 0/180003A0, desc: COMMIT 2023-08-21 22:00:22.279472 CST

rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/18000400, prev 0/180003D8, desc: RUNNING_XACTS nextXid 820 latestCompletedXid 819 oldestRunningXid 820

pg_waldump: fatal: error in WAL record at 0/18000400: invalid record length at 0/18000438: wanted 24, got 0

#按时间排序显示WAL文件名

select * from pg_ls_waldir() order by modification asc;

#默认WAL文件达到16M,自动切换另一个WAL

切换 WAL 日志

select pg_switch_wal();

归档wal日志

把wal日志归档到本地或远程目录

归档日志记录的是checkpoint前的WAL日志,即数据的历史日志,即把pg_wal里面的在线日志备份出来,功能上归档日志相当于MySQL的二进制日志

生产环境中为了保证数据高可用性,通常需要开启归档,当系统故障后可以通过归档的日志文件对数据进行恢复

#配置归档需要开启如下参数:

wal_level = replica

#该参数的可选的值有minimal, replica和logical,wal的级别依次增高,在wal的信息也越多。由于

minimal这一级别的wal不包含从基础的备份和wal日志重建数据的足够信息,在该模式下,无法开启wal日志

归档

#从PostgreSQL 10开始,默认使用的replica此级别,也建议使用此级别,之前版本默认是最小级别

minimal

archive_mode = on

#上述参数为on,表示打开归档备份,可选的参数为on,off,always 默认值为off,所以要手动打开,需要重

启服务生效

开启归档日志

#在 PostgreSQL中配置归档的方法是配置参数 archive_command,参数的配置值可以是一个Unix命令,

此命令把WAL日志文档拷贝到其他地方

postgres@server02:/pgsql/data$ vi postgresql.conf

archive_mode = on # enables archiving; off, on, or always

archive_command = '[ ! -f /archive/%f ] && cp %p /archive/%f'

#用"%p"表示将要归档的wal文件包含完整路径的信息的文件名

#用"%f"代表不包含路径信息的wal文件的文件名

创建文件并授权

root@server02:/pgsql/data# mkdir /archive

root@server02:/pgsql/data# chown postgres:postgres /archive/

切换日志 select pg_switch_wal(); 会拷贝到/archive/

root@server02:/pgsql/data# ls /archive

000000010000000000000018

拷贝到远程

面密钥

postgres@server02:/pgsql/data$ ssh-keygen

postgres@server02:/pgsql/data$ ssh-copy-id postgres@172.29.21.67

修改配置

postgres@server02:/pgsql/data$ vi postgresql.conf

archive_command = 'scp %p postgres@172.29.21.67:/pgsql/backup/%f'

目标主机创建目录授权

root@server01:~# mkdir /pgsql/backup -p

oot@server01:~# chown postgres:postgres /pgsql/backup/ -R

重启

postgres@server02:/pgsql/data$ pg_ctl restart

postgres=# select pg_switch_wal();

#在备份服务器上可看到日志的备份出现

ls /pgsql/backup/

PostgreSQL 备份恢复

逻辑备份

PostgreSQL提供了pg_dump、pg_dumpall 命令进行数据库的逻辑备份。

两者的功能差不多,只是pg_dumpall 是将一个PostgreSQL数据库集群全部转储到一个脚本文件中,而

pg_dump命令可以选择一个数据库或部分表进行备份。

另外利用COPY命令也能对表和SQL子集进行备份,实现表的还原

远程备份

root@server01:~# pg_dump -h 172.16.141.0 -U postgres -f /backup/hellodb hellodb

远程还原到hui数据库

psql -h 172.16.141.0 -U postgres -d hui < /backup/hellodb

本地

psql -d luo < /backup/hellodb

备份 hellodb数据库, -C 会备份创建数据库的命令,可以直接还原

root@server01:~# pg_dump -h 172.16.141.0 -U postgres -f /backup/hellodb3 -C hellodb

删除数据库

hui=# drop database hellodb;

还原

psql -h 172.16.141.0 -U postgres < /backup/hellodb3

#如果想生成的备份文件格式为自定义格式,可以使用下面的命令:

-F自定义文件格式

root@server01:~# pg_dump -Fc -h 172.16.141.0 -U postgres -C hellodb -f /backup/hellodb.dump

要先在恢复机器创建数据库

create database hellodb2;

pg_restore -h 172.16.141.0 -U postgres -d hellodb2 < /backup/hellodb.dump

备份所有数据库,每个数据库要输入密码

root@server01:~# pg_dumpall -h 172.16.141.0 -U postgres -f /backup/all_pgsql.sql

授权postgres用户对db2库有所有权限

GRANT ALL PRIVILEGES ON DATABASE db2 TO postgres;

bash 复制代码
导出为csv文件
hellodb2=# copy students TO '/tmp/students.csv' with csv;
COPY 25
hellodb2=# delete from students;
DELETE 25
hellodb2=# select * from students;
 stuid | name | age | gender | classid | teacherid 
-------+------+-----+--------+---------+-----------
(0 rows)

hellodb2=# copy students from  '/tmp/students.csv' with csv;
COPY 25
hellodb2=# select * from students;
 stuid |     name      | age | gender | classid | teacherid 
-------+---------------+-----+--------+---------+-----------
     1 | Shi Zhongyu   |  22 | M      |       2 |         3
     2 | Shi Potian    |  22 | M      |       1 |         7

导出导入指定字段

bash 复制代码
hellodb2=# copy students from  '/tmp/students.csv' with csv;

hellodb2=# create table students2(id int ,name char (30));

hellodb2=# COPY students2 from '/tmp/students.csv' WITH csv;


hellodb2=# select * from students2;
 id |              name              
----+--------------------------------
  1 | Shi Zhongyu

导出带字段名

hellodb2=# COPY students2 to '/tmp/students.csv' WITH csv header;

导入

COPY students2 from '/tmp/students.csv' WITH csv header;

物理备份

postgres@server02:/pgsql/data$ pg_ctl stop

waiting for server to shut down... done

server stopped

备份

root@server02:/pgsql/data# cp -ap /pgsql/data /backup/20230822pgsql

启动

postgres@server02:/pgsql/data$ pg_ctl start

删除数据库postgres=# drop database hellodb2;

还原

postgres@server02:/pgsql/data$ pg_ctl stop

root@server02:/backup# rm -rf /pgsql/data/*

cp -a /backup/20230822pgsql2/* /pgsql/data/

postgres@server02:/pgsql/data$ pg_ctl start

验证数据库是否恢复

利用PITR实现误删除的实战案例

bash 复制代码
首先备份数据


pg_basebackup  -D /pgsql/backupliu -Ft -Pv -U postgres -h 172.16.141.0 -p5432 -R  

root@server01:/pgsql/data/log# ls /pgsql/backupliu
16448.tar  backup_manifest  base.tar  pg_wal.tar

数据更新#在PG服务器上继续生成测试数据
testdb=# insert into t1 values(2);

#模拟数据库删除
postgres=# drop database testdb;

查看日志文件
postgres=# select pg_walfile_name(pg_current_wal_lsn());
     pg_walfile_name      
--------------------------
 00000002000000000000004D
(1 row)


postgres=# select txid_current();
 txid_current 
--------------
         1054
(1 row

切换归档日志
postgres=# select pg_switch_wal();
 pg_switch_wal 
---------------
 0/4D0000D8
(1 row)

恢复

postgres@server01:~$ tar -xf /pgsql/backupliu/base.tar  -C /pgsql/data

拷贝到从节点
root@server02:/archive# scp  *  172.29.21.67:/archive/

#查看故障点事务ID
pg_waldump /archive/pg_waldump /archive/000000020000000000000020 |grep -B10
"DROP dir" 
查看事务id 1053

#修改配置文件postgresql.conf,或者postgresql.auto.conf文件也可以[postgres@backup ~]$vi /pgsql/data/postgresql.conf 
#加下面两行
restore_command ='cp /archive/%f %p'
#指定还原至上面查到的事务ID
recovery_target_xid ='1053'

启动服务

重节点启动时

查看日志

root@server01:/pgsql/data/log# cat postgresql-2023-08-24_004446.log

2023-08-24 00:44:46.549 CST [271757] LOG: ending log output to stderr

2023-08-24 00:44:46.549 CST [271757] HINT: Future log output will go to log destination "csvlog".

cp: cannot stat '/archive/00000003.history': No such file or directory

cp: cannot open '/archive/00000002.history' for reading: Permission denied

cp: cannot open '/archive/00000002000000000000004C' for reading: Permission denied

cp: cannot stat '/archive/00000003.history': No such file or directory

cp: cannot open '/archive/00000002.history' for reading: Permission denied

注意权限

root@server01:/pgsql/data/log# chown postgres.postgres /archive/ -R

PostgreSQL 高可用

开启wal归档日志

Master 节点配置

创建并授权用户

create role repluser with replication login password '123456';

#修改pg_hba.conf进行授权

[postgres@master ~]$vi /pgsql/data/pg_hba.conf

host replication repluser 0.0.0.0/0 md5

从节点

bash 复制代码
pg_ctl stop -D /pgsql/data
 rm -rf /pgsql/data/* 
 rm -rf /archive/* 
 rm -rf /backup/* 
 rm -rf /pgsql/backup/*
 pg_basebackup -D /pgsql/backup/ -Ft -Pv -Urepluser -h  172.16.141.0 -p 5432 -R 
tar xf /pgsql/backup/base.tar -C /pgsql/data 
tar xf /pgsql/backup/pg_wal.tar -C /archive/
ls -l /pgsql/data
vi /pgsql/data/postgresql.auto.conf
vi /pgsql/data/postgresql.conf 
pg_ctl  -D /pgsql/data start

主库查看

主从切换

bash 复制代码
[postgres@slave ~]$pg_ctl promote
waiting for server to promote.... done
server promoted
[postgres@slave ~]$pg_controldata
[postgres@rocky8 ~]$pg_ctl restart

postgres@server02:~$ pg_ctl stop

waiting for server to shut down... done

server stopped

postgres@server02:~$ rm -rf /pgsql/data/*

postgres@server02:~$ rm -rf /archive/*

postgres@server02:~$ rm -rf /pgsql/backup/

postgres@server02:~$ pg_basebackup -D /pgsql/backup/ -Ft -Pv -Urepluser -h 172.29.21.67 -p 5432 -R

postgres@server02:~$ tar -xf /pgsql/backup/base.tar -C /pgsql/data/

postgres@server02:~$ tar -xf /pgsql/backup/pg_wal.tar -C /archive/

修改配置,修改host

postgres@server02:~$ vi /pgsql/data/postgresql.conf

primary_conninfo ='host=172.29.21.67 port=5432 user=repluser password=123456'

restore_command ='cp /archive/%f %p'

postgres@server02:~$ pg_ctl -D /pgsql/data/ start

bash 复制代码
主库测试写入正常
hellodb=>  delete from teachers where tid=3;
DELETE 1
hellodb=> create table test(id int);
CREATE TABLE
hellodb=> select * from test;
 id 
----
(0 rows)

hellodb=> insert into  test values (1);
INSERT 0 1

实现同步的流复制

vi /pgsql/data/postgresql.conf

synchronous_standby_names = '*' #开启此项,表示同步方式,默认是异步方式

synchronous_commit = on #开启同步模式

相关推荐
Java探秘者12 分钟前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
2301_7869643618 分钟前
3、练习常用的HBase Shell命令+HBase 常用的Java API 及应用实例
java·大数据·数据库·分布式·hbase
阿维的博客日记1 小时前
图文并茂解释水平分表,垂直分表,水平分库,垂直分库
数据库·分库分表
ZhongruiRao2 小时前
Springboot+PostgreSQL+MybatisPlus存储JSON或List、数组(Array)数据
spring boot·postgresql·json
wrx繁星点点2 小时前
事务的四大特性(ACID)
java·开发语言·数据库
小小娥子3 小时前
Redis的基础认识与在ubuntu上的安装教程
java·数据库·redis·缓存
DieSnowK3 小时前
[Redis][集群][下]详细讲解
数据库·redis·分布式·缓存·集群·高可用·新手向
-XWB-3 小时前
【MySQL】数据目录迁移
数据库·mysql
老华带你飞3 小时前
公寓管理系统|SprinBoot+vue夕阳红公寓管理系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·spring boot·课程设计
我明天再来学Web渗透4 小时前
【hot100-java】【二叉树的层序遍历】
java·开发语言·数据库·sql·算法·排序算法