循序渐进丨openGauss / MogDB 列存表vacuum DELTAMERGE过程申请的锁

之前测试 openGauss 列存表vacuum DELTAMERGE的时候,发现pg_delta表会在做完vacuum DELTAMERGE后,使用新的物理文件,pg_delta表的relfilenode会发生变化,相当于表重建了。

同时为了测试vacuum DELTAMERGE过程申请了什么锁,通过走读源码可以发现,vacuum DELTAMERGE过程申请了AccessExclusiveLock锁。

a2927173ed454da7d305e69621ab9296.png

如下是对锁的验证:

由于测试环境配置有限,做vacuum DELTAMERGE较快,比较难抓到锁,所以我想到了直接从锁入手。AccessExclusiveLock是8级锁,主库申请8级锁时,会将其记录到WAL日志里,所以在测试之前我先切了一个日志:

openGauss=# select pg_switch_xlog();
 pg_switch_xlog
----------------
 0/3003058
(1 row)

这样在我使用mog_xlogdump解析新的日志的时候,尽量不让其他的WAL记录干扰我。

omm1@ubuntu-linux-22-04-desktop:/opt/opengauss/data/pg_xlog$ mog_xlogdump  -R int,varchar,timestamp 000000010000000000000004 | grep -i AccessExclusive
mog_xlogdump: FATAL:  error in WAL record at 0/4002B78: invalid record length at 0/40030D0: wanted 32, got 0

e0c9488eb0c8275e4d0956f4a3c03ee1.png

然后获取现在的txid=15156,这样下一次我做操作的txid是15157。

openGauss=# select txid_current();
 txid_current
--------------
        15156
(1 row)


openGauss=# vacuum DELTAMERGE test_cstore;
DELTA MERGE

做完操作后,再用mog_xlogdump解析WAL日志,发现多了三条AccessExclusive Lock的相关记录,xid和预期的15157项对应,三条记录均与做的操作有关。

omm1@ubuntu-linux-22-04-desktop:/opt/opengauss/data/pg_xlog$ mog_xlogdump  -R int,varchar,timestamp 000000010000000000000004 | grep -i AccessExclusive
mog_xlogdump: FATAL:  REDO @ 0/40001D0; LSN 0/4000210: prev 0/4000188; xid 15157; term 1; len 24; total 58; crc 3716495508; desc: Standby - AccessExclusive locks: nlocks 1  xid 15157 db 14595 rel 24576
REDO @ 0/4000700; LSN 0/4000740: prev 0/40005D0; xid 15157; term 1; len 24; total 58; crc 2397906544; desc: Standby - AccessExclusive locks: nlocks 1  xid 15157 db 14595 rel 24580
REDO @ 0/4002150; LSN 0/4002190: prev 0/40020F8; xid 15157; term 1; len 24; total 58; crc 145047305; desc: Standby - AccessExclusive locks: nlocks 1  xid 15157 db 14595 rel 24657
error in WAL record at 0/4003150: invalid record length at 0/40031F0: wanted 32, got 0

13cc064d1e07fca25ec677233244f6e5.png

openGauss=# select oid,relfilenode,relname from pg_class where relfilenode=24576 or relfilenode=24580 or relfilenode=24657;
  oid  | relfilenode |    relname
-------+-------------+----------------
 24576 |       24576 | test_cstore
 24580 |       24657 | pg_delta_24576
(2 rows)

根据上述打印的三个relfilenode,在数据库里查询可以发现,vacuum DELTAMERGE过程中,列存表原表、delta表均获取了8级锁AccessExclusive Lock。另外,还有一个relfilenode对应的表其实是delta表的原表,在vacuum DELTAMERGE过程中,delta表发生了重建,对应的表文件发生了变化。

这一现象和文章开头提到的:原始的pg_delta表会在做完vacuum DELTAMERGE后,抛弃原来的物理文件,直接使用新的物理文件,pg_delta表的relfilenode会发生变化的现象一致。

