zoukankan      html  css  js  c++  java
  • PostgreSQL Autovacuum和vacuum + 参数优化

    1 基础知识

    重点: 如果您的数据库运行了很久,并且从来没有打开过autovacuum,那么请在打开autovacuum之前全库手动运行vacuum analyze(可能要非常久的时间)

    完全禁用autovacuum,请不要这样做,除非你真的知道你在做什么,并且需要定期清理脚本.否则当问题发生时你将不得不处理花费大量的时间处理,甚至可能需要停库、停机

     1.1 dead tuples
    tuple:元组,也就是一行数据

    首先,简要解释什么是"死元组""膨胀".
    
      当您在PostgreSQL中执行DELETE时,行不会立即从数据文件中删除.而是仅通过在页头中设置xmax字段将其标记为已删除.同样对于UPDATE,它可能在PostgreSQL中被视为DELETE+INSERT.
    
      这是PostgreSQL MVCC背后的基本思想之一,因为它允许更大并发,在不同的进程之间最小的锁定.这个MVCC实现的缺点是留下了已删除的元组,即使在所有可能看到这些版本的事务完成之后也是如此.
    如果没有清理,那些"死元组"(对于任何事务实际上是不可见的)将永远留在数据文件中.


    对于DELETE和UPDATE比较多的的表,死元组可能占据很多磁盘空间.



    同时,死元组也将从索引中引用,进一步增加了浪费的磁盘空间量.


    这就是我们在PostgreSQL中称之为“膨胀”的东西,同时因为查询也会变慢。

    1.2 vacuum和autovacuum

    收死元组占用空间的最直接方法是手动运行VACUUM命令

    注意:VACUUM FULL会回收空间并将其返回给操作系统,但是有许多缺点.首先,它将获取表上的独占锁,阻止所有操作(包括SELECT).其次,它实际上创建了一个表的副本(复制了一个表),使所需的磁盘空间加倍,同时复制表非常慢.

    [root@iZ2zeijrvu2s38mfzvzrc3Z ~]# cat /home/pg_freeze.sh
    #!/bin/bash
    #
    # cript: pg_freeze.sh
    #  Date:2020-04-09
    #
    #
    ######################################################################################################################
    #                                  init message
    ######################################################################################################################
    
    # list databases
    # 日期
    #backup_date=`date  "+%Y-%m-%d"`
    # 备份所有业务库  数据库用户根据实际用户进行替换;
    for x in  $(psql -U postgres -h 127.0.0.1  -c "select datname from pg_database where datname not in ('template0','template1'); "  -A -t)
    do
    ##避免错误可直接写死路径
    ` psql -U postgres -h 127.0.0.1  -d ${x} -c " VACUUM FREEZE;"`
    echo "freeze ${x} success!!"
    done
    [root@iZ2zeijrvu2s38mfzvzrc3Z ~]#

     根据以下参数我们可以计算autovacuum完成的"工作成本".然后通过autovacuum_vacuum_cost_limit可以一次完成的清理工作,默认情况下设置为200,每次清理完成后它将睡眠20ms:

    autovacuum_vacuum_cost_delay = 20ms
    autovacuum_vacuum_cost_limit = 200
    
    
    延迟20ms,清理可以每秒进行50轮,每轮200,每秒10000.这意味着:
    
    从shared_buffers读取80MB/s(假设没有脏页,10000/1*8k)
    从OS读取8MB/s(可能来自磁盘,10000/10*8k)
    4 MB / s写入(由autovacuum进程弄脏的页面,10000/20*8k)

    3 阈值和比例因子

    autovacuum会受到两个参数的影响
    autovacuum_vacuum_threshold = 50 #阈值
    autovacuum_vacuum_scale_factor = 0.2 #比例因子

    该公式基本上表示在清理之前,高达20%的表可能是死元组(50行的阈值是为了防止非常频繁地清理微小的表).

    默认的比例因子适用于中小型表,但对于非常大的表则没有那么多(在10GB表上,这大约是2GB的死元组,而在1TB表上则是~200GB).

     参考:PostgreSQL Autovacuum和vacuum - VicLW - 博客园 (cnblogs.com)

    6. pg_repack

    [root@iZ2zeijrvu2s38mfzvzrc3Z ~]# cat /home/pg_repack.sh
    #!/bin/bash
    #
    #  Script: pg_repack.sh
    #  Date:2020-07-21
    #
    #
    ######################################################################################################################
    #                                  init message
    ######################################################################################################################
    pg_repack_log=/home/pg_repack_log
    # 备份日期
    backup_date=`date  "+%Y-%m-%d"`
    log_file=pg_repack_${backup_date}.txt
    echo  `date` >${pg_repack_log}/${log_file}
    # 核心表清单;
    for x in  $(psql -U postgres -h 127.0.0.1 -d tenant_1008446 -c "select relname from pg_class where relname in (
    'kx_kq_store',
    'kx_kq_storeinandout',
    
    'sfa_t_tbascostexec',
    'ka_kq_channelcustomers',
    
    'dms_t_contract',
    'sfa_t_tbasstorephoto',
    'tn_channelscore',
    'sfa_t_tbasstoreperformance',
    'kx_gzq_content',
    'kx_order',
    
    'kx_visit_customerstatus',
    'kx_visit_actual'
    ); "  -A -t)
    do
    ##避免错误可直接写死路径
    ##echo  `date` >> ${pg_repack_log}/${log_file}
    exec=` /usr/pgsql-10/bin/pg_repack -Upostgres -h127.0.0.1 -d tenant_test -t ${x}`
    echo "pg_repack ${x} success!!"  >> ${pg_repack_log}/${log_file}
    echo  `date` >> ${pg_repack_log}/${log_file}
    
    done
    [root@iZ2zeijrvu2s38mfzvzrc3Z ~]#
    用一个例子来演示会更加清晰
  • 相关阅读:
    rxjava rxandroid使用遇到的坑
    使用ARouter遇到的坑
    java(Android)跨Module调用对应类方法需求解决方案
    前端工程师技能之photoshop巧用系列第四篇——图片格式
    前端工程师技能之photoshop巧用系列第三篇——切图篇
    前端工程师技能之photoshop巧用系列第二篇——测量篇
    前端工程师技能之photoshop巧用系列第一篇——准备篇
    js中用tagname和id获取元素的3种方法
    MVC显示Base64图片
    在ASP.NET MVC应用程序中随机获取一个字符串
  • 原文地址:https://www.cnblogs.com/hixiaowei/p/15185031.html
Copyright © 2011-2022 走看看