diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 71e20f2740..00faef73ed 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -8228,6 +8228,11 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
       <entry>time zone names</entry>
      </row>
 
+     <row>
+      <entry><link linkend="view-pg-ts-shared-dictionaries"><structname>pg_ts_shared_dictionaries</structname></link></entry>
+      <entry>dictionaries currently in shared memory</entry>
+     </row>
+
      <row>
       <entry><link linkend="view-pg-user"><structname>pg_user</structname></link></entry>
       <entry>database users</entry>
@@ -10983,6 +10988,63 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
 
  </sect1>
 
+ <sect1 id="view-pg-ts-shared-dictionaries">
+  <title><structname>pg_ts_shared_dictionaries</structname></title>
+
+  <indexterm zone="view-pg-ts-shared-dictionaries">
+   <primary>pg_ts_shared_dictionaries</primary>
+  </indexterm>
+
+  <para>
+   The <structname>pg_ts_shared_dictionaries</structname> view provides a
+   listing of all text search dictionaries that currently allocated in the
+   shared memory. The size of available space in shared memory is controlled by
+   <xref linkend="guc-shared-buffers"/>. A dictionary may have an option which
+   controls allocation in shared memory (see <xref linkend="textsearch-ispell-dictionary"/>).
+  </para>
+
+  <table>
+   <title><structname>pg_ts_shared_dictionaries</structname> Columns</title>
+
+   <tgroup cols="4">
+    <thead>
+     <row>
+      <entry>Name</entry>
+      <entry>Type</entry>
+      <entry>References</entry>
+      <entry>Description</entry>
+     </row>
+    </thead>
+    <tbody>
+     <row>
+      <entry><structfield>dictoid</structfield></entry>
+      <entry><type>oid</type></entry>
+      <entry><literal><link linkend="catalog-pg-ts-dict"><structname>pg_ts_dict</structname></link>.oid</literal></entry>
+      <entry>The OID of the text search dictionary located in shared memory</entry>
+     </row>
+     <row>
+      <entry><structfield>schemaname</structfield></entry>
+      <entry><type>name</type></entry>
+      <entry><literal><link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.nspname</literal></entry>
+      <entry>The name of schema containing the text search dictionary</entry>
+     </row>
+     <row>
+      <entry><structfield>dictname</structfield></entry>
+      <entry><type>name</type></entry>
+      <entry><literal><link linkend="catalog-pg-ts-dict"><structname>pg_ts_dict</structname></link>.dictname</literal></entry>
+      <entry>The text search dictionary name</entry>
+     </row>
+     <row>
+      <entry><structfield>size</structfield></entry>
+      <entry><type>bigint</type></entry>
+      <entry></entry>
+      <entry>Size of the text search dictionary in bytes</entry>
+     </row>
+    </tbody>
+   </tgroup>
+  </table>
+ </sect1>
+
  <sect1 id="view-pg-user">
   <title><structname>pg_user</structname></title>
 
diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml
index 82afe201f8..78ed082994 100644
--- a/doc/src/sgml/textsearch.sgml
+++ b/doc/src/sgml/textsearch.sgml
@@ -3045,6 +3045,12 @@ CREATE TEXT SEARCH DICTIONARY english_stem (
     parameter value greater than zero before server starting.
    </para>
 
+   <para>
+    List of dictionaries currently located in shared memory can be retreived by
+    <link linkend="view-pg-ts-shared-dictionaries"><structname>pg_ts_shared_dictionaries</structname></link>
+    view.
+   </para>
+
   </sect2>
 
  </sect1>
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 5652e9ee6d..c663db3cf2 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -504,6 +504,9 @@ CREATE VIEW pg_config AS
 REVOKE ALL on pg_config FROM PUBLIC;
 REVOKE EXECUTE ON FUNCTION pg_config() FROM PUBLIC;
 
+CREATE VIEW pg_ts_shared_dictionaries AS
+    SELECT * FROM pg_ts_shared_dictionaries();
+
 -- Statistics views
 
 CREATE VIEW pg_stat_all_tables AS
diff --git a/src/backend/tsearch/ts_shared.c b/src/backend/tsearch/ts_shared.c
index 7d1f7544cf..ff3127f207 100644
--- a/src/backend/tsearch/ts_shared.c
+++ b/src/backend/tsearch/ts_shared.c
@@ -13,11 +13,18 @@
  */
 #include "postgres.h"
 
+#include "funcapi.h"
+#include "miscadmin.h"
+
+#include "access/htup_details.h"
+#include "catalog/pg_ts_dict.h"
 #include "lib/dshash.h"
 #include "storage/lwlock.h"
 #include "storage/shmem.h"
 #include "tsearch/ts_shared.h"
+#include "utils/builtins.h"
 #include "utils/hashutils.h"
+#include "utils/lsyscache.h"
 #include "utils/memutils.h"
 
 
@@ -364,3 +371,100 @@ recheck_table:
 
 	MemoryContextSwitchTo(old_context);
 }
