pg运维

PostgreSQL 日常运维

1.启停

postgres –D $PGDATA start

pg_ctl -D $PGDATA start

三种关机模式:

pg_ctl –D $PGDATA stop -m smart

不允许新连接,等待会话结束

pg_ctl –D $PGDATA stop –m fast (默认)

不允许新连接,等待子进程退出,终止备份

pg_ctl –D $PGDATA stop –m immediate

立即退出,下次启动需重放wal日志进行恢复

2.日常清理(VACUUM)

VACUUM;

语法结构; VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ] VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]

描述: VACUUM 回收已删除元组占据的存储空间。

在一般的 PostgreSQL 操作里, 那些已经 DELETE 的元组或者被 UPDATE 过后过时的元组是没有从它们所属的表中物理删除的; 在完成 VACUUM 之前它们仍然存在。 因此我们有必须周期地运行 VACUUM, 特别是在常更新的表上,如果没有参数,VACUUM 处理当前数据库里每个表, 如果有参数,VACUUM 只处理那个表,简单的 VACUUM (没有FULL) 只是简单地回收空间并且令其可以再次使用;

FULL ------选择"完全"清理,这样可以恢复更多的空间, 但是花的时间更多并且在表上施加了排它锁。

FREEZE ------选择激进的元组"冻结"。

VERBOSE ------为每个表打印一份详细的清理工作报告。

ANALYZE ------更新用于优化器的统计信息,以决定执行查询的最有效方法。

table ------要清理的表的名称(可以有模式修饰)。缺省时是当前数据库中的所有表。

column ------要分析的具体的列/字段名称。缺省是所有列/字段。

为什么要用VACUUM;

VACUUM命令的含义为:垃圾收集以及可选地分析一个数据库。VACUUM回收已删除元组占据的存储空间。 在一般的 PostgreSQL 操作里,那些已经 DELETE 的元组或者被 UPDATE 过后过时的元组是没有从它们所属的表中物理删除的; 在完成 VACUUM 之前它们仍然存在。

由于以下几个原因,我们必须周期性运行 PostgreSQL 的 VACUUM 命令∶

1.恢复那些由已更新的或已删除的行占据的磁盘空间。

2.更新 PostgreSQL 查询规划器使用的数据统计信息。

3.避免因为事务 ID 重叠造成的老旧数据的丢失。

对上面每个条件进行 VACUUM 操作的频率和范围因不同的节点而不同。

因此,数据库管理员必须理解这些问题并且开发出合适的维护策略。

建议经常VACUUM(清理)(至少每晚一次)生产数据库, 以保证不断地删除失效的行。尤其是在增删了大量记录之后, 对受影响的表执行 VACUUM ANALYZE 命令是一个很好的习惯。

例如: MH=> vacuum full verbose analyze r_data_main_test;

INFO: vacuuming "public.r_data_main_test"

INFO: "r_data_main_test": found 29230324 removable, 31473910 nonremovable row versions in 1076558 pages

DETAIL: 0 dead row versions cannot be removed yet. CPU 11.11s/35.82u sec elapsed 152.01 sec.

INFO: analyzing "public.r_data_main_test"

INFO: "r_data_main_test": scanned 30000 of 481500 pages, containing 1961024 live rows and 0 dead rows; 30000 rows in sample, 31473943 estimated total rows VACUUM Time: 311716.828 m

VACUUM 这样做将更新系统目录为最近的更改,并且允许 PostgreSQL 查询优化器在规划用户查询时有更好的选择。

不建议日常使用 FULL 选项,但是可以在特殊情况下使用。 一个例子就是在您删除了一个表的大部分行之后,希望从物理上缩小该表以减少磁盘空间占用。

VACUUM FULL 通常要比单纯的 VACUUM 收缩更多表的尺寸。

3. 更新数据库索引

用REINDEX命令周期的重建索引

4. 日志文件维护

把数据库服务器的日志输出保存在一个地方,而不是输出到syslog

5. 常用命令

<1> 查看数据库大小

select pg_database_size(''); 

<2> 索引的删除与重建

当数据库较大时,需要删除索引和约束,恢复完成后再重建

:::::生成删除索引语句

select 'drop index'|| b.indexname from pg_tables a,pg_indexes b where a.tablename=b.tablename and a.tableowner='';

:::::生成创建索引语句

select b.indexdef||';' from pg_tables a,pg_indexes b where a.tablename=b.tablename and a.tableowner='';

:::::生成删除主键语句

select 'alter table '||t.tablename||' drop CONSTRAINT '||i.indexname||';' from  pg_indexes i ,pg_tables t 
where i.schemaname=t.schemaname and i.tablename=t.tablename  and i.indexname like '%pk%' and t.tableowner='';

:::::生成添加主键语句

select 'alter table ' ||t.tablename||'   add primary key using index '||i.indexname||';' from  pg_indexes i ,pg_tables t 
where i.schemaname=t.schemaname and i.tablename=t.tablename  and i.indexname like '%pk%' and t.tableowner='';

:::::查询整库的索引大小并排序

SELECT c.relname,c2.relname, c2.relpages*8/1024 as size_MB, indexdef||';' as index_def
FROM pg_class c, pg_class c2, pg_index i,pg_indexes iv 
WHERE  c.oid = i.indrelid AND c2.oid = i.indexrelid and c2.relname=iv.indexname ORDER BY c2.relpages*8 desc;

<3> 删除整库

