diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py
index f9f50cc2ad..2fb2d713ca 100644
--- a/django/core/management/commands/makemigrations.py
+++ b/django/core/management/commands/makemigrations.py
@@ -4,8 +4,9 @@ import warnings
 from itertools import takewhile
 
 from django.apps import apps
+from django.conf import settings
 from django.core.management.base import BaseCommand, CommandError
-from django.db import connections
+from django.db import DEFAULT_DB_ALIAS, connections, router
 from django.db.migrations import Migration
 from django.db.migrations.autodetector import MigrationAutodetector
 from django.db.migrations.loader import MigrationLoader
@@ -94,9 +95,14 @@ class Command(BaseCommand):
         loader = MigrationLoader(None, ignore_no_migrations=True)
 
         # Raise an error if any migrations are applied before their dependencies.
-        for db in connections:
-            connection = connections[db]
-            if connection.settings_dict['ENGINE'] != 'django.db.backends.dummy':
+        consistency_check_labels = set(config.label for config in apps.get_app_configs())
+        # Non-default databases are only checked if database routers used.
+        aliases_to_check = connections if settings.DATABASE_ROUTERS else [DEFAULT_DB_ALIAS]
+        for alias in sorted(aliases_to_check):
+            connection = connections[alias]
+            if (connection.settings_dict['ENGINE'] != 'django.db.backends.dummy' and
+                    # At least one app must be migrated to the database.
+                    any(router.allow_migrate(connection.alias, label) for label in consistency_check_labels)):
                 loader.check_consistent_history(connection)
 
         # Before anything else, see if there's conflicting apps and drop out
diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py
index c78aaed573..ce6fd9e3c0 100644
--- a/django/db/migrations/loader.py
+++ b/django/db/migrations/loader.py
@@ -6,7 +6,6 @@ from importlib import import_module
 
 from django.apps import apps
 from django.conf import settings
-from django.db.migrations.exceptions import MigrationSchemaMissing
 from django.db.migrations.graph import MigrationGraph
 from django.db.migrations.recorder import MigrationRecorder
 from django.utils import six
@@ -280,12 +279,7 @@ class MigrationLoader(object):
         unapplied dependencies.
         """
         recorder = MigrationRecorder(connection)
-        try:
-            applied = recorder.applied_migrations()
-        except MigrationSchemaMissing:
-            # Skip check if the django_migrations table is missing and can't be
-            # created.
-            return
+        applied = recorder.applied_migrations()
         for migration in applied:
             # If the migration is unknown, skip it.
             if migration not in self.graph.nodes:
diff --git a/docs/releases/1.10.1.txt b/docs/releases/1.10.1.txt
index 6dbf40de02..80313a92b5 100644
--- a/docs/releases/1.10.1.txt
+++ b/docs/releases/1.10.1.txt
@@ -55,7 +55,9 @@ Bugfixes
 
 * Reallowed the ``{% for %}`` tag to unpack any iterable (:ticket:`27058`).
 
-* Fixed ``makemigrations`` crash if a database is read-only (:ticket:`27054`).
+* Made ``makemigrations`` skip inconsistent history checks on non-default
+  databases if database routers aren't in use or if no apps can be migrated
+  to the database (:ticket:`27054`, :ticket:`27110`, :ticket:`27142`).
 
 * Removed duplicated managers in ``Model._meta.managers`` (:ticket:`27073`).
 
diff --git a/tests/migrations/routers.py b/tests/migrations/routers.py
index 8970d9d681..9857363937 100644
--- a/tests/migrations/routers.py
+++ b/tests/migrations/routers.py
@@ -1,3 +1,7 @@
+class EmptyRouter(object):
+    pass
+
+
 class TestRouter(object):
     def allow_migrate(self, db, app_label, model_name=None, **hints):
         """
diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py
index dca1a46780..7ff09de84e 100644
--- a/tests/migrations/test_commands.py
+++ b/tests/migrations/test_commands.py
@@ -22,6 +22,7 @@ from django.utils.deprecation import RemovedInDjango20Warning
 from django.utils.encoding import force_text
 
 from .models import UnicodeModel, UnserializableModel
+from .routers import TestRouter
 from .test_base import MigrationTestBase
 
 
