首页 > 数据库 >postgresql xid回卷预防及排查

postgresql xid回卷预防及排查

时间:2023-09-28 17:26:51浏览次数:32  
标签:postgresql max age oid 回卷 pg vacuum xid

监控

WITH max_age AS ( 

   SELECT 2000000000 as max_old_xid

       , setting AS autovacuum_freeze_max_age 

       FROM pg_catalog.pg_settings 

       WHERE name = 'autovacuum_freeze_max_age' )

, per_database_stats AS ( 

   SELECT datname

       , m.max_old_xid::int

       , m.autovacuum_freeze_max_age::int

       , age(d.datfrozenxid) AS oldest_current_xid 

   FROM pg_catalog.pg_database d 

   JOIN max_age m ON (true) 

   WHERE d.datallowconn ) 

SELECT max(oldest_current_xid) AS oldest_current_xid

   , max(ROUND(100*(oldest_current_xid/max_old_xid::float))) AS percent_towards_wraparound

   , max(ROUND(100*(oldest_current_xid/autovacuum_freeze_max_age::float))) AS percent_towards_emergency_autovac

  

percent_towards_wraparound指标对于警报的设置非常重要。查询使用 age()
函数来确定 TXID 值,因此需要考虑它们是否真的处于耗尽状态,以确定回绕是否是一个真正存在的问题。如果耗尽,数据库将被迫关闭,并可能为了修复而导致停机时间的不确定。这个查询中存在一点缓冲,因为它检查的上限(确切地说是20亿)小于导致耗尽的实际最大整数值。但这已经足够接近了,达到100%的警报应该立即采取行动。

percent_towards_emergency_autovac指标是我们建议监测的附加值,特别是对于以前从未监测过此指标的系统(有关何时可以降低或删除此警报优先级,请参阅下面有关近期冻结成效的说明)。这将监视数据库的最高 TXID 值是否达到autovacuum_freeze_max_age。这是一个用户可调值,默认值为2亿,当任何表的最高 TXID 值达到该值时,该表上会出现更高优先级的autovacuum
。您将认识到这个特殊的vacuum
会话,因为在pg_stat_activity
中它将被标记(以防止回绕)。它的优先级更高,即使禁用autovacuum
,它也会运行,如果手动取消vacuum
,它几乎会立即重新启动。它还需要一些不同的内部低级锁,因此它可能会导致这些表上的争用稍微更高,这取决于它们在紧急vacuum
期间的使用方式。如果您确实遇到争用/锁的问题,并且是紧急vacuum
造成的,则完全可以安全地取消争用/锁,以允许其他事务完成。请注意,它将继续重新启动,直到vacuum
能够成功完成或手动运行vacuum

 

 

排查

# 查看每个库的年龄

SELECT datname, age(datfrozenxid) FROM pg_database;

SELECT c.oid::regclass
, age(c.relfrozenxid)
, pg_size_pretty(pg_total_relation_size(c.oid))
FROM pg_class c
JOIN pg_namespace n on c.relnamespace = n.oid
WHERE relkind IN ('r', 't', 'm')
AND n.nspname NOT IN ('pg_toast')
ORDER BY 2 DESC LIMIT 100;
# 1个库每个表的年龄排序 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') order by age desc;

# 查看1个表的年龄
select oid::regclass,age(relfrozenxid) from pg_class where oid='schema名称.表名称'::regclass::oid;
#这查询按照最老的XID排序,查看大于1G而且是排名前20的表:

select relname, age(relfrozenxid) as xid_age, pg_size_pretty(pg_table_size(oid)) as table_sizefrom pg_class where relkind = 'r' and pg_table_size(oid) > 1073741824order by xid_age desc limit 20;--vacuum前事务年龄为 61436    relname | xid_age | table_size----------------+---------+------------ test_tab | 31260 | 4327 MB

 



#通过以下语句可以查找出age年龄大于vacuum_freeze_table_age的表:
 select datname,age(datfrozenxid) from pg_database where datname not in ('postgres','template0','template1') and age(datfrozenxid)>(select setting::int from pg_settings where name='vacuum_freeze_table_age')order by age(datfrozenxid) desc;

  

运维脚本

# 对指定数据库中年龄最大的前 50 张表进行 vacuum freeze



for cmd in `psql -U用户名 -p端口号 -h连接串 -d数据库名 -c "SELECT 'vacuum freeze '||c.oid::regclass||';' as vacuum_cmd FROM pg_class c LEFT JOIN pg_class t ON c.reltoastrelid = t.oid WHERE c.relkind IN ('r', 'm') order by greatest(age(c.relfrozenxid),age(t.relfrozenxid)) desc offset 50 limit 50;" | grep -v vacuum_cmd  | grep -v row | grep vacuum`; do

  python脚本

from multiprocessing import Pool

import psycopg2



args = dict(host='pgm-bp10xxxx.pg.rds.aliyuncs.com', port=5432, dbname='数据库名',

            user='用户名', password='密码')



def vacuum_handler(sql):

    sql_str = "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') order by age desc limit 10; "

    try:

        conn = psycopg2.connect(**args)

        cur = conn.cursor()

        cur.execute(sql)

        conn.commit()

        cur = conn.cursor()

        cur.execute(sql_str)

        print cur.fetchall()

        conn.close()

    except Exception as e:

        print str(e)