导入整库前,需删除数据库

DROP DATABASE ;

<4> 添加pg_pathman

注意,需要在每个均升级

\l 查询数据库

\c  进入数据库

::::添加插件

create extension pg_pathman;

::::升级插件

alter extension pg_pathman UPDATE to '1.4';
SET pg_pathman.enable = t;

::::删除插件

drop extension pg_pathman

<5> 查询会话

::::正在连接的会话

select * from pg_stat_activity;
select usename,client_addr,waiting,state,pid from pg_stat_activity;
select * from pg_stat_activity where state='active';

::::查看连接数

select count(*) from pg_stat_activity;

:::::生成批量结束会话语句

select 'SELECT pg_terminate_backend('||pid||');'  from pg_stat_activity;
select 'kill ' || pid from pg_stat_activity where query like '%SELECT message.roomid, message.fromjid, message.tojid%';

<6> 锁

:::::查询当前所有锁与对象的对应关系

select a.locktype,a.pid,a.relation,a.mode,a.granted,b.relname from pg_locks a,pg_class b where a.relation=b.oid;

:::::查询锁定query,用户

select usename,query,client_addr, query_start,pid,client_addr from pg_stat_activity where pid=15010;
select query from pg_stat_activity where pid=15008;

:::::pg的锁类型

acesss share: 只与access exclusive冲突,select 加锁,在用户select时不能做ddl操作

row share: 与exclusive和access exclusive冲突,类似mysql共享意向锁,select for update/select for share 加锁

row exclusive: 与share/share row exclusive/exclusive/access exclusive冲突,UPDATE/INSERT/DELETE加这种锁

share update exclusive:与row share/access exclusive/share/share row exclusive/exclusive,vacuum(不带full)/anslyze/create index concurr-ently

share: 与row exclusive/share update exclusive/share row exclusive/exclusive/access exclusive ,create index(不带concurrently选项语句)加锁

share row exclusive:

Conflicts with the ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This mode protects a table against concurrent data changes, and is self-exclusive so that only one session can hold it at a time.

Acquired by CREATE TRIGGER and many forms of ALTER TABLE (see ALTER TABLE).

exclusive:

Conflicts with the ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE lock modes. This mode allows only concurrent ACCESS SHARE locks, i.e., only reads from the table can proceed in parallel with a transaction holding this lock mode.

Acquired by REFRESH MATERIALIZED VIEW CONCURRENTLY.

access exclusive: 类似于mysql的意向排他锁,为并发执行设计

Conflicts with locks of all modes (ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, and ACCESS EXCLUSIVE). This mode guarantees that the holder is the only transaction accessing the table in any way.

Acquired by the DROP TABLE, TRUNCATE, REINDEX, CLUSTER, VACUUM FULL, and REFRESH MATERIALIZED VIEW (without CONCURRENTLY) commands. Many forms of ALTER TABLE also acquire a lock at this level. This is also the default lock mode for LOCK TABLE statements that do not specify a mode explicitly.

详见:https://www.postgresql.org/docs/9.5/static/explicit-locking.html

<7> 权限

\du+ 查看用户权限及角色

pg_stats

select * from pg_tables where tableowner='';

<8> database操作

::::重命名

ALTER DATABASE  RENAME TO ;

::::建库

create database  owner postgres;

::::删库

DROP DATABASE ;

<9> pg_hba.conf

postgres的连接配置文件,标明允许什么用户连接,及连接权限

# TYPE DATABASE USER ADDRESS METHOD

local all all trust

host all all ip/8 md5

注意,修改过后使用pg_ctl reload重新应用

<10> xlog

:::清除20天之前的xlog

find $PGDATA/pg_xlog -mtime +20 -name "000000*"

xlog是pg的wal日志存储目录,相当于Oracle归档日志和redo日志的合体

如果删除掉正在应用的日志会导致数据库不一致,无法start,最好不要做这种操作

find /paic/pg6604/data/pg_xlog -mtime +6 -name "000000*" -exec rm -rf {} \;

<11> 执行sql脚本:

\x

Expanded display is on.

\i a.sql

:::::显示SQL执行时间:

\timing on

:::::显示所有表名:

\d

:::::查看表定义:

\d <表名>

:::::只显示表:

\dt

::::只显示索引:

\di

::::只显示序列:

\ds

::::只显示视图:

\dv

::::显示Schema:

\dn

::::显示表空间:

\db

::::列出用户和角色:

\du或\dg

::::显示表权限分配情况:

\dp <表名>

::::关闭自动提交

\set AUTOCOMMIT off

::::显示所有数据库:

\l

::::进入某一个库:

\c <数据库名>

<12> 查询占用空间

::::查询数据表占用空间大小

SELECT   table_schema || '.' || table_name AS table_full_name,  
    pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS size  
FROM information_schema.tables  
ORDER BY  
    pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC  ;

:::::查询一个索引大小

select pg_size_pretty(pg_relation_size('indexname))

:::::查看一张表及此它上的索引总大小

select pg_size_pretty(pg_total_relation_size('tablename')); 

<13> 执行计划

explain (analyze on, verbose on, buffers on, timing on, costs on)

<14> 查看慢sql

SELECT  query, calls, total_time, (total_time/calls) as average ,rows, 
        100.0 * shared_blks_hit /nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent 
FROM    pg_stat_statements 
ORDER   BY average DESC LIMIT 10;

你可能感兴趣的:(pg运维)