diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
new file mode 100644
index 9a758bd..bded11e
*** a/src/backend/storage/lmgr/proc.c
--- b/src/backend/storage/lmgr/proc.c
*************** int			StatementTimeout = 0;
*** 60,65 ****
--- 60,66 ----
  int			LockTimeout = 0;
  int			IdleInTransactionSessionTimeout = 0;
  bool		log_lock_waits = false;
+ bool		notice_lock_waits = false;
  
  /* Pointer to this process's PGPROC and PGXACT structs, if any */
  PGPROC	   *MyProc = NULL;
*************** ProcSleep(LOCALLOCK *locallock, LockMeth
*** 1307,1313 ****
  		 * If awoken after the deadlock check interrupt has run, and
  		 * log_lock_waits is on, then report about the wait.
  		 */
! 		if (log_lock_waits && deadlock_state != DS_NOT_YET_CHECKED)
  		{
  			StringInfoData buf,
  						lock_waiters_sbuf,
--- 1308,1314 ----
  		 * If awoken after the deadlock check interrupt has run, and
  		 * log_lock_waits is on, then report about the wait.
  		 */
! 		if ((log_lock_waits || notice_lock_waits) && deadlock_state != DS_NOT_YET_CHECKED)
  		{
  			StringInfoData buf,
  						lock_waiters_sbuf,
*************** ProcSleep(LOCALLOCK *locallock, LockMeth
*** 1389,1448 ****
  
  			LWLockRelease(partitionLock);
  
! 			if (deadlock_state == DS_SOFT_DEADLOCK)
! 				ereport(LOG,
! 						(errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
! 								MyProcPid, modename, buf.data, msecs, usecs),
! 						 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
! 						   "Processes holding the lock: %s. Wait queue: %s.",
! 											   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
! 			else if (deadlock_state == DS_HARD_DEADLOCK)
! 			{
! 				/*
! 				 * This message is a bit redundant with the error that will be
! 				 * reported subsequently, but in some cases the error report
! 				 * might not make it to the log (eg, if it's caught by an
! 				 * exception handler), and we want to ensure all long-wait
! 				 * events get logged.
! 				 */
! 				ereport(LOG,
! 						(errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
! 								MyProcPid, modename, buf.data, msecs, usecs),
! 						 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
! 						   "Processes holding the lock: %s. Wait queue: %s.",
! 											   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
! 			}
! 
! 			if (myWaitStatus == STATUS_WAITING)
! 				ereport(LOG,
  						(errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
! 								MyProcPid, modename, buf.data, msecs, usecs),
! 						 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
! 						   "Processes holding the lock: %s. Wait queue: %s.",
! 											   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
! 			else if (myWaitStatus == STATUS_OK)
! 				ereport(LOG,
  					(errmsg("process %d acquired %s on %s after %ld.%03d ms",
  							MyProcPid, modename, buf.data, msecs, usecs)));
! 			else
  			{
! 				Assert(myWaitStatus == STATUS_ERROR);
  
! 				/*
! 				 * Currently, the deadlock checker always kicks its own
! 				 * process, which means that we'll only see STATUS_ERROR when
! 				 * deadlock_state == DS_HARD_DEADLOCK, and there's no need to
! 				 * print redundant messages.  But for completeness and
! 				 * future-proofing, print a message if it looks like someone
! 				 * else kicked us off the lock.
! 				 */
! 				if (deadlock_state != DS_HARD_DEADLOCK)
  					ereport(LOG,
! 							(errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
! 								MyProcPid, modename, buf.data, msecs, usecs),
  							 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
! 						   "Processes holding the lock: %s. Wait queue: %s.",
  												   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
  			}
  
  			/*
--- 1390,1462 ----
  
  			LWLockRelease(partitionLock);
  
! 			if (notice_lock_waits && myWaitStatus == STATUS_WAITING)
! 				ereport(NOTICE,
  						(errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
! 								MyProcPid, modename, buf.data, msecs, usecs)));
! 
! 			if (notice_lock_waits && myWaitStatus == STATUS_OK)
! 				ereport(NOTICE,
  					(errmsg("process %d acquired %s on %s after %ld.%03d ms",
  							MyProcPid, modename, buf.data, msecs, usecs)));
! 
! 			if (log_lock_waits)
  			{
! 				if (deadlock_state == DS_SOFT_DEADLOCK)
! 					ereport(LOG,
! 							(errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
! 									MyProcPid, modename, buf.data, msecs, usecs),
! 							 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
! 							   "Processes holding the lock: %s. Wait queue: %s.",
! 												   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
! 				else if (deadlock_state == DS_HARD_DEADLOCK)
! 				{
! 					/*
! 					 * This message is a bit redundant with the error that will be
! 					 * reported subsequently, but in some cases the error report
! 					 * might not make it to the log (eg, if it's caught by an
! 					 * exception handler), and we want to ensure all long-wait
! 					 * events get logged.
! 					 */
! 					ereport(LOG,
! 							(errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
! 									MyProcPid, modename, buf.data, msecs, usecs),
! 							 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
! 							   "Processes holding the lock: %s. Wait queue: %s.",
! 												   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
! 				}
  
! 				if (myWaitStatus == STATUS_WAITING)
  					ereport(LOG,
! 							(errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
! 									MyProcPid, modename, buf.data, msecs, usecs),
  							 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
! 							   "Processes holding the lock: %s. Wait queue: %s.",
  												   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
+ 				else if (myWaitStatus == STATUS_OK)
+ 					ereport(LOG,
+ 						(errmsg("process %d acquired %s on %s after %ld.%03d ms",
+ 								MyProcPid, modename, buf.data, msecs, usecs)));
+ 				else
+ 				{
+ 					Assert(myWaitStatus == STATUS_ERROR);
+ 
+ 					/*
+ 					 * Currently, the deadlock checker always kicks its own
+ 					 * process, which means that we'll only see STATUS_ERROR when
+ 					 * deadlock_state == DS_HARD_DEADLOCK, and there's no need to
+ 					 * print redundant messages.  But for completeness and
+ 					 * future-proofing, print a message if it looks like someone
+ 					 * else kicked us off the lock.
+ 					 */
+ 					if (deadlock_state != DS_HARD_DEADLOCK)
+ 						ereport(LOG,
+ 								(errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
+ 									MyProcPid, modename, buf.data, msecs, usecs),
+ 								 (errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
+ 							   "Processes holding the lock: %s. Wait queue: %s.",
+ 													   lockHoldersNum, lock_holders_sbuf.data, lock_waiters_sbuf.data))));
+ 				}
  			}
  
  			/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
new file mode 100644
index 9c93df0..fc453b0
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** static struct config_bool ConfigureNames
*** 1289,1294 ****
--- 1289,1304 ----
  	},
  
  	{
+ 		{"notice_lock_waits", PGC_USERSET, LOGGING_WHAT,
+ 			gettext_noop("Issues NOTICES for long lock waits."),
+ 			NULL
+ 		},
+ 		&notice_lock_waits,
+ 		false,
+ 		NULL, NULL, NULL
+ 	},
+ 
+ 	{
  		{"log_hostname", PGC_SIGHUP, LOGGING_WHAT,
  			gettext_noop("Logs the host name in the connection logs."),
  			gettext_noop("By default, connection logs only show the IP address "
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
new file mode 100644
index 775c66a..9e06ffc
*** a/src/include/storage/proc.h
--- b/src/include/storage/proc.h
*************** extern int	StatementTimeout;
*** 260,265 ****
--- 260,266 ----
  extern int	LockTimeout;
  extern int	IdleInTransactionSessionTimeout;
  extern bool log_lock_waits;
+ extern bool notice_lock_waits;
  
  
  /*
