diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml
index 78ed082994..f5e88f7c86 100644
--- a/doc/src/sgml/textsearch.sgml
+++ b/doc/src/sgml/textsearch.sgml
@@ -2829,6 +2829,7 @@ iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic
 <programlisting>
 CREATE TEXT SEARCH DICTIONARY english_hunspell (
     TEMPLATE = ispell,
+    Shareable = false,
     DictFile = en_us,
     AffFile = en_us,
     Stopwords = english);
@@ -2843,6 +2844,9 @@ CREATE TEXT SEARCH DICTIONARY english_hunspell (
     The stop-words file has the same format explained above for the
     <literal>simple</literal> dictionary type.  The format of the other files is
     not specified here but is available from the above-mentioned web sites.
+    <literal>Shareable</literal> controls loading into shared memory.  By
+    default it is <literal>true</literal> (see more in
+    <xref linkend="textsearch-shared-dictionaries"/>).
    </para>
 
    <para>
@@ -3037,7 +3041,8 @@ CREATE TEXT SEARCH DICTIONARY english_stem (
     Some dictionaries, especially <application>Ispell</application>, consumes a
     noticable value of memory.  Size of a dictionary can reach tens of megabytes.
     Most of them also stores configuration in text files.  A dictionary is compiled
-    during first access per a user session.
+    during first access per a user session.  Currently only
+    <application>Ispell</application> supports loading into shared memory.
    </para>
 
    <para>
diff --git a/src/backend/tsearch/dict_ispell.c b/src/backend/tsearch/dict_ispell.c
index f8ab16d825..b423e403cb 100644
--- a/src/backend/tsearch/dict_ispell.c
+++ b/src/backend/tsearch/dict_ispell.c
@@ -38,7 +38,8 @@ typedef struct
 } DictISpell;
 
 static void parse_dictoptions(List *dictoptions,
-							  char **dictfile, char **afffile, char **stopfile);
+							  char **dictfile, char **afffile, char **stopfile,
+							  bool *isshared);
 static void *dispell_build(List *dictoptions, Size *size);
 
 Datum
@@ -48,15 +49,21 @@ dispell_init(PG_FUNCTION_ARGS)
 	DictISpell *d;
 	void	   *dict_location;
 	char	   *stopfile;
+	bool		isshared;
 
 	d = (DictISpell *) palloc0(sizeof(DictISpell));
 
-	parse_dictoptions(init_data->dictoptions, NULL, NULL, &stopfile);
+	parse_dictoptions(init_data->dictoptions, NULL, NULL, &stopfile, &isshared);
 
+	/* Make stop word list */
 	if (stopfile)
 		readstoplist(stopfile, &(d->stoplist), lowerstr);
 
-	dict_location = ts_dict_shmem_location(init_data, dispell_build);
+	/* Make or get from shared memory dictionary itself */
+	if (isshared)
+		dict_location = ts_dict_shmem_location(init_data, dispell_build);
+	else
+		dict_location = dispell_build(init_data->dictoptions, NULL);
 	Assert(dict_location);
 
 	d->obj.dict = (IspellDictData *) dict_location;
