From 5e9934459e8b494221fc8fbcec3e04d0483bc38a Mon Sep 17 00:00:00 2001 From: Manan Gupta Date: Thu, 3 Aug 2023 17:42:05 +0530 Subject: [PATCH 1/2] feat: add 2 more durability policies Signed-off-by: Manan Gupta --- go/vt/vtctl/reparentutil/durability.go | 30 +- go/vt/vtctl/reparentutil/durability_test.go | 316 ++++++++++++-------- 2 files changed, 213 insertions(+), 133 deletions(-) diff --git a/go/vt/vtctl/reparentutil/durability.go b/go/vt/vtctl/reparentutil/durability.go index 735965c3afa..e68485a395c 100644 --- a/go/vt/vtctl/reparentutil/durability.go +++ b/go/vt/vtctl/reparentutil/durability.go @@ -43,10 +43,24 @@ func init() { return &durabilityNone{} }) RegisterDurability("semi_sync", func() Durabler { - return &durabilitySemiSync{} + return &durabilitySemiSync{ + rdonlySemiSync: false, + } }) RegisterDurability("cross_cell", func() Durabler { - return &durabilityCrossCell{} + return &durabilityCrossCell{ + rdonlySemiSync: false, + } + }) + RegisterDurability("semi_sync_with_rdonly_ack", func() Durabler { + return &durabilitySemiSync{ + rdonlySemiSync: true, + } + }) + RegisterDurability("cross_cell_with_rdonly_ack", func() Durabler { + return &durabilityCrossCell{ + rdonlySemiSync: true, + } }) RegisterDurability("test", func() Durabler { return &durabilityTest{} @@ -141,7 +155,9 @@ func (d *durabilityNone) isReplicaSemiSync(primary, replica *topodatapb.Tablet) // durabilitySemiSync has 1 semi-sync setup. It only allows Primary and Replica type servers to acknowledge semi sync // It returns NeutralPromoteRule for Primary and Replica tablet types, MustNotPromoteRule for everything else -type durabilitySemiSync struct{} +type durabilitySemiSync struct { + rdonlySemiSync bool +} // promotionRule implements the Durabler interface func (d *durabilitySemiSync) promotionRule(tablet *topodatapb.Tablet) promotionrule.CandidatePromotionRule { @@ -162,6 +178,8 @@ func (d *durabilitySemiSync) isReplicaSemiSync(primary, replica *topodatapb.Tabl switch replica.Type { case topodatapb.TabletType_PRIMARY, topodatapb.TabletType_REPLICA: return true + case topodatapb.TabletType_RDONLY: + return d.rdonlySemiSync } return false } @@ -171,7 +189,9 @@ func (d *durabilitySemiSync) isReplicaSemiSync(primary, replica *topodatapb.Tabl // durabilityCrossCell has 1 semi-sync setup. It only allows Primary and Replica type servers from a different cell to acknowledge semi sync. // This means that a transaction must be in two cells for it to be acknowledged // It returns NeutralPromoteRule for Primary and Replica tablet types, MustNotPromoteRule for everything else -type durabilityCrossCell struct{} +type durabilityCrossCell struct { + rdonlySemiSync bool +} // promotionRule implements the Durabler interface func (d *durabilityCrossCell) promotionRule(tablet *topodatapb.Tablet) promotionrule.CandidatePromotionRule { @@ -192,6 +212,8 @@ func (d *durabilityCrossCell) isReplicaSemiSync(primary, replica *topodatapb.Tab switch replica.Type { case topodatapb.TabletType_PRIMARY, topodatapb.TabletType_REPLICA: return primary.Alias.Cell != replica.Alias.Cell + case topodatapb.TabletType_RDONLY: + return d.rdonlySemiSync && primary.Alias.Cell != replica.Alias.Cell } return false } diff --git a/go/vt/vtctl/reparentutil/durability_test.go b/go/vt/vtctl/reparentutil/durability_test.go index 857718174c5..f1429b29621 100644 --- a/go/vt/vtctl/reparentutil/durability_test.go +++ b/go/vt/vtctl/reparentutil/durability_test.go @@ -73,146 +73,204 @@ func TestDurabilityNone(t *testing.T) { } func TestDurabilitySemiSync(t *testing.T) { - durability, err := GetDurabilityPolicy("semi_sync") - require.NoError(t, err) - - promoteRule := PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, + testcases := []struct { + durabilityPolicy string + rdonlySemiSync bool + }{ + { + durabilityPolicy: "semi_sync", + rdonlySemiSync: false, + }, { + durabilityPolicy: "semi_sync_with_rdonly_ack", + rdonlySemiSync: true, }, - Type: topodatapb.TabletType_PRIMARY, - }) - assert.Equal(t, promotionrule.Neutral, promoteRule) + } - promoteRule = PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_REPLICA, - }) - assert.Equal(t, promotionrule.Neutral, promoteRule) + for _, tt := range testcases { + t.Run(tt.durabilityPolicy, func(t *testing.T) { + durability, err := GetDurabilityPolicy(tt.durabilityPolicy) + require.NoError(t, err) - promoteRule = PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_RDONLY, - }) - assert.Equal(t, promotionrule.MustNot, promoteRule) + promoteRule := PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + }) + assert.Equal(t, promotionrule.Neutral, promoteRule) - promoteRule = PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_SPARE, - }) - assert.Equal(t, promotionrule.MustNot, promoteRule) - assert.Equal(t, 1, SemiSyncAckers(durability, nil)) - assert.Equal(t, true, IsReplicaSemiSync(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 101, - }, - Type: topodatapb.TabletType_PRIMARY, - }, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_REPLICA, - })) - assert.Equal(t, false, IsReplicaSemiSync(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 101, - }, - Type: topodatapb.TabletType_PRIMARY, - }, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_EXPERIMENTAL, - })) + promoteRule = PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }) + assert.Equal(t, promotionrule.Neutral, promoteRule) + + promoteRule = PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_RDONLY, + }) + assert.Equal(t, promotionrule.MustNot, promoteRule) + + promoteRule = PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_SPARE, + }) + assert.Equal(t, promotionrule.MustNot, promoteRule) + assert.Equal(t, 1, SemiSyncAckers(durability, nil)) + assert.Equal(t, true, IsReplicaSemiSync(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Type: topodatapb.TabletType_PRIMARY, + }, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + })) + assert.Equal(t, false, IsReplicaSemiSync(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Type: topodatapb.TabletType_PRIMARY, + }, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_EXPERIMENTAL, + })) + assert.Equal(t, tt.rdonlySemiSync, IsReplicaSemiSync(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 101, + }, + Type: topodatapb.TabletType_PRIMARY, + }, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_RDONLY, + })) + }) + } } func TestDurabilityCrossCell(t *testing.T) { - durability, err := GetDurabilityPolicy("cross_cell") - require.NoError(t, err) - - promoteRule := PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, + testcases := []struct { + durabilityPolicy string + rdonlySemiSync bool + }{ + { + durabilityPolicy: "cross_cell", + rdonlySemiSync: false, + }, { + durabilityPolicy: "cross_cell_with_rdonly_ack", + rdonlySemiSync: true, }, - Type: topodatapb.TabletType_PRIMARY, - }) - assert.Equal(t, promotionrule.Neutral, promoteRule) + } - promoteRule = PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_REPLICA, - }) - assert.Equal(t, promotionrule.Neutral, promoteRule) + for _, tt := range testcases { + t.Run(tt.durabilityPolicy, func(t *testing.T) { + durability, err := GetDurabilityPolicy(tt.durabilityPolicy) + require.NoError(t, err) - promoteRule = PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_RDONLY, - }) - assert.Equal(t, promotionrule.MustNot, promoteRule) + promoteRule := PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_PRIMARY, + }) + assert.Equal(t, promotionrule.Neutral, promoteRule) - promoteRule = PromotionRule(durability, &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - Uid: 100, - }, - Type: topodatapb.TabletType_SPARE, - }) - assert.Equal(t, promotionrule.MustNot, promoteRule) - assert.Equal(t, 1, SemiSyncAckers(durability, nil)) - assert.Equal(t, false, IsReplicaSemiSync(durability, &topodatapb.Tablet{ - Type: topodatapb.TabletType_PRIMARY, - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - }, - }, &topodatapb.Tablet{ - Type: topodatapb.TabletType_REPLICA, - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - }, - })) - assert.Equal(t, true, IsReplicaSemiSync(durability, &topodatapb.Tablet{ - Type: topodatapb.TabletType_PRIMARY, - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - }, - }, &topodatapb.Tablet{ - Type: topodatapb.TabletType_REPLICA, - Alias: &topodatapb.TabletAlias{ - Cell: "cell2", - }, - })) - assert.Equal(t, false, IsReplicaSemiSync(durability, &topodatapb.Tablet{ - Type: topodatapb.TabletType_PRIMARY, - Alias: &topodatapb.TabletAlias{ - Cell: "cell1", - }, - }, &topodatapb.Tablet{ - Type: topodatapb.TabletType_EXPERIMENTAL, - Alias: &topodatapb.TabletAlias{ - Cell: "cell2", - }, - })) + promoteRule = PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_REPLICA, + }) + assert.Equal(t, promotionrule.Neutral, promoteRule) + + promoteRule = PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_RDONLY, + }) + assert.Equal(t, promotionrule.MustNot, promoteRule) + + promoteRule = PromotionRule(durability, &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 100, + }, + Type: topodatapb.TabletType_SPARE, + }) + assert.Equal(t, promotionrule.MustNot, promoteRule) + assert.Equal(t, 1, SemiSyncAckers(durability, nil)) + assert.Equal(t, false, IsReplicaSemiSync(durability, &topodatapb.Tablet{ + Type: topodatapb.TabletType_PRIMARY, + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + }, + }, &topodatapb.Tablet{ + Type: topodatapb.TabletType_REPLICA, + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + }, + })) + assert.Equal(t, true, IsReplicaSemiSync(durability, &topodatapb.Tablet{ + Type: topodatapb.TabletType_PRIMARY, + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + }, + }, &topodatapb.Tablet{ + Type: topodatapb.TabletType_REPLICA, + Alias: &topodatapb.TabletAlias{ + Cell: "cell2", + }, + })) + assert.Equal(t, false, IsReplicaSemiSync(durability, &topodatapb.Tablet{ + Type: topodatapb.TabletType_PRIMARY, + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + }, + }, &topodatapb.Tablet{ + Type: topodatapb.TabletType_EXPERIMENTAL, + Alias: &topodatapb.TabletAlias{ + Cell: "cell2", + }, + })) + assert.Equal(t, tt.rdonlySemiSync, IsReplicaSemiSync(durability, &topodatapb.Tablet{ + Type: topodatapb.TabletType_PRIMARY, + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + }, + }, &topodatapb.Tablet{ + Type: topodatapb.TabletType_RDONLY, + Alias: &topodatapb.TabletAlias{ + Cell: "cell2", + }, + })) + }) + } } func TestError(t *testing.T) { From 3ef22f28c055a6a2a7aa700a8887e92e8ae12b5a Mon Sep 17 00:00:00 2001 From: Manan Gupta Date: Fri, 18 Aug 2023 11:40:41 +0530 Subject: [PATCH 2/2] feat: add release notes changes Signed-off-by: Manan Gupta --- changelog/18.0/18.0.0/summary.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/changelog/18.0/18.0.0/summary.md b/changelog/18.0/18.0.0/summary.md index 561b209ac06..26f429442a1 100644 --- a/changelog/18.0/18.0.0/summary.md +++ b/changelog/18.0/18.0.0/summary.md @@ -21,6 +21,8 @@ - **[Docker](#docker)** - [Debian: Bookworm added and made default](#debian-bookworm) - [Debian: Buster removed](#debian-buster) + - **[Durability Policies](#durability-policies)** + - [New Durability Policies](#new-durability-policies) ## Major Changes @@ -120,4 +122,10 @@ Bullseye images will still be built and available as long as the OS build is cur Buster LTS supports will stop in June 2024, and Vitess v18.0 will be supported through October 2024. To prevent supporting a deprecated buster build for several months after June 2024, we are preemptively -removing Vitess support. \ No newline at end of file +removing Vitess support. + +### Durability Policies + +#### New Durability Policies + +2 new inbuilt durability policies have been added to Vitess in this release namely `semi_sync_with_rdonly_ack` and `cross_cell_with_rdonly_ack`. These policies are exactly like `semi_sync` and `cross_cell` respectively, and differ just in the part where the rdonly tablets can also send semi-sync ACKs. \ No newline at end of file