diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index f043433..e01e002 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -2591,10 +2591,10 @@ include_dir 'conf.d'
         data to support WAL archiving and replication, including running
         read-only queries on a standby server. <literal>minimal</literal> removes all
         logging except the information required to recover from a crash or
-        immediate shutdown.  Finally,
+        immediate shutdown.  <literal>none</literal> generates no WAL in any case. Finally,
         <literal>logical</literal> adds information necessary to support logical
-        decoding.  Each level includes the information logged at all lower
-        levels.  This parameter can only be set at server start.
+        decoding.  Each level except for <literal>none</literal> includes the
+        information logged at all lower levels.  This parameter can only be set at server start.
        </para>
        <para>
         In <literal>minimal</literal> level, no information is logged for
@@ -2615,6 +2615,13 @@ include_dir 'conf.d'
         data from a base backup and the WAL logs, so <literal>replica</literal> or
         higher must be used to enable WAL archiving
         (<xref linkend="guc-archive-mode"/>) and streaming replication.
+        In the same way, <literal>none</literal> does not create WAL logs.
+        Therefore, this <varname>wal_level</varname> can be used to maximize the speed of data loading.
+        For example, bulk loading into a data warehouse environemnt or version upgrade using pg_dumpall.
+        On the other hand, an unexpected crash of the server makes the database cluster
+        inconsistent. For that reason, before utilizing this level, get a full backup of the cluster and
+        backup of the entire operations that are done under the condition that
+        <varname>wal_level</varname> is <literal>none</literal>.
        </para>
        <para>
         In <literal>logical</literal> level, the same information is logged as
@@ -3372,7 +3379,8 @@ include_dir 'conf.d'
         changed without leaving archiving mode.
         This parameter can only be set at server start.
         <varname>archive_mode</varname> cannot be enabled when
-        <varname>wal_level</varname> is set to <literal>minimal</literal>.
+        <varname>wal_level</varname> is set to <literal>none</literal> or
+        <literal>minimal</literal>.
        </para>
       </listitem>
      </varlistentry>
diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml
index 117a1f7..f035c84 100644
--- a/doc/src/sgml/perform.sgml
+++ b/doc/src/sgml/perform.sgml
@@ -1741,7 +1741,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
     new base backup after the load has completed than to process a large
     amount of incremental WAL data.  To prevent incremental WAL logging
     while loading, disable archiving and streaming replication, by setting
-    <xref linkend="guc-wal-level"/> to <literal>minimal</literal>,
+    <xref linkend="guc-wal-level"/> to either <literal>none</literal>
+    or <literal>minimal</literal>,
     <xref linkend="guc-archive-mode"/> to <literal>off</literal>, and
     <xref linkend="guc-max-wal-senders"/> to zero.
     But note that changing these settings requires a server restart.
@@ -1751,7 +1752,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
     Aside from avoiding the time for the archiver or WAL sender to process the
     WAL data, doing this will actually make certain commands faster, because
     they do not to write WAL at all if <varname>wal_level</varname>
-    is <literal>minimal</literal> and the current subtransaction (or top-level
+    is either <literal>minimal</literal> or <literal>minimal</literal>
+    and the current subtransaction (or top-level
     transaction) created or truncated the table or index they change.  (They
     can guarantee crash safety more cheaply by doing
     an <function>fsync</function> at the end than by writing WAL.)
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index 3200f77..8293b3b 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -25,6 +25,7 @@
  * GUC support
  */
 const struct config_enum_entry wal_level_options[] = {
+	{"none", WAL_LEVEL_NONE, false},
 	{"minimal", WAL_LEVEL_MINIMAL, false},
 	{"replica", WAL_LEVEL_REPLICA, false},
 	{"archive", WAL_LEVEL_REPLICA, true},	/* deprecated */
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 52a67b1..4a5e43b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -4907,6 +4907,27 @@ UpdateControlFile(void)
 }
 
 /*
+ * Perform an inspection of wal_level='none'.
+ */
+void
+SafelyFinishedNoneLevel(void)
+{
+	bool		unexpected_shutdown;
+
+	/*
+	 * Detect if we previously crashed under wal_level='none' or not.
+	 */
+	unexpected_shutdown = ControlFile->state != DB_SHUTDOWNED &&
+		ControlFile->state != DB_SHUTDOWNED_IN_RECOVERY;
+	if ((ControlFile->wal_level == WAL_LEVEL_NONE && unexpected_shutdown))
+	{
+		ereport(ERROR,
+				(errmsg("Server was unexpectedly shut down when WAL logging was disabled"),
+				 errhint("It looks like you need to deploy a new cluster from your full backup again.")));
+	}
+}
+
+/*
  * Returns the unique system identifier from control file.
  */
 uint64
@@ -4937,6 +4958,21 @@ DataChecksumsEnabled(void)
 }
 
 /*
+ * Returns the latest LSN.
+ */
+XLogRecPtr
+GetLatestCheckPointLSN(void)
+{
+	XLogRecPtr	latestLSN;
+
+	LWLockAcquire(ControlFileLock, LW_SHARED);
+	latestLSN = ControlFile->checkPoint;
+	LWLockRelease(ControlFileLock);
+
+	return latestLSN;
+}
+
+/*
  * Returns a fake LSN for unlogged relations.
  *
  * Each call generates an LSN that is greater than any previous value
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index 1f0e4e0..39765ad 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -449,6 +449,13 @@ XLogInsert(RmgrId rmid, uint8 info)
 		return EndPos;
 	}
 
+	/* Issues WAL only for transaction end and check point */
+	if (wal_level == WAL_LEVEL_NONE && rmid != RM_XLOG_ID)
+	{
+		XLogResetInsertion();
+		return GetLatestCheckPointLSN();
+	}
+
 	do
 	{
 		XLogRecPtr	RedoRecPtr;
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 959e3b8..a365cbf 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -918,10 +918,13 @@ PostmasterMain(int argc, char *argv[])
 					 ReservedBackends, MaxConnections);
 		ExitPostmaster(1);
 	}