@@ -597,14 +598,14 @@ class MakeMigrationsTests(MigrationTestBase):
                 init_file = os.path.join(migration_dir, '__init__.py')
                 self.assertTrue(os.path.exists(init_file))
 
-    def test_makemigrations_other_datbase_is_readonly(self):
+    def test_makemigrations_consistency_checks_respect_routers(self):
         """
-        makemigrations ignores the non-default database if it's read-only.
+        The history consistency checks in makemigrations respect
+        settings.DATABASE_ROUTERS.
         """
         def patched_ensure_schema(migration_recorder):
-            from django.db import connections
             if migration_recorder.connection is connections['other']:
-                raise MigrationSchemaMissing()
+                raise MigrationSchemaMissing('Patched')
             else:
                 return mock.DEFAULT
 
@@ -612,11 +613,33 @@ class MakeMigrationsTests(MigrationTestBase):
         apps.register_model('migrations', UnicodeModel)
         with mock.patch.object(
                 MigrationRecorder, 'ensure_schema',
-                autospec=True, side_effect=patched_ensure_schema):
+                autospec=True, side_effect=patched_ensure_schema) as ensure_schema:
             with self.temporary_migration_module() as migration_dir:
                 call_command("makemigrations", "migrations", verbosity=0)
                 initial_file = os.path.join(migration_dir, "0001_initial.py")
                 self.assertTrue(os.path.exists(initial_file))
+                self.assertEqual(ensure_schema.call_count, 1)  # 'default' is checked
+
+                # Router says not to migrate 'other' so consistency shouldn't
+                # be checked.
+                with self.settings(DATABASE_ROUTERS=['migrations.routers.TestRouter']):
+                    call_command('makemigrations', 'migrations', verbosity=0)
+                self.assertEqual(ensure_schema.call_count, 2)  # 'default' again
+
+                # With a router that doesn't prohibit migrating 'other',
+                # consistency is checked.
+                with self.settings(DATABASE_ROUTERS=['migrations.routers.EmptyRouter']):
+                    with self.assertRaisesMessage(MigrationSchemaMissing, 'Patched'):
+                        call_command('makemigrations', 'migrations', verbosity=0)
+                self.assertEqual(ensure_schema.call_count, 4)  # 'default' and 'other'
+
+                # With a router that doesn't allow migrating on any database,
+                # no consistency checks are made.
+                with self.settings(DATABASE_ROUTERS=['migrations.routers.TestRouter']):
+                    with mock.patch.object(TestRouter, 'allow_migrate', return_value=False) as allow_migrate:
+                        call_command('makemigrations', 'migrations', verbosity=0)
+                allow_migrate.assert_called_with('other', 'migrations')
+                self.assertEqual(ensure_schema.call_count, 4)
 
     def test_failing_migration(self):
         # If a migration fails to serialize, it shouldn't generate an empty file. #21280
diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py
index 5b31fcbd2c..05edd7f1e0 100644
--- a/tests/migrations/test_loader.py
+++ b/tests/migrations/test_loader.py
@@ -4,12 +4,11 @@ from unittest import skipIf
 
 from django.db import connection, connections
 from django.db.migrations.exceptions import (
-    AmbiguityError, InconsistentMigrationHistory, MigrationSchemaMissing,
-    NodeNotFoundError,
+    AmbiguityError, InconsistentMigrationHistory, NodeNotFoundError,
 )
 from django.db.migrations.loader import MigrationLoader
 from django.db.migrations.recorder import MigrationRecorder
-from django.test import TestCase, mock, modify_settings, override_settings
+from django.test import TestCase, modify_settings, override_settings
 from django.utils import six
 
 
@@ -484,12 +483,3 @@ class LoaderTests(TestCase):
             ('app1', '4_auto'),
         }
         self.assertEqual(plan, expected_plan)
-
-    def test_readonly_database(self):
-        """
-        check_consistent_history() ignores read-only databases, possibly
-        without a django_migrations table.
-        """
-        with mock.patch.object(MigrationRecorder, 'ensure_schema', side_effect=MigrationSchemaMissing()):
-            loader = MigrationLoader(connection=None)
-            loader.check_consistent_history(connection)