POSTGRESQL 远程链接的乌龙

安装了Postgresql 后,在 pg_hba.conf 中新增了远程链接的IP,远程链接依然抛出 “no pg_hba.conf entry for host “xxx.xx.xxx.xx”, user “xxx”, database “xxx”, SSL off”的错误信息,客户端无法链接

1、检查 postgresql.conflisten_addresses ,已经修改成 listen_addresses = ‘*’

2、检查防火墙,已关闭

但是错误信息依然存在,很是郁闷…

折腾了几个小时后,问题依然存在…到了晚上9点多,遗憾的关闭了电脑

第二天早上,在检查Postgresql的安装环境,顿悟,原来我安装Postgresql的过程中将 data 的文件路径设置在另外一个文件夹下了,而我一直修改的是Postgresql原生bin目录下的 pg_hba.conf ,此时,心中一万头新物种在狂奔!!!

PostgreSQL-获取日期时间、截取年、月、日

未分类

一、获取系统时间函数

1.1 获取当前完整时间

select now();

未分类

select current_timestamp;      --也是一样的效果

1.2 获取当前日期

select current_date;

未分类

1.3 获取当前时间

select current_time;

未分类

时间字段的截取

取年份

select extract(year from now());

未分类

取月份

select extract(month from now());

未分类

取给定的时间的日期

select extract(day from timestamp '2013-04-13');

未分类

postgresql 导入sql,out等sql文件

假设postgresql安装位置

未分类

然后,使用dos窗口
进入这个位置

未分类

导入(本地和默认端口可以不用属性)

psql -d 数据库名 -h ip地址 -p 数据库端口 -U 用户名 -f 文件地址

未分类

完成

未分类

知识只有共享才能传播,才能推崇出新的知识,才能学到更多,这里写的每一篇文字/博客,基本都是从网上查询了一下资料然后记录下来,也有些是原滋原味搬了过来,也有时加了一些自己的想法

PostgreSQL常用操作命令整理

使用yum安装PostgreSQL:

安装PostgreSQL客户端

yum install postgresql-client -y

安装PostgreSQL服务端:

yum install postgresql -y

安装完成后,PostgreSQL服务器会自动在本机的5432端口开启。
安装图形管理界面(可选)

yum install pgadmin3 -y

启动服务

service postgresql start

安装参考:https://www.aliang.org/PostgreSQL/centos7-4-install-postgresql10-1.html

进入控制台

psql -U dbuser -d exampledb -h 127.0.0.1 -p 5432

退出

postgres=# q

创建用户

CREATE USER youusername WITH PASSWORD 'youpassword';

创建数据库并赋予用户

postgres=# CREATE DATABASE youdbname OWNER youusername;
postgres=# GRANT ALL PRIVILEGES ON DATABASE youdbname to youusername;
postgres=# c youdbname;
postgres=# ALTER SCHEMA public OWNER to dbuser;
postgres=# GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO youusername;
postgres=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO youusername;

查看所有用户

postgres=# du

更改密码

postgres=# password youusername

删除用户

postgres=# drop user youusername ;

查看所有库

postgres=# l

切换数据库

postgres=# c exampledb

常用控制台命令

password           设置密码。
q                  退出。
h                  查看SQL命令的解释,比如h select。
?                  查看psql命令列表。
l                  列出所有数据库。
c [database_name]  连接其他数据库。
d                  列出当前数据库的所有表格。
d [table_name]     列出某一张表格的结构。
du                 列出所有用户。
e                  打开文本编辑器。
conninfo           列出当前数据库和连接的信息。

基本的 SQL 语句

# 创建新表
CREATE TABLE user_tbl(name VARCHAR(20), signup_date DATE);

# 插入数据
INSERT INTO user_tbl(name, signup_date) VALUES('张三', '2013-12-22');

# 查询记录
SELECT * FROM user_tbl;

# 更新数据
UPDATE user_tbl set name = '李四' WHERE name = '张三';

# 删除记录
DELETE FROM user_tbl WHERE name = '李四' ;

# 添加字段
ALTER TABLE user_tbl ADD email VARCHAR(40);

# 更改字段类型
ALTER TABLE user_tbl ALTER COLUMN signup_date SET NOT NULL;

# 设置字段默认值(注意字符串使用单引号)
ALTER TABLE user_tbl ALTER COLUMN email SET DEFAULT '[email protected]';

# 去除字段默认值
ALTER TABLE user_tbl ALTER email DROP DEFAULT;

# 重命名字段
ALTER TABLE user_tbl RENAME COLUMN signup_date TO signup;

# 删除字段
ALTER TABLE user_tbl DROP COLUMN email;

# 表重命名
ALTER TABLE user_tbl RENAME TO backup_tbl;

# 删除表
DROP TABLE IF EXISTS backup_tbl;

# 删除库
c hello2;
DROP DATABASE IF EXISTS hello;

PostgreSQL获取table名,字段名

PostgreSQL获取数据库中所有table名:

SELECT   tablename   FROM   pg_tables  
WHERE   tablename   NOT   LIKE   'pg%'  
AND tablename NOT LIKE 'sql_%'
ORDER   BY   tablename;

PostgreSQL获取数据库中所有table名及table的注解信息:

SELECT   tablename,obj_description(relfilenode,'pg_class')  FROM   pg_tables  a, pg_class b
WHERE   
a.tablename = b.relname
and a.tablename   NOT   LIKE   'pg%'  
AND a.tablename NOT LIKE 'sql_%'
ORDER   BY   a.tablename;

PostgreSQL获取指定table的所有字段信息:

SELECT col_description(a.attrelid,a.attnum) as comment,format_type(a.atttypid,a.atttypmod) as type,a.attname as name, a.attnotnull as notnull
FROM pg_class as c,pg_attribute as a
where c.relname = 'tablename' and a.attrelid = c.oid and a.attnum>0

记PostgreSQL的连接问题

今天打开psql的时候出现这个错误

psql: could not connect to server: Connection refused (0x0000274D/10061)
Is the server running on host “localhost” (::1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused (0x0000274D/10061)
Is the server running on host “localhost” (127.0.0.1) and accepting
TCP/IP connections on port 5432?

解决如下

这个问题一般是以下原因造成的:

1.服务器没起来,ps -ef|grep postgres查看是否存在PG进程
2.监听问题,cat postgresql.conf|grep listen 查看监听地址端口是否正确
3.服务端超级用户能进去,其他用户不行,检查是否超出最大连接数限制
4.以上都没问题,服务器端能连进去,但客户端不行,这时需要查看pg_hba.conf文件
5.以上都没问题,检查服务器端的iptables,开启防火墙的访问端口

最后发现端口不是默认的5432,修改即可。

PostgreSQL 主从设置

主库设置

先添加repuser用户

然后设置pg_hba

vi /var/lib/pgsql/10/data/pg_hba.config

未分类

从库设置

把原有数据全删了

rm -rf /var/lib/pgsql/10/data/

然后执行 pg_basebackup -h IP_ADDRESS -R -D /var/lib/pgsql/10/data -U repuser -W

然后运行pgsql

service postgresql-10 start

linux系统中编译安装postgresql

以postgresql-9.6.2为例

# wget https://ftp.postgresql.org/pub/source/v9.6.2/postgresql-9.6.2.tar.gz
# tar zxvf postgresql-9.6.2.tar.gz
# cd postgresql-9.6.2
# ./configure --prefix=/usr/local/postgresql
# make 
# make install

给postgresql添加用户 (因为创建database cluster时不能用root帐号)

# useradd postgres 
# passwd postgres

建立database cluster目标文件夹

# mkdir -p /mnt/data/pgsql 
# chown -R postgres /mnt/data/pgsql

环境变量设置

# su - postgres  //切换到postgres用户
$ vi .bash_profile

在末尾添加如下内容

# postgres 
PGDATA=/mnt/data/pgsql 
PATH=/usr/local/pgsql/bin:$PATH 
export PGDATA PATH

使环境变量生效

$ source .bash_profile

初始化数据库

pg_ctl initdb

启动数据库实例

$pg_ctl -D /mnt/data/pgsql -l logfile start //设置好PGDATA环境变量后,可以不带-D选项

关闭数据库实例

$ pg_ctl stop

PostgreSQL两个库间迁移文件

用pg_dump但不产生中间文件,直接在2个数据库之间导数据。

本机执行从本地库导出数据到远程库

pg_dump -h 本地库IP -U postgres dbname | psql -h 目标库IP -U postgres dbname

本机执行从远程数据库导入数据到本地库

pg_dump -h 目标库IP -U postgres dbname | psql -h 本地库IP -U postgres dbname

PostgreSQL共享缓存区管理

一、共享缓冲区

KingbaseES中的buffer主要是用来将外存中的数据内容读入到内存中,加速运算过程中对数据的访问速度,同时将数据的修改进行缓存,在必要时再将其写出到外存,避免频繁的I/O,以提高效率。
Buffer的种类有很多如Audit buffers、Clog buffers、Data buffers和Xlog buffers,此处所介绍的buffer管理是针对Data buffers而言的。

二、数据结构

  • BufferTag
  • BufferDesc
  • BufferStrategyControl

1、BufferTag

typedef struct buftag
{
    Oid dbid;            /* database identifier */
    FileBlock blockNum;  /* file and blocknumber */
} BufferTag;

2、BufferDesc

typedef struct sbufdesc
{
    BufferTag   tag;              /* ID of page contained in buffer */
    RelFileNode rnode;            /* relation this block belongs to */
    BufFlags    flags;            /* see bit definitions above */
    uint16      usage_count;      /* usage counter for clock sweep code */
    unsigned    refcount;         /* # of backends holding pins on buffer */
    int         wait_backend_pid; /* backend PID of pin-count waiter */
    slock_t     buf_hdr_lock;     /* protects the above fields */
    int         buf_id;           /* buffer's index number (from 0) */
    int         freeNext;         /* link in freelist chain */
    LWLockId    io_in_progress_lock; /* to wait for I/O to complete */
    LWLockId    content_lock;     /* to lock access to buffer contents */
} BufferDesc;

3、引用计数(BufferDesc.refcount)

引用计数(refcount)用于跟踪访问buffer的后台数量,防止错误的将正在被使用的Buffer淘汰。当使用Buffer时,需要将其引用计数(refcount)加1(PinBuffer)。当Buffer不再使用,需要将其引用计数(refcount)减1(UnpinBuffer)。这里需要注意,由于一个后台可以多次访问同一个Buffer,因此后台通过PrivateRefCount来记录自己的引用次数,只有当自己对一个Buffer的引用减少到0,才会真正去修改refcount。PrivateRefCount在后台PinBuffer时将其值加1,UnpinBuffer时将其值减1。

4、使用计数(BufferDesc.usage_count)

usage_count用来标记Buffer被使用的次数,usage_count值越大,说明该Buffer经常被使用,那么在未来的一段时间里被使用的可能就比较大,所以这样的Buffer不能作为被替换的对象;相反,usage_count值越小,说明经常不被使用,可以作为替换的对象。在KingbaseES中,只有当usage_count为0时,才可能作为替换的对象。
usage_count是在一个后台不再使用该Buffer即UnpinBuffer将后台的PrivateRefCount减少为0的时候将其值加1,以表示该Buffer最近被一个后台使用了。对VACUUN操作来说,不会修改usage_count的值,且如果refcount和usage_count的值都为0,则将buffer放入到FreeList的尾部。

5、BufferStrategyControl

typedef struct
{
    int    nextVictimBuffer; // 指向下一Buffer
    int    firstFreeBuffer;  // 第一个空闲缓冲块id
    int    lastFreeBuffer;   // 最后一个空闲缓冲块id
} BufferStrategyControl;
/* Pointers to shared state */
static MT_LOCAL BufferStrategyControl
    *StrategyControl = NULL;

6、Buffer Descriptors

未分类

三、主要函数

  • InitBufferPool
  • BufferAlloc
  • StrategyGetBuffer
  • FlushBuffer
  • PinBuffer
  • UnpinBuffer

1、InitBufferPool流程

未分类

2、BufferAlloc流程

未分类

四、缓冲区替换策略

  • FreeList
  • Clock-sweep
  • buffer-ring

1、FreeList

当执行DROP TABLE时,可以确定该表的所有buffer都会失效,因此将此表的所有buffer都放入到Freelist的头部,这样可以在下一次分配buffer时,直接从Freelist中得到buffer,而不需要执行Clock Sweep算法。

2、Clock-sweep

当Buffer的refcount计数变成0的时候,代表当前系统没有后台引用此数据块。在KingbaseES中,为了能够减低锁的粒度、提高并发性,引用计数等于0的的Buffer并没有被放入Freelist中。在随机访问大量磁盘块、并且没有VACUUM的干扰下,Freelist几乎是空的(除了刚刚启动时)。这里的策略主要是为了避免不必要的持有操作Freelist的互斥锁。
由于大部分时候Buffer不会立即被放入到Freelist中,因此使用了一种被称为Clock Sweep的算法来分配Buffer。此算法类似教科书中时钟算法,每当需要使用Clock Sweep算法选择一个Buffer时,就从上次分配的Buffer的下一个位置开始,搜索引用计数为0(既没有被pin的Buffer)且usage_count为0的Buffer。如果该Buffer不满足上述条件,就将usage_count减1。

3、Clock-sweep

未分类

在上图中Clock Sweep算法从4号buffer开始查找(记录在StrategyControl结构体中)可用的buffer。4号buffer因为引用计数大于0,因此不能被替换。5号buffer虽然没有人引用,但是其usage_count大于0,因此表示此buffer使用频率较高,因此将usage_count减1,并查看6号buffer。6号buffer的引用计数和usage_count都为0,因此选择将6号buffer淘汰。记录下一次搜索的位置是7号,并退出选择算法。

4、buffer-ring

批量读或者vacuum等操作可能会需要占据大量的buffer,影响其他正常业务。buffer-ring机制在批量读等占用的buffer数量达到某个程度(比如总buffer的1/4)时,分配给该操作固定的buffer数量,之后只能使用为其分配的buffer,而不能替换其他buffer。