[ 
https://issues.apache.org/jira/browse/CASSANDRA-20389?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17931910#comment-17931910
 ] 

Sam Tunnicliffe commented on CASSANDRA-20389:
---------------------------------------------

{quote}Fixing this table name validation bug depends if the validation is 
called only for new tables, or also for existing tables, when the schema is 
shared with another node or replica
{quote}
The validation will be enforced whenever a new table, index or view is created 
as well as when a table is altered. At these times, every node will perform the 
validation check independently as the operation is replicated and each peer 
executes it. Additionally, as the operation has been committed to the metadata 
log, it will get replayed at startup which is what's responsible for stacktrace 
[~maxwellguo] posted. A similar issue does also exist in earlier versions 
though, because the table name is written to the {{system_schema.tables}} table 
and reconstructed at startup whereby the call to 
{{ColumnFamilyStore::scrubDataDirectories}} also errors out, causing a failure. 
This should actually simplify things as it should be safe to assume that there 
aren't clusters out there with these abnormally long table names which will be 
broken if we fix the validation.
{quote}bq. There is a bug in 
[TableMetadata|https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/schema/TableMetadata.java#L552]
 which calls a name validation function with expectation of checking the 
length. However, the correct function to use is  
[isValidName|https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/schema/SchemaConstants.java#L83],
 which validates also length, instead of 
[isNameValid|https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/schema/TableMetadata.java#L552],
 which, I guess, shouldn't be present.
{quote}
This looks like something was overlooked either in CASSANDRA-9456 or 
CASSANDRA-16956. The latter added a comment which says
{code:java}
* Before CASSANDRA-16956, we used to care about not having the entire path 
longer than 255 characters because of
* Windows support but this limit is by implementing CASSANDRA-16956 not in 
effect anymore. {code}
It's probably correct that the length of the entire path is not an issue 
outside of Windows, but there are still limits (clearly) on the length of an 
individual file name (255 on most UNIX file systems IIRC). The constraint in 
{{isValidName}} is to limit filenames to a max length of 48 chars, so I don't 
think it's going to be safe to simply switch to using that as there may be 
existing tables which don't cause the 255 limit to be breached, but would fail 
with a 48 char limit. So I think we need another option to ensure that any 
table name does not cause the FS limit of 255 to be exceeded, which must 
include the table id as that is appended to the table name to form the name of 
the data directory.
 
In future, we could move to naming the data dirs solely using the table id as 
these are no longer re-used when a table is dropped and subsequently recreated. 
This would make the dir names fixed length, but it would remove the ability of 
operators to easily identify the data dir for a given table. 
 

> Create table fails on long table names
> --------------------------------------
>
>                 Key: CASSANDRA-20389
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-20389
>             Project: Apache Cassandra
>          Issue Type: Bug
>            Reporter: Ruslan Fomkin
>            Priority: Normal
>
> If CREATE TABLE is called with a long table name, the statement fails due to 
> file name too long error.
> E.g, such test:
> {code:java}
> @Test
> public void testCreatingTableWithLongName() throws Throwable
> {
>     String keyspace = "\"38373639353166362d3566313\"";
>     String table = 
> "test_create_k8yq1r75bpzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaaaaaaaaaaaaaaaa";
>     execute(String.format("CREATE KEYSPACE %s with replication = " +
>                           "{ 'class' : 'SimpleStrategy', 'replication_factor' 
> : 1 }",
>                           keyspace));
>     createTableMayThrow(String.format("CREATE TABLE %s.%s (" +
>                                        "key int PRIMARY KEY," +
>                                        "val int)", keyspace, table));
> }  {code}
> results in:
> {code:java}
> java.lang.RuntimeException: Failed to list files in 
> build/test/cassandra/data/38373639353166362d3566313/test_create_k8yq1r75bpzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaaaaaaaaaaaaaaaa-1b255f4def2540a60000000000000007
>     at 
> org.apache.cassandra.db.lifecycle.LogAwareFileLister.list(LogAwareFileLister.java:77)
>     at 
> org.apache.cassandra.db.lifecycle.LifecycleTransaction.getFiles(LifecycleTransaction.java:636)
>     at 
> org.apache.cassandra.db.Directories$SSTableLister.filter(Directories.java:1139)
>     at 
> org.apache.cassandra.db.Directories$SSTableLister.list(Directories.java:1086)
>     at 
> org.apache.cassandra.db.Directories$SSTableLister.list(Directories.java:1072)
>     at 
> org.apache.cassandra.db.Directories.lambda$getUIDGenerator$5(Directories.java:1297)
>     at 
> java.base/java.util.stream.AbstractPipeline.sourceSpliterator(AbstractPipeline.java:405)
>     at 
> java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
>     at java.base/java.util.stream.IntPipeline.reduce(IntPipeline.java:496)
>     at java.base/java.util.stream.IntPipeline.max(IntPipeline.java:459)
>     at 
> org.apache.cassandra.io.sstable.SequenceBasedSSTableId$Builder.generator(SequenceBasedSSTableId.java:102)
>     at 
> org.apache.cassandra.db.Directories.getUIDGenerator(Directories.java:1302)
>     at 
> org.apache.cassandra.db.ColumnFamilyStore.createColumnFamilyStore(ColumnFamilyStore.java:768)
>     at 
> org.apache.cassandra.db.ColumnFamilyStore.createColumnFamilyStore(ColumnFamilyStore.java:756)
>     at 
> org.apache.cassandra.db.ColumnFamilyStore.createColumnFamilyStore(ColumnFamilyStore.java:747)
>     at org.apache.cassandra.db.Keyspace.initCf(Keyspace.java:379)
>     at 
> org.apache.cassandra.schema.DistributedSchema.createTable(DistributedSchema.java:341)
>     at 
> org.apache.cassandra.schema.DistributedSchema.lambda$initializeKeyspaceInstances$6(DistributedSchema.java:213)
>     at java.base/java.lang.Iterable.forEach(Iterable.java:75)
>     at 
> org.apache.cassandra.schema.DistributedSchema.lambda$initializeKeyspaceInstances$10(DistributedSchema.java:213)
>     at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:422)
>     at 
> org.apache.cassandra.schema.DistributedSchema.initializeKeyspaceInstances(DistributedSchema.java:199)
>     at 
> org.apache.cassandra.tcm.listeners.SchemaListener.notifyInternal(SchemaListener.java:50)
>     at 
> org.apache.cassandra.tcm.listeners.SchemaListener.notifyPreCommit(SchemaListener.java:43)
>     at 
> org.apache.cassandra.tcm.log.LocalLog.notifyPreCommit(LocalLog.java:626)
>     at 
> org.apache.cassandra.tcm.log.LocalLog.processPendingInternal(LocalLog.java:527)
>     at 
> org.apache.cassandra.tcm.log.LocalLog$Async$AsyncRunnable.run(LocalLog.java:819)
>     at 
> org.apache.cassandra.concurrent.InfiniteLoopExecutor.loop(InfiniteLoopExecutor.java:121)
>     at 
> io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
>     at java.base/java.lang.Thread.run(Thread.java:829)
> Caused by: java.nio.file.FileSystemException: 
> build/test/cassandra/data/38373639353166362d3566313/test_create_k8yq1r75bpzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaaaaaaaaaaaaaaaa-1b255f4def2540a60000000000000007:
>  File name too long
>     at 
> java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
>     at 
> java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
>     at 
> java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
>     at 
> java.base/sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:412)
>     at java.base/java.nio.file.Files.newDirectoryStream(Files.java:472)
>     at 
> org.apache.cassandra.db.lifecycle.LogAwareFileLister.innerList(LogAwareFileLister.java:83)
>     at 
> org.apache.cassandra.db.lifecycle.LogAwareFileLister.list(LogAwareFileLister.java:73)
>  {code}
> There is a bug in 
> [TableMetadata|https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/schema/TableMetadata.java#L552]
>  which calls a name validation function with expectation of checking the 
> length. However, the correct function to use is  
> [isValidName|https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/schema/SchemaConstants.java#L83],
>  which validates also length, instead of 
> [isNameValid|https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/schema/TableMetadata.java#L552],
>  which, I guess, shouldn't be present.
> Fixing this table name validation bug depends if the validation is called 
> only for new tables, or also for existing tables, when the schema is shared 
> with another node or replica.
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to