Issue #358: [doc] Postgresql: Can't reconnect until invalid transaction is rolled back
Reported by: | André Klitzing |
State: | resolved |
Created on: | 2020-02-07 11:11 |
Updated on: | 2020-06-18 19:24 |
Description
We have a fresh installation of Kallithea 0.5.2 with Postgresql 11. We uses uwsgi and nginx. The WebUI can be used. Sometimes the server throws a “Internal Server Error” if a single user refreshes the Browser multiple times.
Traceback (most recent call last): File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/wsgiapp.py", line 82, in call response = self.wrapped_dispatch(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/errorpage.py", line 104, in call resp = self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/caching.py", line 54, in call return self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/session.py", line 71, in call response = self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/i18n.py", line 71, in call return self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/wsgiapp.py", line 243, in _dispatch return controller(environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/base.py", line 511, in call ip_addr=ip_addr, File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/base.py", line 438, in _determine_auth_user return AuthUser.from_cookie(session_authuser, ip_addr=ip_addr) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/auth.py", line 563, in from_cookie dbuser=UserModel().get(cookie.get('user_id')), File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/model/user.py", line 57, in get return user.get(user_id) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 1004, in get return self._get_impl(ident, loading.load_on_pk_identity) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 1116, in _get_impl return db_load_fn(self, primary_key_identity) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 284, in load_on_pk_identity return q.one() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3347, in one ret = self.one_or_none() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3316, in one_or_none ret = list(self) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/caching_query.py", line 81, in iter return Query.iter(self) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3389, in iter return self._execute_and_instances(context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3414, in _execute_and_instances result = conn.execute(querycontext.statement, self._params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 982, in execute return meth(self, multiparams, params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 293, in _execute_on_connection return connection._execute_clauseelement(self, multiparams, params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1101, in _execute_clauseelement distilled_params, File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1176, in _execute_context e, util.text_type(statement), parameters, None, None File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1476, in _handle_dbapi_exception util.raise_from_cause(sqlalchemy_exception, exc_info) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 398, in raise_from_cause reraise(type(exception), exception, tb=exc_tb, cause=cause) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1171, in _execute_context conn = self._revalidate_connection() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 457, in _revalidate_connection "Can't reconnect until invalid " StatementError: (sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back [SQL: SELECT users.firstname AS users_firstname, users.email AS users_email, users.user_data AS users_user_data, users.user_id AS users_user_id, users.username AS users_username, users.password AS users_password, users.active AS users_active, users.admin AS users_admin, users.lastname AS users_lastname, users.last_login AS users_last_login, users.extern_type AS users_extern_type, users.extern_name AS users_extern_name, users.api_key AS users_api_key, users.created_on AS users_created_on FROM users WHERE users.user_id = %(param_1)s] [parameters: [{'%(139880833321552 param)s': 2}]]
Attachments
Comments
Comment by Thomas De Schampheleire, on 2020-02-07 17:10
I think there must be one or more other tracebacks and/or errors before this point, could you check the log?
Comment by Thomas De Schampheleire, on 2020-02-07 17:12
Comment by André Klitzing, on 2020-02-08 15:23
Here the whole log after a restart. I want to the browser. Website shown without problems. One reload…. Internal Server Error.
running /usr/bin/uwsgi-core *** has_emperor mode detected (fd: 7) *** [uWSGI] getting INI configuration from k.ini *** Starting uWSGI 2.0.18-debian (64bit) on [Sat Feb 8 16:21:24 2020] *** compiled with version: 8.2.0 on 10 February 2019 02:42:46 os: Linux-4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u2 (2019-11-11) nodename: kallithea machine: x86_64 clock source: unix pcre jit disabled detected number of CPU cores: 8 current working directory: /etc/uwsgi-emperor/vassals detected binary path: /usr/bin/uwsgi-core your processes number limit is 31794 your memory page size is 4096 bytes *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** detected max file descriptor number: 1024 lock engine: pthread robust mutexes thunder lock: disabled (you can enable it with --thunder-lock) uwsgi socket 0 inherited INET address 127.0.0.1:7777 fd 3 Python version: 2.7.16 (default, Oct 10 2019, 22:02:15) [GCC 8.3.0] Python main interpreter initialized at 0x561ea7a9d180 python threads support enabled your server socket listen backlog is limited to 120 connections your mercy for graceful operations on workers is 60 seconds mapped 947960 bytes (925 KB) for 12 cores *** Operational MODE: preforking *** 2020-02-08 16:21:25.913 INFO [alembic.runtime.migration] Context impl PostgresqlImpl. 2020-02-08 16:21:25.913 INFO [alembic.runtime.migration] Will assume transactional DDL. WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x561ea7a9d180 pid: 6158 (default app) *** uWSGI is running in multiple interpreter mode *** gracefully (RE)spawned uWSGI master process (pid: 6158) spawned uWSGI worker 1 (pid: 11676, cores: 1) spawned uWSGI worker 2 (pid: 11677, cores: 1) Sat Feb 8 16:21:26 2020 - [emperor] vassal k.ini is ready to accept requests spawned uWSGI worker 3 (pid: 11678, cores: 1) spawned uWSGI worker 4 (pid: 11679, cores: 1) spawned uWSGI worker 5 (pid: 11680, cores: 1) spawned uWSGI worker 6 (pid: 11681, cores: 1) spawned uWSGI worker 7 (pid: 11682, cores: 1) spawned uWSGI worker 8 (pid: 11683, cores: 1) spawned uWSGI worker 9 (pid: 11684, cores: 1) spawned uWSGI worker 10 (pid: 11685, cores: 1) spawned uWSGI worker 11 (pid: 11686, cores: 1) spawned uWSGI worker 12 (pid: 11687, cores: 1) *** Stats server enabled on /tmp/stats.kallithea.sock fd: 34 *** announcing my loyalty to the Emperor... Sat Feb 8 16:21:37 2020 - [emperor] vassal k.ini is now loyal Traceback (most recent call last): File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/wsgiapp.py", line 82, in __call__ response = self.wrapped_dispatch(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/errorpage.py", line 104, in __call__ resp = self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/caching.py", line 54, in __call__ return self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/session.py", line 71, in __call__ response = self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/i18n.py", line 71, in __call__ return self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/wsgiapp.py", line 243, in _dispatch return controller(environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/base.py", line 511, in __call__ ip_addr=ip_addr, File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/base.py", line 438, in _determine_auth_user return AuthUser.from_cookie(session_authuser, ip_addr=ip_addr) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/auth.py", line 563, in from_cookie dbuser=UserModel().get(cookie.get('user_id')), File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/model/user.py", line 57, in get return user.get(user_id) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 1004, in get return self._get_impl(ident, loading.load_on_pk_identity) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 1116, in _get_impl return db_load_fn(self, primary_key_identity) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 284, in load_on_pk_identity return q.one() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3347, in one ret = self.one_or_none() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3316, in one_or_none ret = list(self) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/caching_query.py", line 81, in __iter__ return Query.__iter__(self) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3389, in __iter__ return self._execute_and_instances(context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3414, in _execute_and_instances result = conn.execute(querycontext.statement, self._params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 982, in execute return meth(self, multiparams, params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 293, in _execute_on_connection return connection._execute_clauseelement(self, multiparams, params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1101, in _execute_clauseelement distilled_params, File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1176, in _execute_context e, util.text_type(statement), parameters, None, None File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1476, in _handle_dbapi_exception util.raise_from_cause(sqlalchemy_exception, exc_info) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 398, in raise_from_cause reraise(type(exception), exception, tb=exc_tb, cause=cause) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1171, in _execute_context conn = self._revalidate_connection() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 457, in _revalidate_connection "Can't reconnect until invalid " StatementError: (sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back [SQL: SELECT users.firstname AS users_firstname, users.email AS users_email, users.user_data AS users_user_data, users.user_id AS users_user_id, users.username AS users_username, users.password AS users_password, users.active AS users_active, users.admin AS users_admin, users.lastname AS users_lastname, users.last_login AS users_last_login, users.extern_type AS users_extern_type, users.extern_name AS users_extern_name, users.api_key AS users_api_key, users.created_on AS users_created_on FROM users WHERE users.user_id = %(param_1)s] [parameters: [{'%(140311501440528 param)s': 2}]] announcing my loyalty to the Emperor... Sat Feb 8 16:21:38 2020 - [emperor] vassal k.ini is now loyal
Comment by André Klitzing, on 2020-02-08 15:26
After a logout and refresh sometimes the browser at the login screen:
2020-02-08 16:26:01.509 WARNI [kallithea.lib.auth] user is anonymous and NOT authenticated with regular auth @ HomeController:index Traceback (most recent call last): File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/wsgiapp.py", line 82, in __call__ response = self.wrapped_dispatch(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/errorpage.py", line 104, in __call__ resp = self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/caching.py", line 54, in __call__ return self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/session.py", line 71, in __call__ response = self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/appwrappers/i18n.py", line 71, in __call__ return self.next_handler(controller, environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/tg/wsgiapp.py", line 243, in _dispatch return controller(environ, context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/base.py", line 511, in __call__ ip_addr=ip_addr, File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/base.py", line 443, in _determine_auth_user for plugin in auth_modules.get_auth_plugins() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/auth_modules/__init__.py", line 322, in get_auth_plugins for plugin_name in Setting.get_by_name("auth_plugins").app_settings_value: File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/model/db.py", line 247, in get_by_name .filter(cls.app_settings_name == key).scalar() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3377, in scalar ret = self.one() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3347, in one ret = self.one_or_none() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3316, in one_or_none ret = list(self) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/kallithea/lib/caching_query.py", line 81, in __iter__ return Query.__iter__(self) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3389, in __iter__ return self._execute_and_instances(context) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3414, in _execute_and_instances result = conn.execute(querycontext.statement, self._params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 982, in execute return meth(self, multiparams, params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 293, in _execute_on_connection return connection._execute_clauseelement(self, multiparams, params) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1101, in _execute_clauseelement distilled_params, File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1176, in _execute_context e, util.text_type(statement), parameters, None, None File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1476, in _handle_dbapi_exception util.raise_from_cause(sqlalchemy_exception, exc_info) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 398, in raise_from_cause reraise(type(exception), exception, tb=exc_tb, cause=cause) File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1171, in _execute_context conn = self._revalidate_connection() File "/opt/kallithea/0.5.2/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 457, in _revalidate_connection "Can't reconnect until invalid " StatementError: (sqlalchemy.exc.InvalidRequestError) Can't reconnect until invalid transaction is rolled back [SQL: SELECT settings.app_settings_value AS settings_app_settings_value, settings.app_settings_type AS settings_app_settings_type, settings.app_settings_id AS settings_app_settings_id, settings.app_settings_name AS settings_app_settings_name FROM settings WHERE settings.app_settings_name = %(app_settings_name_1)s] [parameters: [immutabledict({})]] announcing my loyalty to the Emperor... Sat Feb 8 16:26:03 2020 - [emperor] vassal k.ini is now loyal
Comment by Mads Kiilerich, on 2020-02-08 15:28
I wonder if this could be related to 1a409593f352 or a1115795fabb , combined with interrupting responses before they have finished and thus before the server can clean up the usual way.
As a workaround, we could perhaps start each request by removing any previous transaction. But it would be nice to fix it at the root cause. A first step could perhaps be to assert explicitly that there can’t be any existing transaction when the request starts…
Comment by André Klitzing, on 2020-02-11 09:02
Anything I could try?
Comment by Mads Kiilerich, on 2020-02-11 12:34
Hmm. uwsgi seems great, but I never tried it.
To figure out if the problem comes with uwsgi or something else in your setup (and thus make it more reproducible), could you try to see if you can reproduce the problem with a plain gearbox serve
?
Comment by Thomas De Schampheleire, on 2020-02-11 16:02
For the record, I am using uwsgi + postgresql + celery at work. The Kallithea version we are using is based on rev eee49a119592 which is almost equal to 0.5.0. We don’t see such issue.
Comment by André Klitzing, on 2020-02-11 17:28
No problem with gearbox.
Could you provide your uwsgi and vassal config?
How did you provide celery?
Comment by Thomas De Schampheleire, on 2020-02-12 08:13
We use docker with four containers: postgresql, kallithea, celery, rabbitmq.
The uwsgi configuration in our kallithea .ini file is quite basic, I think only thing we changed is the amount of workers.
We don’t use a separate web server like nginx currently, uwsgi handles that part now.
## UWSGI ## ## run with uwsgi --ini-paste-logged <inifile.ini> [uwsgi] socket = /tmp/uwsgi.sock master = true http = 0.0.0.0:5000 ## set as daemon and redirect all output to file #daemonize = ./uwsgi_kallithea.log ## master process PID pidfile = ./uwsgi_kallithea.pid ## stats server with workers statistics, use uwsgitop ## for monitoring, `uwsgitop 127.0.0.1:1717` stats = 127.0.0.1:1717 memory-report = true ## log 5XX errors log-5xx = true ## Set the socket listen queue size. listen = 128 ## Gracefully Reload workers after the specified amount of managed requests ## (avoid memory leaks). max-requests = 1000 ## enable large buffers buffer-size = 65535 ## socket and http timeouts ## http-timeout = 3600 socket-timeout = 3600 ## Log requests slower than the specified number of milliseconds. log-slow = 10 ## Exit if no app can be loaded. need-app = true ## Set lazy mode (load apps in workers instead of master). lazy = true ## scaling ## ## set cheaper algorithm to use, if not set default will be used cheaper-algo = spare ## minimum number of workers to keep at all times cheaper = 1 ## number of workers to spawn at startup cheaper-initial = 1 ## maximum number of workers that can be spawned workers = 32 ## how many workers should be spawned at a time cheaper-step = 1
I don’t know vassal and I thus think we don’t use it. (What is it and why would you need it?)
For celery there is also not something special. It is started in a separate container via ‘kallithea-cli celery-run’ and uses rabbitmq as broker.
Given that things work for me on 0.5.0, you could try to downgrade to that version to see if it makes a difference. Even though there are some database changes, they are only related to SSH repository access. If you don’t yet use this feature, you could just skip the database upgrade for this test, and set ignore_alembic_revision = True
in the ini file under [app:main]
. (Don’t forget to undo this change when this issue would be resolved).
Comment by André Klitzing, on 2020-02-13 11:26
Thanks…. lazy=true did the trick in my vassal.
Comment by Mads Kiilerich, on 2020-02-13 13:21
Cool. It would be nice to get a small section in the documentation about how to use uwsgi. kallithea-cli config-create new.ini http_server=uwsgi
should perhaps also be better documented.