From 928da3d6d2dc5451183e39fe077191c29ee3bff8 Mon Sep 17 00:00:00 2001 From: chenxiaobin19 <1025221611@qq.com> Date: Thu, 10 Mar 2022 11:39:59 +0800 Subject: [PATCH] fix wal replay of locking an updated tuple --- .../storage/access/heap/heapam.cpp | 8 ++-- .../storage/access/redo/redo_heapam.cpp | 12 +++-- src/test/ha/ha_schedule_multi_single | 1 + .../multi_standby_single/consistency.sh | 48 +++++++++++++++++++ 4 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 src/test/ha/testcase/multi_standby_single/consistency.sh diff --git a/src/gausskernel/storage/access/heap/heapam.cpp b/src/gausskernel/storage/access/heap/heapam.cpp index d94a09803..cddb3cc2f 100755 --- a/src/gausskernel/storage/access/heap/heapam.cpp +++ b/src/gausskernel/storage/access/heap/heapam.cpp @@ -6718,7 +6718,7 @@ failed: xlrec.locking_xid = xid; xlrec.offnum = ItemPointerGetOffsetNumber(&tuple->t_self); xlrec.xid_is_mxact = ((new_infomask & HEAP_XMAX_IS_MULTI) != 0); - xlrec.shared_lock = (mode == LockTupleShared); + xlrec.shared_lock = (mode == LockTupleShared || mode == LockTupleKeyShare); xlrec.infobits_set = ComputeInfobits(new_infomask, tuple->t_data->t_infomask2); xlrec.lock_updated = false; useOldXlog = t_thrd.proc->workingVersionNum < ENHANCED_TUPLE_LOCK_VERSION_NUM || @@ -7260,10 +7260,8 @@ l4: xlrec.xid_is_mxact = ((new_infomask & HEAP_XMAX_IS_MULTI) != 0); xlrec.infobits_set = ComputeInfobits(new_infomask, new_infomask2); xlrec.lock_updated = true; - /* - * We don't record shared_lock, this field is reserverd for compatibility - * This xlog can only be record in new version - */ + xlrec.shared_lock = (mode == LockTupleShared || mode == LockTupleKeyShare); + XLogRegisterData((char *)&xlrec, SizeOfHeapLock); recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK | XLOG_TUPLE_LOCK_UPGRADE_FLAG); diff --git a/src/gausskernel/storage/access/redo/redo_heapam.cpp b/src/gausskernel/storage/access/redo/redo_heapam.cpp index b76ed0ae9..7fbf31acb 100755 --- a/src/gausskernel/storage/access/redo/redo_heapam.cpp +++ b/src/gausskernel/storage/access/redo/redo_heapam.cpp @@ -699,11 +699,17 @@ void HeapXlogLockOperatorPage(RedoBufferInfo *buffer, void *recorddata, bool isT htup->t_infomask2 |= HEAP_KEYS_UPDATED; } } - HeapTupleHeaderClearHotUpdated(htup); + /* + * Clear relevant update flags, but only if the modified infomask says + * there's no update. + */ + if (HEAP_XMAX_IS_LOCKED_ONLY(htup->t_infomask, htup->t_infomask2)) { + HeapTupleHeaderClearHotUpdated(htup); + /* Make sure there is no forward chain link in t_ctid */ + ItemPointerSet(&htup->t_ctid, buffer->blockinfo.blkno, xlrec->offnum); + } HeapTupleHeaderSetXmax(page, htup, xlrec->locking_xid); HeapTupleHeaderSetCmax(htup, FirstCommandId, false); - /* Make sure there is no forward chain link in t_ctid */ - ItemPointerSet(&htup->t_ctid, buffer->blockinfo.blkno, xlrec->offnum); PageSetLSN(page, buffer->lsn); } diff --git a/src/test/ha/ha_schedule_multi_single b/src/test/ha/ha_schedule_multi_single index 16275c6fe..611b83687 100644 --- a/src/test/ha/ha_schedule_multi_single +++ b/src/test/ha/ha_schedule_multi_single @@ -12,3 +12,4 @@ multi_standby_single/xlog_redo_apply_delay #multi_standby_single/most_available multi_standby_single/failover_with_data multi_standby_single/hash_index +multi_standby_single/consistency.sh diff --git a/src/test/ha/testcase/multi_standby_single/consistency.sh b/src/test/ha/testcase/multi_standby_single/consistency.sh new file mode 100644 index 000000000..aea9ec1b5 --- /dev/null +++ b/src/test/ha/testcase/multi_standby_single/consistency.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +source ./util.sh + +function test_1() +{ + set_default + + echo "check 1-sync slaves" + check_synchronous_commit "datanode1" 1 + + echo "create table consistency_t1 (a int primary key, b int); +insert into consistency_t1 values (1, 1); +\parallel on 2 +begin +update consistency_t1 set b = b + 1 where a = 1; +perform pg_sleep(2); +end; +/ +begin +perform pg_sleep(1); +perform * from consistency_t1 where a = 1 for key share; +perform pg_sleep(3); +end; +/ +\parallel off" > consistency_tmp.sql + + gsql -d $db -p $dn1_primary_port -f consistency_tmp.sql + + rm consistency_tmp.sql + + if [ $(gsql -d $db -p $dn1_standby_port -c "select count(*) from consistency_t1 where a = 1;" | grep 0 |wc -l) -eq 0 ]; then + echo "consistency check success on dn1_standby" + else + echo "consistency check failed on dn1_standby" + exit 1 + fi + +} + +function tear_down() { + sleep 1 + set_default + gsql -d $db -p $dn1_primary_port -c "DROP TABLE if exists consistency_t1;" +} + +test_1 +tear_down