Skip to content

Commit

Permalink
分库分表:分片结果不符预期修复 (ecodeclub#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
heroyf authored Mar 26, 2023
1 parent 8996c2e commit 508dbc1
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 199 deletions.
1 change: 1 addition & 0 deletions .CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [eorm: 增强的 ShardingAlgorithm 设计与实现](https://github.com/ecodeclub/eorm/pull/161)
- [eorm: 分库分表: Merger排序实现](https://github.com/ecodeclub/eorm/pull/166)
- [eorm: BasicTypeValue重命名](https://github.com/ecodeclub/eorm/pull/177)
- [eorm: 分库分表: hash、shadow_hash算法不符合预期](https://github.com/ecodeclub/eorm/pull/174)

## v0.0.1:
- [Init Project](https://github.com/ecodeclub/eorm/pull/1)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.18
require (
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/go-sql-driver/mysql v1.6.0
github.com/gotomicro/ekit v0.0.0-20220612043755-81d8a8fb714a
github.com/mattn/go-sqlite3 v1.14.13
github.com/gotomicro/ekit v0.0.6
github.com/mattn/go-sqlite3 v1.14.15
github.com/stretchr/testify v1.7.1
github.com/valyala/bytebufferpool v1.0.0
go.uber.org/multierr v1.9.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/gotomicro/ekit v0.0.0-20220612043755-81d8a8fb714a h1:Zpr8+lnnuUu3VpLZzde0ScX0FJlCZRBQhuVUhMIyh70=
github.com/gotomicro/ekit v0.0.0-20220612043755-81d8a8fb714a/go.mod h1:knWKyV4PLI/HhpXjdOCkH3v3w6RvqDiNvq2is/kjSyY=
github.com/mattn/go-sqlite3 v1.14.13 h1:1tj15ngiFfcZzii7yd82foL+ks+ouQcj8j/TPq3fk1I=
github.com/mattn/go-sqlite3 v1.14.13/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/gotomicro/ekit v0.0.6 h1:Tw3vcx8hltUzFmK7zkp6/5OGlE+ceuq6wha7KxBfpaA=
github.com/gotomicro/ekit v0.0.6/go.mod h1:LpstTheKiI/j532rejAlTwPRemwFQXhyqdH6lpzr4wk=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
2 changes: 1 addition & 1 deletion internal/sharding/hash/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (h *Hash) Sharding(ctx context.Context, req sharding.Request) (sharding.Res
}
skVal, ok := req.SkValues[h.ShardingKey]
if !ok {
return sharding.EmptyResult, nil
return sharding.Result{Dsts: h.Broadcast(ctx)}, nil
}
dbName := h.DBPattern.Name
if !h.DBPattern.NotSharding && strings.Contains(dbName, "%d") {
Expand Down
2 changes: 1 addition & 1 deletion internal/sharding/hash/shadow_hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (h *ShadowHash) Sharding(ctx context.Context, req sharding.Request) (shardi
}
skVal, ok := req.SkValues[h.ShardingKey]
if !ok {
return sharding.EmptyResult, nil
return sharding.Result{Dsts: h.Broadcast(ctx)}, nil
}
dbName := h.DBPattern.Name
if !h.DBPattern.NotSharding && strings.Contains(dbName, "%d") {
Expand Down
54 changes: 10 additions & 44 deletions sharding_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ package eorm
import (
"context"
"database/sql"
"fmt"
"sync"

"github.com/gotomicro/ekit/slice"

"github.com/ecodeclub/eorm/internal/sharding"

"github.com/ecodeclub/eorm/internal/errs"
Expand Down Expand Up @@ -165,36 +166,20 @@ func (s *ShardingSelector[T]) findDstByPredicate(ctx context.Context, pre Predic
if err != nil {
return sharding.EmptyResult, err
}
if len(left.Dsts) == 0 {
return s.findDstByPredicate(ctx, pre.right.(Predicate))
}
right, err := s.findDstByPredicate(ctx, pre.right.(Predicate))
if err != nil {
return sharding.EmptyResult, err
}
if len(right.Dsts) == 0 {
return left, nil
}
return s.mergeAnd(left, right), nil
case opOr:
left, err := s.findDstByPredicate(ctx, pre.left.(Predicate))
if err != nil {
return sharding.EmptyResult, err
}
if len(left.Dsts) == 0 {
return sharding.Result{
Dsts: s.meta.ShardingAlgorithm.Broadcast(ctx),
}, nil
}
right, err := s.findDstByPredicate(ctx, pre.right.(Predicate))
if err != nil {
return sharding.EmptyResult, err
}
if len(right.Dsts) == 0 {
return sharding.Result{
Dsts: s.meta.ShardingAlgorithm.Broadcast(ctx),
}, nil
}
return s.mergeOR(left, right), nil
case opEQ:
col, isCol := pre.left.(Column)
Expand All @@ -209,38 +194,19 @@ func (s *ShardingSelector[T]) findDstByPredicate(ctx context.Context, pre Predic
}
}

// mergeAnd 两个分片结果的交集
func (*ShardingSelector[T]) mergeAnd(left, right sharding.Result) sharding.Result {
dsts := make([]sharding.Dst, 0, len(left.Dsts)+len(right.Dsts))
for _, r := range right.Dsts {
exist := false
for _, l := range left.Dsts {
if r.Equals(l) {
exist = true
}
}
if exist {
dsts = append(dsts, r)
}
}
dsts := slice.IntersectSetFunc[sharding.Dst](left.Dsts, right.Dsts, func(src, dst sharding.Dst) bool {
return src.Equals(dst)
})
return sharding.Result{Dsts: dsts}
}

// mergeAnd 两个分片结果的并集
func (*ShardingSelector[T]) mergeOR(left, right sharding.Result) sharding.Result {
dsts := make([]sharding.Dst, 0, len(left.Dsts)+len(right.Dsts))
m := make(map[string]bool, 8)
for _, r := range right.Dsts {
for _, l := range left.Dsts {
if r.NotEquals(l) {
tbl := fmt.Sprintf("%s_%s_%s", l.Name, l.DB, l.Table)
if _, ok := m[tbl]; ok {
continue
}
dsts = append(dsts, l)
m[tbl] = true
}
}
dsts = append(dsts, r)
}
dsts := slice.UnionSetFunc[sharding.Dst](left.Dsts, right.Dsts, func(src, dst sharding.Dst) bool {
return src.Equals(dst)
})
return sharding.Result{Dsts: dsts}
}

Expand Down
Loading

0 comments on commit 508dbc1

Please sign in to comment.