日常数据库维护工作
定期备份,定期”清理“数据库,周期性的日志文件管理
check_postgres可用于检测数据库的健康并报告异常情况

1. 日常清理

PostgreSQL数据库要求周期性的清理维护。对于很多安装,让自动清理守护进程来执行清理已经足够

1.1. 清理的基础知识

PostgreSQL的VACUUM命令出于几个原因必须定期处理每一个表:
1. 恢复或重用被已更新或已删除行所占用的磁盘空间。
2. 更新被PostgreSQL查询规划器使用的数据统计信息。
3. 更新可见性映射,它可以加速只用索引的扫描。
4. 保护老旧数据不会由于事务ID回卷或多事务ID回卷而丢失。
有 两 种VACUUM的变体:标准VACUUM和VACUUM FULL。
VACUUM FULL可以收回更多磁盘空间但是运行起来更慢。VACUUM FULL要求在其工作的表上得到一个排他锁,因此无法和对此表的其他使用并行。
标准形式的VACUUM可以和生产数据库操作并行运行(SELECT、INSERT、UPDATE和DELETE等命令将继续正常工作,但在清理期间你无法使
用ALTER TABLE等命令来更新表的定义)。
VACUUM会产生大量I/O流量,这将导致其他活动会话性能变差。
-bash-4.2$ vacuumdb --help
vacuumdb cleans and analyzes a PostgreSQL database.

Usage:
vacuumdb [OPTION]... [DBNAME]

Options:
-a, --all vacuum all databases
-d, --dbname=DBNAME database to vacuum
-e, --echo show the commands being sent to the server
-f, --full do full vacuuming
-F, --freeze freeze row transaction information
-j, --jobs=NUM use this many concurrent connections to vacuum
-q, --quiet don't write any messages
-t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only
-v, --verbose write a lot of output
-V, --version output version information, then exit
-z, --analyze update optimizer statistics
-Z, --analyze-only only update optimizer statistics; no vacuum
--analyze-in-stages only update optimizer statistics, in multiple
stages for faster results; no vacuum
-?, --help show this help, then exit

Connection options:
-h, --host=HOSTNAME database server host or socket directory
-p, --port=PORT database server port
-U, --username=USERNAME user name to connect as
-w, --no-password never prompt for password
-W, --password force password prompt
--maintenance-db=DBNAME alternate maintenance database

Read the description of the SQL command VACUUM for details.

Report bugs to <pgsql-bugs@postgresql.org>.
-bash-4.2$ vacuumdb -d hq -f -z -v >> /tmp/vacuumdb.log
INFO: vacuuming "pg_catalog.pg_statistic"
INFO: "pg_statistic": found 127 removable, 402 nonremovable row versions in 26 pages

1.2. 恢复磁盘空间

在PostgreSQL中,一次行的UPDATE或DELETE不会立即移除该行的旧版本。这种方法对于从多版本并发控制(MVCC)获益是必需的:
当旧版本仍可能对其他事务可见时,它不能被删除。但是最后,任何事务都不会再对一个过时的或者被删除的行版本感兴
趣。它所占用的空间必须被回收来用于新行,这样可避免磁盘空间需求的无限制增长。这通过运行VACUUM完成。
VACUUM的标准形式移除表和索引中的死亡行版本并将该空间标记为可在未来重用。不过,它将不会把该空间交还给操作系统,除非在
特殊的情况中表尾部的一个或多个页面变成完全空闲并且能够很容易地得到一个排他表锁。
相反,VACUUM FULL通过把死亡空间之外的内容写成一个完整的新版本表文件来主动紧缩表。这将最小化表的尺寸,但是要花较长的时间。
它也需要额外的磁盘空间用于表的新副本,直到操作完成。
例行清理的一般目标是多做标准的VACUUM来避免需要VACUUM FULL。
  提示: 当一个表因为大量更新或删除活动而包含大量死亡行版本时,纯粹的VACUUM可能不能令人满意。