# 对指定数据库中年龄最大的前 1000 张表进行 vacuum freeze,32 个进程并发执行

def multi_vacuum():

    pool = Pool(processes=32)

    sql_str = "SELECT 'vacuum freeze '||c.oid::regclass||';' as vacuum_cmd FROM pg_class c LEFT JOIN pg_class t ON c.reltoastrelid = t.oid WHERE c.relkind IN ('r', 'm') order by greatest(age(c.relfrozenxid),age(t.relfrozenxid)) desc limit 1000;";

    try:

        conn = psycopg2.connect(**args)

        cur = conn.cursor()

        cur.execute(sql_str)

        rows = cur.fetchall()

        for row in rows:

            cmd = row['vacuum_cmd']

            pool.apply_async(vacuum_handler, (cmd, ))

        conn.close()

        pool.close()

        pool.join()

    except Exception as e:

        print str(e)





multi_vacuum()

  

标签:postgresql,max,age,oid,回卷,pg,vacuum,xid
From: https://www.cnblogs.com/lovezhr/p/17736177.html

相关文章

  • postgresql临时表
    PostgreSQL中的临时表分两种,一种是会话级临时表,一种是事务级临时表。在会话级临时表中,数据可以存在于整个会话的生命周期中,在事务级临时表中,数据只能存在于事务的生命周期中。不管是会话级还是事务级的临时表,当会话结束后,临时表会消失,这和Oracle数据库不同。Oracle数据库当会话......
  • PostgreSQL数据库WAL日志空间大小以及不清理的原因深入分析
    1.背景很多初学者会对WAL日志占用多少空间比较疑惑,听网上的一些文章说是由max_wal_size来控制的,但发现很多时候WAL日志空间会超过这个设置的值,不知道为什么?同时有时会发现WAL日志不清理了,占用空间在不停的增长,然后不知道为什么?看一些网上的文章,发现情况不是网上说的那种情况。......
  • Linux CentOS 7.x离线安装PostgreSQL操作手册
    一、准备环节rpm-qa|greppostgres检查PostgreSQL是否已经安装rpm-qal|greppostgres检查PostgreSQL安装位置postgresql-12.2.tar.gz二、Pgsql数据库安装下载下载地址:http://www.postgresql.org/ftp/source/选择你你需要的版本,本次安装12.2的版......
  • PostgreSQL Serial
    概念描述PostgreSQL中的SERIAL是一种特殊的类型,用于创建自增长的整数列,通常用作表的主键或其他需要唯一标识的列。SERIAL实际上不是真正的类型,而是一种便捷的写法,它会自动创建一个SEQUENCE对象,并将该SEQUENCE的下一个值作为该列的默认值。PostgreSQLSERIAL是一种特殊的用于生产整......
  • PostgreSQL教程:备份与恢复(物理备份、物理恢复)
    物理备份(归档+物理)这里需要基于前面的文件系统的备份和归档备份实现最终的操作单独使用文件系统的方式,不推荐毕竟数据会丢失。这里直接上PostgreSQL提供的pg_basebackup命令来实现。pg_basebackup会做两个事情、会将内存中的脏数据落到磁盘中,然后将数据全部备份会将wal日志直接做归......
  • PostgreSQL教程:事务的ACID特性及基本使用
    什么是ACID?在日常操作中,对于一组相关操作,通常要求要么都成功,要么都失败。在关系型数据库中,称这一组操作为事务。为了保证整体事务的安全性,有ACID这一说:原子性A:事务是一个最小的执行单位,一次事务中的操作要么都成功,要么都失败。一致性C:在事务完成时,所有数据必须保持在一致的状态。(事......
  • PostgreSQL教程:触发器
    触发器Trigger,是由事件触发的一种存储过程当对标进行insert,update,delete,truncate操作时,会触发表的Trigger(看触发器的创建时指定的事件)构建两张表,学生信息表,学生分数表。在删除学生信息的同时,自动删除学生的分数。先构建表信息,填充数据createtablestudent(idint,namev......
  • PostgreSQL教程:约束(主键、非空、唯一、检查约束)
    核心在于构建表时,要指定上一些约束。约束主键--主键约束droptabletest;createtabletest(idbigserialprimarykey,namevarchar(32));非空--非空约束droptabletest;createtabletest(idbigserialprimarykey,namevarchar(32)notnull);......
  • PostgreSQL教程:数组类型
    数组还是要依赖其他类型,比如在设置住址,住址可能有多个住址,可以采用数组类型去修饰字符串。PGSQL中,指定数组的方式就是[],可以指定一维数组,也支持二维甚至更多维数组。构建数组的方式:droptabletest;createtabletest(idserial,col1int[],col2int[2],col3......
  • PostgreSQL教程:JSON&JSONB类型
    JSON在MySQL8.x中也做了支持,但是MySQL支持的不好,因为JSON类型做查询时,基本无法给JSON字段做索引。PGSQL支持JSON类型以及JSONB类型。JSON和JSONB的使用基本没区别。撇去JSON类型,本质上JSON格式就是一个字符串,比如MySQL5.7不支持JSON的情况的下,使用text也可以,但是字符串类型无法校验......