diff --git a/src/backend/utils/hash/hashfn.c b/src/backend/utils/hash/hashfn.c
index 260d8806dbb9dfca7e9c89c952f44a2028dedf07..bdd438d4cabeca494344e98a8a613d1476e95dd9 100644
--- a/src/backend/utils/hash/hashfn.c
+++ b/src/backend/utils/hash/hashfn.c
@@ -22,6 +22,7 @@
 #include "postgres.h"
 
 #include "access/hash.h"
+#include "utils/hsearch.h"
 
 
 /*
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index d86590ac111e6064c06a85b4dbc7b9979b9192b2..d9d05a08ffe1f67a4d47b4e22088e30b030efff7 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -17,7 +17,7 @@
 #include "access/sdir.h"
 #include "access/skey.h"
 #include "nodes/tidbitmap.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
 #include "utils/relcache.h"
 #include "utils/snapshot.h"
 
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index 93cc8afcebc2209569fd53881d422e1fb03b645a..97cb859fa50456586eef4c0d7fc3a05e9114f20f 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -24,7 +24,7 @@
 #include "fmgr.h"
 #include "lib/stringinfo.h"
 #include "storage/bufmgr.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
 #include "utils/relcache.h"
 
 /*
diff --git a/src/include/access/tuptoaster.h b/src/include/access/tuptoaster.h
index 7d185357714f886df52b3367c8799f9d848af4fa..77f637e90d735890b2d57cce6f96a7750dbc462e 100644
--- a/src/include/access/tuptoaster.h
+++ b/src/include/access/tuptoaster.h
@@ -14,8 +14,8 @@
 #define TUPTOASTER_H
 
 #include "access/htup_details.h"
+#include "storage/lockdefs.h"
 #include "utils/relcache.h"
-#include "storage/lock.h"
 
 /*
  * This enables de-toasting of index entries.  Needed until VACUUM is
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 37808c03c6e0b7244ddbde00de7b2279b78f3089..0fc16ed717396d50a34fa28ece934f23d8345f50 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -14,7 +14,7 @@
 #define OBJECTADDRESS_H
 
 #include "nodes/pg_list.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
 #include "utils/acl.h"
 #include "utils/relcache.h"
 
diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h
index bb87945088938e1414595e1b984faeab82352d8b..65cfa3f8249deb79c8b8c0b1941adcf901f66041 100644
--- a/src/include/port/atomics.h
+++ b/src/include/port/atomics.h
@@ -37,6 +37,10 @@
 #ifndef ATOMICS_H
 #define ATOMICS_H
 
+#ifdef FRONTEND
+#error "atomics.h may not be included from frontend code"
+#endif
+
 #define INSIDE_ATOMICS_H
 
 #include <limits.h>
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 96fe3a66ab080c8628ad7c227147e4105128cd4c..a9cd08c5276aae45b659b8c7d15532d593acacf7 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -14,6 +14,11 @@
 #ifndef LOCK_H_
 #define LOCK_H_
 
+#ifdef FRONTEND
+#error "lock.h may not be included from frontend code"
+#endif
+
+#include "storage/lockdefs.h"
 #include "storage/backendid.h"
 #include "storage/lwlock.h"
 #include "storage/shmem.h"
@@ -77,15 +82,6 @@ typedef struct
 	((vxid).backendId = (proc).backendId, \
 	 (vxid).localTransactionId = (proc).lxid)
 
-
-/*
- * LOCKMODE is an integer (1..N) indicating a lock type.  LOCKMASK is a bit
- * mask indicating a set of held or requested lock types (the bit 1<<mode
- * corresponds to a particular lock mode).
- */
-typedef int LOCKMASK;
-typedef int LOCKMODE;
-
 /* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
 #define MAX_LOCKMODES		10
 
@@ -133,28 +129,6 @@ typedef uint16 LOCKMETHODID;
 #define DEFAULT_LOCKMETHOD	1
 #define USER_LOCKMETHOD		2
 
-/*
- * These are the valid values of type LOCKMODE for all the standard lock
- * methods (both DEFAULT and USER).
- */
-
-/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
-#define NoLock					0
-
-#define AccessShareLock			1		/* SELECT */
-#define RowShareLock			2		/* SELECT FOR UPDATE/FOR SHARE */
-#define RowExclusiveLock		3		/* INSERT, UPDATE, DELETE */
-#define ShareUpdateExclusiveLock 4		/* VACUUM (non-FULL),ANALYZE, CREATE
-										 * INDEX CONCURRENTLY */
-#define ShareLock				5		/* CREATE INDEX (WITHOUT CONCURRENTLY) */
-#define ShareRowExclusiveLock	6		/* like EXCLUSIVE MODE, but allows ROW
-										 * SHARE */
-#define ExclusiveLock			7		/* blocks ROW SHARE/SELECT...FOR
-										 * UPDATE */
-#define AccessExclusiveLock		8		/* ALTER TABLE, DROP TABLE, VACUUM
-										 * FULL, and unqualified LOCK TABLE */
-
-
 /*
  * LOCKTAG is the key information needed to look up a LOCK item in the
  * lock hashtable.  A LOCKTAG value uniquely identifies a lockable object.
@@ -536,13 +510,6 @@ extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
 extern Size LockShmemSize(void);
 extern LockData *GetLockStatusData(void);
 
-typedef struct xl_standby_lock
-{
-	TransactionId xid;			/* xid of holder of AccessExclusiveLock */
-	Oid			dbOid;
-	Oid			relOid;
-} xl_standby_lock;
-
 extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);
 extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);
 
diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfbcdbaf119b6dfc5d054629d506c4957532cb84
--- /dev/null
+++ b/src/include/storage/lockdefs.h
@@ -0,0 +1,56 @@
+/*-------------------------------------------------------------------------
+ *
+ * lockdefs.h
+ *	   Frontend exposed parts of postgres' low level lock mechanism
+ *
+ * The split between lockdefs.h and lock.h is not very principled. This file
+ * contains definition that have to (indirectly) be available when included by
+ * FRONTEND code.
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/storage/lockdefs.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef LOCKDEFS_H_
+#define LOCKDEFS_H_
+
+/*
+ * LOCKMODE is an integer (1..N) indicating a lock type.  LOCKMASK is a bit
+ * mask indicating a set of held or requested lock types (the bit 1<<mode
+ * corresponds to a particular lock mode).
+ */
+typedef int LOCKMASK;
+typedef int LOCKMODE;
+
+/*
+ * These are the valid values of type LOCKMODE for all the standard lock
+ * methods (both DEFAULT and USER).
+ */
+
+/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
+#define NoLock					0
+
+#define AccessShareLock			1		/* SELECT */
+#define RowShareLock			2		/* SELECT FOR UPDATE/FOR SHARE */
+#define RowExclusiveLock		3		/* INSERT, UPDATE, DELETE */
+#define ShareUpdateExclusiveLock 4		/* VACUUM (non-FULL),ANALYZE, CREATE
+										 * INDEX CONCURRENTLY */
+#define ShareLock				5		/* CREATE INDEX (WITHOUT CONCURRENTLY) */
+#define ShareRowExclusiveLock	6		/* like EXCLUSIVE MODE, but allows ROW
+										 * SHARE */
+#define ExclusiveLock			7		/* blocks ROW SHARE/SELECT...FOR
+										 * UPDATE */
+#define AccessExclusiveLock		8		/* ALTER TABLE, DROP TABLE, VACUUM
+										 * FULL, and unqualified LOCK TABLE */
+
+typedef struct xl_standby_lock
+{
+	TransactionId xid;			/* xid of holder of AccessExclusiveLock */
+	Oid			dbOid;
+	Oid			relOid;
+} xl_standby_lock;
+
+#endif /* LOCKDEF_H_ */
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index cbd63184b9b4c131afd91a7e3187da3f89a92c87..f2ff6a06f0187feb89f87e7d5b42d44645b7bdae 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -14,6 +14,10 @@
 #ifndef LWLOCK_H
 #define LWLOCK_H
 
+#ifdef FRONTEND
+#error "lwlock.h may not be included from frontend code"
+#endif
+
 #include "lib/ilist.h"
 #include "storage/s_lock.h"
 #include "port/atomics.h"
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index a9b40ed944f7e8dbb526efb05eaa2c4d75746715..834f99b9918250be994a3af49b488bc74182688b 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -14,6 +14,7 @@
 #ifndef PROCARRAY_H
 #define PROCARRAY_H
 
+#include "storage/lock.h"
 #include "storage/standby.h"
 #include "utils/relcache.h"
 #include "utils/snapshot.h"
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 30f28b088ab2d2985e8b3093002f666af6f9c296..c461fda251b6d593a3a3b088dd8b0d907d3580de 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -96,6 +96,10 @@
 #ifndef S_LOCK_H
 #define S_LOCK_H
 
+#ifdef FRONTEND
+#error "s_lock.h may not be included from frontend code"
+#endif
+
 #ifdef HAVE_SPINLOCKS	/* skip spinlocks if requested */
 
 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h
index 7626c4c4f4bde6f3a59799fb01a6c4178e91db14..40b329b2a3c73027cbabc132ca69e927f9def886 100644
--- a/src/include/storage/standby.h
+++ b/src/include/storage/standby.h
@@ -16,7 +16,7 @@
 
 #include "access/xlogreader.h"
 #include "lib/stringinfo.h"
-#include "storage/lock.h"
+#include "storage/lockdefs.h"
 #include "storage/procsignal.h"
 #include "storage/relfilenode.h"