如果你有这样一个表并且你需要回收它占用的过量磁盘空间,你将需要使用VACUUMFULL,或者CLUSTER,或者ALTER TABLE的表重写变体之一。
  提示: 如果你有一个表,它的整个内容会被周期性删除,考虑用TRUNCATE而不是先用DELETE再用VACUUM。

1.3. 更新规划器统计信息

PostgreSQL查询规划器依赖于有关表内容的统计信息来为查询产生好的计划。
这些统计信息由ANALYZE命令收集,它除了直接被调用之外还可以作为VACUUM的一个可选步骤被调用。
拥有适度准确的统计信息很重要,否则差的计划可能降低数据库性能。
自动清理守护进程如果被启用,当一个表的内容被改变得足够多时,它将自动发出ANALYZE命令。
  提示: 自动清理守护进程不会为外部表发出ANALYZE命令,因为无法确定一个合适的频度。

1.4. 更新可见性映射

清理机制为每一个表维护着一个可见性映射,它被用来跟踪哪些页面只包含对所有活动事务可见的元组。
这样做有两个目的。
第一,清理本身可以在下一次运行时跳过这样的页面,因为其中没有什么需要被清除。
第二,这允许PostgreSQL回答一些只用索引的查询,而不需要引用底层表。

1.5. 防止事务ID 回卷失败

PostgreSQL的 MVCC 事务语义依赖于能够比较事务 ID(XID)数字
如果一个行版本的插入 XID 大于当前事务的 XID,它就是“属于未来的”并且不应该对当前事务可见。
必要至少每 20 亿个事务就清理每个数据库中的每个表。
周期性的清理能够解决该问题的原因是,VACUUM会把行标记为 冻结,这表示它们是被一个在足够远的过去提交的事务所插入,
这样从 MVCC 的角度来看,效果就是该插入事务对所有当前和未来事务来说当然都 是可见的。
PostgreSQL保留了一个特殊的 XID(FrozenTransactionId),这个 XID 并不遵循普通 XID 的比较规则 并且总是被认为比任
何普通 XID 要老。普通 XID 使用模-232算 法来比较。
VACUUM通常会跳过不含有任何死亡行版本的页面,但是不会跳过那些含有带旧XID值的行版本的页面。
要保证所有旧的行版本都已经被冻结,需要对整个表做一次扫描。vacuum_freeze_table_age控制VACUUM什么时候这样做:如果该表经
过vacuum_freeze_table_age减去vacuum_freeze_min_age个事务还没有被完全扫描过,则会强制一次全表清扫。将这个参数设置为 0
将强制VACUUM总是扫描所有页面而实际上忽略可见性映射。
一个数据库的pg_database行的datfrozenxid列是出现在该数据库中的未冻结 XID 的下界 — 它只是数据库中每一个表的relfrozenxid值的最小值。

SELECT c.oid::regclass as table_name,
greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age
FROM pg_class c
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
WHERE c.relkind IN ('r', 'm');
SELECT datname, age(datfrozenxid) FROM pg_database;

age列度量从该截断 XID 到当前事务 XID 的事务数。
VACUUM通常只扫描从上次清理后备修改过的页面,但是只有当全表被扫描时relfrozenxid才能被推进。
当relfrozenxid比vacuum_freeze_table_age个事务还老时、当VACUUM的FREEZE选项被使用时或当所有页面正好要求清理来移除死亡行版本时,全表将被扫描。
如果出于某种原因自动清理无法从一个表中清除旧的 XID,当数据库的最旧 XID 和回卷点之间达到 1 千万个事务时,系统将开始发出这样的警告消息:
WARNING: database "mydb" must be vacuumed within 177009986 transactions
HINT: To avoid a database shutdown, execute a database-wide VACUUM in "mydb".
如果这些警告被忽略,一旦距离回滚点只剩下 1 百万个事务时,该系统将会关闭并且拒绝开始任何新的事务:
ERROR: database is not accepting commands to avoid wraparound data loss in database mydb
HINT: Stop the postmaster and vacuum that database in single-user mode.
由于一旦系统进入到安全关闭模式,它将不会执行命令。做这个操作的唯一方法是停止服务器并且以单一用户启动服务器来执行VACUUM。
1.5.1. 多事务和回卷
Multixact ID被用来支持被多个事务锁定的行。
只要有多于一个事务并发地锁住一个行, 锁信息将使用一个“多个事务ID”(或简称多事务 ID)来编码。
作为一种安全设备,对任何多事务年龄超过 autovacuum_multixact_freeze_max_age的表, 都将发生一次全表清理扫描。
如果已用的成员存储空间超过总量的 50%,全表清理扫描 也将逐步在所有表上进行,这会从那些具有最老多事务年龄的表开始。