除此之外也可以在一个线程做vacuum DELTAMERGE的同时,使用perf命令记录调用栈,并生成svg火焰图,可以看到vacuum DELTAMERGE过程申请了AccessExclusiveLock,需要用LogAccessExclusiveLock()调用LogAccessExclusiveLocks()把锁记录写到xlog里。

/*
 * Wholesale logging of AccessExclusiveLocks. Other lock types need not be
 * logged, as described in backend/storage/lmgr/README.
 */
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock* locks)
{
    xl_standby_locks xlrec;


    xlrec.nlocks = nlocks;


    XLogBeginInsert();
    XLogRegisterData((char*)&xlrec, MinSizeOfXactStandbyLocks);
    XLogRegisterData((char*)locks, nlocks * sizeof(xl_standby_lock));


    (void)XLogInsert(RM_STANDBY_ID, XLOG_STANDBY_LOCK);
}


/*
 * Individual logging of AccessExclusiveLocks for use during LockAcquire()
 */
void LogAccessExclusiveLock(Oid dbOid, Oid relOid)
{
    if (ENABLE_DMS) {
        return;
    }


    xl_standby_lock xlrec;


    xlrec.xid = GetTopTransactionId();


    /*
     * Decode the locktag back to the original values, to avoid sending lots
     * of empty bytes with every message.  See lock.h to check how a locktag
     * is defined for LOCKTAG_RELATION
     */
    xlrec.dbOid = dbOid;
    xlrec.relOid = relOid;


    LogAccessExclusiveLocks(1, &xlrec);
}

c3db47c26eec386ca3131f2b61c8f2ca.jpeg

cb5470e70f1528913c9f4a03954a8d2e.png

上述方法其实是比较取巧地用了主库申请8级锁时,会将其记录到WAL日志里这一特点进行分析。除此之外,也可以使用gdb在 openGauss / MogDB 调用的相关函数打上断点,等到触发的时候,逐步调试,查看申请的锁情况。

使用gdb调试的方法可以参考以下链接这篇文章里使用gdb调试 PostgreSQL 数据库的相关操作,原理是基本类似的。

https://www.modb.pro/db/1743847348848123904(复制链接至浏览器查阅)

6452c358a6159f907d3a78cc475f5957.png

作者简介

/ Author Introduction

阎书利 / 云和恩墨PG技术顾问

PostgreSQL ACE,《快速掌握 PostgreSQL 版本新特性》一书副主编,中国PG分会认证讲师,PGfans 2021年度MVP,Gauss松鼠会2021年度优秀会员,拥有PGCM、OCP(MySQL)等十多项数据库认证,目前主要从事于 PostgreSQL、openGauss / MogDB 的运维以及去O工作。

f78e18c9d11d3f0d8a4fd260b72617b2.png

756561f5419c7b30b3cb060e02b392ff.gif

数据驱动,成就未来,云和恩墨,不负所托!


云和恩墨:智能的数据技术提供商,创立于2011年,总部位于中国北京,在国内外35个地区设有本地办公室并开展业务。

我们以“数据驱动,成就未来”为使命,致力于将创新的数据技术产品和解决方案带给全球的企业和组织,帮助客户构建起安全、高效、敏捷且经济的数据环境,并增强客户在数据洞察和决策上的竞争优势,实现数据驱动的业务创新和升级发展。

自成立以来,我们始终专注于数据技术领域,根据不断变化的市场需求和技术进步,创新研发了系列软件产品,涵盖数据库、数据库存储、数据库云化管理和数据智能分析等领域。这些产品已经在集团型、大中型、高成长型客户以及行业云场景中得到广泛应用,证明了我们的技术和商业竞争力,展现了我们在数据技术端到端解决方案方面的优势。

在云化、数字化和智能化的时代背景下,我们始终以正和多赢为目标,感恩每一位客户和合作伙伴的信任与支持,“利他先行”,坚持长期投入于数据技术核心能力的理念,为构建智能的数字世界而不懈努力。

fff858b149857afd21b0c6692c20aeb4.gif

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值