From 767a68cd00050298abf7bbfd8b322e5663439c23 Mon Sep 17 00:00:00 2001 From: Marcus Eriksson Date: Thu, 17 Oct 2019 10:24:57 +0200 Subject: [PATCH] Ensure legacy rows have primary key livenessinfo when they contain illegal cells Patch by marcuse and Sam Tunnicliffe; reviewed by Benedict Elliott Smith for CASSANDRA-15365 --- CHANGES.txt | 1 + .../org/apache/cassandra/db/LegacyLayout.java | 56 ++++++++++-- ...illegal_cell_names-ka-2-CompressionInfo.db | Bin 0 -> 43 bytes ...cy_ka_with_illegal_cell_names-ka-2-Data.db | Bin 0 -> 59 bytes ...a_with_illegal_cell_names-ka-2-Digest.sha1 | 1 + ..._ka_with_illegal_cell_names-ka-2-Filter.db | Bin 0 -> 16 bytes ...y_ka_with_illegal_cell_names-ka-2-Index.db | Bin 0 -> 18 bytes ...with_illegal_cell_names-ka-2-Statistics.db | Bin 0 -> 4452 bytes ...cy_ka_with_illegal_cell_names-ka-2-TOC.txt | 8 ++ ...legal_cell_names_2-ka-1-CompressionInfo.db | Bin 0 -> 43 bytes ..._ka_with_illegal_cell_names_2-ka-1-Data.db | Bin 0 -> 67 bytes ...with_illegal_cell_names_2-ka-1-Digest.sha1 | 1 + ...a_with_illegal_cell_names_2-ka-1-Filter.db | Bin 0 -> 16 bytes ...ka_with_illegal_cell_names_2-ka-1-Index.db | Bin 0 -> 18 bytes ...th_illegal_cell_names_2-ka-1-Statistics.db | Bin 0 -> 4452 bytes ..._with_illegal_cell_names_2-ka-1-Summary.db | Bin 0 -> 92 bytes ..._ka_with_illegal_cell_names_2-ka-1-TOC.txt | 8 ++ .../io/sstable/LegacySSTableTest.java | 80 ++++++++++++++++-- 18 files changed, 141 insertions(+), 14 deletions(-) create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-CompressionInfo.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Data.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Digest.sha1 create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Filter.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Index.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Statistics.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-TOC.txt create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-CompressionInfo.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Data.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Digest.sha1 create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Filter.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Index.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Statistics.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Summary.db create mode 100644 test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-TOC.txt diff --git a/CHANGES.txt b/CHANGES.txt index bd129421b8..d58a199fd5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.20 + * Ensure legacy rows have primary key livenessinfo when they contain illegal cells (CASSANDRA-15365) Merged from 2.2 * In-JVM DTest: Set correct internode message version for upgrade test (CASSANDRA-15371) diff --git a/src/java/org/apache/cassandra/db/LegacyLayout.java b/src/java/org/apache/cassandra/db/LegacyLayout.java index 1a03c91371..6e93d0838e 100644 --- a/src/java/org/apache/cassandra/db/LegacyLayout.java +++ b/src/java/org/apache/cassandra/db/LegacyLayout.java @@ -1291,6 +1291,22 @@ public abstract class LegacyLayout private LegacyRangeTombstone rowDeletion; private LegacyRangeTombstone collectionDeletion; + /** + * Used to track if we need to add pk liveness info (row marker) when removing invalid legacy cells. + * + * In 2.1 these invalid cells existed but were not queryable, in this case specifically because they + * represented values for clustering key columns that were written as data cells. + * + * However, the presence (or not) of such cells on an otherwise empty CQL row (or partition) would decide + * if an empty result row were returned for the CQL row (or partition). To maintain this behaviour we + * insert a row marker containing the liveness info of these invalid cells iff we have no other data + * on the row. + * + * See also CASSANDRA-15365 + */ + private boolean hasValidCells = false; + private LivenessInfo invalidLivenessInfo = null; + public CellGrouper(CFMetaData metadata, SerializationHelper helper) { this(metadata, helper, false); @@ -1317,6 +1333,8 @@ public abstract class LegacyLayout this.clustering = null; this.rowDeletion = null; this.collectionDeletion = null; + this.invalidLivenessInfo = null; + this.hasValidCells = false; } public boolean addAtom(LegacyAtom atom) @@ -1326,7 +1344,7 @@ public abstract class LegacyLayout : addRangeTombstone(atom.asRangeTombstone()); } - public boolean addCell(LegacyCell cell) + private boolean addCell(LegacyCell cell) { if (clustering == null) { @@ -1359,21 +1377,38 @@ public abstract class LegacyLayout builder.addRowDeletion(Row.Deletion.regular(new DeletionTime(cell.timestamp, cell.localDeletionTime))); else builder.addPrimaryKeyLivenessInfo(LivenessInfo.create(cell.timestamp, FAKE_TTL, cell.localDeletionTime)); + hasValidCells = true; + } + else if (column.isPrimaryKeyColumn() && metadata.isCQLTable()) + { + // SSTables generated offline and side-loaded may include invalid cells which have the column name + // of a primary key column. So that we don't fail when encountering these cells, we treat them the + // same way as 2.1 did, namely we include their clusterings in the new CQL row, but drop the invalid + // column part of the cell + noSpamLogger.warn("Illegal cell name for CQL3 table {}.{}. {} is defined as a primary key column", + metadata.ksName, metadata.cfName, column.name); + + if (invalidLivenessInfo != null) + { + // when we have several invalid cells we follow the logic in LivenessInfo#supersedes when picking the PKLI to keep: + LivenessInfo newInvalidLiveness = LivenessInfo.create(cell.timestamp, cell.isTombstone() ? FAKE_TTL : cell.ttl, cell.localDeletionTime); + if (newInvalidLiveness.supersedes(invalidLivenessInfo)) + invalidLivenessInfo = newInvalidLiveness; + } + else + { + invalidLivenessInfo = LivenessInfo.create(cell.timestamp, cell.isTombstone() ? FAKE_TTL : cell.ttl, cell.localDeletionTime); + } + return true; } else { if (collectionDeletion != null && collectionDeletion.start.collectionName.name.equals(column.name) && collectionDeletion.deletionTime.deletes(cell.timestamp)) return true; - if (column.isPrimaryKeyColumn() && metadata.isCQLTable()) - { - noSpamLogger.warn("Illegal cell name for CQL3 table {}.{}. {} is defined as a primary key column", - metadata.ksName, metadata.cfName, column.name); - return true; - } - if (helper.includes(column)) { + hasValidCells = true; CellPath path = null; if (column.isComplex()) { @@ -1422,6 +1457,7 @@ public abstract class LegacyLayout { builder.addRowDeletion(Row.Deletion.regular(tombstone.deletionTime)); rowDeletion = tombstone; + hasValidCells = true; } return true; } @@ -1434,6 +1470,7 @@ public abstract class LegacyLayout builder.newRow(clustering); builder.addRowDeletion(Row.Deletion.regular(tombstone.deletionTime)); rowDeletion = tombstone; + hasValidCells = true; return true; } @@ -1464,6 +1501,7 @@ public abstract class LegacyLayout builder.addComplexDeletion(tombstone.start.collectionName, tombstone.deletionTime); if (rowDeletion == null || tombstone.deletionTime.supersedes(rowDeletion.deletionTime)) collectionDeletion = tombstone; + hasValidCells = true; return true; } @@ -1488,6 +1526,8 @@ public abstract class LegacyLayout public Row getRow() { + if (!hasValidCells && invalidLivenessInfo != null) + builder.addPrimaryKeyLivenessInfo(invalidLivenessInfo); return builder.build(); } } diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-CompressionInfo.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-CompressionInfo.db new file mode 100644 index 0000000000000000000000000000000000000000..26a0dbeab4c4b867266df98a4fb516e81fea424f GIT binary patch literal 43 fcmZSJ^@%cZ&d)6;M1%-@w4g(7?yQn8?7ul*r1UP>?Ok@PU~zcU7=yHBb#(Mruw@ Mz5xS6LM+dI0G7uNM*si- literal 0 HcmV?d00001 diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Digest.sha1 b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Digest.sha1 new file mode 100644 index 0000000000..0c696fbd10 --- /dev/null +++ b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Digest.sha1 @@ -0,0 +1 @@ +2529627719 \ No newline at end of file diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Filter.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Filter.db new file mode 100644 index 0000000000000000000000000000000000000000..55433281172fcd95413597915e3189f0b8ed77bc GIT binary patch literal 16 XcmZQzU|?lnU|?io5MXFvVNd`70`>sC literal 0 HcmV?d00001 diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Index.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Index.db new file mode 100644 index 0000000000000000000000000000000000000000..fbdd95081da260bedef7a940475304f25f656ffb GIT binary patch literal 18 QcmZQzVPIfj24Xk>004ae2mk;8 literal 0 HcmV?d00001 diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Statistics.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names/legacy_tables-legacy_ka_with_illegal_cell_names-ka-2-Statistics.db new file mode 100644 index 0000000000000000000000000000000000000000..0e471d4f026f9a051b78f5040a7e061ff32d9a6a GIT binary patch literal 4452 zcmeI$`%6<%902fp?>6Ui>3pS?lxCL1l*~-9RyLW7Ky#V)BCl@v03XazW`NRSeYhEFN-~-*CyyRTAfyt$m;aj z`t1BXtxjH6{9bv(>oE6Wb8_Avd*paX^VOPQu!XAXZ2rneOgm4hyP{M1h=I14bh{qG&NjQ^m3E}gETL=$f z)5P@XDBXuRDtX;(TMD*HX%FBYLQ)L&F>yt zl4$UH^iX`V1-X(}yASfh5r5<*LrKU%efW8YPUGhtQF#xw-!S?CdFy7}zg_+Y6wmo0 zMLwF)j9mR|J#yOvJU_#2Xg+CY_et2EmMc#omj+%#etJI~nh9w|?^ou6{j z6%QMg(AU+~fzZ#Z%1%R1-5HDnrdPV9w?k)a*#h@J-I&-4_djhqCxQE)(HcfN!RMLL zrj5nG0zGXw3oKmTCsjdDPnW>wBl=l+9{zraS9y+Y2JIcIZWiALc22n5qXTx`U-1== zU-HId9FE^(AihNk+IzF*1@QO4@0z?r2I2va$E5IiE&r}mm4o=|WMeQq4@5?M?va4F zeCT7xLEvpQ%}uaBdyLVMa6RWGDH}6`Tu(6;->-aajw#S=Hh2&F1Me#&~#AtGZ&f< z`OZVyAMs+0je}*M5;M1%-@w4gFqwyeF_D3RDKSxifsu(pFolglj8B@ukf|VB7%0rJ T;RH}MOKxgv0RzKiNA3>*#}*C0 literal 0 HcmV?d00001 diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Digest.sha1 b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Digest.sha1 new file mode 100644 index 0000000000..20deb5b232 --- /dev/null +++ b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Digest.sha1 @@ -0,0 +1 @@ +3340111295 \ No newline at end of file diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Filter.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Filter.db new file mode 100644 index 0000000000000000000000000000000000000000..55433281172fcd95413597915e3189f0b8ed77bc GIT binary patch literal 16 XcmZQzU|?lnU|?io5MXFvVNd`70`>sC literal 0 HcmV?d00001 diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Index.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Index.db new file mode 100644 index 0000000000000000000000000000000000000000..fbdd95081da260bedef7a940475304f25f656ffb GIT binary patch literal 18 QcmZQzVPIfj24Xk>004ae2mk;8 literal 0 HcmV?d00001 diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Statistics.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Statistics.db new file mode 100644 index 0000000000000000000000000000000000000000..f83575cfa835a348fd652254c1f377b4aaca19c2 GIT binary patch literal 4452 zcmeI$`AZa0902g0*ebe@ljy6fJKafP(VZL?Zh%~y zfUD^DLc%75O$nP3wjgXpSVY*CusvaC!fu2;3HuV>PB?^cjNaV5B@^*X!o`HE2zL;k z#HNV*LG2{sD#HEPv=iY{Y(DY({8}6r=n@hXVE_PIH3`KwC9c&{_| zuVXtN#CDy)-sp$DxdB^}iXBvk9nps!?|_}=f?co=yPUypB=UDihT|G{WXk#f8Ha$R^*Kkb(2I-3@csyYRaU|8hv`KR`tonA*U0{p28-q$OnE;19=J3~dn6$4{&-dl@0Zt)=-6@)-5SLDV z=s5wrx3;|%j^~gjI1uJ@Zi1|_67(-i?;4r`u75k#*9hEy^Hw_?uX@0DBFGS@#AiqT zL;%O;%rBQ3%q!5>@jKYC2IJakaEz{MTyxBcF>jm(G{dlM|EhlhcYsZ4 literal 0 HcmV?d00001 diff --git a/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Summary.db b/test/data/legacy-sstables/ka/legacy_tables/legacy_ka_with_illegal_cell_names_2/legacy_tables-legacy_ka_with_illegal_cell_names_2-ka-1-Summary.db new file mode 100644 index 0000000000000000000000000000000000000000..9b9000596da2a87ab0262fc4e1893b7161b9f76d GIT binary patch literal 92 zcmZQzU}#`qU|