1.6. 自动清理后台进程

PostgreSQL有一个可选的但是被高度推荐的特性autovacuum,它的目的是自动执行VACUUM和ANALYZE 命令。
当它被启用时,自动清理会检查被大量插入、更新或删除元组的表。这些检查会利用统计信息收集功能,
因此除非track_counts被设置为true,自动清理不能被使用。在默认配置下,自动清理是被启用的并且相关配置参数已被正确配置。
#autovacuum = on # Enable autovacuum subprocess? 'on'
# requires track_counts to also be on.
#track_counts = on
“自动清理后台进程”实际上由多个进程组成。有一个称为 自动清理启动器的常驻后台进程, 它负责为所有数据库启动自动清理工作者进程。

2. 日常重建索引

在某些情况下值得周期性地使用REINDEX命令或一系列独立重构步骤来重建索引。
已经完全变成空的B树索引页面被收回重用。但是,还是有一种低效的空间利用的可能性:如果一个页面上除少量索引键之外的全部键被删除,该页面仍然被分配。
因此,在这种每个范围中大部分但不是全部键最终被删除的使用模式中,可以看到空间的使用是很差的。对于
这样的使用模式,推荐使用定期重索引。
对于非B树索引可能的膨胀还没有很好地定量分析。在使用非B树索引时定期监控索引的物理尺寸是个好主意。
对于B树索引,一个新建立的索引比更新了多次的索引访问起来要略快, 因为在新建立的索引上,逻辑上相邻的页面通常物理上也相邻
。仅仅为了提高访问速度也值得定期重索引。
REINDEX在所有情况下都可以安全和容易地使用。但是由于该命令要求一个排他表锁,因此更好的方法是用一个由创建和替换步骤组成的序列来执行索引重建。
支持带CONCURRENTLY选项的CREATE INDEX的索引类型可以用这种方式重建。

3. 日志文件维护

把数据库服务器的日志输出保存在一个地方是个好主意, 而不是仅仅通过/dev/null丢弃它们。 在进行问题诊断的时候,日志输出是非常宝贵的。
如果你简单地把postgres的stderr定向到一个文件中,你会得到日志输出, 但是截断该日志文件的唯一方法是停止并重起服务器。这
一个更好的办法是把服务器的stderr输出发送到某种日志轮转程序里。

postgresql.conf里logging_collector为true

