forked from huawei/openGauss-server
!1576 修复多事务并发对同一元组更新加锁的xlog回放导致的数据不一致问题
Merge pull request !1576 from chenxiaobin/fixRelay
This commit is contained in:
commit
9e4aa05aa5
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue