!1576 修复多事务并发对同一元组更新加锁的xlog回放导致的数据不一致问题

Merge pull request !1576 from chenxiaobin/fixRelay
This commit is contained in:
opengauss-bot 2022-03-15 11:53:55 +00:00 committed by Gitee
commit 9e4aa05aa5
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 61 additions and 8 deletions

View File

@ -6779,7 +6779,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 ||
@ -7321,10 +7321,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);

View File

@ -725,11 +725,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);
}

View File

@ -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

View File

@ -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