Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Add a Postgres REPLICA IDENTITY to tables that do not have an impli…
Browse files Browse the repository at this point in the history
…cit one. This should allow use of Postgres logical replication. (take 2, now with no added deadlocks!) (#16658)

* Add `ALTER TABLE ... REPLICA IDENTITY ...` for individual tables

We can't combine them into one file as it makes it likely to hit a deadlock

if Synapse is running, as it only takes one other transaction to access two

tables in a different order to the schema delta.

* Add notes

* Newsfile

Signed-off-by: Olivier Wilkinson (reivilibre) <oliverw@matrix.org>

* Re-introduce REPLICA IDENTITY test

---------

Signed-off-by: Olivier Wilkinson (reivilibre) <oliverw@matrix.org>
  • Loading branch information
reivilibre committed Dec 4, 2023
1 parent 0aa4d3b commit 51e4e35
Show file tree
Hide file tree
Showing 123 changed files with 218 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog.d/16658.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a Postgres `REPLICA IDENTITY` to tables that do not have an implicit one. This should allow use of Postgres logical replication.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE applied_module_schemas REPLICA IDENTITY USING INDEX applied_module_schemas_module_name_file_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE applied_schema_deltas REPLICA IDENTITY USING INDEX applied_schema_deltas_version_file_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE background_updates REPLICA IDENTITY USING INDEX background_updates_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE schema_compat_version REPLICA IDENTITY USING INDEX schema_compat_version_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE schema_version REPLICA IDENTITY USING INDEX schema_version_lock_key;
13 changes: 13 additions & 0 deletions synapse/storage/schema/main/delta/83/10_replica_identity_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
The `10_replica_identity_xxx.sql.postgres` series of schema deltas adds replica identities for tables that do not have one implicitly as a result of having a primary key.

This is needed to use logical replication with Synapse (at least without `UPDATE` and `DELETE` statements failing!).

Where possible, we use an existing `UNIQUE` index on `NOT NULL` columns as the replica identity. Otherwise, we have to fall back to using the full row as a replica identity.

Unfortunately, by running all the `ALTER TABLE` statements in one schema delta per database, it was too likely to hit a deadlock as it would only take
one other transaction from a running Synapse worker to access the tables out of order and trigger a deadlock.

By having each statement in its own delta file, each one is run in its own transaction and only needs to take a very brief (instant) lock on the table but no other tables,
so there should be no chance of deadlock.

Like many schema deltas we already apply to Synapse, it is probably blocked by an ongoing `pg_dump`.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE account_data REPLICA IDENTITY USING INDEX account_data_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE application_services_txns REPLICA IDENTITY USING INDEX application_services_txns_as_id_txn_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE appservice_room_list REPLICA IDENTITY USING INDEX appservice_room_list_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE appservice_stream_position REPLICA IDENTITY USING INDEX appservice_stream_position_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE batch_events REPLICA IDENTITY USING INDEX chunk_events_event_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE blocked_rooms REPLICA IDENTITY USING INDEX blocked_rooms_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE cache_invalidation_stream_by_instance REPLICA IDENTITY USING INDEX cache_invalidation_stream_by_instance_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE current_state_delta_stream REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE current_state_events REPLICA IDENTITY USING INDEX current_state_events_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE deleted_pushers REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_auth_providers REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_federation_inbox REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_federation_outbox REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_inbox REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_changes_converted_stream_position REPLICA IDENTITY USING INDEX device_lists_changes_converted_stream_position_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_changes_in_room REPLICA IDENTITY USING INDEX device_lists_changes_in_stream_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_outbound_last_success REPLICA IDENTITY USING INDEX device_lists_outbound_last_success_unique_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_outbound_pokes REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_remote_cache REPLICA IDENTITY USING INDEX device_lists_remote_cache_unique_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_remote_extremeties REPLICA IDENTITY USING INDEX device_lists_remote_extremeties_unique_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_remote_resync REPLICA IDENTITY USING INDEX device_lists_remote_resync_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE device_lists_stream REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE devices REPLICA IDENTITY USING INDEX device_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE e2e_cross_signing_keys REPLICA IDENTITY USING INDEX e2e_cross_signing_keys_stream_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE e2e_cross_signing_signatures REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE e2e_device_keys_json REPLICA IDENTITY USING INDEX e2e_device_keys_json_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE e2e_fallback_keys_json REPLICA IDENTITY USING INDEX e2e_fallback_keys_json_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE e2e_one_time_keys_json REPLICA IDENTITY USING INDEX e2e_one_time_keys_json_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE e2e_room_keys REPLICA IDENTITY USING INDEX e2e_room_keys_with_version_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE e2e_room_keys_versions REPLICA IDENTITY USING INDEX e2e_room_keys_versions_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE erased_users REPLICA IDENTITY USING INDEX erased_users_user;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_auth REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_auth_chain_links REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_backward_extremities REPLICA IDENTITY USING INDEX event_backward_extremities_event_id_room_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_edges REPLICA IDENTITY USING INDEX event_edges_event_id_prev_event_id_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_forward_extremities REPLICA IDENTITY USING INDEX event_forward_extremities_event_id_room_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_json REPLICA IDENTITY USING INDEX event_json_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_push_actions REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_push_actions_staging REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_push_summary REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_push_summary_last_receipt_stream_id REPLICA IDENTITY USING INDEX event_push_summary_last_receipt_stream_id_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_push_summary_stream_ordering REPLICA IDENTITY USING INDEX event_push_summary_stream_ordering_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_relations REPLICA IDENTITY USING INDEX event_relations_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_search REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_to_state_groups REPLICA IDENTITY USING INDEX event_to_state_groups_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_txn_id REPLICA IDENTITY USING INDEX event_txn_id_event_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE event_txn_id_device_id REPLICA IDENTITY USING INDEX event_txn_id_device_id_event_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE events REPLICA IDENTITY USING INDEX events_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE federation_inbound_events_staging REPLICA IDENTITY USING INDEX federation_inbound_events_staging_instance_event;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE federation_stream_position REPLICA IDENTITY USING INDEX federation_stream_position_instance;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE ignored_users REPLICA IDENTITY USING INDEX ignored_users_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE insertion_event_edges REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE insertion_event_extremities REPLICA IDENTITY USING INDEX insertion_event_extremities_event_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE insertion_events REPLICA IDENTITY USING INDEX insertion_events_event_id;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE local_current_membership REPLICA IDENTITY USING INDEX local_current_membership_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE local_media_repository REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE local_media_repository_thumbnails REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE local_media_repository_url_cache REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE monthly_active_users REPLICA IDENTITY USING INDEX monthly_active_users_users;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE partial_state_events REPLICA IDENTITY USING INDEX partial_state_events_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE partial_state_rooms_servers REPLICA IDENTITY USING INDEX partial_state_rooms_servers_room_id_server_name_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE presence_stream REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE profiles REPLICA IDENTITY USING INDEX profiles_user_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE push_rules_stream REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE ratelimit_override REPLICA IDENTITY USING INDEX ratelimit_override_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE receipts_graph REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE receipts_linearized REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE received_transactions REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE redactions REPLICA IDENTITY USING INDEX redactions_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE registration_tokens REPLICA IDENTITY USING INDEX registration_tokens_token_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE rejections REPLICA IDENTITY USING INDEX rejections_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE remote_media_cache REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE remote_media_cache_thumbnails REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_account_data REPLICA IDENTITY USING INDEX room_account_data_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_alias_servers REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_aliases REPLICA IDENTITY USING INDEX room_aliases_room_alias_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_depth REPLICA IDENTITY USING INDEX room_depth_room_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_forgetter_stream_pos REPLICA IDENTITY USING INDEX room_forgetter_stream_pos_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_memberships REPLICA IDENTITY USING INDEX room_memberships_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_stats_earliest_token REPLICA IDENTITY USING INDEX room_stats_earliest_token_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_stats_state REPLICA IDENTITY USING INDEX room_stats_state_room;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_tags REPLICA IDENTITY USING INDEX room_tag_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE room_tags_revisions REPLICA IDENTITY USING INDEX room_tag_revisions_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE server_keys_json REPLICA IDENTITY USING INDEX server_keys_json_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE server_signature_keys REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE sessions REPLICA IDENTITY USING INDEX sessions_session_type_session_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE state_events REPLICA IDENTITY USING INDEX state_events_event_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE stats_incremental_position REPLICA IDENTITY USING INDEX stats_incremental_position_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE stream_ordering_to_exterm REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE stream_positions REPLICA IDENTITY USING INDEX stream_positions_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE threads REPLICA IDENTITY USING INDEX threads_uniqueness;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE threepid_guest_access_tokens REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE timeline_gaps REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE ui_auth_sessions REPLICA IDENTITY USING INDEX ui_auth_sessions_session_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE ui_auth_sessions_credentials REPLICA IDENTITY USING INDEX ui_auth_sessions_credentials_session_id_stage_type_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE ui_auth_sessions_ips REPLICA IDENTITY USING INDEX ui_auth_sessions_ips_session_id_ip_user_agent_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_daily_visits REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_directory REPLICA IDENTITY USING INDEX user_directory_user_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_directory_search REPLICA IDENTITY USING INDEX user_directory_search_user_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_directory_stream_pos REPLICA IDENTITY USING INDEX user_directory_stream_pos_lock_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_external_ids REPLICA IDENTITY USING INDEX user_external_ids_auth_provider_external_id_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_filters REPLICA IDENTITY FULL; -- sadly the `CHECK` constraint is not enough here
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_ips REPLICA IDENTITY USING INDEX user_ips_user_token_ip_unique_index;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_signature_stream REPLICA IDENTITY USING INDEX user_signature_stream_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_threepid_id_server REPLICA IDENTITY USING INDEX user_threepid_id_server_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE user_threepids REPLICA IDENTITY USING INDEX medium_address;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users_in_public_rooms REPLICA IDENTITY USING INDEX users_in_public_rooms_u_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users_pending_deactivation REPLICA IDENTITY FULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users_who_share_private_rooms REPLICA IDENTITY USING INDEX users_who_share_private_rooms_u_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE worker_locks REPLICA IDENTITY USING INDEX worker_locks_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE worker_read_write_locks REPLICA IDENTITY USING INDEX worker_read_write_locks_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE worker_read_write_locks_mode REPLICA IDENTITY USING INDEX worker_read_write_locks_mode_key;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE state_group_edges REPLICA IDENTITY USING INDEX state_group_edges_unique_idx;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE state_groups_state REPLICA IDENTITY FULL;
85 changes: 84 additions & 1 deletion tests/storage/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Callable, Tuple
from typing import Callable, List, Tuple
from unittest.mock import Mock, call

from twisted.internet import defer
Expand All @@ -29,6 +29,7 @@
from synapse.util import Clock

from tests import unittest
from tests.utils import USE_POSTGRES_FOR_TESTS


class TupleComparisonClauseTestCase(unittest.TestCase):
Expand Down Expand Up @@ -279,3 +280,85 @@ def _test_txn(txn: LoggingTransaction) -> None:
]
)
self.assertEqual(exception_callback.call_count, 6) # no additional calls