+
+/*
+ * pg_ts_shared_dictionaries - SQL SRF showing dictionaries currently in
+ * shared memory.
+ */
+Datum
+pg_ts_shared_dictionaries(PG_FUNCTION_ARGS)
+{
+	ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
+	MemoryContext oldcontext;
+	TupleDesc	tupdesc;
+	Tuplestorestate *tupstore;
+	Relation	rel;
+	HeapTuple	tuple;
+	SysScanDesc scan;
+
+	/* check to see if caller supports us returning a tuplestore */
+	if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("set-valued function called in context that cannot accept a set")));
+	if (!(rsinfo->allowedModes & SFRM_Materialize))
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("materialize mode required, but it is not " \
+						"allowed in this context")));
+
+	/* Build a tuple descriptor for our result type */
+	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+		elog(ERROR, "return type must be a row type");
+
+	/* Build tuplestore to hold the result rows */
+	oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
+
+	tupstore = tuplestore_begin_heap(true, false, work_mem);
+	rsinfo->returnMode = SFRM_Materialize;
+	rsinfo->setResult = tupstore;
+	rsinfo->setDesc = tupdesc;
+
+	MemoryContextSwitchTo(oldcontext);
+
+	init_dict_table();
+
+	/*
+	 * If a hash table wasn't created return zero records.
+	 */
+	if (!DsaPointerIsValid(tsearch_ctl->dict_table_handle))
+	{
+		tuplestore_donestoring(tupstore);
+
+		PG_RETURN_VOID();
+	}
+
+	/* Start to scan pg_ts_dict */
+	rel = heap_open(TSDictionaryRelationId, AccessShareLock);
+	scan = systable_beginscan(rel, InvalidOid, false, NULL, 0, NULL);
+
+	while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+	{
+		Datum		values[4];
+		bool		nulls[4];
+		Form_pg_ts_dict dict = (Form_pg_ts_dict) GETSTRUCT(tuple);
+		Oid			dictid = HeapTupleGetOid(tuple);
+		TsearchDictEntry *entry;
+		NameData	dict_name;
+
+		/* If dictionary isn't located in shared memory try following */
+		entry = (TsearchDictEntry *) dshash_find(dict_table, &dictid, false);
+		if (!entry)
+			continue;
+
+		namecpy(&dict_name, &dict->dictname);
+
+		memset(nulls, 0, sizeof(nulls));
+
+		values[0] = ObjectIdGetDatum(dictid);
+
+		if (OidIsValid(dict->dictnamespace))
+			values[1] = CStringGetDatum(get_namespace_name(dict->dictnamespace));
+		else
+			nulls[1] = true;
+
+		values[2] = NameGetDatum(&dict_name);
+		values[3] = Int64GetDatum(entry->dict_size);
+
+		dshash_release_lock(dict_table, entry);
+
+		tuplestore_putvalues(tupstore, tupdesc, values, nulls);
+	}
+
+	systable_endscan(scan);
+	heap_close(rel, AccessShareLock);
+
+	tuplestore_donestoring(tupstore);
+
+	PG_RETURN_VOID();
+}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index ecec8f7ff8..71f704fc92 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -4961,6 +4961,9 @@ DESCR("trigger for automatic update of tsvector column");
 DATA(insert OID = 3759 (  get_current_ts_config PGNSP PGUID 12 1 0 0 0 f f f f t f s s 0 0 3734 "" _null_ _null_ _null_ _null_ _null_ get_current_ts_config _null_ _null_ _null_ ));
 DESCR("get current tsearch configuration");
 
+DATA(insert OID = 4213 (  pg_ts_shared_dictionaries PGNSP PGUID 12 1 10 0 0 f f f f f t s s 0 0 2249 "" "{26,19,19,20}" "{o,o,o,o}" "{dictoid,schemaname,dictname,size}" _null_ _null_ pg_ts_shared_dictionaries _null_ _null_ _null_ ));
+DESCR("information about text search dictionaries currently in shared memory");
+
 DATA(insert OID = 3736 (  regconfigin		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 3734 "2275" _null_ _null_ _null_ _null_ _null_ regconfigin _null_ _null_ _null_ ));
 DESCR("I/O");
 DATA(insert OID = 3737 (  regconfigout		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 2275 "3734" _null_ _null_ _null_ _null_ _null_ regconfigout _null_ _null_ _null_ ));
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 5433944c6a..235b066119 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2209,6 +2209,11 @@ pg_timezone_names| SELECT pg_timezone_names.name,
     pg_timezone_names.utc_offset,
     pg_timezone_names.is_dst
    FROM pg_timezone_names() pg_timezone_names(name, abbrev, utc_offset, is_dst);
+pg_ts_shared_dictionaries| SELECT pg_ts_shared_dictionaries.dictoid,
+    pg_ts_shared_dictionaries.schemaname,
+    pg_ts_shared_dictionaries.dictname,
+    pg_ts_shared_dictionaries.size
+   FROM pg_ts_shared_dictionaries() pg_ts_shared_dictionaries(dictoid, schemaname, dictname, size);
 pg_user| SELECT pg_shadow.usename,
     pg_shadow.usesysid,
     pg_shadow.usecreatedb,
