question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cockroachdb unimplemented feature multiple active portals not supported

See original GitHub issue
  • asyncpg version: 0.20.1
  • Cockroachdb version: v20.1.0 (connected to a 5-node on premise cluster)
  • Python version: 3.8.0
  • Platform: Linux
  • Do you use pgbouncer?: No
  • Did you install asyncpg with pip?: Yes

Example code:


    async with pool.acquire() as conn:
        async with conn.transaction():
            if not await conn.table_exists("sys_app_config"):
                await conn.execute("""
                    CREATE TABLE sys_app_config(
                        key  text NOT NULL PRIMARY KEY,
                        value jsonb
                    );
                """)

The table_exists method looks like this:


class MyConnection(Connection):
    async def table_exists(self, table_name: str) -> bool:
        """Tell if a table exists."""
        return await self.fetchval(
            "select table_name from information_schema.tables where table_name=$1", table_name) is not None

This code is actually called from tornado.ioloop.IOLoop.current().run_sync so it is guaranteed that nothing else is running queries concurrently.

Here is the traceback that I’m getting:


 File "/home/user/my_project/db/initialize.py", line 19, in init_database
    if not await conn.table_exists("sys_app_config"):
  File "/home/user/.local/share/virtualenvs/backend-YgzYW8Ky/lib/python3.8/site-packages/asyncpg/transaction.py", line 91, in __aexit__
    await self.__commit()
  File "/home/user/.local/share/virtualenvs/backend-YgzYW8Ky/lib/python3.8/site-packages/asyncpg/transaction.py", line 179, in __commit
    await self._connection.execute(query)
  File "/home/user/.local/share/virtualenvs/backend-YgzYW8Ky/lib/python3.8/site-packages/asyncpg/connection.py", line 272, in execute
    return await self._protocol.query(query, timeout)
  File "asyncpg/protocol/protocol.pyx", line 316, in query
asyncpg.exceptions.FeatureNotSupportedError: unimplemented: multiple active portals not supported
HINT:  You have attempted to use a feature that is not yet implemented.
See: https://github.com/cockroachdb/cockroach/issues/40195

The referenced issue tells that it is not possible to keep multiple queries open and fetch from them interleaved.

However, I’m not doing anything that should result in opening multiple queries and fetching from them that way. As far as I see, my code should not open a new query before closing the previous one.

I suspect that asyncpg itself forgot to close something in the background.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:19 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
rimadeodharcommented, Jul 29, 2022

For the above code snippet by @hifi, one workaround that I noticed is that the error goes away by replace fetchval with fetch. By examining the difference over Wireshark between the two calls, I noticed since fetch results in fetching all rows, the execution step completes with a CommandComplete message as opposed to the PortalSuspended message by using fetchval. This doesn’t obviate the need for a general fix on the cockroachdb side though as we should still follow the unnamed portal semantics to be properly wire-compatible.

1reaction
jordanlewiscommented, Jun 17, 2022

Hi, I’m also a maintainer for CockroachDB.

The root cause of this is that Postgres permits leaving cursors open and beginning new cursors. CockroachDB does not.

The problem here is that asyncpg doesn’t explicitly close portals when it’s done using them. The example code from @hifi is correct in Postgres, but it actually leads to cursor leakage: if you run this against Postgres, you won’t get errors, but you will have leaked server-side cursors until you close your connection.

This is bad for performance in Postgres, and just plain doesn’t work in CockroachDB.

I think the best solution would be for asyncpg to provide a cursor.close() method that permits explicit closure of cursors. A call like conn.fetchRow should close the cursor it opens under the hood before exiting.

I believe this will improve performance in Postgres, and make the library compatible with CockroachDB.

Read more comments on GitHub >

github_iconTop Results From Across the Web

pgwire: multiple active result sets (portals) not supported #40195
CockroachDB does not currently support multiple active pgwire portals on the same session. This means that you can't perform the following ...
Read more >
Known Limitations in CockroachDB v22.2
This page describes newly identified limitations in the CockroachDB v22.2.0 release as well as unresolved limitations identified in earlier releases.
Read more >
What's New in v21.2 | CockroachDB Docs
Now these hazardous schema changes are not allowed. ... transaction when a portal was suspended would cause a "multiple active portals not supported"...
Read more >
Common Errors and Solutions | CockroachDB Docs
This message indicates a client is trying to connect to a node that is either not running or is not listening on the...
Read more >
What's New in v22.2 | CockroachDB Docs
Docs, Unsupported Features in CockroachDB Serverless, This page describes the features that are either unsupported or partially supported in CockroachDB ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found