Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to sequential execution if the index name is long #4209

Merged
merged 4 commits into from
Oct 2, 2020

Conversation

onderkalaci
Copy link
Member

fixes #2714

/*

  • Citus has the logic to truncate the long shard names to prevent
  • various issues, including self-deadlocks. However, for partitioned
  • tables, when index is created on the parent table, the index names
  • on the partitions are auto-generated by Postgres. We use the same
  • Postgres function to generate the index names on the shards of the
  • partitions. If the length exceeds the limit, we switch to sequential
  • execution mode.
    */

DESCRIPTION: Fixes a bug that could cause deadlocks on CREATE INDEX

* The argument list is pretty ad-hoc :-(
*/
char *
ChooseIndexName(const char *tabname, Oid namespaceId,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can even use this function to support unnamed indexes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codecov
Copy link

codecov bot commented Sep 30, 2020

Codecov Report

Merging #4209 into master will increase coverage by 0.04%.
The diff coverage is 83.83%.

@@            Coverage Diff             @@
##           master    #4209      +/-   ##
==========================================
+ Coverage   90.84%   90.88%   +0.04%     
==========================================
  Files         188      189       +1     
  Lines       37056    37155      +99     
==========================================
+ Hits        33664    33770     +106     
+ Misses       3392     3385       -7     

@marcocitus marcocitus changed the title Switch to sequetial execution if the index name is long Switch to sequential execution if the index name is long Sep 30, 2020
CREATE INDEX ix_test_index_creation4
ON test_index_creation1 USING btree
(tenant_id, timeperiod);
DEBUG: the index name on the shards of the partition is too long, switching to sequential execution mode to prevent self deadlocks: test_index_creation1_p2020_09_26_10311_tenant_id_timeperiod_idx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be worth using a NOTICE? not sure whether it will inform or scare the user

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not have NOTICE when we switch to sequential execution due to fkey relationships. That's why I followed the same approach by adding DEBUG1.

If table is empty, NOTICE would be confusing. If the table has reasonable amount of data, then it might be beneficial.

Do we have a trick to get that information without calling master_update_shard_stats?

namespaceId,
true);
}
else if (isconstraint)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not supported on PG, that's why I cannot add tests:

alter table test_index_creation1 ADD CONSTRAINT c1 PRIMARY KEY usiNG INDEX ix_test_index_creation6;

ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables

namespaceId,
true);
}
else if (exclusionOpNames != NIL)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not supported on PG, that's why I cannot add tests:

ERROR:  exclusion constraints are not supported on partitioned tables

{
char *indexname;

if (primary)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we cannot add tests, because we hit #1664. The reason we hit it is that this type of index only adds table_name_pkey. However, shard names are longer than _pkey. We could add a test by manually setting shardId less than 4 chars, but that seems overkill


int largestShardIndex = cacheEntry->shardIntervalArrayLength - 1;
ShardInterval *shardInterval =
CopyShardInterval(cacheEntry->sortedShardIntervalArray[largestShardIndex]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this the shard with the largest hash range?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we are interested in the hash ranges here? The idea is to find the shard name in longest length, so we are searching some edge cases like the table has shards table_99999 and table_100000, we want to pick the latter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this array is sorted by (hash) range

which would no longer be the biggest shard ID after tenant isolation

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yes I see what you mean now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could be more defensive for future change and always loop over the shards, but that seems not very likely that we change the shardIds monotonically increasing per table?

/*
* Citus has the logic to truncate the long shard names to prevent
* various issues, including self-deadlocks. However, for partitioned
* tables, when index is created on the parent table, the index names
* on the partitions are auto-generated by Postgres. We use the same
* Postgres function to generate the index names on the shards of the
* partitions. If the length exceeds the limit, we switch to sequential
* execution mode.
*/
/* this cannot happen, still be defensive */
if (largestShardId == 0)
{
ereport(ERROR, (errmsg("unexpected shardId: %lu", largestShardId)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

append-distributed tables can have 0 shards

Copy link
Member

@onurctirtir onurctirtir Oct 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as far as I see, we already don't allow partitioning append distributed tables, so do you think that error check/message is sufficient @marcocitus ?

SELECT create_distributed_table('measurement','city_id','append');
ERROR: distributing partitioned tables in only supported for hash-distributed tables

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deadlock when creating index on partitioned table
3 participants