-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Repair step to fix orphan reshares #30653
Conversation
@@ -191,6 +192,7 @@ public static function getBeforeUpgradeRepairSteps() { | |||
new InnoDB(), | |||
new Collation(\OC::$server->getConfig(), $connection), | |||
new SqliteAutoincrement($connection), | |||
new RepairOrphanedSubshare($connection), |
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.
Added the change here so that we trigger the repair step in the initial stage.
@@ -249,7 +251,7 @@ public function advance($step = 1, $description = '') { | |||
} | |||
|
|||
/** | |||
* @param int $max | |||
* emit signal |
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.
This has nothing to do with the commit. But then it doesn't make sense to have a PHPdoc which is wrong.
* @param $pageLimit | ||
* @param $paginationOffset | ||
*/ | ||
private function setSelectGetAllParents($pageLimit, $paginationOffset) { |
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.
The idea with this method is to get all the parents grouped and get the result.
* This select query is to get the result of parents === id | ||
* @param $parentId | ||
*/ | ||
private function setSelectShareId($parentId) { |
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.
This query will help us know if we have parents available in the table.
* This delete query deletes orphan shares whose parents are missing | ||
* @param $parentId | ||
*/ | ||
private function setDeleteOrphanSharesQuery($parentId) { |
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.
This query will delete the orphan shares.
*/ | ||
if ((count($getIdRows) === 0) && | ||
(in_array($row['parent'], $missingParents, true) === false)) { | ||
$missingParents[] = $row['parent']; |
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.
If the parents are missing, that is if the share is orphan, then add to $missingParents
array.
if (count($missingParents) > 0) { | ||
foreach ($missingParents as $missingParent) { | ||
$this->setDeleteOrphanSharesQuery($missingParent); | ||
$deleteRows[] = $this->deleteOrphanReshares; |
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.
Delete the rows if the $missingParents
array has elements.
67917b2
to
00fbe49
Compare
Codecov Report
@@ Coverage Diff @@
## master #30653 +/- ##
============================================
+ Coverage 62.25% 62.27% +0.01%
- Complexity 18205 18211 +6
============================================
Files 1140 1141 +1
Lines 68042 68076 +34
Branches 1230 1230
============================================
+ Hits 42361 42392 +31
- Misses 25318 25321 +3
Partials 363 363
Continue to review full report at Codecov.
|
Why not add your github comments directly in the PHP code, if you think they are needed to understand the code ? |
055e710
to
b1b43d1
Compare
Sure |
bf04aae
to
91c18e9
Compare
8c99c8c
to
f04cdd6
Compare
* @param int $pageLimit | ||
* @param int $paginationOffset | ||
*/ | ||
private function setParentsToExcludeFromShare($pageLimit, $paginationOffset) { |
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.
This query looks bit expensive to me. Any pointers to reduce the load would be helpful.
f04cdd6
to
a1d00b8
Compare
$builder = $this->connection->getQueryBuilder(); | ||
$builder | ||
->delete('share') | ||
->where($builder->expr()->eq('parent', $builder->createNamedParameter($parentId))); |
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.
please build the query without a value and use a real parameter name that you set later
see https://github.com/owncloud/core/blob/v10.0.7/lib/private/SystemTag/SystemTagManager.php#L172
a1d00b8
to
3a14dd1
Compare
->from('share'); | ||
$builder->where($builder->expr()->notIn('parent', $builder->createFunction($qb->getSQL()))); | ||
$builder->groupBy('parent'); | ||
$builder->setMaxResults($pageLimit); |
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.
these need to be set by whatever code is using the query, not in the generic query
$lastCount++; | ||
$paginationOffset += $pageLimit; | ||
foreach ($rows as $row) { | ||
$this->setDeleteOrphanSharesQuery(); |
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.
no, the query is only created once in the constructor and never again
then the code just sets the parameters
3a14dd1
to
bbe5aaf
Compare
$rows = $results->fetchAll(); | ||
$results->closeCursor(); | ||
if (count($rows) > 0) { | ||
$lastCount++; |
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.
you could simply use empty($rows)
in the while condition, no need for this extra variable
additionally $lastCount
seems to only ever count from 0 to 1, it doesn't count the results or pages, which could make it confusing for devs having a quick read. Better remove it.
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.
Latest change removes lastCount
var and uses empty($rows)
in the while condition.
$lastCount++; | ||
$paginationOffset += $pageLimit; | ||
foreach ($rows as $row) { | ||
$deleteParents[] = $row['parent']; |
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.
Should we delete the parents right away ?
If we do, then you don't need pagination in the missingParents
query as the next iteration will not return the already deleted entries.
This proposed approach would likely save memory in case of lots of shares and avoid having a too long list stored in $deleteParents
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.
The latest change does the deletion right away.
//Total 10 rows where there, we deleted 3 and the repair deleted another | ||
//3 rows. So total 6 rows were deleted and 4 rows were remaining | ||
//Hence 2 is the expected result. | ||
//For pgsql the result comes as 3, because null is included |
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.
can you exclude null somehow by adding a "is not null" in the query somehow and make it consistent across DBs ?
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.
Done.
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.
Looks better. A few more adjustments needed.
Its being reported that shares are orphaned. And in such state when an upgrade operation is performed results in failure. This repair step fixes the orphan shares. Signed-off-by: Sujith H <[email protected]>
bbe5aaf
to
d3df649
Compare
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.
Looks good 👍
Please backport
@sharidas I might have merged too quickly :-( the main query is doing pagination if yes then you need to remove pagination and only keep querying the first 1000 entries until there is nothing to fix |
backport will need to include: |
Backport PR: #31004 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Its being reported that shares are orphaned.
And in such state when an upgrade operation is
performed results in failure. This repair
step fixes the orphan shares.
Signed-off-by: Sujith H [email protected]
Description
This change would help to fix the failures caused during upgrade operation, when orphan reshares are residing in oc_share.
Related Issue
#30199
Motivation and Context
This change would help to fix the failures caused during upgrade operation, when orphan reshares are residing in oc_share. This change tries to remove the orphan shares fro the table which doesn't have parent.
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: