-
Notifications
You must be signed in to change notification settings - Fork 623
HDDS-9347. Fix Ozone FS listStatus() cache-table inconsistencies. #5399
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
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1441,7 +1441,9 @@ public static boolean isKeyDeleted(String key, Table keyTable) { | |
| private void listStatusFindKeyInTableCache( | ||
| Iterator<Map.Entry<CacheKey<String>, CacheValue<OmKeyInfo>>> cacheIter, | ||
| String keyArgs, String startCacheKey, boolean recursive, | ||
| TreeMap<String, OzoneFileStatus> cacheKeyMap) { | ||
| TreeMap<String, OzoneFileStatus> cacheKeyMap) throws IOException { | ||
|
|
||
| Map<String, OmKeyInfo> remainingKeys = new HashMap<>(); | ||
|
|
||
| while (cacheIter.hasNext()) { | ||
| Map.Entry<CacheKey<String>, CacheValue<OmKeyInfo>> entry = | ||
|
|
@@ -1452,14 +1454,14 @@ private void listStatusFindKeyInTableCache( | |
| } | ||
| OmKeyInfo cacheOmKeyInfo = entry.getValue().getCacheValue(); | ||
| // cacheOmKeyInfo is null if an entry is deleted in cache | ||
| if (cacheOmKeyInfo != null | ||
| && cacheKey.startsWith(startCacheKey) | ||
| && cacheKey.compareTo(startCacheKey) >= 0) { | ||
| if (cacheOmKeyInfo != null && cacheKey.startsWith( | ||
| keyArgs) && cacheKey.compareTo(startCacheKey) >= 0) { | ||
| if (!recursive) { | ||
| String remainingKey = StringUtils.stripEnd(cacheKey.substring( | ||
| startCacheKey.length()), OZONE_URI_DELIMITER); | ||
| keyArgs.length()), OZONE_URI_DELIMITER); | ||
| // For non-recursive, the remaining part of key can't have '/' | ||
| if (remainingKey.contains(OZONE_URI_DELIMITER)) { | ||
| remainingKeys.put(cacheKey, cacheOmKeyInfo); | ||
| continue; | ||
| } | ||
| } | ||
|
|
@@ -1474,6 +1476,34 @@ private void listStatusFindKeyInTableCache( | |
| cacheKeyMap.put(cacheKey, null); | ||
| } | ||
| } | ||
|
|
||
| // let's say fsPaths is disabled, then creating a key like a/b/c | ||
| // will not create intermediate keys in the keyTable so only entry | ||
| // in the keyTable would be {a/b/c}. This would be skipped from getting | ||
| // added to cacheKeyMap above as remainingKey would be {b/c} and it | ||
| // contains the slash, In this case we track such keys which are not added | ||
| // to the map, find the immediate child and check if they are present in | ||
| // the map. If not create a fake dir and add it. This is similar to the | ||
| // logic in findKeyInDbWithIterator. | ||
| if (!recursive) { | ||
| for (Map.Entry<String, OmKeyInfo> entry : remainingKeys.entrySet()) { | ||
| String remainingKey = entry.getKey(); | ||
| String immediateChild = | ||
| OzoneFSUtils.getImmediateChild(remainingKey, keyArgs); | ||
| if (!cacheKeyMap.containsKey(immediateChild)) { | ||
| // immediateChild contains volume/bucket prefix remove it. | ||
| String volumeBuckPrefix = OZONE_URI_DELIMITER + entry.getValue() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. from what i understand this list would be for only one bucket. This can be outside the loop, it would be a constant string for this function.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we move this to a follow-up task? It would be nice to avoid blocking the fix for a single nitpicky comment.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @swamirishi for the review. Addressed the comment. |
||
| .getVolumeName() + OZONE_URI_DELIMITER + entry.getValue() | ||
| .getBucketName() + OZONE_URI_DELIMITER; | ||
| String immediateChildKeyName = | ||
| immediateChild.replaceAll(volumeBuckPrefix, ""); | ||
| OmKeyInfo fakeDirEntry = | ||
| createDirectoryKey(entry.getValue(), immediateChildKeyName); | ||
| cacheKeyMap.put(immediateChild, | ||
| new OzoneFileStatus(fakeDirEntry, scmBlockSize, true)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -1687,7 +1717,11 @@ private void findKeyInDbWithIterator(boolean recursive, String startKey, | |
| if (!entryKeyName.equals(immediateChild)) { | ||
| OmKeyInfo fakeDirEntry = createDirectoryKey( | ||
| omKeyInfo, immediateChild); | ||
| cacheKeyMap.put(entryInDb, | ||
| String fakeDirKey = ozoneManager.getMetadataManager() | ||
| .getOzoneKey(fakeDirEntry.getVolumeName(), | ||
| fakeDirEntry.getBucketName(), | ||
| fakeDirEntry.getKeyName()); | ||
| cacheKeyMap.put(fakeDirKey, | ||
| new OzoneFileStatus(fakeDirEntry, | ||
| scmBlockSize, true)); | ||
| } else { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test that will fail without this fix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, e.g.
testListStatusIteratorOnPageSizefails intermittently with small page size.https://github.com/apache/ozone/actions/runs/6263989725/job/17010674585#step:5:3786
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the new test changes in this PR will fail without code changes