diff --git a/docs/production/upgrade-or-modify.md b/docs/production/upgrade-or-modify.md index 4b8479b55d..f2233f3763 100644 --- a/docs/production/upgrade-or-modify.md +++ b/docs/production/upgrade-or-modify.md @@ -239,12 +239,14 @@ instructions for other supported platforms. 5. Finally, we need to reinstall the current version of Zulip, which among other things will recompile Zulip's Python module - dependencies for your new version of Python: + dependencies for your new version of Python and rewrite Zulip's + full-text search indexes to work with the upgraded dictionary + packages: ``` rm -rf /srv/zulip-venv-cache/* /home/zulip/deployments/current/scripts/lib/upgrade-zulip-stage-2 \ - /home/zulip/deployments/current/ --ignore-static-assets + /home/zulip/deployments/current/ --ignore-static-assets --audit-fts-indexes ``` That last command will finish by restarting your Zulip server; you @@ -378,9 +380,9 @@ To upgrade the version of PostgreSQL on the Zulip server: /home/zulip/deployments/current/scripts/setup/upgrade-postgres ``` -That last command will finish by restarting your Zulip server; you -should now be able to navigate to its URL and confirm everything is -working correctly. +`upgrade-postgres` will have finished by restarting your Zulip server; +you should now be able to navigate to its URL and confirm everything +is working correctly. ## Modifying Zulip diff --git a/scripts/lib/upgrade-zulip-stage-2 b/scripts/lib/upgrade-zulip-stage-2 index 206c547290..5fa68ced5e 100755 --- a/scripts/lib/upgrade-zulip-stage-2 +++ b/scripts/lib/upgrade-zulip-stage-2 @@ -81,6 +81,8 @@ parser.add_argument("--ignore-static-assets", dest="ignore_static_assets", actio help="Do not attempt to copy/manage static assets.") parser.add_argument("--skip-purge-old-deployments", dest="skip_purge_old_deployments", action="store_true", help="Skip purging old deployments.") +parser.add_argument("--audit-fts-indexes", dest="audit_fts_indexes", + action="store_true", help="Audit and fix full text search indexes.") args = parser.parse_args() deploy_path = args.deploy_path @@ -268,6 +270,11 @@ logging.info("Restarting Zulip...") subprocess.check_output(["./scripts/restart-server", "--fill-cache"], preexec_fn=su_to_zulip) logging.info("Upgrade complete!") +if args.audit_fts_indexes: + logging.info("Correcting full-text search indexes for updated dictionary files") + logging.info("This may take a while but the server should work while it runs.") + subprocess.check_call(["./manage.py", "audit_fts_indexes"], preexec_fn=su_to_zulip) + if not args.skip_purge_old_deployments: logging.info("Purging old deployments...") subprocess.check_call(["./scripts/purge-old-deployments"]) diff --git a/zerver/management/commands/audit_fts_indexes.py b/zerver/management/commands/audit_fts_indexes.py new file mode 100644 index 0000000000..84e468aa1e --- /dev/null +++ b/zerver/management/commands/audit_fts_indexes.py @@ -0,0 +1,19 @@ +from typing import Any + +from django.db import connection + +from zerver.lib.management import ZulipBaseCommand + + +class Command(ZulipBaseCommand): + def handle(self, *args: Any, **kwargs: str) -> None: + with connection.cursor() as cursor: + cursor.execute(""" + UPDATE zerver_message + SET search_tsvector = + to_tsvector('zulip.english_us_search', subject || rendered_content) + WHERE to_tsvector('zulip.english_us_search', subject || rendered_content) != search_tsvector + """) + + fixed_message_count = cursor.rowcount + print(f"Fixed {fixed_message_count} messages.")