diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index e6606e5e57a..592a12fa95b 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1975,13 +1975,19 @@ ExecuteTruncateGuts(List *explicit_rels,
 	 * Check foreign key references.  In CASCADE mode, this should be
 	 * unnecessary since we just pulled in all the references; but as a
 	 * cross-check, do it anyway if in an Assert-enabled build.
+	 * 
+	 * Skip foreign key checks when `session_replication_role = replica` to
+	 * match the behaviour of disabling FK triggers in the same situation
 	 */
+	if (SessionReplicationRole != SESSION_REPLICATION_ROLE_REPLICA)
+	{
 #ifdef USE_ASSERT_CHECKING
-	heap_truncate_check_FKs(rels, false);
-#else
-	if (behavior == DROP_RESTRICT)
 		heap_truncate_check_FKs(rels, false);
+#else
+		if (behavior == DROP_RESTRICT)
+			heap_truncate_check_FKs(rels, false);
 #endif
+	}
 
 	/*
 	 * If we are asked to restart sequences, find all the sequences, lock them
@@ -5918,49 +5924,55 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode,
 	 * theoretically possible that we have changed both relations of the
 	 * foreign key, and we'd better have finished both rewrites before we try
 	 * to read the tables.
+	 * 
+	 * Skip the check when `session_replication_mode = replica` to save time 
+	 * and to match the FK trigger behaviour in the same situation 
 	 */
-	foreach(ltab, *wqueue)
+	if (SessionReplicationRole != SESSION_REPLICATION_ROLE_REPLICA)
 	{
-		AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
-		Relation	rel = NULL;
-		ListCell   *lcon;
-
-		/* Relations without storage may be ignored here too */
-		if (!RELKIND_HAS_STORAGE(tab->relkind))
-			continue;
-
-		foreach(lcon, tab->constraints)
+		foreach(ltab, *wqueue)
 		{
-			NewConstraint *con = lfirst(lcon);
+			AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
+			Relation	rel = NULL;
+			ListCell   *lcon;
 
-			if (con->contype == CONSTR_FOREIGN)
+			/* Relations without storage may be ignored here too */
+			if (!RELKIND_HAS_STORAGE(tab->relkind))
+				continue;
+
+			foreach(lcon, tab->constraints)
 			{
-				Constraint *fkconstraint = (Constraint *) con->qual;
-				Relation	refrel;
+				NewConstraint *con = lfirst(lcon);
 
-				if (rel == NULL)
+				if (con->contype == CONSTR_FOREIGN)
 				{
-					/* Long since locked, no need for another */
-					rel = table_open(tab->relid, NoLock);
-				}
+					Constraint *fkconstraint = (Constraint *) con->qual;
+					Relation	refrel;
 
-				refrel = table_open(con->refrelid, RowShareLock);
+					if (rel == NULL)
+					{
+						/* Long since locked, no need for another */
+						rel = table_open(tab->relid, NoLock);
+					}
 
-				validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
-											 con->refindid,
-											 con->conid);
+					refrel = table_open(con->refrelid, RowShareLock);
 
-				/*
-				 * No need to mark the constraint row as validated, we did
-				 * that when we inserted the row earlier.
-				 */
+					validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
+												con->refindid,
+												con->conid);
 
-				table_close(refrel, NoLock);
+					/*
+					* No need to mark the constraint row as validated, we did
+					* that when we inserted the row earlier.
+					*/
+
+					table_close(refrel, NoLock);
+				}
 			}
-		}
 
-		if (rel)
-			table_close(rel, NoLock);
+			if (rel)
+				table_close(rel, NoLock);
+		}
 	}
 
 	/* Finally, run any afterStmts that were queued up */
diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out
index 8cbad245217..b6d41e6df11 100644
--- a/src/test/regress/expected/foreign_key.out
+++ b/src/test/regress/expected/foreign_key.out
@@ -3073,6 +3073,41 @@ ALTER TABLE fk_r DROP CONSTRAINT fk_r_p_id_p_jd_fkey1;
 ERROR:  cannot drop inherited constraint "fk_r_p_id_p_jd_fkey1" of relation "fk_r"
 ALTER TABLE fk_r_2 DROP CONSTRAINT fk_r_p_id_p_jd_fkey;
 ERROR:  cannot drop inherited constraint "fk_r_p_id_p_jd_fkey" of relation "fk_r_2"
