mirror of
https://github.com/postgres/postgres.git
synced 2025-10-15 05:46:52 +03:00
Message wording improvements
Use "row" instead of "tuple" for user-facing information for logical replication conflicts.
This commit is contained in:
@@ -1824,7 +1824,7 @@ Publications:
|
||||
<term><literal>update_missing</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The tuple to be updated was not found. The update will simply be
|
||||
The row to be updated was not found. The update will simply be
|
||||
skipped in this scenario.
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -1845,7 +1845,7 @@ Publications:
|
||||
<term><literal>delete_missing</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The tuple to be deleted was not found. The delete will simply be
|
||||
The row to be deleted was not found. The delete will simply be
|
||||
skipped in this scenario.
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -1879,8 +1879,8 @@ DETAIL: <replaceable class="parameter">detailed_explanation</replaceable>.
|
||||
<phrase>where <replaceable class="parameter">detail_values</replaceable> is one of:</phrase>
|
||||
|
||||
<literal>Key</literal> (<replaceable>column_name</replaceable> <optional>, ...</optional>)=(<replaceable>column_value</replaceable> <optional>, ...</optional>)
|
||||
<literal>existing local tuple</literal> <optional>(<replaceable>column_name</replaceable> <optional>, ...</optional>)=</optional>(<replaceable>column_value</replaceable> <optional>, ...</optional>)
|
||||
<literal>remote tuple</literal> <optional>(<replaceable>column_name</replaceable> <optional>, ...</optional>)=</optional>(<replaceable>column_value</replaceable> <optional>, ...</optional>)
|
||||
<literal>existing local row</literal> <optional>(<replaceable>column_name</replaceable> <optional>, ...</optional>)=</optional>(<replaceable>column_value</replaceable> <optional>, ...</optional>)
|
||||
<literal>remote row</literal> <optional>(<replaceable>column_name</replaceable> <optional>, ...</optional>)=</optional>(<replaceable>column_value</replaceable> <optional>, ...</optional>)
|
||||
<literal>replica identity</literal> {(<replaceable>column_name</replaceable> <optional>, ...</optional>)=(<replaceable>column_value</replaceable> <optional>, ...</optional>) | full <optional>(<replaceable>column_name</replaceable> <optional>, ...</optional>)=</optional>(<replaceable>column_value</replaceable> <optional>, ...</optional>)}
|
||||
</synopsis>
|
||||
|
||||
@@ -1914,32 +1914,32 @@ DETAIL: <replaceable class="parameter">detailed_explanation</replaceable>.
|
||||
<para>
|
||||
<replaceable class="parameter">detailed_explanation</replaceable> includes
|
||||
the origin, transaction ID, and commit timestamp of the transaction that
|
||||
modified the existing local tuple, if available.
|
||||
modified the existing local row, if available.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>Key</literal> section includes the key values of the local
|
||||
tuple that violated a unique constraint for
|
||||
row that violated a unique constraint for
|
||||
<literal>insert_exists</literal>, <literal>update_exists</literal> or
|
||||
<literal>multiple_unique_conflicts</literal> conflicts.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>existing local tuple</literal> section includes the local
|
||||
tuple if its origin differs from the remote tuple for
|
||||
The <literal>existing local row</literal> section includes the local
|
||||
row if its origin differs from the remote row for
|
||||
<literal>update_origin_differs</literal> or <literal>delete_origin_differs</literal>
|
||||
conflicts, or if the key value conflicts with the remote tuple for
|
||||
conflicts, or if the key value conflicts with the remote row for
|
||||
<literal>insert_exists</literal>, <literal>update_exists</literal> or
|
||||
<literal>multiple_unique_conflicts</literal> conflicts.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>remote tuple</literal> section includes the new tuple from
|
||||
The <literal>remote row</literal> section includes the new row from
|
||||
the remote insert or update operation that caused the conflict. Note that
|
||||
for an update operation, the column value of the new tuple will be null
|
||||
for an update operation, the column value of the new row will be null
|
||||
if the value is unchanged and toasted.
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -1947,7 +1947,7 @@ DETAIL: <replaceable class="parameter">detailed_explanation</replaceable>.
|
||||
<para>
|
||||
The <literal>replica identity</literal> section includes the replica
|
||||
identity key values that were used to search for the existing local
|
||||
tuple to be updated or deleted. This may include the full tuple value
|
||||
row to be updated or deleted. This may include the full row value
|
||||
if the local relation is marked with
|
||||
<link linkend="sql-altertable-replica-identity-full"><literal>REPLICA IDENTITY FULL</literal></link>.
|
||||
</para>
|
||||
@@ -1955,7 +1955,7 @@ DETAIL: <replaceable class="parameter">detailed_explanation</replaceable>.
|
||||
<listitem>
|
||||
<para>
|
||||
<replaceable class="parameter">column_name</replaceable> is the column name.
|
||||
For <literal>existing local tuple</literal>, <literal>remote tuple</literal>,
|
||||
For <literal>existing local row</literal>, <literal>remote row</literal>,
|
||||
and <literal>replica identity full</literal> cases, column names are
|
||||
logged only if the user lacks the privilege to access all columns of
|
||||
the table. If column names are present, they appear in the same order
|
||||
@@ -2012,7 +2012,7 @@ DETAIL: <replaceable class="parameter">detailed_explanation</replaceable>.
|
||||
<screen>
|
||||
ERROR: conflict detected on relation "public.test": conflict=insert_exists
|
||||
DETAIL: Key already exists in unique index "t_pkey", which was modified locally in transaction 740 at 2024-06-26 10:47:04.727375+08.
|
||||
Key (c)=(1); existing local tuple (1, 'local'); remote tuple (1, 'remote').
|
||||
Key (c)=(1); existing local row (1, 'local'); remote row (1, 'remote').
|
||||
CONTEXT: processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/014C0378
|
||||
</screen>
|
||||
The LSN of the transaction that contains the change violating the constraint and
|
||||
|
@@ -852,10 +852,10 @@ ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo,
|
||||
conflictindexes, false);
|
||||
|
||||
/*
|
||||
* Checks the conflict indexes to fetch the conflicting local tuple
|
||||
* and reports the conflict. We perform this check here, instead of
|
||||
* Checks the conflict indexes to fetch the conflicting local row and
|
||||
* reports the conflict. We perform this check here, instead of
|
||||
* performing an additional index scan before the actual insertion and
|
||||
* reporting the conflict if any conflicting tuples are found. This is
|
||||
* reporting the conflict if any conflicting rows are found. This is
|
||||
* to avoid the overhead of executing the extra scan for each INSERT
|
||||
* operation, even when no conflict arises, which could introduce
|
||||
* significant overhead to replication, particularly in cases where
|
||||
|
@@ -55,7 +55,7 @@ static char *build_index_value_desc(EState *estate, Relation localrel,
|
||||
|
||||
/*
|
||||
* Get the xmin and commit timestamp data (origin and timestamp) associated
|
||||
* with the provided local tuple.
|
||||
* with the provided local row.
|
||||
*
|
||||
* Return true if the commit timestamp data was found, false otherwise.
|
||||
*/
|
||||
@@ -89,12 +89,12 @@ GetTupleTransactionInfo(TupleTableSlot *localslot, TransactionId *xmin,
|
||||
* This function is used to report a conflict while applying replication
|
||||
* changes.
|
||||
*
|
||||
* 'searchslot' should contain the tuple used to search the local tuple to be
|
||||
* 'searchslot' should contain the tuple used to search the local row to be
|
||||
* updated or deleted.
|
||||
*
|
||||
* 'remoteslot' should contain the remote new tuple, if any.
|
||||
*
|
||||
* conflicttuples is a list of local tuples that caused the conflict and the
|
||||
* conflicttuples is a list of local rows that caused the conflict and the
|
||||
* conflict related information. See ConflictTupleInfo.
|
||||
*
|
||||
* The caller must ensure that all the indexes passed in ConflictTupleInfo are
|
||||
@@ -191,9 +191,9 @@ errcode_apply_conflict(ConflictType type)
|
||||
*
|
||||
* The DETAIL line comprises of two parts:
|
||||
* 1. Explanation of the conflict type, including the origin and commit
|
||||
* timestamp of the existing local tuple.
|
||||
* 2. Display of conflicting key, existing local tuple, remote new tuple, and
|
||||
* replica identity columns, if any. The remote old tuple is excluded as its
|
||||
* timestamp of the existing local row.
|
||||
* 2. Display of conflicting key, existing local row, remote new row, and
|
||||
* replica identity columns, if any. The remote old row is excluded as its
|
||||
* information is covered in the replica identity columns.
|
||||
*/
|
||||
static void
|
||||
@@ -313,7 +313,7 @@ errdetail_apply_conflict(EState *estate, ResultRelInfo *relinfo,
|
||||
localslot, remoteslot, indexoid);
|
||||
|
||||
/*
|
||||
* Next, append the key values, existing local tuple, remote tuple and
|
||||
* Next, append the key values, existing local row, remote row, and
|
||||
* replica identity columns after the message.
|
||||
*/
|
||||
if (val_desc)
|
||||
@@ -331,7 +331,7 @@ errdetail_apply_conflict(EState *estate, ResultRelInfo *relinfo,
|
||||
|
||||
/*
|
||||
* Helper function to build the additional details for conflicting key,
|
||||
* existing local tuple, remote tuple, and replica identity columns.
|
||||
* existing local row, remote row, and replica identity columns.
|
||||
*
|
||||
* If the return value is NULL, it indicates that the current user lacks
|
||||
* permissions to view the columns involved.
|
||||
@@ -373,7 +373,7 @@ build_tuple_value_details(EState *estate, ResultRelInfo *relinfo,
|
||||
{
|
||||
/*
|
||||
* The 'modifiedCols' only applies to the new tuple, hence we pass
|
||||
* NULL for the existing local tuple.
|
||||
* NULL for the existing local row.
|
||||
*/
|
||||
desc = ExecBuildSlotValueDescription(relid, localslot, tupdesc,
|
||||
NULL, 64);
|
||||
@@ -383,12 +383,12 @@ build_tuple_value_details(EState *estate, ResultRelInfo *relinfo,
|
||||
if (tuple_value.len > 0)
|
||||
{
|
||||
appendStringInfoString(&tuple_value, "; ");
|
||||
appendStringInfo(&tuple_value, _("existing local tuple %s"),
|
||||
appendStringInfo(&tuple_value, _("existing local row %s"),
|
||||
desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(&tuple_value, _("Existing local tuple %s"),
|
||||
appendStringInfo(&tuple_value, _("Existing local row %s"),
|
||||
desc);
|
||||
}
|
||||
}
|
||||
@@ -415,11 +415,11 @@ build_tuple_value_details(EState *estate, ResultRelInfo *relinfo,
|
||||
if (tuple_value.len > 0)
|
||||
{
|
||||
appendStringInfoString(&tuple_value, "; ");
|
||||
appendStringInfo(&tuple_value, _("remote tuple %s"), desc);
|
||||
appendStringInfo(&tuple_value, _("remote row %s"), desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfo(&tuple_value, _("Remote tuple %s"), desc);
|
||||
appendStringInfo(&tuple_value, _("Remote row %s"), desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ typedef enum
|
||||
#define CONFLICT_NUM_TYPES (CT_MULTIPLE_UNIQUE_CONFLICTS + 1)
|
||||
|
||||
/*
|
||||
* Information for the existing local tuple that caused the conflict.
|
||||
* Information for the existing local row that caused the conflict.
|
||||
*/
|
||||
typedef struct ConflictTupleInfo
|
||||
{
|
||||
@@ -69,7 +69,7 @@ typedef struct ConflictTupleInfo
|
||||
* the conflict */
|
||||
RepOriginId origin; /* origin identifier of the modification */
|
||||
TimestampTz ts; /* timestamp of when the modification on the
|
||||
* conflicting local tuple occurred */
|
||||
* conflicting local row occurred */
|
||||
} ConflictTupleInfo;
|
||||
|
||||
extern bool GetTupleTransactionInfo(TupleTableSlot *localslot,
|
||||
|
@@ -365,10 +365,10 @@ $node_publisher->wait_for_catchup('tap_sub');
|
||||
|
||||
my $logfile = slurp_file($node_subscriber->logfile, $log_location);
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab_full_pk": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote tuple \(1, quux\); replica identity \(a\)=\(1\)/m,
|
||||
qr/conflict detected on relation "public.tab_full_pk": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote row \(1, quux\); replica identity \(a\)=\(1\)/m,
|
||||
'update target row is missing');
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab_full": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote tuple \(26\); replica identity full \(25\)/m,
|
||||
qr/conflict detected on relation "public.tab_full": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote row \(26\); replica identity full \(25\)/m,
|
||||
'update target row is missing');
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab_full_pk": conflict=delete_missing.*\n.*DETAIL:.* Could not find the row to be deleted.*\n.*Replica identity \(a\)=\(2\)/m,
|
||||
|
@@ -368,7 +368,7 @@ $node_publisher->wait_for_catchup('sub2');
|
||||
|
||||
my $logfile = slurp_file($node_subscriber1->logfile(), $log_location);
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab1_2_2": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote tuple \(null, 4, quux\); replica identity \(a\)=\(4\)/,
|
||||
qr/conflict detected on relation "public.tab1_2_2": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote row \(null, 4, quux\); replica identity \(a\)=\(4\)/,
|
||||
'update target row is missing in tab1_2_2');
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab1_1": conflict=delete_missing.*\n.*DETAIL:.* Could not find the row to be deleted.*\n.*Replica identity \(a\)=\(1\)/,
|
||||
@@ -781,7 +781,7 @@ $node_publisher->wait_for_catchup('sub2');
|
||||
|
||||
$logfile = slurp_file($node_subscriber1->logfile(), $log_location);
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab2_1": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote tuple \(pub_tab2, quux, 5\); replica identity \(a\)=\(5\)/,
|
||||
qr/conflict detected on relation "public.tab2_1": conflict=update_missing.*\n.*DETAIL:.* Could not find the row to be updated.*\n.*Remote row \(pub_tab2, quux, 5\); replica identity \(a\)=\(5\)/,
|
||||
'update target row is missing in tab2_1');
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab2_1": conflict=delete_missing.*\n.*DETAIL:.* Could not find the row to be deleted.*\n.*Replica identity \(a\)=\(1\)/,
|
||||
@@ -802,8 +802,8 @@ $node_publisher->wait_for_catchup('sub_viaroot');
|
||||
|
||||
$logfile = slurp_file($node_subscriber1->logfile(), $log_location);
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab2_1": conflict=update_origin_differs.*\n.*DETAIL:.* Updating the row that was modified locally in transaction [0-9]+ at .*\n.*Existing local tuple \(yyy, null, 3\); remote tuple \(pub_tab2, quux, 3\); replica identity \(a\)=\(3\)/,
|
||||
'updating a tuple that was modified by a different origin');
|
||||
qr/conflict detected on relation "public.tab2_1": conflict=update_origin_differs.*\n.*DETAIL:.* Updating the row that was modified locally in transaction [0-9]+ at .*\n.*Existing local row \(yyy, null, 3\); remote row \(pub_tab2, quux, 3\); replica identity \(a\)=\(3\)/,
|
||||
'updating a row that was modified by a different origin');
|
||||
|
||||
# The remaining tests no longer test conflict detection.
|
||||
$node_subscriber1->append_conf('postgresql.conf',
|
||||
|
@@ -30,7 +30,7 @@ sub test_skip_lsn
|
||||
# ERROR with its CONTEXT when retrieving this information.
|
||||
my $contents = slurp_file($node_subscriber->logfile, $offset);
|
||||
$contents =~
|
||||
qr/conflict detected on relation "public.tbl".*\n.*DETAIL:.* Key already exists in unique index "tbl_pkey", modified by .*origin.* transaction \d+ at .*\n.*Key \(i\)=\(\d+\); existing local tuple .*; remote tuple .*\n.*CONTEXT:.* for replication target relation "public.tbl" in transaction \d+, finished at ([[:xdigit:]]+\/[[:xdigit:]]+)/m
|
||||
qr/conflict detected on relation "public.tbl".*\n.*DETAIL:.* Key already exists in unique index "tbl_pkey", modified by .*origin.* transaction \d+ at .*\n.*Key \(i\)=\(\d+\); existing local row .*; remote row .*\n.*CONTEXT:.* for replication target relation "public.tbl" in transaction \d+, finished at ([[:xdigit:]]+\/[[:xdigit:]]+)/m
|
||||
or die "could not get error-LSN";
|
||||
my $lsn = $1;
|
||||
|
||||
|
@@ -163,7 +163,7 @@ is($result, qq(32), 'The node_A data replicated to node_B');
|
||||
$node_C->safe_psql('postgres', "UPDATE tab SET a = 33 WHERE a = 32;");
|
||||
|
||||
$node_B->wait_for_log(
|
||||
qr/conflict detected on relation "public.tab": conflict=update_origin_differs.*\n.*DETAIL:.* Updating the row that was modified by a different origin ".*" in transaction [0-9]+ at .*\n.*Existing local tuple \(32\); remote tuple \(33\); replica identity \(a\)=\(32\)/
|
||||
qr/conflict detected on relation "public.tab": conflict=update_origin_differs.*\n.*DETAIL:.* Updating the row that was modified by a different origin ".*" in transaction [0-9]+ at .*\n.*Existing local row \(32\); remote row \(33\); replica identity \(a\)=\(32\)/
|
||||
);
|
||||
|
||||
$node_B->safe_psql('postgres', "DELETE FROM tab;");
|
||||
@@ -179,7 +179,7 @@ is($result, qq(33), 'The node_A data replicated to node_B');
|
||||
$node_C->safe_psql('postgres', "DELETE FROM tab WHERE a = 33;");
|
||||
|
||||
$node_B->wait_for_log(
|
||||
qr/conflict detected on relation "public.tab": conflict=delete_origin_differs.*\n.*DETAIL:.* Deleting the row that was modified by a different origin ".*" in transaction [0-9]+ at .*\n.*Existing local tuple \(33\); replica identity \(a\)=\(33\)/
|
||||
qr/conflict detected on relation "public.tab": conflict=delete_origin_differs.*\n.*DETAIL:.* Deleting the row that was modified by a different origin ".*" in transaction [0-9]+ at .*\n.*Existing local row \(33\); replica identity \(a\)=\(33\)/
|
||||
);
|
||||
|
||||
# The remaining tests no longer test conflict detection.
|
||||
|
@@ -79,11 +79,11 @@ $node_publisher->safe_psql('postgres',
|
||||
$node_subscriber->wait_for_log(
|
||||
qr/conflict detected on relation \"public.conf_tab\": conflict=multiple_unique_conflicts.*
|
||||
.*Key already exists in unique index \"conf_tab_pkey\".*
|
||||
.*Key \(a\)=\(2\); existing local tuple \(2, 2, 2\); remote tuple \(2, 3, 4\).*
|
||||
.*Key \(a\)=\(2\); existing local row \(2, 2, 2\); remote row \(2, 3, 4\).*
|
||||
.*Key already exists in unique index \"conf_tab_b_key\".*
|
||||
.*Key \(b\)=\(3\); existing local tuple \(3, 3, 3\); remote tuple \(2, 3, 4\).*
|
||||
.*Key \(b\)=\(3\); existing local row \(3, 3, 3\); remote row \(2, 3, 4\).*
|
||||
.*Key already exists in unique index \"conf_tab_c_key\".*
|
||||
.*Key \(c\)=\(4\); existing local tuple \(4, 4, 4\); remote tuple \(2, 3, 4\)./,
|
||||
.*Key \(c\)=\(4\); existing local row \(4, 4, 4\); remote row \(2, 3, 4\)./,
|
||||
$log_offset);
|
||||
|
||||
pass('multiple_unique_conflicts detected during insert');
|
||||
@@ -111,11 +111,11 @@ $node_publisher->safe_psql('postgres',
|
||||
$node_subscriber->wait_for_log(
|
||||
qr/conflict detected on relation \"public.conf_tab\": conflict=multiple_unique_conflicts.*
|
||||
.*Key already exists in unique index \"conf_tab_pkey\".*
|
||||
.*Key \(a\)=\(6\); existing local tuple \(6, 6, 6\); remote tuple \(6, 7, 8\).*
|
||||
.*Key \(a\)=\(6\); existing local row \(6, 6, 6\); remote row \(6, 7, 8\).*
|
||||
.*Key already exists in unique index \"conf_tab_b_key\".*
|
||||
.*Key \(b\)=\(7\); existing local tuple \(7, 7, 7\); remote tuple \(6, 7, 8\).*
|
||||
.*Key \(b\)=\(7\); existing local row \(7, 7, 7\); remote row \(6, 7, 8\).*
|
||||
.*Key already exists in unique index \"conf_tab_c_key\".*
|
||||
.*Key \(c\)=\(8\); existing local tuple \(8, 8, 8\); remote tuple \(6, 7, 8\)./,
|
||||
.*Key \(c\)=\(8\); existing local row \(8, 8, 8\); remote row \(6, 7, 8\)./,
|
||||
$log_offset);
|
||||
|
||||
pass('multiple_unique_conflicts detected during update');
|
||||
@@ -139,9 +139,9 @@ $node_publisher->safe_psql('postgres',
|
||||
$node_subscriber->wait_for_log(
|
||||
qr/conflict detected on relation \"public.conf_tab_2_p1\": conflict=multiple_unique_conflicts.*
|
||||
.*Key already exists in unique index \"conf_tab_2_p1_pkey\".*
|
||||
.*Key \(a\)=\(55\); existing local tuple \(55, 2, 3\); remote tuple \(55, 2, 3\).*
|
||||
.*Key \(a\)=\(55\); existing local row \(55, 2, 3\); remote row \(55, 2, 3\).*
|
||||
.*Key already exists in unique index \"conf_tab_2_p1_a_b_key\".*
|
||||
.*Key \(a, b\)=\(55, 2\); existing local tuple \(55, 2, 3\); remote tuple \(55, 2, 3\)./,
|
||||
.*Key \(a, b\)=\(55, 2\); existing local row \(55, 2, 3\); remote row \(55, 2, 3\)./,
|
||||
$log_offset);
|
||||
|
||||
pass('multiple_unique_conflicts detected on a leaf partition during insert');
|
||||
@@ -314,7 +314,7 @@ my $logfile = slurp_file($node_B->logfile(), $log_location);
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab": conflict=delete_origin_differs.*
|
||||
.*DETAIL:.* Deleting the row that was modified locally in transaction [0-9]+ at .*
|
||||
.*Existing local tuple \(1, 3\); replica identity \(a\)=\(1\)/,
|
||||
.*Existing local row \(1, 3\); replica identity \(a\)=\(1\)/,
|
||||
'delete target row was modified in tab');
|
||||
|
||||
$log_location = -s $node_A->logfile;
|
||||
@@ -327,7 +327,7 @@ $logfile = slurp_file($node_A->logfile(), $log_location);
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab": conflict=update_deleted.*
|
||||
.*DETAIL:.* The row to be updated was deleted locally in transaction [0-9]+ at .*
|
||||
.*Remote tuple \(1, 3\); replica identity \(a\)=\(1\)/,
|
||||
.*Remote row \(1, 3\); replica identity \(a\)=\(1\)/,
|
||||
'update target row was deleted in tab');
|
||||
|
||||
# Remember the next transaction ID to be assigned
|
||||
@@ -383,7 +383,7 @@ $logfile = slurp_file($node_A->logfile(), $log_location);
|
||||
ok( $logfile =~
|
||||
qr/conflict detected on relation "public.tab": conflict=update_deleted.*
|
||||
.*DETAIL:.* The row to be updated was deleted locally in transaction [0-9]+ at .*
|
||||
.*Remote tuple \(2, 4\); replica identity full \(2, 2\)/,
|
||||
.*Remote row \(2, 4\); replica identity full \(2, 2\)/,
|
||||
'update target row was deleted in tab');
|
||||
|
||||
###############################################################################
|
||||
|
Reference in New Issue
Block a user