数据库之PostgreSQL详解
2601_962181962026-08-31 11:24
一、PostgreSQL介绍PostgreSQL是一个功能强大的 开源 的关系型数据库。底层基于C实现。PostgreSQL的开源协议和Linux内核版本的开源协议是一样的。。BDS协议,这个协议基本和MIT开源协议一样,说人话,就是你可以对PostgreSQL进行一些封装,然后商业化是收费。PostgreSQL的名字咋来的。之前叫Ingres,后面为了解决一些ingres中的一些问题,作为后面的ingres,就起名叫postgre。PostgreSQL版本迭代的速度比较快,现在最新的正式的发布版本,已经到了15.RELEASE。PGSQL的版本选择一般有两种:* 如果为了稳定的运行,推荐使用12.x版本。* 如果想体验新特性,推荐使用14.x版本。PGSQL允许跨版本升级,而且没有什么大问题。PGSQL社区特别活跃,基本是三个月一发版。意味着很多常见的BUG都可以得到及时的修复。PGSQL其实在国外使用的比较多,国内暂时还是以MySQL为主。但是国内很多国产数据库都是基于PGSQL做的二次封装:比如华为GaussDB还有腾讯的Tbase等等。真实很多公司原来玩的Oracle,直接平转到PGSQL。同时国内的很多云产品都支持PGSQL了。PGSQL因为开源,有很多做数据迁移的工具,可以让你快速的从MySQL,SQLServer,Oracle直接平转到PGSQL中内部,比如pgloader这样的数据迁移工具。PGSQL的官方地址:https://www.postgresql.org/PGSQL的国内社区:http://www.postgres.cn/v2/home### 二、PostgreSQL和MySQL的区别技术没有好坏之分,知识看一下是否符合你的业务,能否解决你的业务需求。其次也要查看社区的活跃度以及更新的频次。MySQL不支持的几点内容:* MySQL的数据类型不够丰富。* MySQL不支持序列概念,Sequence。* 使用MySQL时,网上比较好用的插件。* MySQL的性能优化监控工具不是很多,定位问题的成本是比较高。* MySQL的主从复制没有一个官方的同步策略,同步问题难以解决。* MySQL虽然开源,but,不够彻底。PostgreSQL相对MySQL上述问题的特点:* PostgreSQL的数据类型嘎嘎丰富。* PostgreSQL是有序列的概念的。* PostgreSQL的插件特别丰富。* PostgreSQL支持主从复制的同步操作,可以实现数据的0丢失。* PostgreSQL的MVCC实现和MySQL不大一样。PostgreSQL一行数据会存储多个版本。最多可以存储40亿个事务版本。### 三、PostgreSQL的安装咱们只在Linux中安装,不推荐大家在Windows下安装。Linux的版本尽量使用7.x版本,最好是7.6或者是7.8版本。去官网找按照的方式
相关推荐
疯狂打码的少年16 分钟前
【数据库技术】SQL概述与数据定义(DDL:CREATE/DROP/ALTER)数据库小学妹30 分钟前
关系型数据库内置图查询来了:SQL/PGQ标准怎么用pnoker1 小时前
IoT DC3 时序存储选型:四款数据库可插拔黑臂麒麟1 小时前
HarmonyOS鸿蒙实战应用6:随手账本——Preferences本地持久化2601_962174171 小时前
小试牛刀-SpringBoot集成SOL链如何取名1 小时前
结合实际业务进行LRU淘汰算法优化设计(数据库开发日志)HanhahnaH1 小时前
Outbox 投递器:事务性发件箱模式详解新时代牛马2 小时前
epoll 源码路径:从epoll_ctl 到ep_poll 的就绪唤醒
选择好PGSQL的版本,已经Linux的发行版本
拿到命令,麻也不管,直接扔到Linux中运行即可 # 下载PGSQL的rpm包 sudo yum install -y
上图可以看到,postgreSQL的核心文件,都属于postgres用户,操作的时候,尽可能的别用root用户,容易玩出坑,尽可能先切换到postgres用户去玩。#### 4.1 远程连接配置PostgreSQL默认情况下不支持远程连接的,这个跟MySQL几乎一样* MySQL给mysql.user追加用户,一般是采用grant的命令去玩。* PostgreSQL要基于配置文件修改,才能制定用户是否可以远程连接。直接去修改pg_hba.conf配置文件用户以及对应数据库和连接方式的编写模板
# 第一块 local:代表本地连接,host代表可以指定连接的ADDRESS # 第二块 database编写数据库名,如果写all,代表所有库都可以连接 # 第三块 user编写连接的用户,可以写all,代表所有用户 # 第四块 address代表那些IP地址可以连接 # 第五块 method加密方式,这块不用过多关注,直接md5 # 直接来个痛快的配置吗,允许任意地址的全部用户连接所有数据库 host all all 0.0.0.0/0 md5
为了实现远程连接,除了用户级别的这种配置,还要针对服务级别修改一个配置服务级别的配置在postgresql.conf
发现默认情况下,PGSQL只允许localhost连接,直接配置为*即可解决问题
记得,为了生效,一定要重启 # postgres密码不管,直接root用户 sudo systemctl restart postgresql-12 #### 4.2 配置数据库的日志查看postgresql.conf文件
postgreSQL默认情况下,只保存7天的日志,循环覆盖。 # 代表日志是开启的。 logging_collector = on # 日志存放的路径,默认放到当前目录下的log里 log_directory = 'log' # 日志的文件名,默认是postgresql为前缀,星期作为后缀 log_filename = 'postgresql-%a.log' # 默认一周过后,日志文件会被覆盖 log_truncate_on_rotation = on # 一天一个日志文件 log_rotation_age = 1d # 一个日志文件,没有大小限制 log_rotation_size = 0 ### 五、PostgreSQL的基操只在psql命令行(客户端)下,执行了一次l,查看了所有的库信息可以直接基于psql查看一些信息,也可以基于psql进入到命令行后,再做具体操作
可以直接基于psql去玩 可以数据psql --help,查看psql的命令 可以直接进入到命令行的原因,是psql默认情况下,就是以postgres用户去连接本地的pgsql,所以可以直接进入 下面的图是默认的连接方式
后面都基于psql的命令行(客户端)去进行操作命令绝对不要去背,需要使用的时候,直接找帮助文档,在psql命令行中,直接注入 help,即可查看到数据库级别的一些命令 ?,可以查看到服务级别的一些命令 #### 5.1 用户操作构建用户命令巨简单 # 区别就是create user默认有连接权限,create role没有,不过可以基于选项去设置 CREATE USER 名称
退出psql命令行
编写psql命令尝试去用root用户登录 psql -h 192.168.11.32 -p 5432 -U root -W 发现,光有用户不让登录,得让用户有一个数据库,直接构建一个root库 create database root;
可以在不退出psql的前提下,直接切换数据库
也可以退出psql,重新基于psql命令去切换用户以及数据库如果要修改用户信息,或者删除用户,可以查看 # 修改用户,直接基于ALTER命令操作 # 删除用户,直接基于DROP命令操作 如果要查看现在的全部用户信息
#### 5.2 权限操作权限操作前,要先掌握一下PGSQL的逻辑结构逻辑结构图
可以看到PGSQL一个数据库中有多个schema,在每个schema下都有自己的相应的库表信息,权限粒度会比MySQL更细一些。在PGSQL中,权限的管理分为很多多层> server、cluster、tablespace级别:这个级别一般是基于pg_hba.conf去配置> > database级别:通过命令级别操作,grant> > namespace、schema级别:玩的不多......不去多了解这个~~> > 对象级别:通过grant命令去设置后面如果需要对database或者是对象级别做权限控制,直接基于grant命令去操作即可 # 查看grant命令 help grant #### 小任务构建一个用户(你自己名字)构建一个数据库在这个数据库下构建一个schema(数据库默认有一个public的schema)将这个schema的权限赋予用户在这个schema下构建一个表将表的select,update,insert权限赋予用户#### 完成上述操作 -- 准备用户 create user laozheng with password 'laozheng'; -- 准备数据库 create database laozheng; -- 切换数据库 c laozheng; -- 构建schema create schema laozheng; -- 将schema的拥有者修改为laozheng用户 alter schema laozheng owner to laozheng; -- 将laozheng库下的laozheng的schema中的表的增,改,查权限赋予给laozheng用户 grant select,insert,update on all tables in schema laozheng to laozheng; -- 用postgres用户先构建一张表 create table laozheng.test(id int); -- 切换到laozheng用户。 c laozheng -laozheng -- 报错: -- 致命错误: 对用户"-laozheng"的对等认证失败 -- Previous connection kept -- 上述方式直接凉凉,原因是匹配连接方式时,基于pg_hba.conf文件去从上往下找 -- 找到的第一个是local,匹配上的。发现连接方式是peer。 -- peer代表用当前系统用户去连接PostgreSQL -- 当前系统用户只有postgres,没有laozheng,无法使用peer连接 -- 想构建laozheng用户时,发现postgreSQL的所有文件拥有者和所属组都是postgres,并且能操作的只有拥有者
-- 基于上述问题,不采用本地连接即可。 -- 采用远程连接。 psql -h 192.168.11.32 -p 5432 -U laozheng -W -- 这样依赖,跳过了local链接方式的匹配,直接锁定到后面的host,host的连接方式是md5,md5其实就是密码加密了。 -- 登录后,直接输入 dn -- 查看到当前database下有两个schema
这种权限的赋予方式,可以用管理员用户去构建整体表结构,如此一来,分配指定用户,赋予不同的权限,这样一来,就不怕用户误操了。### 六、图形化界面安装图形化界面可以连接PGSQL的很多,Navicat(收费)。也可以直接使用PostgreSQL官方提供的图形化界面。(完全免费)官方提供的:
#### 8.8 IP类型PGSQL支持IP类型的存储,支持IPv4,IPv6这种,甚至Mac内种诡异类型也支持这种IP类型,可以在存储IP时,帮助做校验,其次也可以针对IP做范围查找。IP校验的效果
IP也支持范围查找。
#### 8.9 JSON&JSONB类型JSON在MySQL8.x中也做了支持,但是MySQL支持的不好,因为JSON类型做查询时,基本无法给JSON字段做索引。PGSQL支持JSON类型以及JSONB类型。JSON和JSONB的使用基本没区别。撇去JSON类型,本质上JSON格式就是一个字符串,比如MySQL5.7不支持JSON的情况的下,使用text也可以,但是字符串类型无法校验JSON的格式,其次单独的字符串没有办法只获取JSON中某个key对应的value。JSON和JSONB的区别:* JSON类型无法构建索引,JSONB类型可以创建索引。* JSON类型的数据中多余的空格会被存储下来。JSONB会自动取消多余的空格。* JSON类型甚至可以存储重复的key,以最后一个为准。JSONB不会保留多余的重复key(保留最后一个)。* JSON会保留存储时key的顺序,JSONB不会保留原有顺序。JSON中key对应的value的数据类型JSONPGSQLStringtextnumbernumericbooleanbooleannull(none)
select '{"name": "张三","age": 23,"birthday": "2011-11-11","gender": null}'::json; select '{"name": "张三","age": 23,"birthday": "2011-11-11","gender": null}'::jsonb; * 构建表存储JSON create table test( id bigserial, info json, infob jsonb ); insert into test (info,infob) values ('{"name": "张三" ,"age": 23,"birthday": "2011-11-11","gender": null}', '{"name": "张三" ,"age": 23,"birthday": "2011-11-11","gender": null}') select * from test; * 构建索引的效果
create index json_index on test(info); create index jsonb_index on test(infob); JSON还支持很多函数。可以直接查看
CREATE
这个位置是在$PG_DATA后的存放地址 P G D A T A = = / v a r / l i b / p g s q l / 12 / d a t a / 41000 其实就是存储数据的物理文件 ∗ ∗ ∗ 构建表空间,指定数据存放位置 !
#### 9.4 视图跟MySQL的没啥区别,把一些复杂的操作封装起来,还可以隐藏一些敏感数据。视图对于用户来说,就是一张真实的表,可以直接基于视图查询一张或者多张表的信息。视图对于开发来说,就是一条SQL语句。
在PGSQL中,简单(单表)的视图是允许写操作的。但是强烈不推荐对视图进行写操作,虽然PGSQL默认允许(简单的视图)。写入的时候,其实修改的是表本身 -- 构建一个简单视图 create view vw_score as (select id,math_score from score); select * from vw_score; update vw_score set math_score = 99 where id = 2; 多表视图 -- 复杂视图(两张表关联) create view vw_student_score as (select
#### 9.5 索引##### 9.5.1 索引的基本概念先了解概念和使用索引是数据库中快速查询数据的方法。索引能提升查询效率的同时,也会带来一些问题* 增加了存储空间* 写操作时,花费的时间比较多索引可以提升效率,甚至还可以给字段做一些约束##### 9.5.2 索引的分类B-Tree索引:最常用的索引。Hash索引:跟MySQL类似,做等值判断,范围凉凉~GIN索引:针对字段的多个值的类型,比如数组类型。##### 9.5.3 创建索引看效果
准备大量测试数据,方便查看索引效果 -- 测试索引效果 create table tb_index( id bigserial primary key, name varchar(64), phone varchar(64)\[\] ); -- 添加300W条数据测试效果 do d e c l a r e i i n t : = 0 ; b e g i n w h i l e i < 3000000 l o o p i = i + 1 ; i n s e r t i n t o t b i n d e x ( n a m e , p h o n e ) v a l u e s ( m d 5 ( r a n d o m ( ) : : t e x t ∣ ∣ c u r r e n t t i m e s t a m p : : t e x t ) : : u u i d , a r r a y
干活! -- 构建物化视图 create materialized view mv_test as (select id,name,price from test); -- 操作物化视图和操作表的方式没啥区别。 select * from mv_test; -- 操作原表时,对物化视图没任何影响 insert into test values (4,'月饼',50,10); -- 物化视图的添加操作(不允许写物化视图),会报错 insert into mv_test values (5,'大阅兵',66); 物化视图如何从原表中进行同步操作。PostgreSQL中,对物化视图的同步,提供了两种方式,一种是全量更新,另一种是增量更新。全量更新语法,没什么限制,直接执行,全量更新 -- 查询原来物化视图的数据 select * from mv_test; -- 全量更新物化视图 refresh materialized view mv_test; -- 再次查询物化视图的数据 select * from mv_test; 增量更新,增量更新需要一个唯一标识,来判断哪些是增量,同时也会有行数据的版本号约束。 -- 查询原来物化视图的数据 select * from mv_test; -- 增量更新物化视图,因为物化视图没有唯一索引,无法判断出哪些是增量数据 refresh materialized view concurrently mv_test; -- 给物化视图添加唯一索引。 create unique index index_mv_test on mv_test(id); -- 增量更新物化视图 refresh materialized view concurrently mv_test; -- 再次查询物化视图的数据 select * from mv_test; -- 增量更新时,即便是修改数据,物化视图的同步,也会根据一个xmin和xmax的字段做正常的数据同步 update test set name = '汤圆' where id = 5; insert into test values (5,'猪头肉',99,40); select * from test; ### 十、事务#### 10.1 什么是ACID?(常识)在日常操作中,对于一组相关操作,通常要求要么都成功,要么都失败。在关系型数据库中,称这一组操作为事务。为了保证整体事务的安全性,有ACID这一说: 原子性A:事务是一个最小的执行单位,一次事务中的操作要么都成功,要么都失败。* 一致性C:在事务完成时,所有数据必须保持在一致的状态。(事务完成后吗,最终结果和预期结果是一致的)* 隔离性:一次事务操作,要么是其他事务操作前的状态,要么是其他事务操作后的状态,不存在中间状态。* 持久性:事务提交后,数据会落到本地磁盘,修改是永久性的。PostgreSQL中,在事务的并发问题里,也是基于MVCC,多版本并发控制去维护数据的一致性。相比于传统的锁操作,MVCC最大的有点就是可以让 读写互相不冲突 。当然,PostgreSQL也支持表锁和行锁,可以解决写写的冲突问题。PostgreSQL相比于其他数据,有一个比较大的优化,DDL也可以包含在一个事务中。比如集群中的操作,一个事务可以保证多个节点都构建出一个表,才算成功。#### 10.2 事务的基本使用首先基于前面的各种操作,应该已经体会到了,PostgreSQL是自动提交事务。跟MySQL是一样的。可以基于关闭PostgreSQL的自动提交事务来进行操作。
但是上述方式比较麻烦,传统的方式。就是三个命令:* begin:开始事务 * commit:提交事务 * rollback:回滚事务 -- 开启事务 begin; -- 操作 insert into test values (7,'bbb',12,5); -- 提交事务 commit; #### 10.3 保存点(了解)比如项目中有一个大事务操作,不好控制,超时有影响,回滚会造成一切重来,成本太高。我针对大事务,拆分成几个部分,第一部分完成后,构建一个保存点。如果后面操作失败了,需要回滚,不需要全盘回滚,回滚到之前的保存点,继续重试。有人会发现,破坏了整体事务的原子性。But,只要操作合理,可以在保存点的举出上,做重试,只要重试不成功,依然可以全盘回滚。比如一个电商项目,下订单,扣库存,创建订单,删除购物车,增加用户积分,通知商家............。这个其实就是一个大事务。可以将扣库存和下订单这种核心功能完成后,增加一个保存点,如果说后续操作有失败的,可以从创建订单成功后的阶段,再做重试。不过其实上述的业务,基于最终一致性有更好的处理方式,可以保证可用性。简单操作一下。 -- savepoint操作 -- 开启事务 begin; -- 插入一条数据 insert into test values (8,'铃铛',55,11); -- 添加一个保存点 savepoint ok1; -- 再插入数据,比如出了一场 insert into test values (9,'大唐官府',66,22); -- 回滚到之前的提交点 rollback to savepoint ok1; -- 就可以开始重试操作,重试成功,commit,失败可以rollback; commit; ### 十一、并发问题#### 11.1 事务的隔离级别在不考虑隔离性的前提下,事务的并发可能会出现的问题:* 脏读:读到了其他事务未提交的数据。(必须避免这种情况)* 不可重复读:同一事务中,多次查询同一数据,结果不一致,因为其他事务修改造成的。(一些业务中这种不可重复读不是问题)* 幻读:同一事务中,多次查询同一数据,因为其他事务对数据进行了增删吗,导致出现了一些问题。(一些业务中这种幻读不是问题)针对这些并发问题,关系型数据库有一些事务的隔离级别,一般用4种。* READ UNCOMMITTED:读未提交(啥用没用,并且PGSQL没有,提供了只是为了完整性)* READ COMMITTED:读已提交,可以解决脏读(PGSQL默认隔离级别)* REPEATABLE READ:可重复读,可以解决脏读和不可重复读(MySQL默认是这个隔离级别,PGSQL也提供了,但是设置为可重复读,效果还是串行化)* SERIALIZABLE:串行化,啥都能解决(锁,效率慢)PGSQL在老版本中,只有两个隔离级别,读已提交和串行化。在PGSQL中就不存在脏读问题。#### 11.2 MVCC首先要清楚,为啥要有MVCC。如果一个数据库,频繁的进行读写操作,为了保证安全,采用锁的机制。但是如果采用锁机制,如果一些事务在写数据,另外一个事务就无法读数据。会造成读写之间相互阻塞。 大多数的数据库都会采用一个机制 多版本并发控制 MVCC 来解决这个问题。比如你要查询一行数据,但是这行数据正在被修改,事务还没提交,如果此时对这行数据加锁,会导致其他的读操作阻塞,需要等待。如果采用PostgreSQL,他的内部会针对这一行数据保存多个版本,如果数据正在被写入,包就保存之前的数据版本。让读操作去查询之前的版本,不需要阻塞。等写操作的事务提交了,读操作才能查看到最新的数据。 这几个及时可以确保 读写操作没有冲突 ,这个就是MVCC的主要特点。写写操作,和MVCC没关系,那个就是加锁的方式!Ps:这里的MVCC是基于 读已提交 去聊的,如果是串行化,那就读不到了。在操作之前,先了解一下PGSQL中,每张表都会自带两个字段 xmin:给当前事务分配的数据版本。如果有其他事务做了写操作,并且提交事务了,就给xmin分配新的版本。 xmax:当前事务没有存在新版本,xmax就是0。如果有其他事务做了写操作,未提交事务,将写操作的版本放到xmax中。提交事务后,xmax会分配到xmin中,然后xmax归0。
基于上图的操作查看一波效果事务A -- 左,事务A --1、开启事务 begin; --2、查询某一行数据, xmin = 630,xmax = 0 select xmin,xmax, from test where id = 8; --3、每次开启事务后,会分配一个事务ID 事务id=631 select txid_current(); --7、修改id为8的数据,然后在本事务中查询 xmin = 631, xmax = 0 update test set name = '铃铛' where id = 8; select xmin,xmax, from test where id = 8; --9、提交事务 commit; 事务B -- 右,事务B --4、开启事务 begin; --5、查询某一行数据, xmin = 630,xmax = 0 select xmin,xmax, from test where id = 8; --6、每次开启事务后,会分配一个事务ID 事务id=632 select txid_current(); --8、事务A修改完,事务B再查询 xmin = 630 xmax = 631 select xmin,xmax, from test where id = 8; --10、事务A提交后,事务B再查询 xmin = 631 xmax = 0 select xmin,xmax, from test where id = 8; ### 十二、锁PostgreSQL中主要有两种锁,一个表锁一个行锁PostgreSQL中也提供了页锁,咨询锁,But,这个不需要关注,他是为了锁的完整性#### 12.1 表锁表锁显而易见,就是锁住整张表。表锁也分为很多中模式。表锁的模式很多,其中最核心的两个: ACCESS SHARE:共享锁(读锁),读读操作不阻塞,但是不允许出现写操作并行* ACCESS EXCLUSIVE:互斥锁(写锁),无论什么操作进来,都阻塞。具体的可以查看官网文档:
这些就是归档日志> wal日志的名称,是三块内容组成,> > 没8个字符分成一组,用16进制标识的> > 00000001 00000000 0000000A> > 时间线 逻辑id 物理id查询当前库用的是哪个wal日志 -- 查看当前使用的wal日志 查询到的lsn:0/47233270 select pg_current_wal_lsn(); -- 基于lsn查询具体的wal日志名称 000000010000000000000047 select pg_walfile_name('0/47233270'); 归档默认不是开启的,需要手动开启归档操作,才能保证wal日志的完整性修改postgresql.conf文件 # 开启wal日志的内容,注释去掉即可 wal_level = replica fsync = on
# 开启归档操作 archive_mode = on # 修改一小下命令,修改存放归档日志的路径 archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'
修改完上述配置文件后,记得重启postgreSQL进程,才会生效!!!!归档操作执行时,需要保证/archive存在,并且postgres用户有权限进行w操作构建/archive路径 # postgres没有权限在/目录下构建目录 # 切换到root,构建目录,将目录的拥有者更改为postgres mkdir /archive chown -R postgres. archive 在当前库中做大量写操作,接入到wal日志,重置切换wal日志,再查看归档情况发现,将当前的正在使用的wal日志和最新的上一个wal日志归档过来了,但是之前的没归档,不要慌,后期备份时,会执行命令,这个命令会直接要求wal日志立即归档,然后最全量备份。#### 13.1 逻辑备份&恢复PostgreSQL提供了pg_dump以及pg_dumpall的命令来实现逻辑备份。这两命令差不多,看名字猜!pg_dump这种备份,不会造成用户对数据的操作出现阻塞。数据库不是很大的时候,pg_dump也不是不成!查看一波命令:
这个命令从三块去看:
删除当前laozheng库中的表等信息,然后恢复数据
* 除此之外,也可以通过图形化界面备份,在库的位置点击备份就成,导出一个文本文件。#### 13.2 物理备份(归档+物理)这里需要基于前面的文件系统的备份和归档备份实现最终的操作单独使用文件系统的方式,不推荐毕竟数据会丢失。这里直接上PostgreSQL提供的pg_basebackup命令来实现。pg_basebackup会做两个事情、 会将内存中的脏数据落到磁盘中,然后将数据全部备份 会将wal日志直接做归档,然后将归档也备走。查看一波pg_basebackup命令
先准备一个pg_basebackup的备份命令 # -D 指定备份文件的存储位置 # -Ft 备份文件打个包 # -Pv 输出备份的详细信息 # -U 用户名(要拥有备份的权限) # -h ip地址 -p 端口号 # -R 复制写配置文件 pg_basebackup -D /pg_basebackup -Ft -Pv -Upostgres -h 192.168.11.32 -p 5432 -R 准备测试,走你~ 提前准备出/pg_basebackup目录。记得将拥有者赋予postgres用户 mkdir /pg_basebackup chown -R postgres. /pg_basebackup/ * 给postgres用户提供replication的权限,修改pg_hba.conf,记得重启生效
* 执行备份 pg_basebackup -D /pg_basebackup -Ft -Pv -Upostgres -h 192.168.11.32 -p 5432 -R * 需要输入postgres的密码,这里可以设置,重新备份。
* 执行备份
#### 13.3 物理恢复(归档+物理)模拟数据库崩盘,先停止postgresql服务,然后直接删掉data目录下的全部内容
将之前备份的两个文件准备好,一个base.tar,一个pg_wal.tar第一步:将base.tar中的内容,全部解压到 12/data 目录下第二步:将pg_wal.tar中的内容,全部解压到 /archive 目录下
第三步:在postgresql.auto.conf文件中,指定归档文件的存储位置,以及恢复数据的方式
第四步:启动postgresql服务 systemctl start postgresql-12 第五步:启动后,发现查询没问题,但是执行写操作时,出错,不让写。需要执行一个函数,取消这种恢复数据后的状态,才允许正常的执行写操作。 select pg_wal_replay_resume(); #### 13.4 物理备份&恢复(PITR-Point in time Recovery)##### 模拟场景> 场景:每天凌晨02:00,开始做全备(PBK),到了第二天,如果有人14:00分将数据做了误删,希望将数据恢复到14:00分误删之前的状态?1、恢复全备数据,使用PBK的全备数据恢复到凌晨02:00的数据。(数据会丢失很多)2、归档恢复:备份中的归档,有02:00~14:00之间的额数据信息,可以基于归档日志将数据恢复到指定的事务id或者是指定时间点,从而实现数据的完整恢复。##### 准备场景和具体操作1、构建一张t3表查询一些数据 -- 构建一张表 create table t3 (id int); insert into t3 values (1); insert into t3 values (11); 2、模拟凌晨2点开始做全备操作 pg_basebackup -D /pg_basebackup -Ft -Pv -Upostgres -h 192.168.11.32 -p 5432 -R 3、再次做一些写操作,然后误删数据 -- 凌晨2点已经全备完毕 -- 模拟第二天操作 insert into t3 values (111); insert into t3 values (1111); -- 误删操作 2023年3月20日20:13:26 delete from t3; 4、恢复数据(确认有归档日志)将当前服务的数据全部干掉,按照之前的全备恢复的套路先走着
然后将全备的内容中的base.tar扔data目录下,归档日志也扔到/archive位置。5、查看归档日志,找到指定的事务id查看归档日志,需要基于postgresql提供的一个命令 # 如果命令未找到,说明两种情况,要么没有这个可执行文件,要么是文件在,没设置环境变量 # 咱们这是后者 pg_waldump # 也可以采用全路径的方式 /usr/pgsql-12/bin/pg_waldump 
6、修改data目录下的恢复数据的方式修改postgresql.auto.conf文件将之前的最大恢复,更换为指定的事务id恢复基于提供的配置例子,如何指定事务id
修改postgresql.auto.conf文件指定好事务ID
7、启动postgreSQL服务,查看是否恢复到指定事务ID
8、记得执行会后的函数,避免无法执行写操作 select pg_wal_replay_resume(); ### 十四、数据迁移PostgreSQL做数据迁移的插件非常多,可以从MySQL迁移到PostgreSQL也可以基于其他数据源迁移到PostgreSQL这种迁移的插件很多,这里只说一个,pgloader(巨方便)以MySQL数据迁移到PostgreSQL为例,分为几个操作:1、准备MySQL服务(防火墙问题,远程连接问题,权限问题)准备了一个sms_platform的库,里面大概有26W条左右的数据2、准备PostgreSQL的服务(使用当前一直玩的PostgreSQL)3、安装pgloaderpgloader可以安装在任何位置,比如安装在MySQL所在服务,或者PostgreSQL所在服务,再或者一个独立的服务都可以我就在PostgreSQL所在服务安装 # 用root用户下载 yum -y install pgloader 4、准备pgloader需要的脚本文件官方文档:
5、执行脚本,完成数据迁移先确认pgloader命令可以使用
执行脚本: pgloader 刚刚写好的脚本文件
### 十五、主从操作PostgreSQL自身只支持简单的主从,没有主从自动切换,仿照类似Nginx的效果一样,采用keepalived的形式,在主节点宕机后,通过脚本的执行完成主从切换。#### 15.1 主从实现(异步流复制)操作方式类似与之前的备份和恢复##### 1、准备环境:角色IP端口Master192.168.11.665432Standby192.168.11.675432准备两台虚拟机,完成上述的环境准备修改好ip,安装好postgresql服务##### 2、给主准备一些数据 create table t1 (id int); insert into t1 values (111); select * from t1; ##### 3、配置主节点信息(主从都配置,因为后面会有主从切换的操作)修改 pg_hba.conf 文件
修改 postgresql.conf 文件
提前构建好归档日志和备份目录,并且设置好拥有者
重启PostgreSQL服务 systemctl restart postgresql-12 ##### 4、从节点加入到主节点关闭从节点服务 systemctl stop postgresql-12 删除从节点数据(删除data目录) rm -rf ~/12/data/ 基于pbk去主节点备份数据 # 确认好备份的路径,还有主节点的ip pg_basebackup -D /pgbasebackup -Ft -Pv -Upostgres -h 192.168.11.66 -p 5432 -R 恢复数据操作,解压tar包 cd /pgbasebackuo tar -xf base.tar -C ~/12/data tar -xf pg_wal.tar -C /archive 修改postgresql.auto.conf文件 # 确认有这两个配置,一般第一个需要手写,第二个会自动生成 restore_command = 'cp /archive/%f %p' primary_conninfo = 'user=postgres password=postgres host=192.168.11.66 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any' 修改standby.signal文件,开启从节点备份模式 # 开启从节点备份 standby_mode = 'on' 启动从节点服务 systemctl restart postgresql-12 查看主从信息* 查看从节点是否有t1表 * 主节点添加一行数据,从节点再查询,可以看到最新的数据 * 从节点无法完成写操作,他是只读模式 * 主节点查看从节点信息 select * from pg_stat_replication * 从节点查看主节点信息 select * from pg_stat_wal_receiver #### 15.2 主从切换(不这么玩)其实主从的本质就是从节点去主节点不停的备份新的数据。配置文件的系统其实就是两个:* standby.signal文件,这个是从节点开启备份* postgresql.auto.conf文件,这个从节点指定主节点的地址信息切换就是原主追加上述配置,原从删除上述配追1、主从节点全部stop停止:..................2、原从删除上述配置:............3、原从新主启动服务:.........4、原主新从去原从新主备份一次数据:pg_basebackup操作,同时做解压,然后修改postgresql.conf文件以及standby.signal配置文件5、启动原主新从查看信息#### 15.3 主从故障切换默认情况下,这里的主从备份是异步的,导致一个问题,如果主节点写入的数据还没有备份到从节点,主节点忽然宕机了,导致后面如果基于上述方式实现主从切换,数据可能丢失。PGSQL在9.5版本后提供了一个pg_rewind的操作,基于归档日志帮咱们做一个比对,比对归档日志,是否有时间差冲突。实现操作:1、rewind需要开启一项配置才可以使用修改postgresql.conf中的 **wal_log_hints = 'on'2、为了可以更方便的使用rewind,需要设置一下 /usr/pgsql-12/bin/ 的环境变量 vi /etc/profile 追加信息 export PATH=/usr/pgsql-12/bin/:KaTeX parse error: Expected 'EOF', got '#' at position 63: ...4、从节点切换为主节点 #̲ 因为他会去找PGDATA,我没配置,就基于-D指定一下PGSQL的data目录 pg_ctl promote -D ~/12/data/ 5、将原主节点开机,执行命令,搞定归档日志的同步 启动虚拟机 * 停止PGSQL服务 pg_ctl stop -D ~/12/data * 基于pg_rewind加入到集群 pg_rewind -D ~/12/data/ --source-server='host=192.168.11.66 user=postgres password=postgres' * 如果上述命令失败,需要启动再关闭PGSQL,并且在执行,完成归档日志的同步 pg_ctl start -D ~/12/data pg_ctl stop -D ~/12/data pg_rewind -D ~/12/data/ --source-server='host=192.168.11.66 user=postgres password=postgres' 6、修改新从节点的配置,然后启动 构建standby.signal standby_mode = 'on' * 修改postgresql.auto.conf文件 # 注意ip地址 primary_conninfo = 'user=postgres password=postgres host=192.168.11.66 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any' restore_command = 'cp /archive/%f %p' * 启动新的从节点 pg_ctl start -D ~/12/data/