class PostgresReplicaIdentityTestCase(unittest.HomeserverTestCase):
if not USE_POSTGRES_FOR_TESTS:
skip = "Requires Postgres"

def prepare(
self, reactor: MemoryReactor, clock: Clock, homeserver: HomeServer
) -> None:
self.db_pools = homeserver.get_datastores().databases

def test_all_tables_have_postgres_replica_identity(self) -> None:
"""
Tests that all tables have a Postgres REPLICA IDENTITY.
(See https://github.com/matrix-org/synapse/issues/16224).

Tables with a PRIMARY KEY have an implied REPLICA IDENTITY and are fine.
Other tables need them to be set with `ALTER TABLE`.

A REPLICA IDENTITY is required for Postgres logical replication to work
properly without blocking updates and deletes.
"""

sql = """
-- Select tables that have no primary key and use the default replica identity rule
-- (the default is to use the primary key)
WITH tables_no_pkey AS (
SELECT tbl.table_schema, tbl.table_name
FROM information_schema.tables tbl
WHERE table_type = 'BASE TABLE'
AND table_schema not in ('pg_catalog', 'information_schema')
AND NOT EXISTS (
SELECT 1
FROM information_schema.table_constraints tc
WHERE tc.constraint_type = 'PRIMARY KEY'
AND tc.table_schema = tbl.table_schema
AND tc.table_name = tbl.table_name
)
)
SELECT pg_class.oid::regclass FROM tables_no_pkey INNER JOIN pg_class ON pg_class.oid::regclass = table_name::regclass
WHERE relreplident = 'd'

UNION

-- Also select tables that use an index as a replica identity
-- but where the index doesn't exist
-- (e.g. it could have been deleted)
SELECT pg_class.oid::regclass
FROM information_schema.tables tbl
INNER JOIN pg_class ON pg_class.oid::regclass = table_name::regclass
WHERE table_type = 'BASE TABLE'
AND table_schema not in ('pg_catalog', 'information_schema')

-- 'i' means an index is used as the replica identity
AND relreplident = 'i'

-- look for indices that are marked as the replica identity
AND NOT EXISTS (
SELECT indexrelid::regclass
FROM pg_index
WHERE indrelid = pg_class.oid::regclass AND indisreplident
)
"""

def _list_tables_with_missing_replica_identities_txn(
txn: LoggingTransaction,
) -> List[str]:
txn.execute(sql)
return [table_name for table_name, in txn]

for pool in self.db_pools:
missing = self.get_success(
pool.runInteraction(
"test_list_missing_replica_identities",
_list_tables_with_missing_replica_identities_txn,
)
)
self.assertEqual(
len(missing),
0,
f"The following tables in the {pool.name()!r} database are missing REPLICA IDENTITIES: {missing!r}.",
)

0 comments on commit 51e4e35

Please sign in to comment.