diff --git a/CHANGES.rst b/CHANGES.rst
index 039cc6ec..f3f7d1cd 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -9,6 +9,8 @@
 
 - Drop support for Python 3.3.
 
+- Ensure that the ``HistoricalStorageAdapter`` forwards the ``release`` method to
+  its base instance. See `issue 78 <https://github.com/zopefoundation/ZODB/issues/788>`_.
 
 5.2.4 (2017-05-17)
 ==================
diff --git a/src/ZODB/mvccadapter.py b/src/ZODB/mvccadapter.py
index cacb6584..121e579b 100644
--- a/src/ZODB/mvccadapter.py
+++ b/src/ZODB/mvccadapter.py
@@ -27,10 +27,9 @@ class Base(object):
 
     def __getattr__(self, name):
         if name in self._copy_methods:
-            if hasattr(self._storage, name):
-                m = getattr(self._storage, name)
-                setattr(self, name, m)
-                return m
+            m = getattr(self._storage, name)
+            setattr(self, name, m)
+            return m
 
         raise AttributeError(name)
 
@@ -204,7 +203,12 @@ class HistoricalStorageAdapter(Base):
         return False
 
     def release(self):
-        pass
+        try:
+            release = self._storage.release
+        except AttributeError:
+            pass
+        else:
+            release()
 
     close = release
 

HistoricalStorageAdapter does not forward release to its base
This causes a connection leak on RelStorage.

diff --git a/src/ZODB/tests/test_mvccadapter.py b/src/ZODB/tests/test_mvccadapter.py
new file mode 100644
index 00000000..9b1f28cf
--- /dev/null
+++ b/src/ZODB/tests/test_mvccadapter.py
@@ -0,0 +1,60 @@
+##############################################################################
+#
+# Copyright (c) 2017 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import unittest
+
+from ZODB import mvccadapter
+
+
+class TestBase(unittest.TestCase):
+
+    def test_getattr_does_not_hide_exceptions(self):
+        class TheException(Exception):
+            pass
+
+        class RaisesOnAccess(object):
+
+            @property
+            def thing(self):
+                raise TheException()
+
+        base = mvccadapter.Base(RaisesOnAccess())
+        base._copy_methods = ('thing',)
+
+        with self.assertRaises(TheException):
+            getattr(base, 'thing')
+
+    def test_getattr_raises_if_missing(self):
+        base = mvccadapter.Base(self)
+        base._copy_methods = ('thing',)
+
+        with self.assertRaises(AttributeError):
+            getattr(base, 'thing')
+
+
+class TestHistoricalStorageAdapter(unittest.TestCase):
+
+    def test_forwards_release(self):
+        class Base(object):
+            released = False
+
+            def release(self):
+                self.released = True
+
+        base = Base()
+        adapter = mvccadapter.HistoricalStorageAdapter(base, None)
+
+        adapter.release()
+
+        self.assertTrue(base.released)

pip install -e .[test]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
BTrees==6.1
cffi==1.17.1
exceptiongroup==1.2.2
iniconfig==2.1.0
manuel==1.13.0
packaging==24.2
persistent==6.1.1
pluggy==1.5.0
pycparser==2.22
pytest==8.3.5
six==1.17.0
tomli==2.2.1
transaction==5.0
zc.lockfile==3.0.post1
ZConfig==4.2
-e git+https://github.com/zopefoundation/ZODB.git@5056d49e79bc06f6d343973d71c3c3185e18975e#egg=ZODB
zodbpickle==4.2
zope.deferredimport==5.0
zope.exceptions==5.2
zope.interface==7.2
zope.proxy==6.1
zope.testing==5.1
zope.testrunner==7.2

name: ZODB
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - btrees==6.1
      - cffi==1.17.1
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - manuel==1.13.0
      - packaging==24.2
      - persistent==6.1.1
      - pluggy==1.5.0
      - pycparser==2.22
      - pytest==8.3.5
      - six==1.17.0
      - tomli==2.2.1
      - transaction==5.0
      - zc-lockfile==3.0.post1
      - zconfig==4.2
      - zodbpickle==4.2
      - zope-deferredimport==5.0
      - zope-exceptions==5.2
      - zope-interface==7.2
      - zope-proxy==6.1
      - zope-testing==5.1
      - zope-testrunner==7.2
prefix: /opt/conda/envs/ZODB

src/ZODB/tests/test_mvccadapter.py::TestHistoricalStorageAdapter::test_forwards_release
src/ZODB/tests/test_mvccadapter.py::TestBase::test_getattr_does_not_hide_exceptions src/ZODB/tests/test_mvccadapter.py::TestBase::test_getattr_raises_if_missing
src/ZODB/mvccadapter.py CHANGES.rst
src/ZODB/mvccadapter.py CHANGES.rst