

如下是对锁的验证:
由于测试环境配置有限,做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 AccessExclusivemog_xlogdump: FATAL: error in WAL record at 0/4002B78: invalid record length at 0/40030D0: wanted 32, got 0

然后获取现在的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 AccessExclusivemog_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 24576REDO @ 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 24580REDO @ 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 24657error in WAL record at 0/4003150: invalid record length at 0/40031F0: wanted 32, got 0

openGauss=# select oid,relfilenode,relname from pg_class where relfilenode=24576 or relfilenode=24580 or relfilenode=24657;oid | relfilenode | relname-------+-------------+----------------24576 | 24576 | test_cstore24580 | 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);}


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

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

END
MogDB 是云和恩墨基于 openGauss 开源内核进行增强提升,推出的一款安稳易用的企业级关系型数据库。其具备金融级高可用和全密态计算的极致安全、面向多核处理器的极致性能、AI自诊断调优的极致智能能力,能够满足从核心交易到复杂计算的企业级业务需求。
访问官网了解更多:www.mogdb.io
产品兼容适配申请:partner@enmotech.com
进入交流群:Roger_database






