ITPub博客

首页 > 数据库 > 国内数据库 > openGauss/MogDB列存表vacuum DELTAMERGE过程申请的锁

openGauss/MogDB列存表vacuum DELTAMERGE过程申请的锁

原创 国内数据库 作者:T1YSL 时间:2024-01-02 18:05:13 0 删除 编辑

之前测试openGauss列存表vacuum DELTAMERGE的时候,发现pg_delta表会在做完vacuum DELTAMERGE后,使用新的物理文件,pg_delta表的relfilenode会发生变化,相当于表重建了。
同时为了测试vacuum DELTAMERGE过程申请了什么锁,大致瞅了眼源码,从源码里看vacuum DELTAMERGE过程申请了AccessExclusiveLock锁。

image.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

image.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

image.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);
}

image.png
image.png


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69990629/viewspace-3002422/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
中国开源软件推进联盟PG分会系列技术丛书《快速掌握PostgreSQL版本新特性》一书副主编。数据库技术专家。数据库认证讲师、恩墨学院数据库讲师。擅长MySQL数据库、PostgreSQL等开源数据库。拥有MySQL-OCP 、PostgreSQL-PGCM等数据库认证。

注册时间:2020-12-12

  • 博文量
    152
  • 访问量
    160730