PostgreSQL 日常数据库维护工作的更多相关文章

  1. 使用 iMacros 来自动化日常的工作

    利用 iMacros 的浏览器附加组件来提高工作效率 介绍 iMacros 这个强大的工具,使用简单的范例演示了如何使用这个工具来完成对于网页的操作,对于大量的具有重复性的工作内容尤其可以提高效率.对 ...

  2. postgresql 日常sql

    查看服务进程: select pid,usename,client_addr,client_port from pg_stat_activity;   查看当前数据库实例的版本:  select ve ...

  3. PostgreSQL 日常SQL记录

    平时用的比较多的SQL语句,有时候会忘掉一点点,在这里记录一下: 1.创建表的同时,插入数据: create table test as select generate_series(1, 10000 ...

  4. 日常开发工作常用linux命令

    :wq 保存退出 :q! 强制退出 vi 查看 vim 编辑 rpm -qa|grep jdk 命令查看当前的jdk情况 yum -y remove java java-1.7.0-openjdk* ...

  5. 第二章 psql客户端工具

    第二章 psql客户端工具 pgAdmin是一款功能丰富.开源免费的PostgreSQL图形化工具.psql是PostgreSQL自带的命令行工具,功能全面,是PostgreSQL数据库工程师必须熟练 ...

  6. 数据库并发事务控制四:postgresql数据库的锁机制二:表锁 <转>

    在博文<数据库并发事务控制四:postgresql数据库的锁机制 > http://blog.csdn.net/beiigang/article/details/43302947 中后面提 ...

  7. linux运维工作职责

     (1)运维人员要谨记的6个字:运维人员做事需遵循:简单.易用.高效(2)运维人员服务的3大宗旨:1.企业数据安全保障.2.7*24小时业务持续提供服务.3.不断提升用户感受.体验.(3)初中级运维的 ...

  8. AIX系统的日常监控维护

    UNIX操作系统在各电信运营商中应用非常广泛,各种业务管理系统的后台服务器几乎都采用UNIX操作系统.AIX作为UNIX操作系统中的一种, 因其稳定性高.兼容性好的特点受到众多系统管理员的欢迎.下面提 ...

  9. 工作的思考十七:工作中容易犯的错误 - Delay

    其实IT是一个很严谨的行业,不管是从代码角度还是从日常的工作分配都是按计划来的. 从今年年初到现在,在我的工作中出现了两次“Delay”,第一次不以为然,虽然上司也找过我谈话,但没意识到问题的严重性. ...

随机推荐

  1. 多校hdu-5775 Bubble sort(线段树)

    题意根据题目中给的冒泡排序写出每个元素交换过程中该元素位置左右最大差距: 分析:因为题目中冒泡程序从后向前遍历的,假设第i个元素左边有k个比i小的数,那么i必定会向右移动k位,我们用k1记住i+k,用 ...

  2. EntityFramework 学习 一 Validate Entity

    可以为实体实现自定义验证,重写DBContext中的个ValidateEntity方法 protected override System.Data.Entity.Validation.DbEntit ...

  3. Java执行过程

    Java的运行原理 在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能 ...

  4. 什么是 RegExp?

    RegExp 是正则表达式的缩写. regular expression 当您检索某个文本时,可以使用一种模式来描述要检索的内容.RegExp 就是这种模式. 简单的模式可以是一个单独的字符. 更复杂 ...

  5. Python staticmethod

    1 @staticmethod 静态方法 when this method is called, we don't pass an instance of the class to it (as we ...

  6. ios 获取导航栏和状态栏高度,针对iPhoneX

    因为iPhoneX的产生,原本的导航栏再也不是44了,那么会出现什么问题呢?在隐藏导航栏的页面,原本的高度要向上调整一个导航栏+状态栏的高度.那么iPhoneX的导航栏高度不是44了,我们需要手动获取 ...

  7. codeforces 798C.Mike and gcd problem 解题报告

    题目意思:给出一个n个数的序列:a1,a2,...,an (n的范围[2,100000],ax的范围[1,1e9] ) 现在需要对序列a进行若干变换,来构造一个beautiful的序列: b1,b2, ...

  8. Generator函数介绍

    Generator函数 基本概念 英文意思为 "生成器". generator函数是es6提供的一种异步编程解决方案,语法行为与传统函数完全不同.从状态上,首先我们把他理解成一种状 ...

  9. 清北学堂(2019 5 1) part 4

    今天讲数论 1.进制问题(将n转换成k进制数): 1.方法:短除法 将n/k,保存,将商当做新的n,将余数保存,直到商为0,将余数(包括0),倒序输出,即得n的k进制数 2.关于高精四则运算(我本以为 ...

  10. 算法练习4---冒泡排序java版

    冒泡排序的基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们的排序与排序要求相反 ...