+-- tests for SET session_replication_role = replica;
+RESET session_replication_role;
+-- disabling FK checks
+CREATE TABLE pkt(id int PRIMARY KEY);
+CREATE TABLE fkt(fk int REFERENCES pkt(id));
+INSERT INTO fkt VALUES(1); -- should fail
+ERROR:  insert or update on table "fkt" violates foreign key constraint "fkt_fk_fkey"
+DETAIL:  Key (fk)=(1) is not present in table "pkt".
+SET session_replication_role=replica;
+INSERT INTO fkt VALUES(1); -- should succeed now
+DROP TABLE fkt, pkt;
+RESET session_replication_role;
+-- skipping FK validation during ALTER TABLE ... ADD FOREIGN KEY
+CREATE TABLE pkt(id int PRIMARY KEY);
+CREATE TABLE fkt(fk int);
+INSERT INTO fkt VALUES(1);
+ALTER TABLE fkt ADD FOREIGN KEY (fk) REFERENCES pkt(id); -- should fail
+ERROR:  insert or update on table "fkt" violates foreign key constraint "fkt_fk_fkey"
+DETAIL:  Key (fk)=(1) is not present in table "pkt".
+SET session_replication_role=replica;
+ALTER TABLE fkt ADD FOREIGN KEY (fk) REFERENCES pkt(id); -- should succeed now
+DROP TABLE fkt, pkt;
+RESET session_replication_role;
+-- skipping FK existence checks during TRUNCATE
+CREATE TABLE pkt(id int PRIMARY KEY);
+CREATE TABLE fkt(fk int REFERENCES pkt(id));
+TRUNCATE pkt; -- should fail
+ERROR:  cannot truncate a table referenced in a foreign key constraint
+DETAIL:  Table "fkt" references "pkt".
+HINT:  Truncate table "fkt" at the same time, or use TRUNCATE ... CASCADE.
+SET session_replication_role=replica;
+TRUNCATE pkt; -- should succeed now
+DROP TABLE fkt, pkt;
+RESET session_replication_role;
+-- end of tests for SET session_replication_role = replica;
 SET client_min_messages TO warning;
 DROP SCHEMA fkpart12 CASCADE;
 RESET client_min_messages;
diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql
index ea08fd5a6f6..b24277a901f 100644
--- a/src/test/regress/sql/foreign_key.sql
+++ b/src/test/regress/sql/foreign_key.sql
@@ -1151,6 +1151,10 @@ commit;
 
 drop table pktable2, fktable2;
 
+--
+-- 
+--
+
 --
 -- Test keys that "look" different but compare as equal
 --
@@ -2177,7 +2181,54 @@ ALTER TABLE fk_r_1 DROP CONSTRAINT fk_r_p_id_p_jd_fkey;
 ALTER TABLE fk_r DROP CONSTRAINT fk_r_p_id_p_jd_fkey1;
 ALTER TABLE fk_r_2 DROP CONSTRAINT fk_r_p_id_p_jd_fkey;
 
+-- tests for SET session_replication_role = replica;
+
+RESET session_replication_role;
+
+-- disabling FK checks
+
+CREATE TABLE pkt(id int PRIMARY KEY);
+CREATE TABLE fkt(fk int REFERENCES pkt(id));
+
+INSERT INTO fkt VALUES(1); -- should fail
+
+SET session_replication_role=replica;
+INSERT INTO fkt VALUES(1); -- should succeed now
+
+DROP TABLE fkt, pkt;
+RESET session_replication_role;
+
+-- skipping FK validation during ALTER TABLE ... ADD FOREIGN KEY
+
+CREATE TABLE pkt(id int PRIMARY KEY);
+CREATE TABLE fkt(fk int);
+INSERT INTO fkt VALUES(1);
+
+ALTER TABLE fkt ADD FOREIGN KEY (fk) REFERENCES pkt(id); -- should fail
+
+SET session_replication_role=replica;
+ALTER TABLE fkt ADD FOREIGN KEY (fk) REFERENCES pkt(id); -- should succeed now
+
+DROP TABLE fkt, pkt;
+RESET session_replication_role;
+
+-- skipping FK existence checks during TRUNCATE
+
+CREATE TABLE pkt(id int PRIMARY KEY);
+CREATE TABLE fkt(fk int REFERENCES pkt(id));
+
+TRUNCATE pkt; -- should fail
+
+SET session_replication_role=replica;
+TRUNCATE pkt; -- should succeed now
+
+DROP TABLE fkt, pkt;
+RESET session_replication_role;
+
+-- end of tests for SET session_replication_role = replica;
+
 SET client_min_messages TO warning;
 DROP SCHEMA fkpart12 CASCADE;
 RESET client_min_messages;
 RESET search_path;
+
