loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Don't use subselect in `DeleteIssuesByRepoID` (#27332)

Part of https://codeberg.org/forgejo/discussions/issues/61

This is workaround for a bug in MariaDB

authored by

JakobDev and committed by
GitHub
08507e27 2b06c106

+79 -64
+79 -64
models/issues/issue_update.go
··· 685 685 686 686 // DeleteIssuesByRepoID deletes issues by repositories id 687 687 func DeleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths []string, err error) { 688 - deleteCond := builder.Select("id").From("issue").Where(builder.Eq{"issue.repo_id": repoID}) 689 - 688 + // MariaDB has a performance bug: https://jira.mariadb.org/browse/MDEV-16289 689 + // so here it uses "DELETE ... WHERE IN" with pre-queried IDs. 690 690 sess := db.GetEngine(ctx) 691 - // Delete content histories 692 - if _, err = sess.In("issue_id", deleteCond). 693 - Delete(&ContentHistory{}); err != nil { 694 - return nil, err 695 - } 696 691 697 - // Delete comments and attachments 698 - if _, err = sess.In("issue_id", deleteCond). 699 - Delete(&Comment{}); err != nil { 700 - return nil, err 701 - } 692 + for { 693 + issueIDs := make([]int64, 0, db.DefaultMaxInSize) 702 694 703 - // Dependencies for issues in this repository 704 - if _, err = sess.In("issue_id", deleteCond). 705 - Delete(&IssueDependency{}); err != nil { 706 - return nil, err 707 - } 695 + err := sess.Table(&Issue{}).Where("repo_id = ?", repoID).OrderBy("id").Limit(db.DefaultMaxInSize).Cols("id").Find(&issueIDs) 696 + if err != nil { 697 + return nil, err 698 + } 708 699 709 - // Delete dependencies for issues in other repositories 710 - if _, err = sess.In("dependency_id", deleteCond). 711 - Delete(&IssueDependency{}); err != nil { 712 - return nil, err 713 - } 700 + if len(issueIDs) == 0 { 701 + break 702 + } 714 703 715 - if _, err = sess.In("issue_id", deleteCond). 716 - Delete(&IssueUser{}); err != nil { 717 - return nil, err 718 - } 704 + // Delete content histories 705 + _, err = sess.In("issue_id", issueIDs).Delete(&ContentHistory{}) 706 + if err != nil { 707 + return nil, err 708 + } 719 709 720 - if _, err = sess.In("issue_id", deleteCond). 721 - Delete(&Reaction{}); err != nil { 722 - return nil, err 723 - } 710 + // Delete comments and attachments 711 + _, err = sess.In("issue_id", issueIDs).Delete(&Comment{}) 712 + if err != nil { 713 + return nil, err 714 + } 715 + 716 + // Dependencies for issues in this repository 717 + _, err = sess.In("issue_id", issueIDs).Delete(&IssueDependency{}) 718 + if err != nil { 719 + return nil, err 720 + } 721 + 722 + // Delete dependencies for issues in other repositories 723 + _, err = sess.In("dependency_id", issueIDs).Delete(&IssueDependency{}) 724 + if err != nil { 725 + return nil, err 726 + } 727 + 728 + _, err = sess.In("issue_id", issueIDs).Delete(&IssueUser{}) 729 + if err != nil { 730 + return nil, err 731 + } 732 + 733 + _, err = sess.In("issue_id", issueIDs).Delete(&Reaction{}) 734 + if err != nil { 735 + return nil, err 736 + } 724 737 725 - if _, err = sess.In("issue_id", deleteCond). 726 - Delete(&IssueWatch{}); err != nil { 727 - return nil, err 728 - } 738 + _, err = sess.In("issue_id", issueIDs).Delete(&IssueWatch{}) 739 + if err != nil { 740 + return nil, err 741 + } 729 742 730 - if _, err = sess.In("issue_id", deleteCond). 731 - Delete(&Stopwatch{}); err != nil { 732 - return nil, err 733 - } 743 + _, err = sess.In("issue_id", issueIDs).Delete(&Stopwatch{}) 744 + if err != nil { 745 + return nil, err 746 + } 734 747 735 - if _, err = sess.In("issue_id", deleteCond). 736 - Delete(&TrackedTime{}); err != nil { 737 - return nil, err 738 - } 748 + _, err = sess.In("issue_id", issueIDs).Delete(&TrackedTime{}) 749 + if err != nil { 750 + return nil, err 751 + } 739 752 740 - if _, err = sess.In("issue_id", deleteCond). 741 - Delete(&project_model.ProjectIssue{}); err != nil { 742 - return nil, err 743 - } 753 + _, err = sess.In("issue_id", issueIDs).Delete(&project_model.ProjectIssue{}) 754 + if err != nil { 755 + return nil, err 756 + } 744 757 745 - if _, err = sess.In("dependent_issue_id", deleteCond). 746 - Delete(&Comment{}); err != nil { 747 - return nil, err 748 - } 758 + _, err = sess.In("dependent_issue_id", issueIDs).Delete(&Comment{}) 759 + if err != nil { 760 + return nil, err 761 + } 749 762 750 - var attachments []*repo_model.Attachment 751 - if err = sess.In("issue_id", deleteCond). 752 - Find(&attachments); err != nil { 753 - return nil, err 754 - } 763 + var attachments []*repo_model.Attachment 764 + err = sess.In("issue_id", issueIDs).Find(&attachments) 765 + if err != nil { 766 + return nil, err 767 + } 755 768 756 - for j := range attachments { 757 - attachmentPaths = append(attachmentPaths, attachments[j].RelativePath()) 758 - } 769 + for j := range attachments { 770 + attachmentPaths = append(attachmentPaths, attachments[j].RelativePath()) 771 + } 759 772 760 - if _, err = sess.In("issue_id", deleteCond). 761 - Delete(&repo_model.Attachment{}); err != nil { 762 - return nil, err 763 - } 773 + _, err = sess.In("issue_id", issueIDs).Delete(&repo_model.Attachment{}) 774 + if err != nil { 775 + return nil, err 776 + } 764 777 765 - if _, err = db.DeleteByBean(ctx, &Issue{RepoID: repoID}); err != nil { 766 - return nil, err 778 + _, err = sess.In("id", issueIDs).Delete(&Issue{}) 779 + if err != nil { 780 + return nil, err 781 + } 767 782 } 768 783 769 784 return attachmentPaths, err