@@ -110,9 +117,10 @@ dispell_lexize(PG_FUNCTION_ARGS)
 
 static void
 parse_dictoptions(List *dictoptions, char **dictfile, char **afffile,
-				  char **stopfile)
+				  char **stopfile, bool *isshared)
 {
 	ListCell   *l;
+	bool		isshared_defined = false;
 
 	if (dictfile)
 		*dictfile = NULL;
@@ -120,6 +128,8 @@ parse_dictoptions(List *dictoptions, char **dictfile, char **afffile,
 		*afffile = NULL;
 	if (stopfile)
 		*stopfile = NULL;
+	if (isshared)
+		*isshared = true;
 
 	foreach(l, dictoptions)
 	{
@@ -158,6 +168,19 @@ parse_dictoptions(List *dictoptions, char **dictfile, char **afffile,
 						 errmsg("multiple StopWords parameters")));
 			*stopfile = defGetString(defel);
 		}
+		else if (pg_strcasecmp(defel->defname, "Shareable") == 0)
+		{
+			if (!isshared)
+				continue;
+
+			if (isshared_defined)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("multiple Shareable parameters")));
+
+			*isshared = defGetBoolean(defel);
+			isshared_defined = true;
+		}
 		else
 		{
 			ereport(ERROR,
@@ -180,7 +203,7 @@ dispell_build(List *dictoptions, Size *size)
 	char	   *dictfile,
 			   *afffile;
 
-	parse_dictoptions(dictoptions, &dictfile, &afffile, NULL);
+	parse_dictoptions(dictoptions, &dictfile, &afffile, NULL, NULL);
 
 	if (!afffile)
 	{
@@ -212,6 +235,7 @@ dispell_build(List *dictoptions, Size *size)
 	NIFinishBuild(&build);
 
 	/* Return the buffer and its size */
-	*size = build.dict_size;
+	if (size)
+		*size = build.dict_size;
 	return build.dict;
 }
diff --git a/src/test/regress/expected/tsdicts.out b/src/test/regress/expected/tsdicts.out
index 0c1d7c7675..6f6bca4f42 100644
--- a/src/test/regress/expected/tsdicts.out
+++ b/src/test/regress/expected/tsdicts.out
@@ -194,6 +194,7 @@ SELECT ts_lexize('hunspell', 'footballyklubber');
 -- Test ISpell dictionary with hunspell affix file with FLAG long parameter
 CREATE TEXT SEARCH DICTIONARY hunspell_long (
                         Template=ispell,
+                        Shareable=false,
                         DictFile=hunspell_sample_long,
                         AffFile=hunspell_sample_long
 );
@@ -290,6 +291,7 @@ SELECT ts_lexize('hunspell_long', 'footballyklubber');
 -- Test ISpell dictionary with hunspell affix file with FLAG num parameter
 CREATE TEXT SEARCH DICTIONARY hunspell_num (
                         Template=ispell,
+                        Shareable=false,
                         DictFile=hunspell_sample_num,
                         AffFile=hunspell_sample_num
 );
@@ -588,3 +590,58 @@ CREATE TEXT SEARCH DICTIONARY tsdict_case
 	"AffFile" = ispell_sample
 );
 ERROR:  unrecognized Ispell parameter: "DictFile"
+-- Test shared dictionaries
+CREATE TEXT SEARCH DICTIONARY shared_ispell (
+                        Template=ispell,
+                        DictFile=ispell_sample,
+                        AffFile=ispell_sample
+);
+-- Make sure that dictionaries in shared memory
+SELECT ts_lexize('ispell', 'skies');
+ ts_lexize 
+-----------
+ {sky}
+(1 row)
+
+SELECT ts_lexize('hunspell', 'skies');
+ ts_lexize 
+-----------
+ {sky}
+(1 row)
+
+SELECT ts_lexize('shared_ispell', 'skies');
+ ts_lexize 
+-----------
+ {sky}
+(1 row)
+
+SELECT schemaname, dictname FROM pg_ts_shared_dictionaries;
+ schemaname |   dictname    
+------------+---------------
+ public     | ispell
+ public     | hunspell
+ public     | shared_ispell
+(3 rows)
+
+-- shared_ispell space should be released in shared memory
+DROP TEXT SEARCH DICTIONARY shared_ispell;
+-- Make sure that dictionaries in shared memory, DROP invalidates cache
+SELECT ts_lexize('ispell', 'skies');
+ ts_lexize 
+-----------
+ {sky}
+(1 row)
+
+SELECT ts_lexize('hunspell', 'skies');
+ ts_lexize 
+-----------
+ {sky}
+(1 row)
+
+SELECT schemaname, dictname FROM pg_ts_shared_dictionaries;
+ schemaname | dictname 
+------------+----------
+ public     | ispell
+ public     | hunspell
+(2 rows)
+
diff --git a/src/test/regress/sql/tsdicts.sql b/src/test/regress/sql/tsdicts.sql
index 1633c0d066..66a7c37e53 100644
--- a/src/test/regress/sql/tsdicts.sql
+++ b/src/test/regress/sql/tsdicts.sql
@@ -51,6 +51,7 @@ SELECT ts_lexize('hunspell', 'footballyklubber');
 -- Test ISpell dictionary with hunspell affix file with FLAG long parameter
 CREATE TEXT SEARCH DICTIONARY hunspell_long (
                         Template=ispell,
+                        Shareable=false,
                         DictFile=hunspell_sample_long,
                         AffFile=hunspell_sample_long
 );
@@ -75,6 +76,7 @@ SELECT ts_lexize('hunspell_long', 'footballyklubber');
 -- Test ISpell dictionary with hunspell affix file with FLAG num parameter
 CREATE TEXT SEARCH DICTIONARY hunspell_num (
                         Template=ispell,
+                        Shareable=false,
                         DictFile=hunspell_sample_num,
                         AffFile=hunspell_sample_num
 );
@@ -196,3 +198,26 @@ CREATE TEXT SEARCH DICTIONARY tsdict_case
 	"DictFile" = ispell_sample,
 	"AffFile" = ispell_sample
 );
+
+-- Test shared dictionaries
+CREATE TEXT SEARCH DICTIONARY shared_ispell (
+                        Template=ispell,
+                        DictFile=ispell_sample,
+                        AffFile=ispell_sample
+);
+
+-- Make sure that dictionaries in shared memory
+SELECT ts_lexize('ispell', 'skies');
+SELECT ts_lexize('hunspell', 'skies');
+SELECT ts_lexize('shared_ispell', 'skies');
+
+SELECT schemaname, dictname FROM pg_ts_shared_dictionaries;
+
+-- shared_ispell space should be released in shared memory
+DROP TEXT SEARCH DICTIONARY shared_ispell;
+
+-- Make sure that dictionaries in shared memory, DROP invalidates cache
+SELECT ts_lexize('ispell', 'skies');
+SELECT ts_lexize('hunspell', 'skies');
+
+SELECT schemaname, dictname FROM pg_ts_shared_dictionaries;