-	if (XLogArchiveMode > ARCHIVE_MODE_OFF && wal_level == WAL_LEVEL_MINIMAL)
+	if ((XLogArchiveMode > ARCHIVE_MODE_OFF && wal_level == WAL_LEVEL_NONE) ||
+		(XLogArchiveMode > ARCHIVE_MODE_OFF && wal_level == WAL_LEVEL_MINIMAL))
 		ereport(ERROR,
-				(errmsg("WAL archival cannot be enabled when wal_level is \"minimal\"")));
-	if (max_wal_senders > 0 && wal_level == WAL_LEVEL_MINIMAL)
+				(errmsg("WAL archival cannot be enabled when wal_level is \"%s\"",
+						wal_level == WAL_LEVEL_MINIMAL ? "minimal" : "none")));
+	if ((max_wal_senders > 0 && wal_level == WAL_LEVEL_NONE) ||
+		(max_wal_senders > 0 && wal_level == WAL_LEVEL_MINIMAL))
 		ereport(ERROR,
 				(errmsg("WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"")));
 
@@ -989,6 +992,12 @@ PostmasterMain(int argc, char *argv[])
 	LocalProcessControlFile(false);
 
 	/*
+	 * Check some conditions specific to wal_level='none' and ensures the
+	 * database isn't inconsistent.
+	 */
+	SafelyFinishedNoneLevel();
+
+	/*
 	 * Register the apply launcher.  Since it registers a background worker,
 	 * it needs to be called before InitializeMaxBackends(), and it's probably
 	 * a good idea to call it before any modules had chance to take the
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 3e00ac0..90ec0dc 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -74,6 +74,8 @@ wal_level_str(WalLevel wal_level)
 {
 	switch (wal_level)
 	{
+		case WAL_LEVEL_NONE:
+			return "none";
 		case WAL_LEVEL_MINIMAL:
 			return "minimal";
 		case WAL_LEVEL_REPLICA:
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 221af87..e21b3cc 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -161,7 +161,8 @@ extern int	XLogArchiveMode;
 /* WAL levels */
 typedef enum WalLevel
 {
-	WAL_LEVEL_MINIMAL = 0,
+	WAL_LEVEL_NONE = 0,
+	WAL_LEVEL_MINIMAL,
 	WAL_LEVEL_REPLICA,
 	WAL_LEVEL_LOGICAL
 } WalLevel;
@@ -316,9 +317,11 @@ extern TimestampTz GetLatestXTime(void);
 extern TimestampTz GetCurrentChunkReplayStartTime(void);
 
 extern void UpdateControlFile(void);
+extern void SafelyFinishedNoneLevel(void);
 extern uint64 GetSystemIdentifier(void);
 extern char *GetMockAuthenticationNonce(void);
 extern bool DataChecksumsEnabled(void);
+extern XLogRecPtr GetLatestCheckPointLSN(void);
 extern XLogRecPtr GetFakeLSNForUnloggedRel(void);
 extern Size XLOGShmemSize(void);
 extern void XLOGShmemInit(void);
