Repository: vitessio/vitess
Pull request #11611 (2022-10-31 19:03:47)

Removing SharedPitr_tls and Backup_transfrom test from CI
## Description

This PR is doing bunch of cleanup in CI 

1. Remove pitr_tls test
    -  Since the test is not doing what it is suppose to do. It was trying to use SSL which is not a Vitess feature instead it is MySQL feature and we don't need to test it. So test was not adding any value.
    -  During SSL certificate generation, we were creating the certificate but we weren't using them correctly in our cnf file. Instead of using hardcoded server-001 for all the sql servers we are using their respective certificates.
     This is an example of excerpt of my.cnf after this change:
    ```
    ## /Users/rameezsajwani/Code/fork/vitess/vtdataroot/vtroot_8101/ssl_0000004121/ssl.cnf

    ssl_ca=/Users/rameezsajwani/Code/fork/vitess/vtdataroot/vtroot_8101/ssl_0000004121/ca-cert.pem
    ssl_cert=/Users/rameezsajwani/Code/fork/vitess/vtdataroot/vtroot_8101/ssl_0000004121/server-instance-009-cert.pem
    ssl_key=/Users/rameezsajwani/Code/fork/vitess/vtdataroot/vtroot_8101/ssl_0000004121/server-instance-009-key.pem
    ```
log before this change
```
2022-10-31T20:38:04.004973Z 0 [Warning] [MY-013595] [Server] Failed to initialize TLS for channel: mysql_main. See below for the description of exact issue.
2022-10-31T20:38:04.004993Z 0 [Warning] [MY-010069] [Server] Failed to set up SSL because of the following SSL library error: Unable to get certificate
```

logs after this change.
```
2022-10-31T21:56:46.060895Z 0 [Warning] [MY-010068] [Server] CA certificate /Users/rameezsajwani/Code/fork/vitess/vtdataroot/vtroot_8301/ssl_0000001869/ca-cert.pem is self signed.
2022-10-31T21:56:46.060914Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
```


2. Standard pitr test was using semi_sync but with only one replica and primary, which was resulting in indeterministic behavior during backup. So we are changing the test topology to use two replica with a primary.
3. Since backup_transform is deprecated, we are removing it from CI.
4. Delete vtbackup_transofrm test.
5. Rename 'vtbackup_transform' cluster name to 'vtbackup' because it no longer have any transform test.

## Related Issue(s)

  - Fixes: #11642

## Checklist

-   [ ] "Backport me!" label has been added if this change should be backported
-   [x] Tests were added or are not required
-   [x] Documentation was added or is not required

vitess-bot[bot]: ### Review Checklist
            
Hello reviewers! :wave: Please follow this checklist when reviewing this Pull Request.

#### General
- [ ] Ensure that the Pull Request has a descriptive title.
- [ ] If this is a change that users need to know about, please apply the `release notes (needs details)` label so that merging is blocked unless the summary release notes document is included.

#### If a new flag is being introduced:
- [ ] Is it really necessary to add this flag?
- [ ] Flag names should be clear and intuitive (as far as possible)
- [ ] Help text should be descriptive.
- [ ] Flag names should use dashes (`-`) as word separators rather than underscores (`_`).

#### If a workflow is added or modified:
- [ ] Each item in `Jobs` should be named in order to mark it as `required`.
- [ ] If the workflow should be required, the maintainer team should be notified.

#### Bug fixes
- [ ] There should be at least one unit or end-to-end test.
- [ ] The Pull Request description should include a link to an issue that describes the bug.

#### Non-trivial changes
- [ ] There should be some code comments as to why things are implemented the way they are.

#### New/Existing features
- [ ] Should be documented, either by modifying the existing documentation or creating new documentation.
- [ ] New features should have a link to a feature request issue or an RFC that documents the use cases, corner cases and test cases.

#### Backward compatibility            
- [ ] Protobuf changes should be wire-compatible.
- [ ] Changes to `_vt` tables and RPCs need to be backward compatible.
- [ ] `vtctl` command output order should be stable and `awk`-able.
- [ ] RPC changes should be compatible with vitess-operator
- [ ] If a flag is removed, then it should also be removed from VTop, if used there.

rsajwani: spoke to Matt offline. I am going to delete the vtbackup_transform test as well.
deepthi: > Since backup_transform is deprecated, we are removing it from CI.

And this is fine because the code is slated for deletion before v16

Patch:
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 3dadefe6e6..7405fe7f21 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,45 +1,46 @@
 * @deepthi
-bootstrap.sh @deepthi
-/.github/ISSUE_TEMPLATE/ @frouioui
-/.github/workflows/ @frouioui
+bootstrap.sh @ajm188 @deepthi @frouioui @vmg
+/.github/ISSUE_TEMPLATE/ @deepthi @frouioui @mattlord
+/.github/workflows/ @deepthi @frouioui @mattlord
 /config/mycnf/ @deepthi @shlomi-noach @mattlord
-/docker/ @derekperkins @dkhenry @mattlord
+/doc/ @deepthi @frouioui @GuptaManan100 @rsajwani
+/docker/ @deepthi @derekperkins @dkhenry @mattlord
 /examples/compose @shlomi-noach @GuptaManan100 @frouioui
-/examples/demo @sougou @mattlord
+/examples/demo @mattlord @rohit-nayak-ps
 /examples/local @rohit-nayak-ps @frouioui @mattlord @GuptaManan100
-/examples/operator @GuptaManan100 @frouioui
-/examples/region_sharding @deepthi
+/examples/operator @GuptaManan100 @frouioui @mattlord
+/examples/region_sharding @deepthi @mattlord
 /java/ @harshit-gangal
 /go/cache @vmg
-/go/cmd @ajm188
-/go/cmd/vtadmin @ajm188 @doeg @notfelineit
+/go/cmd @ajm188 @deepthi
+/go/cmd/vtadmin @ajm188 @notfelineit
 /go/cmd/vtctldclient @ajm188 @notfelineit
-/go/internal/flag @ajm188
+/go/internal/flag @ajm188 @rohit-nayak-ps
 /go/mysql @harshit-gangal @systay @mattlord
-/go/pools @harshit-gangal
-/go/protoutil @ajm188
-/go/sqltypes @harshit-gangal
-/go/test/endtoend/onlineddl @shlomi-noach
+/go/pools @deepthi @harshit-gangal
+/go/protoutil @ajm188 @deepthi
+/go/sqltypes @harshit-gangal @shlomi-noach @vmg
+/go/test/endtoend/onlineddl @rohit-nayak-ps @shlomi-noach
 /go/test/endtoend/messaging @mattlord @rohit-nayak-ps @derekperkins
 /go/test/endtoend/vtgate @harshit-gangal @systay @frouioui
 /go/test/endtoend/vtorc @deepthi @shlomi-noach @GuptaManan100 @rsajwani
 /go/tools/ @frouioui @systay
-/go/vt/dbconnpool @harshit-gangal
-/go/vt/discovery @deepthi
+/go/vt/dbconnpool @harshit-gangal @mattlord
+/go/vt/discovery @deepthi @frouioui
 /go/vt/mysqlctl @deepthi @mattlord @rsajwani
-/go/vt/proto @harshit-gangal
-/go/vt/proto/vtadmin @ajm188 @doeg @notfelineit
-/go/vt/schema @shlomi-noach
+/go/vt/proto @deepthi @harshit-gangal @mattlord
+/go/vt/proto/vtadmin @ajm188 @notfelineit
+/go/vt/schema @mattlord @shlomi-noach
 /go/vt/servenv @deepthi @ajm188
 /go/vt/sqlparser @harshit-gangal @systay @GuptaManan100
-/go/vt/srvtopo @rafael @mattlord
+/go/vt/srvtopo @deepthi @rafael @mattlord
 /go/vt/sysvars @harshit-gangal @systay
 /go/vt/topo @deepthi @rafael @mattlord @rsajwani
 /go/vt/topotools @deepthi @rafael @mattlord @rsajwani
 /go/vt/vitessdriver @harshit-gangal
-/go/vt/vtadmin @ajm188 @doeg @notfelineit @rohit-nayak-ps
-/go/vt/vtctl @deepthi
-/go/vt/vtctl/vtctl.go @ajm188 @notfelineit
+/go/vt/vtadmin @ajm188 @notfelineit @rohit-nayak-ps
+/go/vt/vtctl @ajm188 @deepthi @rohit-nayak-ps
+/go/vt/vtctl/vtctl.go @notfelineit @rohit-nayak-ps
 /go/vt/vtctl/grpcvtctldclient @ajm188 @notfelineit
 /go/vt/vtctl/grpcvtctldserver @ajm188 @notfelineit
 /go/vt/vtctl/reparentutil @ajm188 @GuptaManan100 @deepthi
@@ -49,18 +50,25 @@ bootstrap.sh @deepthi
 /go/vt/vtexplain @systay @harshit-gangal
 /go/vt/vtgate @harshit-gangal @systay @frouioui @GuptaManan100
 /go/vt/vtorc @deepthi @shlomi-noach @GuptaManan100 @rsajwani
+/go/vt/vttablet/*conn* @harshit-gangal @systay
+/go/vt/vttablet/endtoend @harshit-gangal @mattlord @rohit-nayak-ps @systay
+/go/vt/vttablet/grpc* @ajm188 @rohit-nayak-ps @rsajwani @shlomi-noach @harshit-gangal
+/go/vt/vttablet/onlineddl @mattlord @rohit-nayak-ps @shlomi-noach
 /go/vt/vttablet/queryservice @harshit-gangal @systay
-/go/vt/vttablet/tabletmanager @deepthi @shlomi-noach @rsajwani @rohit-nayak-ps
+/go/vt/vttablet/tabletmanager @deepthi @GuptaManan100 @rohit-nayak-ps @rsajwani @shlomi-noach
 /go/vt/vttablet/tabletmanager/vreplication @rohit-nayak-ps @mattlord
 /go/vt/vttablet/tabletmanager/vstreamer @rohit-nayak-ps @mattlord
-/go/vt/vttablet/tabletserver @harshit-gangal @systay @shlomi-noach @rohit-nayak-ps
+/go/vt/vttablet/tabletserver* @harshit-gangal @systay @shlomi-noach @rohit-nayak-ps
 /go/vt/vttablet/tabletserver/messager @mattlord @rohit-nayak-ps @derekperkins
-/go/vt/wrangler @deepthi @rohit-nayak-ps @mattlord
-/go/vt/workflow @rohit-nayak-ps @mattlord
-/proto/vtadmin.proto @ajm188 @doeg @notfelineit
+/go/vt/vttablet/*tmclient* @ajm188 @GuptaManan100 @rohit-nayak-ps @rsajwani @shlomi-noach
+/go/vt/vttablet/vexec @mattlord @rohit-nayak-ps @shlomi-noach
+/go/vt/wrangler @deepthi @mattlord @rohit-nayak-ps
+/go/vt/workflow @mattlord @rohit-nayak-ps
+/proto/ @deepthi @harshit-gangal
+/proto/vtadmin.proto @ajm188 @notfelineit
 /proto/vtctldata.proto @ajm188 @notfelineit
 /proto/vtctlservice.proto @ajm188 @notfelineit
 /test/ @GuptaManan100 @frouioui @rohit-nayak-ps
 /tools/ @frouioui @rohit-nayak-ps
-/web/vtadmin @ajm188 @doeg @notfelineit
+/web/vtadmin @ajm188 @notfelineit
 /web/vtctld2 @notfelineit @rohit-nayak-ps
diff --git a/.github/workflows/cluster_endtoend_26.yml b/.github/workflows/cluster_endtoend_26.yml
deleted file mode 100644
index 99253bde7f..0000000000
--- a/.github/workflows/cluster_endtoend_26.yml
+++ /dev/null
@@ -1,134 +0,0 @@
-# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
-
-name: Cluster (26)
-on: [push, pull_request]
-concurrency:
-  group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (26)')
-  cancel-in-progress: true
-
-env:
-  LAUNCHABLE_ORGANIZATION: "vitess"
-  LAUNCHABLE_WORKSPACE: "vitess-app"
-  GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}"
-
-jobs:
-  build:
-    name: Run endtoend tests on Cluster (26)
-    runs-on: ubuntu-20.04
-
-    steps:
-    - name: Skip CI
-      run: |
-        if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then
-          echo "skipping CI due to the 'Skip CI' label"
-          exit 1
-        fi
-
-    - name: Check if workflow needs to be skipped
-      id: skip-workflow
-      run: |
-        skip='false'
-        if [[ "${{github.event.pull_request}}" ==  "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then
-          skip='true'
-        fi
-        echo Skip ${skip}
-        echo "::set-output name=skip-workflow::${skip}"
-
-    - name: Check out code
-      if: steps.skip-workflow.outputs.skip-workflow == 'false'
-      uses: actions/checkout@v3
-
-    - name: Check for changes in relevant files
-      if: steps.skip-workflow.outputs.skip-workflow == 'false'
-      uses: frouioui/paths-filter@main
-      id: changes
-      with:
-        token: ''
-        filters: |
-          end_to_end:
-            - 'go/**/*.go'
-            - 'test.go'
-            - 'Makefile'
-            - 'build.env'
-            - 'go.[sumod]'
-            - 'proto/*.proto'
-            - 'tools/**'
-            - 'config/**'
-            - 'bootstrap.sh'
-            - '.github/workflows/cluster_endtoend_26.yml'
-
-    - name: Set up Go
-      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-      uses: actions/setup-go@v3
-      with:
-        go-version: 1.18.7
-
-    - name: Set up python
-      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-      uses: actions/setup-python@v4
-
-    - name: Tune the OS
-      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-      run: |
-        echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range
-        # Increase the asynchronous non-blocking I/O. More information at https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_use_native_aio
-        echo "fs.aio-max-nr = 1048576" | sudo tee -a /etc/sysctl.conf
-        sudo sysctl -p /etc/sysctl.conf
-
-    - name: Get dependencies
-      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-      run: |
-        
-        # Get key to latest MySQL repo
-        sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29
-        # Setup MySQL 8.0
-        wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.20-1_all.deb
-        echo mysql-apt-config mysql-apt-config/select-server select mysql-8.0 | sudo debconf-set-selections
-        sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config*
-        sudo apt-get update
-        # Install everything else we need, and configure
-        sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata xz-utils
-
-        sudo service mysql stop
-        sudo service etcd stop
-        sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
-        sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
-        go mod download
-
-        # install JUnit report formatter
-        go install github.com/vitessio/go-junit-report@HEAD
-
-    - name: Setup launchable dependencies
-      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-      run: |
-        # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up
-        pip3 install --user launchable~=1.0 > /dev/null
-
-        # verify that launchable setup is all correct.
-        launchable verify || true
-
-        # Tell Launchable about the build you are producing and testing
-        launchable record build --name "$GITHUB_RUN_ID" --source .
-
-    - name: Run cluster endtoend test
-      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-      timeout-minutes: 45
-      run: |
-        # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file
-        # which musn't be more than 107 characters long.
-        export VTDATAROOT="/tmp/"
-        source build.env
-
-        set -x
-
-        # run the tests however you normally do, then produce a JUnit XML file
-        eatmydata -- go run test.go -docker=false -follow -shard 26 | tee -a output.txt | go-junit-report -set-exit-code > report.xml
-
-    - name: Print test output and Record test result in launchable
-      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always()
-      run: |
-        # send recorded tests to launchable
-        launchable record tests --build "$GITHUB_RUN_ID" go-test . || true
-
-        # print test output
-        cat output.txt
diff --git a/.github/workflows/cluster_endtoend_vtbackup_transform.yml b/.github/workflows/cluster_endtoend_vtbackup.yml
similarity index 95%
rename from .github/workflows/cluster_endtoend_vtbackup_transform.yml
rename to .github/workflows/cluster_endtoend_vtbackup.yml
index 2a79f2817c..1ba7adf8bb 100644
--- a/.github/workflows/cluster_endtoend_vtbackup_transform.yml
+++ b/.github/workflows/cluster_endtoend_vtbackup.yml
@@ -1,9 +1,9 @@
 # DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
 
-name: Cluster (vtbackup_transform)
+name: Cluster (vtbackup)
 on: [push, pull_request]
 concurrency:
-  group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtbackup_transform)')
+  group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtbackup)')
   cancel-in-progress: true
 
 env:
@@ -13,7 +13,7 @@ env:
 
 jobs:
   build:
-    name: Run endtoend tests on Cluster (vtbackup_transform)
+    name: Run endtoend tests on Cluster (vtbackup)
     runs-on: ubuntu-20.04
 
     steps:
@@ -55,7 +55,7 @@ jobs:
             - 'tools/**'
             - 'config/**'
             - 'bootstrap.sh'
-            - '.github/workflows/cluster_endtoend_vtbackup_transform.yml'
+            - '.github/workflows/cluster_endtoend_vtbackup.yml'
 
     - name: Set up Go
       if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
@@ -122,7 +122,7 @@ jobs:
         set -x
 
         # run the tests however you normally do, then produce a JUnit XML file
-        eatmydata -- go run test.go -docker=false -follow -shard vtbackup_transform | tee -a output.txt | go-junit-report -set-exit-code > report.xml
+        eatmydata -- go run test.go -docker=false -follow -shard vtbackup | tee -a output.txt | go-junit-report -set-exit-code > report.xml
 
     - name: Print test output and Record test result in launchable
       if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always()
diff --git a/doc/releasenotes/14_0_0_release_notes.md b/doc/releasenotes/14_0_0_release_notes.md
index 50d02232ae..a7b4bcf4ef 100644
--- a/doc/releasenotes/14_0_0_release_notes.md
+++ b/doc/releasenotes/14_0_0_release_notes.md
@@ -18,6 +18,7 @@
 ## Known Issues
 
 - [VTOrc doesn't discover the tablets](https://github.com/vitessio/vitess/issues/10650) of a keyspace if the durability policy doesn't exist in the topo server when it comes up. This can be resolved by restarting VTOrc.
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
 
 ## Major Changes
 
diff --git a/doc/releasenotes/14_0_0_summary.md b/doc/releasenotes/14_0_0_summary.md
index e02c9d9a28..6047ec7ec1 100644
--- a/doc/releasenotes/14_0_0_summary.md
+++ b/doc/releasenotes/14_0_0_summary.md
@@ -17,6 +17,7 @@
 ## Known Issues
 
 - [VTOrc doesn't discover the tablets](https://github.com/vitessio/vitess/issues/10650) of a keyspace if the durability policy doesn't exist in the topo server when it comes up. This can be resolved by restarting VTOrc.
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
 
 ## Major Changes
 
diff --git a/doc/releasenotes/14_0_1_release_notes.md b/doc/releasenotes/14_0_1_release_notes.md
index 7215301939..57d68be31c 100644
--- a/doc/releasenotes/14_0_1_release_notes.md
+++ b/doc/releasenotes/14_0_1_release_notes.md
@@ -1,4 +1,8 @@
 # Release of Vitess v14.0.1
+## Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### Upgrade to `go1.18.4`
diff --git a/doc/releasenotes/14_0_1_summary.md b/doc/releasenotes/14_0_1_summary.md
index 1f2f985bab..5a176b6af1 100644
--- a/doc/releasenotes/14_0_1_summary.md
+++ b/doc/releasenotes/14_0_1_summary.md
@@ -1,3 +1,7 @@
+## Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### Upgrade to `go1.18.4`
diff --git a/doc/releasenotes/14_0_2_release_notes.md b/doc/releasenotes/14_0_2_release_notes.md
index 956ca21ef6..d83b940f45 100644
--- a/doc/releasenotes/14_0_2_release_notes.md
+++ b/doc/releasenotes/14_0_2_release_notes.md
@@ -1,4 +1,8 @@
 # Release of Vitess v14.0.2
+## Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### Upgrade to `go1.18.5`
diff --git a/doc/releasenotes/14_0_2_summary.md b/doc/releasenotes/14_0_2_summary.md
index 05a1aac5d6..8b26887dd0 100644
--- a/doc/releasenotes/14_0_2_summary.md
+++ b/doc/releasenotes/14_0_2_summary.md
@@ -1,3 +1,7 @@
+## Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### Upgrade to `go1.18.5`
diff --git a/doc/releasenotes/14_0_3_release_notes.md b/doc/releasenotes/14_0_3_release_notes.md
index d9cd4ac7a6..721c47640e 100644
--- a/doc/releasenotes/14_0_3_release_notes.md
+++ b/doc/releasenotes/14_0_3_release_notes.md
@@ -1,4 +1,8 @@
 # Release of Vitess v14.0.3
+## Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### Fix VTOrc Discovery
diff --git a/doc/releasenotes/14_0_3_summary.md b/doc/releasenotes/14_0_3_summary.md
index 9d9364f67b..121d9054a1 100644
--- a/doc/releasenotes/14_0_3_summary.md
+++ b/doc/releasenotes/14_0_3_summary.md
@@ -1,3 +1,7 @@
+## Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### Fix VTOrc Discovery
diff --git a/doc/releasenotes/15_0_0_release_notes.md b/doc/releasenotes/15_0_0_release_notes.md
index a67dbb9881..430100fa8f 100644
--- a/doc/releasenotes/15_0_0_release_notes.md
+++ b/doc/releasenotes/15_0_0_release_notes.md
@@ -1,6 +1,7 @@
 # Release of Vitess v15.0.0
 ## Summary
 
+- **[Known Issues](#known-issues)**
 - **[Breaking Changes](#breaking-changes)**
   - [Flags](#flags)
   - [VTTablet Flag Deletions](#vttablet-flag-deletions)
@@ -44,6 +45,10 @@
 - **[Flags Restructure](#flags-restructure)**
   - [Flags Diff](#flags-diff)
 
+## <a id="known-issues"/>Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### <a id="breaking-changes"/>Breaking Changes
diff --git a/doc/releasenotes/15_0_0_summary.md b/doc/releasenotes/15_0_0_summary.md
index 069f2c217b..56b784b55d 100644
--- a/doc/releasenotes/15_0_0_summary.md
+++ b/doc/releasenotes/15_0_0_summary.md
@@ -1,5 +1,6 @@
 ## Summary
 
+- **[Known Issues](#known-issues)**
 - **[Breaking Changes](#breaking-changes)**
   - [Flags](#flags)
   - [VTTablet Flag Deletions](#vttablet-flag-deletions)
@@ -43,6 +44,10 @@
 - **[Flags Restructure](#flags-restructure)**
   - [Flags Diff](#flags-diff)
 
+## <a id="known-issues"/>Known Issues
+
+- [Corrupted results for non-full-group-by queries with JOINs](https://github.com/vitessio/vitess/issues/11625). This can be resolved by using full-group-by queries.
+
 ## Major Changes
 
 ### <a id="breaking-changes"/>Breaking Changes
diff --git a/doc/releasenotes/16_0_0_summary.md b/doc/releasenotes/16_0_0_summary.md
index 8347d75b8c..41050fea6f 100644
--- a/doc/releasenotes/16_0_0_summary.md
+++ b/doc/releasenotes/16_0_0_summary.md
@@ -34,6 +34,13 @@ Other aspects of the VReplication copy-phase logic are preserved:
 
  Other phases, catchup, fast-forward, and replicating/"running", are unchanged.
 
+### Important bug fixes
+
+#### Corrupted results for non-full-group-by queries with JOINs
+
+An issue in versions `<= v14.0.3` and `<= v15.0.0` that generated corrupted results for non-full-group-by queries with a JOIN
+is now fixed. The full issue can be found [here](https://github.com/vitessio/vitess/issues/11625), and its fix [here](https://github.com/vitessio/vitess/pull/11633).
+
 ### Deprecations
 
 The V3 planner is deprecated as of the V16 release, and will be removed in the V17 release of Vitess.
diff --git a/go/ioutil2/ioutil.go b/go/ioutil2/ioutil.go
deleted file mode 100644
index 0b2ae7a645..0000000000
--- a/go/ioutil2/ioutil.go
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-Copyright 2019 The Vitess Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package ioutil2 provides extra functionality along similar lines to io/ioutil.
-package ioutil2
-
-import (
-	"os"
-	"path"
-)
-
-// WriteFileAtomic writes the data to a temp file and atomically move if everything else succeeds.
-func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error {
-	dir, name := path.Split(filename)
-	f, err := os.CreateTemp(dir, name)
-	if err != nil {
-		return err
-	}
-	_, err = f.Write(data)
-	if err == nil {
-		err = f.Sync()
-	}
-	if closeErr := f.Close(); err == nil {
-		err = closeErr
-	}
-	if permErr := os.Chmod(f.Name(), perm); err == nil {
-		err = permErr
-	}
-	if err == nil {
-		err = os.Rename(f.Name(), filename)
-	}
-	// Any err should result in full cleanup.
-	if err != nil {
-		os.Remove(f.Name())
-	}
-	return err
-}
diff --git a/go/sqltypes/value.go b/go/sqltypes/value.go
index 20b8843b4b..cdb1ce9ccb 100644
--- a/go/sqltypes/value.go
+++ b/go/sqltypes/value.go
@@ -73,12 +73,12 @@ type (
 func NewValue(typ querypb.Type, val []byte) (v Value, err error) {
 	switch {
 	case IsSigned(typ):
-		if _, err := strconv.ParseInt(string(val), 0, 64); err != nil {
+		if _, err := strconv.ParseInt(string(val), 10, 64); err != nil {
 			return NULL, err
 		}
 		return MakeTrusted(typ, val), nil
 	case IsUnsigned(typ):
-		if _, err := strconv.ParseUint(string(val), 0, 64); err != nil {
+		if _, err := strconv.ParseUint(string(val), 10, 64); err != nil {
 			return NULL, err
 		}
 		return MakeTrusted(typ, val), nil
diff --git a/go/vt/vtgate/planbuilder/aggregation_pushing.go b/go/vt/vtgate/planbuilder/aggregation_pushing.go
index e677be660b..f6d72d2943 100644
--- a/go/vt/vtgate/planbuilder/aggregation_pushing.go
+++ b/go/vt/vtgate/planbuilder/aggregation_pushing.go
@@ -429,6 +429,10 @@ func isMinOrMax(in engine.AggregateOpcode) bool {
 	}
 }
 
+func isRandom(in engine.AggregateOpcode) bool {
+	return in == engine.AggregateRandom
+}
+
 func splitAggregationsToLeftAndRight(
 	ctx *plancontext.PlanningContext,
 	aggregations []operators.Aggr,
@@ -443,8 +447,8 @@ func splitAggregationsToLeftAndRight(
 		} else {
 			deps := ctx.SemTable.RecursiveDeps(aggr.Original.Expr)
 			var other *operators.Aggr
-			// if we are sending down min/max, we don't have to multiply the results with anything
-			if !isMinOrMax(aggr.OpCode) {
+			// if we are sending down min/max/random, we don't have to multiply the results with anything
+			if !isMinOrMax(aggr.OpCode) && !isRandom(aggr.OpCode) {
 				other = countStarAggr()
 			}
 			switch {
diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go
index e1390fca75..2644c26140 100644
--- a/go/vt/vtgate/vindexes/lookup_internal.go
+++ b/go/vt/vtgate/vindexes/lookup_internal.go
@@ -39,7 +39,7 @@ var (
 	readLockNone      = "none"
 	readLockDefault   = readLockExclusive
 
-	readLockExprs map[string]string = map[string]string{
+	readLockExprs = map[string]string{
 		readLockExclusive: "for update",
 		readLockShared:    "lock in share mode",
 		readLockNone:      "",
diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go
index 49df47d985..a2ebdb540d 100644
--- a/go/vt/vttablet/onlineddl/executor.go
+++ b/go/vt/vttablet/onlineddl/executor.go
@@ -943,6 +943,53 @@ func (e *Executor) initMigrationSQLMode(ctx context.Context, onlineDDL *schema.O
 	return deferFunc, nil
 }
 
+// newConstraintName generates a new, unique name for a constraint. Our problem is that a MySQL
+// constraint's name is unique in the schema (!). And so as we duplicate the original table, we must
+// create completely new names for all constraints.
+// Moreover, we really want this name to be consistent across all shards. We therefore use a deterministic
+// UUIDv5 (SHA) function over the migration UUID, table name, and constraint's _contents_.
+// We _also_ include the original constraint name as prefix, as room allows
+// for example, if the original constraint name is "check_1",
+// we might generate "check_1_cps1okb4uafunfqusi2lp22u3".
+// If we then again migrate a table whose constraint name is "check_1_cps1okb4uafunfqusi2lp22u3	" we
+// get for example "check_1_19l09s37kbhj4axnzmi10e18k" (hash changes, and we still try to preserve original name)
+//
+// Furthermore, per bug report https://bugs.mysql.com/bug.php?id=107772, if the user doesn't provide a name for
+// their CHECK constraint, then MySQL picks a name in this format <tablename>_chk_<number>.
+// Example: sometable_chk_1
+// Next, when MySQL is asked to RENAME TABLE and sees a constraint with this format, it attempts to rename
+// the constraint with the new table's name. This is problematic for Vitess, because we often rename tables to
+// very long names, such as _vt_HOLD_394f9e6dfc3d11eca0390a43f95f28a3_20220706091048.
+// As we rename the constraint to e.g. `sometable_chk_1_cps1okb4uafunfqusi2lp22u3`, this makes MySQL want to
+// call the new constraint something like _vt_HOLD_394f9e6dfc3d11eca0390a43f95f28a3_20220706091048_chk_1_cps1okb4uafunfqusi2lp22u3,
+// which exceeds the 64 character limit for table names. Long story short, we also trim down <tablename> if the constraint seems
+// to be auto-generated.
+func (e *Executor) newConstraintName(onlineDDL *schema.OnlineDDL, hashExists map[string]bool, seed string, oldName string) string {
+	oldName = schemadiff.ExtractConstraintOriginalName(oldName)
+	autoGeneratedName := fmt.Sprintf("%s_chk_", onlineDDL.Table)
+	if strings.HasPrefix(oldName, autoGeneratedName) {
+		// strip out table name
+		oldName = "chk_" + oldName[len(autoGeneratedName):]
+	}
+
+	hash := textutil.UUIDv5Base36(onlineDDL.UUID, onlineDDL.Table, seed)
+	for i := 1; hashExists[hash]; i++ {
+		hash = textutil.UUIDv5Base36(onlineDDL.UUID, onlineDDL.Table, seed, fmt.Sprintf("%d", i))
+	}
+	hashExists[hash] = true
+	suffix := "_" + hash
+	maxAllowedNameLength := maxConstraintNameLength - len(suffix)
+	newName := oldName
+	if newName == "" {
+		newName = "chk" // start with something that looks consistent with MySQL's naming
+	}
+	if len(newName) > maxAllowedNameLength {
+		newName = newName[0:maxAllowedNameLength]
+	}
+	newName = newName + suffix
+	return newName
+}
+
 // validateAndEditCreateTableStatement inspects the CreateTable AST and does the following:
 // - extra validation (no FKs for now...)
 // - generate new and unique names for all constraints (CHECK and FK; yes, why not handle FK names; even as we don't support FKs today, we may in the future)
@@ -950,56 +997,13 @@ func (e *Executor) validateAndEditCreateTableStatement(ctx context.Context, onli
 	constraintMap = map[string]string{}
 	hashExists := map[string]bool{}
 
-	// newConstraintName generates a new, unique name for a constraint. Our problem is that a MySQL
-	// constraint's name is unique in the schema (!). And so as we duplicate the original table, we must
-	// create completely new names for all constraints.
-	// Moreover, we really want this name to be consistent across all shards. We therefore use a deterministic
-	// UUIDv5 (SHA) function over the migration UUID, table name, and constraint's _contents_.
-	// We _also_ include the original constraint name as prefix, as room allows
-	// for example, if the original constraint name is "check_1",
-	// we might generate "check_1_cps1okb4uafunfqusi2lp22u3".
-	// If we then again migrate a table whose constraint name is "check_1_cps1okb4uafunfqusi2lp22u3	" we
-	// get for example "check_1_19l09s37kbhj4axnzmi10e18k" (hash changes, and we still try to preserve original name)
-	//
-	// Furthermore, per bug report https://bugs.mysql.com/bug.php?id=107772, if the user doesn' tprovide a name for
-	// their CHECK constraint, then MySQL picks a name in this format <tablename>_chk_<number>.
-	// Example: sometable_chk_1
-	// Next, when MySQL is asked to RENAME TABLE and sees a constraint with this format, it attempts to rename
-	// the constraint with the new table's name. This is problematic for Vitess, because we often rename tables to
-	// very long names, such as _vt_HOLD_394f9e6dfc3d11eca0390a43f95f28a3_20220706091048.
-	// As we rename the constraint to e.g. `sometable_chk_1_cps1okb4uafunfqusi2lp22u3`, this makes MySQL want to
-	// call the new constraint something like _vt_HOLD_394f9e6dfc3d11eca0390a43f95f28a3_20220706091048_chk_1_cps1okb4uafunfqusi2lp22u3,
-	// which exceeds the 64 character limit for table names. Long story short, we also trim down <tablename> if the constraint seems
-	// to be auto-generated.
-	newConstraintName := func(seed string, oldName string) string {
-		oldName = schemadiff.ExtractConstraintOriginalName(oldName)
-		autoGeneratedName := fmt.Sprintf("%s_chk_", onlineDDL.Table)
-		if strings.HasPrefix(oldName, autoGeneratedName) {
-			// strip out table name
-			oldName = "chk_" + oldName[len(autoGeneratedName):]
-		}
-
-		hash := textutil.UUIDv5Base36(onlineDDL.UUID, onlineDDL.Table, seed)
-		for i := 1; hashExists[hash]; i++ {
-			hash = textutil.UUIDv5Base36(onlineDDL.UUID, onlineDDL.Table, seed, fmt.Sprintf("%d", i))
-		}
-		hashExists[hash] = true
-		suffix := "_" + hash
-		maxAllowedNameLength := maxConstraintNameLength - len(suffix)
-		newName := oldName
-		if len(newName) > maxAllowedNameLength {
-			newName = newName[0:maxAllowedNameLength]
-		}
-		newName = newName + suffix
-		return newName
-	}
 	validateWalk := func(node sqlparser.SQLNode) (kontinue bool, err error) {
 		switch node := node.(type) {
 		case *sqlparser.ForeignKeyDefinition:
 			return false, schema.ErrForeignKeyFound
 		case *sqlparser.ConstraintDefinition:
 			oldName := node.Name.String()
-			newName := newConstraintName(sqlparser.CanonicalString(node.Details), oldName)
+			newName := e.newConstraintName(onlineDDL, hashExists, sqlparser.CanonicalString(node.Details), oldName)
 			node.Name = sqlparser.NewIdentifierCI(newName)
 			constraintMap[oldName] = newName
 		}
@@ -1014,7 +1018,8 @@ func (e *Executor) validateAndEditCreateTableStatement(ctx context.Context, onli
 // validateAndEditAlterTableStatement inspects the AlterTable statement and:
 // - modifies any CONSTRAINT name according to given name mapping
 // - explode ADD FULLTEXT KEY into multiple statements
-func (e *Executor) validateAndEditAlterTableStatement(ctx context.Context, alterTable *sqlparser.AlterTable, constraintMap map[string]string) (alters []*sqlparser.AlterTable, err error) {
+func (e *Executor) validateAndEditAlterTableStatement(ctx context.Context, onlineDDL *schema.OnlineDDL, alterTable *sqlparser.AlterTable, constraintMap map[string]string) (alters []*sqlparser.AlterTable, err error) {
+	hashExists := map[string]bool{}
 	validateWalk := func(node sqlparser.SQLNode) (kontinue bool, err error) {
 		switch node := node.(type) {
 		case *sqlparser.DropKey:
@@ -1026,6 +1031,11 @@ func (e *Executor) validateAndEditAlterTableStatement(ctx context.Context, alter
 				}
 				node.Name = sqlparser.NewIdentifierCI(mappedName)
 			}
+		case *sqlparser.AddConstraintDefinition:
+			oldName := node.ConstraintDefinition.Name.String()
+			newName := e.newConstraintName(onlineDDL, hashExists, sqlparser.CanonicalString(node.ConstraintDefinition.Details), oldName)
+			node.ConstraintDefinition.Name = sqlparser.NewIdentifierCI(newName)
+			constraintMap[oldName] = newName
 		}
 		return true, nil
 	}
@@ -1125,7 +1135,7 @@ func (e *Executor) initVreplicationOriginalMigration(ctx context.Context, online
 		// ALTER TABLE should apply to the vrepl table
 		alterTable.SetTable(alterTable.GetTable().Qualifier.CompliantName(), vreplTableName)
 		// Also, change any constraint names:
-		alters, err := e.validateAndEditAlterTableStatement(ctx, alterTable, constraintMap)
+		alters, err := e.validateAndEditAlterTableStatement(ctx, onlineDDL, alterTable, constraintMap)
 		if err != nil {
 			return v, err
 		}
diff --git a/web/vtadmin/package-lock.json b/web/vtadmin/package-lock.json
index a91a0ae0e1..433d25c170 100644
--- a/web/vtadmin/package-lock.json
+++ b/web/vtadmin/package-lock.json
@@ -5817,9 +5817,9 @@
       }
     },
     "node_modules/babel-loader/node_modules/loader-utils": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
-      "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.1.tgz",
+      "integrity": "sha512-1Qo97Y2oKaU+Ro2xnDMR26g1BwMT29jNbem1EvcujW2jqt+j5COXyscjM7bLQkM9HaxI7pkWeW7gnI072yMI9Q==",
       "dependencies": {
         "big.js": "^5.2.2",
         "emojis-list": "^3.0.0",
@@ -14747,9 +14747,9 @@
       }
     },
     "node_modules/loader-utils": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
-      "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz",
+      "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==",
       "dependencies": {
         "big.js": "^5.2.2",
         "emojis-list": "^3.0.0",
@@ -25605,9 +25605,9 @@
           }
         },
         "loader-utils": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
-          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.1.tgz",
+          "integrity": "sha512-1Qo97Y2oKaU+Ro2xnDMR26g1BwMT29jNbem1EvcujW2jqt+j5COXyscjM7bLQkM9HaxI7pkWeW7gnI072yMI9Q==",
           "requires": {
             "big.js": "^5.2.2",
             "emojis-list": "^3.0.0",
@@ -32099,9 +32099,9 @@
       "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw=="
     },
     "loader-utils": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
-      "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz",
+      "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==",
       "requires": {
         "big.js": "^5.2.2",
         "emojis-list": "^3.0.0",


Test patch:
diff --git a/go/ioutil2/ioutil_test.go b/go/ioutil2/ioutil_test.go
deleted file mode 100644
index 916b1fe207..0000000000
--- a/go/ioutil2/ioutil_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Copyright 2019 The Vitess Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreedto in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package ioutil2
-
-import (
-	"bytes"
-	"fmt"
-	"os"
-	"testing"
-	"time"
-)
-
-func TestWrite(t *testing.T) {
-	data := []byte("test string\n")
-	fname := fmt.Sprintf("/tmp/atomic-file-test-%v.txt", time.Now().UnixNano())
-	err := WriteFileAtomic(fname, data, 0664)
-	if err != nil {
-		t.Fatal(err)
-	}
-	rData, err := os.ReadFile(fname)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(data, rData) {
-		t.Fatalf("data mismatch: %v != %v", data, rData)
-	}
-	if err := os.Remove(fname); err != nil {
-		t.Fatal(err)
-	}
-}
diff --git a/go/sqltypes/value_test.go b/go/sqltypes/value_test.go
index a6d91c814d..1e6c597bd9 100644
--- a/go/sqltypes/value_test.go
+++ b/go/sqltypes/value_test.go
@@ -86,6 +86,14 @@ func TestNewValue(t *testing.T) {
 		inType: Uint64,
 		inVal:  "1",
 		outVal: TestValue(Uint64, "1"),
+	}, {
+		inType: Uint64,
+		inVal:  "01",
+		outVal: TestValue(Uint64, "01"),
+	}, {
+		inType: Int64,
+		inVal:  "01",
+		outVal: TestValue(Int64, "01"),
 	}, {
 		inType: Float32,
 		inVal:  "1.00",
diff --git a/go/test/endtoend/backup/transform/backup_transform_test.go b/go/test/endtoend/backup/transform/backup_transform_test.go
deleted file mode 100644
index 071f7d536e..0000000000
--- a/go/test/endtoend/backup/transform/backup_transform_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-Copyright 2019 The Vitess Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package transform
-
-import "testing"
-
-func TestMain(m *testing.M) {
-	TestMainSetup(m, false)
-}
-
-func TestBackupTransform(t *testing.T) {
-	TestBackupTransformImpl(t)
-}
-func TestBackupTransformError(t *testing.T) {
-	TestBackupTransformErrorImpl(t)
-}
diff --git a/go/test/endtoend/backup/transform/backup_transform_utils.go b/go/test/endtoend/backup/transform/backup_transform_utils.go
deleted file mode 100644
index 8418f7e999..0000000000
--- a/go/test/endtoend/backup/transform/backup_transform_utils.go
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
-Copyright 2019 The Vitess Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package transform
-
-import (
-	"encoding/json"
-	"flag"
-	"fmt"
-	"os"
-	"os/exec"
-	"path"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"vitess.io/vitess/go/test/endtoend/cluster"
-	"vitess.io/vitess/go/vt/log"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
-)
-
-// test main part of the testcase
-var (
-	primary          *cluster.Vttablet
-	replica1         *cluster.Vttablet
-	replica2         *cluster.Vttablet
-	testTablets      []*cluster.Vttablet
-	localCluster     *cluster.LocalProcessCluster
-	newInitDBFile    string
-	cell             = cluster.DefaultCell
-	hostname         = "localhost"
-	keyspaceName     = "ks"
-	dbPassword       = "VtDbaPass"
-	shardKsName      = fmt.Sprintf("%s/%s", keyspaceName, shardName)
-	dbCredentialFile string
-	shardName        = "0"
-	commonTabletArg  = []string{
-		"--vreplication_healthcheck_topology_refresh", "1s",
-		"--vreplication_healthcheck_retry_delay", "1s",
-		"--vreplication_retry_delay", "1s",
-		"--degraded_threshold", "5s",
-		"--lock_tables_timeout", "5s",
-		"--watch_replication_stream",
-		"--enable_replication_reporter",
-		"--serving_state_grace_period", "1s"}
-)
-
-// TestMainSetup sets up the basic test cluster
-func TestMainSetup(m *testing.M, useMysqlctld bool) {
-	defer cluster.PanicHandler(nil)
-	flag.Parse()
-
-	exitCode, err := func() (int, error) {
-		localCluster = cluster.NewCluster(cell, hostname)
-		defer localCluster.Teardown()
-
-		// Start topo server
-		err := localCluster.StartTopo()
-		if err != nil {
-			return 1, err
-		}
-
-		// Start keyspace
-		localCluster.Keyspaces = []cluster.Keyspace{
-			{
-				Name: keyspaceName,
-				Shards: []cluster.Shard{
-					{
-						Name: shardName,
-					},
-				},
-			},
-		}
-		shard := &localCluster.Keyspaces[0].Shards[0]
-		// changing password for mysql user
-		dbCredentialFile = cluster.WriteDbCredentialToTmp(localCluster.TmpDirectory)
-		initDb, _ := os.ReadFile(path.Join(os.Getenv("VTROOT"), "/config/init_db.sql"))
-		sql := string(initDb)
-		newInitDBFile = path.Join(localCluster.TmpDirectory, "init_db_with_passwords.sql")
-		sql = sql + cluster.GetPasswordUpdateSQL(localCluster)
-		os.WriteFile(newInitDBFile, []byte(sql), 0666)
-
-		extraArgs := []string{"--db-credentials-file", dbCredentialFile}
-		commonTabletArg = append(commonTabletArg, "--db-credentials-file", dbCredentialFile)
-
-		// start mysql process for all replicas and primary
-		var mysqlProcs []*exec.Cmd
-		for i := 0; i < 3; i++ {
-			tabletType := "replica"
-			tablet := localCluster.NewVttabletInstance(tabletType, 0, cell)
-			tablet.VttabletProcess = localCluster.VtprocessInstanceFromVttablet(tablet, shard.Name, keyspaceName)
-			tablet.VttabletProcess.DbPassword = dbPassword
-			tablet.VttabletProcess.ExtraArgs = commonTabletArg
-			tablet.VttabletProcess.SupportsBackup = true
-			tablet.VttabletProcess.EnableSemiSync = true
-
-			if useMysqlctld {
-				tablet.MysqlctldProcess = *cluster.MysqlCtldProcessInstance(tablet.TabletUID, tablet.MySQLPort, localCluster.TmpDirectory)
-				tablet.MysqlctldProcess.InitDBFile = newInitDBFile
-				tablet.MysqlctldProcess.ExtraArgs = extraArgs
-				tablet.MysqlctldProcess.Password = tablet.VttabletProcess.DbPassword
-				err := tablet.MysqlctldProcess.Start()
-				if err != nil {
-					return 1, err
-				}
-
-				shard.Vttablets = append(shard.Vttablets, tablet)
-				continue
-			}
-
-			tablet.MysqlctlProcess = *cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, localCluster.TmpDirectory)
-			tablet.MysqlctlProcess.InitDBFile = newInitDBFile
-			tablet.MysqlctlProcess.ExtraArgs = extraArgs
-			proc, err := tablet.MysqlctlProcess.StartProcess()
-			if err != nil {
-				return 1, err
-			}
-			mysqlProcs = append(mysqlProcs, proc)
-
-			shard.Vttablets = append(shard.Vttablets, tablet)
-		}
-		for _, proc := range mysqlProcs {
-			if err := proc.Wait(); err != nil {
-				return 1, err
-			}
-		}
-
-		// initialize tablets
-		primary = shard.Vttablets[0]
-		replica1 = shard.Vttablets[1]
-		replica2 = shard.Vttablets[2]
-		testTablets = []*cluster.Vttablet{primary, replica1, replica2}
-
-		for _, tablet := range testTablets {
-			if err := localCluster.VtctlclientProcess.InitTablet(tablet, cell, keyspaceName, hostname, shard.Name); err != nil {
-				return 1, err
-			}
-		}
-		vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", localCluster.VtctldProcess.GrpcPort, localCluster.TmpDirectory)
-		_, err = vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync")
-		if err != nil {
-			return 1, err
-		}
-
-		// create database for primary and replicas
-		for _, tablet := range testTablets {
-			if err := tablet.VttabletProcess.CreateDB(keyspaceName); err != nil {
-				return 1, err
-			}
-			if err := tablet.VttabletProcess.Setup(); err != nil {
-				return 1, err
-			}
-		}
-
-		// initialize primary and start replication
-		if err := localCluster.VtctlclientProcess.InitShardPrimary(keyspaceName, shard.Name, cell, primary.TabletUID); err != nil {
-			return 1, err
-		}
-		primary.Type = topodatapb.TabletType_PRIMARY.String()
-		return m.Run(), nil
-	}()
-
-	if err != nil {
-		log.Error(err.Error())
-		os.Exit(1)
-	} else {
-		os.Exit(exitCode)
-	}
-}
-
-// create query for test table creation
-var vtInsertTest = `create table vt_insert_test (
-	id bigint auto_increment,
-	msg varchar(64),
-	primary key (id)
-	) Engine=InnoDB`
-
-// TestBackupTransformImpl tests backups with transform hooks
-func TestBackupTransformImpl(t *testing.T) {
-	// insert data in primary, validate same in replica
-	defer cluster.PanicHandler(t)
-	verifyInitialReplication(t)
-
-	// restart the replica1 tablet with transform hook parameter
-	replica1.VttabletProcess.TearDown()
-	replica1.VttabletProcess.ExtraArgs = []string{
-		"--db-credentials-file", dbCredentialFile,
-		"--backup_storage_hook", "test_backup_transform",
-		"--backup_storage_compress=false",
-		"--restore_from_backup",
-		"--backup_storage_implementation", "file",
-		"--file_backup_storage_root", localCluster.VtctldProcess.FileBackupStorageRoot}
-	replica1.VttabletProcess.ServingStatus = "SERVING"
-	err := replica1.VttabletProcess.Setup()
-	require.Nil(t, err)
-
-	if err := cluster.WaitForTabletSetup(&localCluster.VtctlclientProcess, 2, []string{"replica", "primary"}); err != nil {
-		require.Nil(t, err)
-	}
-
-	// take backup, it should not give any error
-	err = localCluster.VtctlclientProcess.ExecuteCommand("Backup", replica1.Alias)
-	require.Nil(t, err)
-
-	// insert data in primary
-	_, err = primary.VttabletProcess.QueryTablet("insert into vt_insert_test (msg) values ('test2')", keyspaceName, true)
-	require.Nil(t, err)
-
-	// validate backup_list, expecting 1 backup available
-	backups := localCluster.VerifyBackupCount(t, shardKsName, 1)
-
-	backupLocation := localCluster.CurrentVTDATAROOT + "/backups/" + shardKsName + "/" + backups[0]
-
-	// validate that MANIFEST has TransformHook
-	// every file should start with 'header'
-	validateManifestFile(t, backupLocation)
-
-	// restore replica2 from backup, should not give any error
-	// Note: we don't need to pass in the backup_storage_transform parameter,
-	// as it is read from the MANIFEST.
-	// clear replica2
-
-	// Stop the tablet
-	replica2.VttabletProcess.TearDown()
-	// Remove the data
-	if replica2.MysqlctlProcess.TabletUID > 0 {
-		err = replica2.MysqlctlProcess.Stop()
-		require.NoError(t, err)
-		replica2.MysqlctlProcess.CleanupFiles(replica2.TabletUID)
-		err = replica2.MysqlctlProcess.Start()
-		require.Nil(t, err)
-	} else {
-		err = replica2.MysqlctldProcess.Stop()
-		require.NoError(t, err)
-		replica2.MysqlctldProcess.CleanupFiles(replica2.TabletUID)
-		require.NoError(t, err)
-		err = replica2.MysqlctldProcess.Start()
-		require.Nil(t, err)
-	}
-
-	// Start from the backup
-	err = localCluster.VtctlclientProcess.InitTablet(replica2, cell, keyspaceName, hostname, shardName)
-	require.Nil(t, err)
-	replica2.VttabletProcess.ExtraArgs = []string{
-		"--db-credentials-file", dbCredentialFile,
-		"--restore_from_backup",
-		"--backup_storage_implementation", "file",
-		"--file_backup_storage_root", localCluster.VtctldProcess.FileBackupStorageRoot}
-	replica2.VttabletProcess.ServingStatus = ""
-	err = replica2.VttabletProcess.Setup()
-	require.Nil(t, err)
-	err = replica2.VttabletProcess.WaitForTabletStatusesForTimeout([]string{"SERVING"}, 30*time.Second)
-	require.Nil(t, err)
-	defer replica2.VttabletProcess.TearDown()
-	// We restart replication here because semi-sync will not be set correctly on tablet startup since
-	// we deprecated enable_semi_sync. StartReplication RPC fixes the semi-sync settings by consulting the
-	// durability policies set.
-	err = localCluster.VtctlclientProcess.ExecuteCommand("StopReplication", replica2.Alias)
-	require.NoError(t, err)
-	err = localCluster.VtctlclientProcess.ExecuteCommand("StartReplication", replica2.Alias)
-	require.NoError(t, err)
-
-	// validate that semi-sync is enabled for replica, disable for rdOnly
-	if replica2.Type == "replica" {
-		verifySemiSyncStatus(t, replica2, "ON")
-	} else if replica2.Type == "rdonly" {
-		verifySemiSyncStatus(t, replica2, "OFF")
-	}
-
-	// validate that new replica has all the data
-	cluster.VerifyRowsInTablet(t, replica2, keyspaceName, 2)
-
-	// Remove all backups
-	localCluster.RemoveAllBackups(t, shardKsName)
-
-}
-
-// TestBackupTransformErrorImpl validates backup behavior with transform hook
-// when the hook encounters an error
-func TestBackupTransformErrorImpl(t *testing.T) {
-	// restart the replica with transform hook parameter
-	defer cluster.PanicHandler(t)
-	err := replica1.VttabletProcess.TearDown()
-	require.Nil(t, err)
-
-	replica1.VttabletProcess.ExtraArgs = []string{
-		"--db-credentials-file", dbCredentialFile,
-		"--backup_storage_hook", "test_backup_error",
-		"--restore_from_backup",
-		"--backup_storage_implementation", "file",
-		"--file_backup_storage_root", localCluster.VtctldProcess.FileBackupStorageRoot}
-	replica1.VttabletProcess.ServingStatus = "SERVING"
-	err = replica1.VttabletProcess.Setup()
-	require.Nil(t, err)
-
-	// create backup, it should fail
-	out, err := localCluster.VtctlclientProcess.ExecuteCommandWithOutput("Backup", replica1.Alias)
-	require.NotNil(t, err)
-	require.Containsf(t, out, "backup is not usable, aborting it", "unexpected error received %v", err)
-
-	// validate there is no backup left
-	localCluster.VerifyBackupCount(t, shardKsName, 0)
-}
-
-// validateManifestFile reads manifest and validates that it
-// has a TransformHook, SkipCompress and FileEntries. It also
-// validates that backup_files available in FileEntries have
-// 'header' as their first line.
-func validateManifestFile(t *testing.T, backupLocation string) {
-
-	// reading manifest
-	data, err := os.ReadFile(backupLocation + "/MANIFEST")
-	require.Nilf(t, err, "error while reading MANIFEST %v", err)
-	manifest := make(map[string]any)
-
-	// parsing manifest
-	err = json.Unmarshal(data, &manifest)
-	require.Nilf(t, err, "error while parsing MANIFEST %v", err)
-
-	// validate manifest
-	transformHook := manifest["TransformHook"]
-	require.Equalf(t, "test_backup_transform", transformHook, "invalid transformHook in MANIFEST")
-	skipCompress := manifest["SkipCompress"]
-	assert.Equalf(t, skipCompress, true, "invalid value of skipCompress")
-
-	// validate backup files
-	fielEntries := manifest["FileEntries"]
-	fileArr, ok := fielEntries.([]any)
-	require.True(t, ok)
-	for i := range fileArr {
-		f, err := os.Open(fmt.Sprintf("%s/%d", backupLocation, i))
-		require.Nilf(t, err, "error while opening backup_file %d: %v", i, err)
-		var fileHeader string
-		_, err = fmt.Fscanln(f, &fileHeader)
-		f.Close()
-
-		require.Nilf(t, err, "error while reading backup_file %d: %v", i, err)
-		require.Equalf(t, "header", fileHeader, "wrong file contents for %d", i)
-	}
-
-}
-
-// verifySemiSyncStatus validates the replication status in tablet.
-func verifySemiSyncStatus(t *testing.T, vttablet *cluster.Vttablet, expectedStatus string) {
-	status, err := vttablet.VttabletProcess.GetDBVar("rpl_semi_sync_slave_enabled", keyspaceName)
-	require.Nil(t, err)
-	assert.Equal(t, expectedStatus, status)
-	status, err = vttablet.VttabletProcess.GetDBStatus("rpl_semi_sync_slave_status", keyspaceName)
-	require.Nil(t, err)
-	assert.Equal(t, expectedStatus, status)
-}
-
-// verifyInitialReplication generates a record on the primary and verifies that the record
-// exists on all tablets in the shard. We also check the PRIMARY as with lossless semi-sync
-// it's possible that a GTID is applied on a replica but not (yet) on the source:
-// http://my-replication-life.blogspot.com/2013/09/loss-less-semi-synchronous-replication.html
-func verifyInitialReplication(t *testing.T) {
-	// confirm that semi-sync is enabled for the replica tablets
-	healthyReplicaCount := 0
-	for _, tablet := range testTablets {
-		if tablet.Type == "replica" {
-			verifySemiSyncStatus(t, tablet, "ON")
-			healthyReplicaCount++
-		}
-	}
-
-	if healthyReplicaCount < 2 {
-		log.Errorf("Not enough healthy replicas to guarantee safe backups when semi-sync is enabled! Should have at least two, currently have %d",
-			healthyReplicaCount)
-	}
-
-	_, err := primary.VttabletProcess.QueryTablet(vtInsertTest, keyspaceName, true)
-	require.Nil(t, err)
-	_, err = primary.VttabletProcess.QueryTablet("insert into vt_insert_test (msg) values ('test1')", keyspaceName, true)
-	require.Nil(t, err)
-
-	for _, tablet := range testTablets {
-		cluster.VerifyRowsInTablet(t, tablet, keyspaceName, 1)
-	}
-}
diff --git a/go/test/endtoend/backup/transform/mysqlctld/backup_transform_mysqlctld_test.go b/go/test/endtoend/backup/transform/mysqlctld/backup_transform_mysqlctld_test.go
deleted file mode 100644
index 0a3b11227d..0000000000
--- a/go/test/endtoend/backup/transform/mysqlctld/backup_transform_mysqlctld_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-Copyright 2019 The Vitess Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package mysqlctld
-
-import (
-	"testing"
-
-	"vitess.io/vitess/go/test/endtoend/backup/transform"
-)
-
-func TestMain(m *testing.M) {
-	transform.TestMainSetup(m, true)
-}
-
-func TestBackupTransform(t *testing.T) {
-	transform.TestBackupTransformImpl(t)
-}
-func TestBackupTransformError(t *testing.T) {
-	transform.TestBackupTransformErrorImpl(t)
-}
diff --git a/go/test/endtoend/cluster/mysqlctl_process.go b/go/test/endtoend/cluster/mysqlctl_process.go
index 3478d5dc80..21908efafd 100644
--- a/go/test/endtoend/cluster/mysqlctl_process.go
+++ b/go/test/endtoend/cluster/mysqlctl_process.go
@@ -104,13 +104,22 @@ func (mysqlctl *MysqlctlProcess) startProcess(init bool) (*exec.Cmd, error) {
 		if mysqlctl.SecureTransport {
 			// Set up EXTRA_MY_CNF for ssl
 			sslPath := path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/ssl_%010d", mysqlctl.TabletUID))
+			os.MkdirAll(sslPath, 0755)
+
+			// create certificates
+			clientServerKeyPair := tlstest.CreateClientServerCertPairs(sslPath)
+
+			// use the certificate values in template to create cnf file
 			sslPathData := struct {
-				Dir string
+				Dir        string
+				ServerCert string
+				ServerKey  string
 			}{
-				Dir: sslPath,
+				Dir:        sslPath,
+				ServerCert: clientServerKeyPair.ServerCert,
+				ServerKey:  clientServerKeyPair.ServerKey,
 			}
 
-			os.MkdirAll(sslPath, 0755)
 			extraMyCNF := path.Join(sslPath, "ssl.cnf")
 			fout, err := os.Create(extraMyCNF)
 			if err != nil {
@@ -120,15 +129,13 @@ func (mysqlctl *MysqlctlProcess) startProcess(init bool) (*exec.Cmd, error) {
 
 			template.Must(template.New(fmt.Sprintf("%010d", mysqlctl.TabletUID)).Parse(`
 ssl_ca={{.Dir}}/ca-cert.pem
-ssl_cert={{.Dir}}/server-001-cert.pem
-ssl_key={{.Dir}}/server-001-key.pem
+ssl_cert={{.ServerCert}}
+ssl_key={{.ServerKey}}
 `)).Execute(fout, sslPathData)
 			if err := fout.Close(); err != nil {
 				return nil, err
 			}
 
-			tlstest.CreateClientServerCertPairs(sslPath)
-
 			tmpProcess.Env = append(tmpProcess.Env, "EXTRA_MY_CNF="+extraMyCNF)
 			tmpProcess.Env = append(tmpProcess.Env, "VTDATAROOT="+os.Getenv("VTDATAROOT"))
 		}
diff --git a/go/test/endtoend/recovery/pitr/shardedpitr_test.go b/go/test/endtoend/recovery/pitr/shardedpitr_test.go
index 6ae2e72b1a..a594fe05d0 100644
--- a/go/test/endtoend/recovery/pitr/shardedpitr_test.go
+++ b/go/test/endtoend/recovery/pitr/shardedpitr_test.go
@@ -40,12 +40,15 @@ var (
 var (
 	clusterInstance *cluster.LocalProcessCluster
 
-	primary       *cluster.Vttablet
-	replica       *cluster.Vttablet
-	shard0Primary *cluster.Vttablet
-	shard0Replica *cluster.Vttablet
-	shard1Primary *cluster.Vttablet
-	shard1Replica *cluster.Vttablet
+	primary        *cluster.Vttablet
+	replica1       *cluster.Vttablet
+	replica2       *cluster.Vttablet
+	shard0Primary  *cluster.Vttablet
+	shard0Replica1 *cluster.Vttablet
+	shard0Replica2 *cluster.Vttablet
+	shard1Primary  *cluster.Vttablet
+	shard1Replica1 *cluster.Vttablet
+	shard1Replica2 *cluster.Vttablet
 
 	cell           = "zone1"
 	hostname       = "localhost"
@@ -127,10 +130,10 @@ func TestPITRRecovery(t *testing.T) {
 	insertRow(t, 1, "prd-1", false)
 	insertRow(t, 2, "prd-2", false)
 
-	cluster.VerifyRowsInTabletForTable(t, replica, keyspaceName, 2, "product")
+	cluster.VerifyRowsInTabletForTable(t, replica1, keyspaceName, 2, "product")
 
 	// backup the replica
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", replica.Alias)
+	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", replica1.Alias)
 	require.NoError(t, err)
 
 	// check that the backup shows up in the listing
@@ -166,14 +169,14 @@ func TestPITRRecovery(t *testing.T) {
 	}
 
 	// wait till all the shards have required data
-	cluster.VerifyRowsInTabletForTable(t, shard0Replica, keyspaceName, 6, "product")
-	cluster.VerifyRowsInTabletForTable(t, shard1Replica, keyspaceName, 4, "product")
+	cluster.VerifyRowsInTabletForTable(t, shard0Replica1, keyspaceName, 6, "product")
+	cluster.VerifyRowsInTabletForTable(t, shard1Replica1, keyspaceName, 4, "product")
 
 	// take the backup (to simulate the regular backup)
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", shard0Replica.Alias)
+	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", shard0Replica1.Alias)
 	require.NoError(t, err)
 	// take the backup (to simulate the regular backup)
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", shard1Replica.Alias)
+	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", shard1Replica1.Alias)
 	require.NoError(t, err)
 
 	backups, err := clusterInstance.ListBackups(keyspaceName + "/-80")
@@ -313,9 +316,9 @@ func performResharding(t *testing.T) {
 	require.NoError(t, err)
 
 	// remove the original tablets in the original shard
-	removeTablets(t, []*cluster.Vttablet{primary, replica})
+	removeTablets(t, []*cluster.Vttablet{primary, replica1, replica2})
 
-	for _, tablet := range []*cluster.Vttablet{replica} {
+	for _, tablet := range []*cluster.Vttablet{replica1, replica2} {
 		err = clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteTablet", tablet.Alias)
 		require.NoError(t, err)
 	}
@@ -394,15 +397,18 @@ func initializeCluster(t *testing.T) {
 
 	// Defining all the tablets
 	primary = clusterInstance.NewVttabletInstance("replica", 0, "")
-	replica = clusterInstance.NewVttabletInstance("replica", 0, "")
+	replica1 = clusterInstance.NewVttabletInstance("replica", 0, "")
+	replica2 = clusterInstance.NewVttabletInstance("replica", 0, "")
 	shard0Primary = clusterInstance.NewVttabletInstance("replica", 0, "")
-	shard0Replica = clusterInstance.NewVttabletInstance("replica", 0, "")
+	shard0Replica1 = clusterInstance.NewVttabletInstance("replica", 0, "")
+	shard0Replica2 = clusterInstance.NewVttabletInstance("replica", 0, "")
 	shard1Primary = clusterInstance.NewVttabletInstance("replica", 0, "")
-	shard1Replica = clusterInstance.NewVttabletInstance("replica", 0, "")
+	shard1Replica1 = clusterInstance.NewVttabletInstance("replica", 0, "")
+	shard1Replica2 = clusterInstance.NewVttabletInstance("replica", 0, "")
 
-	shard.Vttablets = []*cluster.Vttablet{primary, replica}
-	shard0.Vttablets = []*cluster.Vttablet{shard0Primary, shard0Replica}
-	shard1.Vttablets = []*cluster.Vttablet{shard1Primary, shard1Replica}
+	shard.Vttablets = []*cluster.Vttablet{primary, replica1, replica2}
+	shard0.Vttablets = []*cluster.Vttablet{shard0Primary, shard0Replica1, shard0Replica2}
+	shard1.Vttablets = []*cluster.Vttablet{shard1Primary, shard1Replica1, shard1Replica2}
 
 	clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, commonTabletArg...)
 	clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, "--restore_from_backup")
@@ -436,14 +442,16 @@ func initializeCluster(t *testing.T) {
 		"FLUSH PRIVILEGES;",
 	}
 
-	for _, tablet := range []*cluster.Vttablet{primary, replica, shard0Primary, shard0Replica, shard1Primary, shard1Replica} {
-		for _, query := range queryCmds {
-			_, err = tablet.VttabletProcess.QueryTablet(query, keyspace.Name, false)
+	for _, shard := range clusterInstance.Keyspaces[0].Shards {
+		for _, tablet := range shard.Vttablets {
+			for _, query := range queryCmds {
+				_, err = tablet.VttabletProcess.QueryTablet(query, keyspace.Name, false)
+				require.NoError(t, err)
+			}
+
+			err = tablet.VttabletProcess.Setup()
 			require.NoError(t, err)
 		}
-
-		err = tablet.VttabletProcess.Setup()
-		require.NoError(t, err)
 	}
 
 	err = clusterInstance.VtctlclientProcess.InitShardPrimary(keyspaceName, shard.Name, cell, primary.TabletUID)
diff --git a/go/test/endtoend/recovery/pitrtls/shardedpitr_tls_test.go b/go/test/endtoend/recovery/pitrtls/shardedpitr_tls_test.go
deleted file mode 100644
index ab0020d373..0000000000
--- a/go/test/endtoend/recovery/pitrtls/shardedpitr_tls_test.go
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
-Copyright 2020 The Vitess Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package pitrtls
-
-import (
-	"context"
-	"crypto/x509"
-	"encoding/pem"
-	"fmt"
-	"os"
-	"os/exec"
-	"path"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"vitess.io/vitess/go/mysql"
-	"vitess.io/vitess/go/test/endtoend/cluster"
-	"vitess.io/vitess/go/vt/log"
-)
-
-var (
-	createTable = `create table product (id bigint(20) primary key, name char(10), created bigint(20));`
-	insertTable = `insert into product (id, name, created) values(%d, '%s', unix_timestamp());`
-	getCountID  = `select count(*) from product`
-)
-
-var (
-	clusterInstance *cluster.LocalProcessCluster
-
-	primary       *cluster.Vttablet
-	replica       *cluster.Vttablet
-	shard0Primary *cluster.Vttablet
-	shard0Replica *cluster.Vttablet
-	shard1Primary *cluster.Vttablet
-	shard1Replica *cluster.Vttablet
-
-	cell           = "zone1"
-	hostname       = "localhost"
-	keyspaceName   = "ks"
-	restoreKS1Name = "restoreks1"
-	restoreKS2Name = "restoreks2"
-	restoreKS3Name = "restoreks3"
-	shardName      = "0"
-	shard0Name     = "-80"
-	shard1Name     = "80-"
-	dbName         = "vt_ks"
-	mysqlUserName  = "vt_dba"
-	mysqlPassword  = "password"
-	vSchema        = `{
-		"sharded": true,
-		"vindexes": {
-			"hash_index": {
-				"type": "hash"
-			}
-		},
-		"tables": {
-			"product": {
-				"column_vindexes": [
-					{
-						"column": "id",
-						"name": "hash_index"
-					}
-				]
-			}
-		}
-	}`
-	commonTabletArg = []string{
-		"--vreplication_healthcheck_topology_refresh", "1s",
-		"--vreplication_healthcheck_retry_delay", "1s",
-		"--vreplication_retry_delay", "1s",
-		"--degraded_threshold", "5s",
-		"--lock_tables_timeout", "5s",
-		"--watch_replication_stream",
-		"--serving_state_grace_period", "1s"}
-)
-
-func removeTablets(t *testing.T, tablets []*cluster.Vttablet) {
-	var mysqlProcs []*exec.Cmd
-	for _, tablet := range tablets {
-		proc, _ := tablet.MysqlctlProcess.StopProcess()
-		mysqlProcs = append(mysqlProcs, proc)
-	}
-	for _, proc := range mysqlProcs {
-		err := proc.Wait()
-		require.NoError(t, err)
-	}
-	for _, tablet := range tablets {
-		tablet.VttabletProcess.TearDown()
-	}
-}
-
-func initializeCluster(t *testing.T) {
-	clusterInstance = cluster.NewCluster(cell, hostname)
-
-	// Start topo server
-	err := clusterInstance.StartTopo()
-	require.NoError(t, err)
-
-	// Start keyspace
-	keyspace := &cluster.Keyspace{
-		Name: keyspaceName,
-	}
-	clusterInstance.Keyspaces = append(clusterInstance.Keyspaces, *keyspace)
-
-	shard := &cluster.Shard{
-		Name: shardName,
-	}
-	shard0 := &cluster.Shard{
-		Name: shard0Name,
-	}
-	shard1 := &cluster.Shard{
-		Name: shard1Name,
-	}
-
-	// Defining all the tablets
-	primary = clusterInstance.NewVttabletInstance("replica", 0, "")
-	replica = clusterInstance.NewVttabletInstance("replica", 0, "")
-	shard0Primary = clusterInstance.NewVttabletInstance("replica", 0, "")
-	shard0Replica = clusterInstance.NewVttabletInstance("replica", 0, "")
-	shard1Primary = clusterInstance.NewVttabletInstance("replica", 0, "")
-	shard1Replica = clusterInstance.NewVttabletInstance("replica", 0, "")
-
-	shard.Vttablets = []*cluster.Vttablet{primary, replica}
-	shard0.Vttablets = []*cluster.Vttablet{shard0Primary, shard0Replica}
-	shard1.Vttablets = []*cluster.Vttablet{shard1Primary, shard1Replica}
-
-	clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, commonTabletArg...)
-	clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, "--restore_from_backup")
-
-	err = clusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard, *shard0, *shard1})
-	require.NoError(t, err)
-	vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory)
-	out, err := vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync")
-	require.NoError(t, err, out)
-	// Start MySql
-	var mysqlCtlProcessList []*exec.Cmd
-	for _, shard := range clusterInstance.Keyspaces[0].Shards {
-		for _, tablet := range shard.Vttablets {
-			tablet.MysqlctlProcess.SecureTransport = true
-			proc, err := tablet.MysqlctlProcess.StartProcess()
-			require.NoError(t, err)
-			mysqlCtlProcessList = append(mysqlCtlProcessList, proc)
-		}
-	}
-
-	// Wait for mysql processes to start
-	for _, proc := range mysqlCtlProcessList {
-		err = proc.Wait()
-		require.NoError(t, err)
-	}
-
-	queryCmds := []string{
-		fmt.Sprintf("CREATE USER '%s'@'%%' IDENTIFIED BY '%s';", mysqlUserName, mysqlPassword),
-		fmt.Sprintf("GRANT ALL ON *.* TO '%s'@'%%';", mysqlUserName),
-		fmt.Sprintf("GRANT GRANT OPTION ON *.* TO '%s'@'%%';", mysqlUserName),
-		fmt.Sprintf("create database %s;", "vt_ks"),
-		"FLUSH PRIVILEGES;",
-	}
-
-	for _, tablet := range []*cluster.Vttablet{primary, replica, shard0Primary, shard0Replica, shard1Primary, shard1Replica} {
-		for _, query := range queryCmds {
-			_, err = tablet.VttabletProcess.QueryTablet(query, keyspace.Name, false)
-			require.NoError(t, err)
-		}
-
-		err = tablet.VttabletProcess.Setup()
-		require.NoError(t, err)
-	}
-
-	err = clusterInstance.VtctlclientProcess.InitShardPrimary(keyspaceName, shard.Name, cell, primary.TabletUID)
-	require.NoError(t, err)
-
-	// Start vtgate
-	err = clusterInstance.StartVtgate()
-	require.NoError(t, err)
-}
-
-func insertRow(t *testing.T, id int, productName string, isSlow bool) {
-	ctx := context.Background()
-	vtParams := mysql.ConnParams{
-		Host: clusterInstance.Hostname,
-		Port: clusterInstance.VtgateMySQLPort,
-	}
-	conn, err := mysql.Connect(ctx, &vtParams)
-	require.NoError(t, err)
-	defer conn.Close()
-
-	insertSmt := fmt.Sprintf(insertTable, id, productName)
-	_, err = conn.ExecuteFetch(insertSmt, 1000, true)
-	require.NoError(t, err)
-
-	if isSlow {
-		time.Sleep(1 * time.Second)
-	}
-}
-
-func createRestoreKeyspace(t *testing.T, timeToRecover, restoreKeyspaceName string) {
-	output, err := clusterInstance.VtctlclientProcess.ExecuteCommandWithOutput("CreateKeyspace", "--",
-		"--keyspace_type=SNAPSHOT", "--base_keyspace="+keyspaceName,
-		"--snapshot_time", timeToRecover, restoreKeyspaceName)
-	log.Info(output)
-	require.NoError(t, err)
-}
-
-// Test pitr (Point in time recovery).
-// -------------------------------------------
-// The following test will:
-// - create a shard with primary and replica
-// - run InitShardPrimary
-// - insert some data using vtgate (e.g. here we have inserted rows 1,2)
-// - verify the replication
-// - take backup of replica
-// - insert some data using vtgate (e.g. we inserted rows 3 4 5 6), while inserting row-4, note down the time (restoreTime1)
-// - perform a resharding to create 2 shards (-80, 80-), and delete the old shard
-// - insert some data using vtgate (e.g. we will insert 7 8 9 10) and verify we get required number of rows in -80, 80- shard
-// - take backup of both shards
-// - insert some more data using vtgate (e.g. we will insert 11 12 13 14 15), while inserting row-13, note down the time (restoreTime2)
-// - note down the current time (restoreTime3)
-
-// - Till now we did all the presetup for assertions
-
-// - asserting that restoring to restoreTime1 (going from 2 shards to 1 shard) is working, i.e. we should get 4 rows.
-// - asserting that while restoring if we give small timeout value, it will restore upto to the last available backup (asserting only -80 shard)
-// - asserting that restoring to restoreTime2 (going from 2 shards to 2 shards with past time) is working, it will assert for both shards
-// - asserting that restoring to restoreTime3 is working, we should get complete data after restoring,  as we have in existing shards.
-func TestTLSPITRRecovery(t *testing.T) {
-	defer cluster.PanicHandler(nil)
-	initializeCluster(t)
-	defer clusterInstance.Teardown()
-
-	// Creating the table
-	_, err := primary.VttabletProcess.QueryTablet(createTable, keyspaceName, true)
-	require.NoError(t, err)
-
-	insertRow(t, 1, "prd-1", false)
-	insertRow(t, 2, "prd-2", false)
-
-	cluster.VerifyRowsInTabletForTable(t, replica, keyspaceName, 2, "product")
-
-	// backup the replica
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", replica.Alias)
-	require.NoError(t, err)
-
-	// check that the backup shows up in the listing
-	output, err := clusterInstance.ListBackups("ks/0")
-	require.NoError(t, err)
-	assert.Equal(t, 1, len(output))
-
-	// now insert some more data to simulate the changes after regular backup
-	// every insert has some time lag/difference to simulate the time gap between rows
-	// and when we recover to certain time, this time gap will be able to identify the exact eligible row
-	var restoreTime1 string
-	for counter := 3; counter <= 6; counter++ {
-		if counter == 4 { // we want to recovery till this, so noting the time
-			tm := time.Now().Add(1 * time.Second).UTC()
-			restoreTime1 = tm.Format(time.RFC3339)
-		}
-		insertRow(t, counter, fmt.Sprintf("prd-%d", counter), true)
-	}
-
-	// creating restore keyspace with snapshot time as restoreTime1
-	//   Need to test this before resharding and we tear down the
-	//   original mysql replica, which we use as a binlog source
-	createRestoreKeyspace(t, restoreTime1, restoreKS1Name)
-
-	// Launching a recovery tablet which recovers data from the primary till the restoreTime1
-	tlsTestTabletRecovery(t, replica, "2m", restoreKS1Name, "0", "INT64(4)")
-
-	// starting resharding process
-	tlsPerformResharding(t)
-
-	for counter := 7; counter <= 10; counter++ {
-		insertRow(t, counter, fmt.Sprintf("prd-%d", counter), false)
-	}
-
-	// wait till all the shards have required data
-	cluster.VerifyRowsInTabletForTable(t, shard0Replica, keyspaceName, 6, "product")
-	cluster.VerifyRowsInTabletForTable(t, shard1Replica, keyspaceName, 4, "product")
-
-	// take the backup (to simulate the regular backup)
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", shard0Replica.Alias)
-	require.NoError(t, err)
-	// take the backup (to simulate the regular backup)
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Backup", shard1Replica.Alias)
-	require.NoError(t, err)
-
-	backups, err := clusterInstance.ListBackups(keyspaceName + "/-80")
-	require.NoError(t, err)
-	require.Equal(t, len(backups), 1)
-
-	backups, err = clusterInstance.ListBackups(keyspaceName + "/80-")
-	require.NoError(t, err)
-	require.Equal(t, len(backups), 1)
-
-	// now insert some more data to simulate the changes after regular backup
-	// every insert has some time lag/difference to simulate the time gap between rows
-	// and when we recover to certain time, this time gap will be able to identify the exact eligible row
-	var restoreTime2 string
-	for counter := 11; counter <= 15; counter++ {
-		if counter == 13 { // we want to recovery till this, so noting the time
-			tm := time.Now().Add(1 * time.Second).UTC()
-			restoreTime2 = tm.Format(time.RFC3339)
-		}
-		insertRow(t, counter, fmt.Sprintf("prd-%d", counter), true)
-	}
-	restoreTime3 := time.Now().UTC().Format(time.RFC3339)
-
-	// create restoreKeyspace with snapshot time as restoreTime2
-	createRestoreKeyspace(t, restoreTime2, restoreKS2Name)
-
-	// test the recovery with smaller binlog_lookup_timeout for shard0
-	// since we have small lookup timeout, it will just get whatever available in the backup
-	// mysql> select * from product;
-	// +----+--------+------------+
-	// | id | name   | created    |
-	// +----+--------+------------+
-	// |  1 | prd-1  | 1597219030 |
-	// |  2 | prd-2  | 1597219030 |
-	// |  3 | prd-3  | 1597219043 |
-	// |  5 | prd-5  | 1597219045 |
-	// |  9 | prd-9  | 1597219130 |
-	// | 10 | prd-10 | 1597219130 |
-	// +----+--------+------------+
-	tlsTestTabletRecovery(t, shard0Replica, "1ms", restoreKS2Name, "-80", "INT64(6)")
-
-	// test the recovery with valid binlog_lookup_timeout for shard0 and getting the data till the restoreTime2
-	// 	mysql> select * from product;
-	// +----+--------+------------+
-	// | id | name   | created    |
-	// +----+--------+------------+
-	// |  1 | prd-1  | 1597219030 |
-	// |  2 | prd-2  | 1597219030 |
-	// |  3 | prd-3  | 1597219043 |
-	// |  5 | prd-5  | 1597219045 |
-	// |  9 | prd-9  | 1597219130 |
-	// | 10 | prd-10 | 1597219130 |
-	// | 13 | prd-13 | 1597219141 |
-	// +----+--------+------------+
-	tlsTestTabletRecovery(t, shard0Replica, "2m", restoreKS2Name, "-80", "INT64(7)")
-
-	// test the recovery with valid binlog_lookup_timeout for shard1 and getting the data till the restoreTime2
-	// 	mysql> select * from product;
-	// +----+--------+------------+
-	// | id | name   | created    |
-	// +----+--------+------------+
-	// |  4 | prd-4  | 1597219044 |
-	// |  6 | prd-6  | 1597219046 |
-	// |  7 | prd-7  | 1597219130 |
-	// |  8 | prd-8  | 1597219130 |
-	// | 11 | prd-11 | 1597219139 |
-	// | 12 | prd-12 | 1597219140 |
-	// +----+--------+------------+
-	tlsTestTabletRecovery(t, shard1Replica, "2m", restoreKS2Name, "80-", "INT64(6)")
-
-	// test the recovery with timetorecover > (timestamp of last binlog event in binlog server)
-	createRestoreKeyspace(t, restoreTime3, restoreKS3Name)
-
-	// 	mysql> select * from product;
-	// +----+--------+------------+
-	// | id | name   | created    |
-	// +----+--------+------------+
-	// |  1 | prd-1  | 1597219030 |
-	// |  2 | prd-2  | 1597219030 |
-	// |  3 | prd-3  | 1597219043 |
-	// |  5 | prd-5  | 1597219045 |
-	// |  9 | prd-9  | 1597219130 |
-	// | 10 | prd-10 | 1597219130 |
-	// | 13 | prd-13 | 1597219141 |
-	// | 15 | prd-15 | 1597219142 |
-	// +----+--------+------------+
-	tlsTestTabletRecovery(t, shard0Replica, "2m", restoreKS3Name, "-80", "INT64(8)")
-
-	// 	mysql> select * from product;
-	// +----+--------+------------+
-	// | id | name   | created    |
-	// +----+--------+------------+
-	// |  4 | prd-4  | 1597219044 |
-	// |  6 | prd-6  | 1597219046 |
-	// |  7 | prd-7  | 1597219130 |
-	// |  8 | prd-8  | 1597219130 |
-	// | 11 | prd-11 | 1597219139 |
-	// | 12 | prd-12 | 1597219140 |
-	// | 14 | prd-14 | 1597219142 |
-	// +----+--------+------------+
-	tlsTestTabletRecovery(t, shard1Replica, "2m", restoreKS3Name, "80-", "INT64(7)")
-}
-
-func tlsPerformResharding(t *testing.T) {
-	err := clusterInstance.VtctlclientProcess.ApplyVSchema(keyspaceName, vSchema)
-	require.NoError(t, err)
-
-	err = clusterInstance.VtctlProcess.ExecuteCommand("InitShardPrimary", "--", "--force", "ks/-80", shard0Primary.Alias)
-	require.NoError(t, err)
-
-	err = clusterInstance.VtctlProcess.ExecuteCommand("InitShardPrimary", "--", "--force", "ks/80-", shard1Primary.Alias)
-	require.NoError(t, err)
-
-	// we need to create the schema, and the worker will do data copying
-	for _, keyspaceShard := range []string{"ks/-80", "ks/80-"} {
-		err = clusterInstance.VtctlclientProcess.ExecuteCommand("CopySchemaShard", "ks/0", keyspaceShard)
-		require.NoError(t, err)
-	}
-
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("Reshard", "ks.reshardWorkflow", "0", "--", "-80,80-")
-	require.NoError(t, err)
-
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("SwitchReads", "--", "--tablet_type=rdonly", "ks.reshardWorkflow")
-	require.NoError(t, err)
-
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("SwitchReads", "--", "--tablet_type=replica", "ks.reshardWorkflow")
-	require.NoError(t, err)
-
-	// then serve primary from the split shards
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("SwitchWrites", "ks.reshardWorkflow")
-	require.NoError(t, err)
-
-	// remove the original tablets in the original shard
-	removeTablets(t, []*cluster.Vttablet{primary, replica})
-
-	for _, tablet := range []*cluster.Vttablet{replica} {
-		err = clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteTablet", tablet.Alias)
-		require.NoError(t, err)
-	}
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteTablet", "--", "--allow_primary", primary.Alias)
-	require.NoError(t, err)
-
-	// rebuild the serving graph, all mentions of the old shards should be gone
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("RebuildKeyspaceGraph", "ks")
-	require.NoError(t, err)
-
-	// delete the original shard
-	err = clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteShard", "ks/0")
-	require.NoError(t, err)
-
-	// Restart vtgate process
-	err = clusterInstance.VtgateProcess.TearDown()
-	require.NoError(t, err)
-
-	err = clusterInstance.VtgateProcess.Setup()
-	require.NoError(t, err)
-
-	clusterInstance.WaitForTabletsToHealthyInVtgate()
-}
-
-func tlsTestTabletRecovery(t *testing.T, tabletForBinlogs *cluster.Vttablet, lookupTimeout, restoreKeyspaceName, shardName, expectedRows string) {
-	recoveryTablet := clusterInstance.NewVttabletInstance("replica", 0, cell)
-	tlsLaunchRecoveryTablet(t, recoveryTablet, tabletForBinlogs, lookupTimeout, restoreKeyspaceName, shardName)
-
-	sqlRes, err := recoveryTablet.VttabletProcess.QueryTablet(getCountID, keyspaceName, true)
-	require.NoError(t, err)
-	assert.Equal(t, expectedRows, sqlRes.Rows[0][0].String())
-
-	defer recoveryTablet.MysqlctlProcess.Stop()
-	defer recoveryTablet.VttabletProcess.TearDown()
-}
-
-func tlsLaunchRecoveryTablet(t *testing.T, tablet *cluster.Vttablet, tabletForBinlogs *cluster.Vttablet, lookupTimeout, restoreKeyspaceName, shardName string) {
-	tablet.MysqlctlProcess = *cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, clusterInstance.TmpDirectory)
-	tablet.MysqlctlProcess.SecureTransport = true
-	err := tablet.MysqlctlProcess.Start()
-	require.NoError(t, err)
-
-	tablet.VttabletProcess = cluster.VttabletProcessInstance(
-		tablet.HTTPPort,
-		tablet.GrpcPort,
-		tablet.TabletUID,
-		clusterInstance.Cell,
-		shardName,
-		keyspaceName,
-		clusterInstance.VtctldProcess.Port,
-		tablet.Type,
-		clusterInstance.TopoProcess.Port,
-		clusterInstance.Hostname,
-		clusterInstance.TmpDirectory,
-		clusterInstance.VtTabletExtraArgs,
-		clusterInstance.EnableSemiSync,
-		clusterInstance.DefaultCharset)
-	tablet.Alias = tablet.VttabletProcess.TabletPath
-	tablet.VttabletProcess.SupportsBackup = true
-	tablet.VttabletProcess.Keyspace = restoreKeyspaceName
-
-	certDir := path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/ssl_%010d", tablet.MysqlctlProcess.TabletUID))
-	tablet.VttabletProcess.ExtraArgs = []string{
-		"--disable_active_reparents",
-		"--enable_replication_reporter=false",
-		"--init_db_name_override", dbName,
-		"--init_tablet_type", "replica",
-		"--init_keyspace", restoreKeyspaceName,
-		"--init_shard", shardName,
-		"--binlog_host", clusterInstance.Hostname,
-		"--binlog_port", fmt.Sprintf("%d", tabletForBinlogs.MySQLPort),
-		"--binlog_user", mysqlUserName,
-		"--binlog_password", mysqlPassword,
-		"--binlog_ssl_ca", certDir + "/ca-cert.pem",
-		"--binlog_ssl_server_name", getCNFromCertPEM(certDir + "/server-001-cert.pem"),
-		"--pitr_gtid_lookup_timeout", lookupTimeout,
-		"--vreplication_healthcheck_topology_refresh", "1s",
-		"--vreplication_healthcheck_retry_delay", "1s",
-		"--vreplication_tablet_type", "replica",
-		"--vreplication_retry_delay", "1s",
-		"--degraded_threshold", "5s",
-		"--lock_tables_timeout", "5s",
-		"--watch_replication_stream",
-		"--serving_state_grace_period", "1s",
-	}
-	tablet.VttabletProcess.ServingStatus = ""
-
-	err = tablet.VttabletProcess.Setup()
-	require.NoError(t, err)
-
-	tablet.VttabletProcess.WaitForTabletStatusesForTimeout([]string{"SERVING"}, 20*time.Second)
-}
-
-func getCNFromCertPEM(filename string) string {
-	pemBytes, _ := os.ReadFile(filename)
-	block, _ := pem.Decode(pemBytes)
-	cert, _ := x509.ParseCertificate(block.Bytes)
-	rdn := cert.Subject.ToRDNSequence()[0][0]
-	t := rdn.Type
-
-	// 2.5.4.3 is ASN OID for "CN"
-	if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 && t[3] == 3 {
-		return fmt.Sprintf("%s", rdn.Value)
-	}
-	// As good a fallback as any
-	return "localhost"
-}
diff --git a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go
index 820e6ad36e..ba9bbd8b19 100644
--- a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go
+++ b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go
@@ -374,3 +374,13 @@ func TestOrderByCount(t *testing.T) {
 
 	mcmp.AssertMatches("SELECT /*vt+ PLANNER=gen4 */ t9.id2 FROM t9 GROUP BY t9.id2 ORDER BY COUNT(t9.id2) DESC", `[[VARCHAR("3")] [VARCHAR("2")] [VARCHAR("1")]]`)
 }
+
+func TestAggregateRandom(t *testing.T) {
+	mcmp, closer := start(t)
+	defer closer()
+
+	mcmp.Exec("insert into t1(t1_id, name, value, shardKey) values (1, 'name 1', 'value 1', 1), (2, 'name 2', 'value 2', 2)")
+	mcmp.Exec("insert into t2(id, shardKey) values (1, 10), (2, 20)")
+
+	mcmp.AssertMatches("SELECT /*vt+ PLANNER=gen4 */ t1.shardKey, t1.name, count(t2.id) FROM t1 JOIN t2 ON t1.value != t2.shardKey GROUP BY t1.t1_id", `[[INT64(1) VARCHAR("name 1") INT64(2)] [INT64(2) VARCHAR("name 2") INT64(2)]]`)
+}
diff --git a/go/vt/sqlparser/normalizer_test.go b/go/vt/sqlparser/normalizer_test.go
index f8f72ceff2..3fbb7687d6 100644
--- a/go/vt/sqlparser/normalizer_test.go
+++ b/go/vt/sqlparser/normalizer_test.go
@@ -311,6 +311,13 @@ func TestNormalize(t *testing.T) {
 			"bv1":                   sqltypes.Int64BindVariable(1),
 			"comms_by_companies_id": sqltypes.StringBindVariable("rjve634shXzaavKHbAH16ql6OrxJ"),
 		},
+	}, {
+		// Int leading with zero should also be normalized
+		in:      `select * from t where zipcode = 01001900`,
+		outstmt: `select * from t where zipcode = :zipcode`,
+		outbv: map[string]*querypb.BindVariable{
+			"zipcode": sqltypes.ValueBindVariable(sqltypes.MakeTrusted(sqltypes.Int64, []byte("01001900"))),
+		},
 	}}
 	for _, tc := range testcases {
 		t.Run(tc.in, func(t *testing.T) {
diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json
index 45a6cb7238..760a136eca 100644
--- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json
@@ -4324,7 +4324,7 @@
           {
             "OperatorType": "Projection",
             "Expressions": [
-              "[COLUMN 2] * [COLUMN 3] as col",
+              "[COLUMN 2] as col",
               "[COLUMN 1]",
               "[COLUMN 0] as id"
             ],
@@ -4332,7 +4332,7 @@
               {
                 "OperatorType": "Join",
                 "Variant": "Join",
-                "JoinColumnIndexes": "L:1,L:2,L:0,R:1",
+                "JoinColumnIndexes": "L:1,L:2,L:0",
                 "JoinVars": {
                   "user_col": 0
                 },
@@ -4357,8 +4357,8 @@
                       "Name": "user",
                       "Sharded": true
                     },
-                    "FieldQuery": "select 1, count(*) from user_extra where 1 != 1 group by 1",
-                    "Query": "select 1, count(*) from user_extra where user_extra.col = :user_col group by 1",
+                    "FieldQuery": "select 1 from user_extra where 1 != 1 group by 1",
+                    "Query": "select 1 from user_extra where user_extra.col = :user_col group by 1",
                     "Table": "user_extra"
                   }
                 ]
@@ -4473,7 +4473,7 @@
           {
             "OperatorType": "Projection",
             "Expressions": [
-              "[COLUMN 2] * [COLUMN 3] as id",
+              "[COLUMN 2] as id",
               "[COLUMN 1]",
               "[COLUMN 0] as id"
             ],
@@ -4481,7 +4481,7 @@
               {
                 "OperatorType": "Join",
                 "Variant": "Join",
-                "JoinColumnIndexes": "L:0,L:1,L:0,R:1",
+                "JoinColumnIndexes": "L:0,L:1,L:0",
                 "TableName": "`user`_user_extra",
                 "Inputs": [
                   {
@@ -4503,8 +4503,8 @@
                       "Name": "user",
                       "Sharded": true
                     },
-                    "FieldQuery": "select 1, count(*) from user_extra where 1 != 1 group by 1",
-                    "Query": "select 1, count(*) from user_extra group by 1",
+                    "FieldQuery": "select 1 from user_extra where 1 != 1 group by 1",
+                    "Query": "select 1 from user_extra group by 1",
                     "Table": "user_extra"
                   }
                 ]
@@ -4819,5 +4819,82 @@
         "user.user"
       ]
     }
+  },
+  {
+    "comment": "AggregateRandom in non full group by query",
+    "query": "select u.id, u.name, count(m.predef1) from user.user as u join user.user_extra as m on u.id = m.order group by u.id",
+    "v3-plan": "unsupported: cross-shard query with aggregates",
+    "gen4-plan": {
+      "QueryType": "SELECT",
+      "Original": "select u.id, u.name, count(m.predef1) from user.user as u join user.user_extra as m on u.id = m.order group by u.id",
+      "Instructions": {
+        "OperatorType": "Aggregate",
+        "Variant": "Ordered",
+        "Aggregates": "random(1) AS name, sum_count(2) AS count(m.predef1)",
+        "GroupBy": "(0|3)",
+        "ResultColumns": 3,
+        "Inputs": [
+          {
+            "OperatorType": "Projection",
+            "Expressions": [
+              "[COLUMN 0] as id",
+              "[COLUMN 2] as name",
+              "[COLUMN 3] * [COLUMN 4] as count(m.predef1)",
+              "[COLUMN 1]"
+            ],
+            "Inputs": [
+              {
+                "OperatorType": "Sort",
+                "Variant": "Memory",
+                "OrderBy": "(0|1) ASC",
+                "Inputs": [
+                  {
+                    "OperatorType": "Join",
+                    "Variant": "Join",
+                    "JoinColumnIndexes": "R:2,R:3,R:0,L:1,R:1",
+                    "JoinVars": {
+                      "m_order": 0
+                    },
+                    "TableName": "user_extra_`user`",
+                    "Inputs": [
+                      {
+                        "OperatorType": "Route",
+                        "Variant": "Scatter",
+                        "Keyspace": {
+                          "Name": "user",
+                          "Sharded": true
+                        },
+                        "FieldQuery": "select m.`order`, count(m.predef1), weight_string(m.`order`) from user_extra as m where 1 != 1 group by m.`order`, weight_string(m.`order`)",
+                        "Query": "select m.`order`, count(m.predef1), weight_string(m.`order`) from user_extra as m group by m.`order`, weight_string(m.`order`)",
+                        "Table": "user_extra"
+                      },
+                      {
+                        "OperatorType": "Route",
+                        "Variant": "EqualUnique",
+                        "Keyspace": {
+                          "Name": "user",
+                          "Sharded": true
+                        },
+                        "FieldQuery": "select u.`name`, count(*), u.id, weight_string(u.id) from `user` as u where 1 != 1 group by u.id, weight_string(u.id)",
+                        "Query": "select u.`name`, count(*), u.id, weight_string(u.id) from `user` as u where u.id = :m_order group by u.id, weight_string(u.id)",
+                        "Table": "`user`",
+                        "Values": [
+                          ":m_order"
+                        ],
+                        "Vindex": "user_index"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ]
+      },
+      "TablesUsed": [
+        "user.user",
+        "user.user_extra"
+      ]
+    }
   }
 ]
\ No newline at end of file
diff --git a/go/vt/vttablet/onlineddl/executor_test.go b/go/vt/vttablet/onlineddl/executor_test.go
index c41f3b24f3..2d9be7630f 100644
--- a/go/vt/vttablet/onlineddl/executor_test.go
+++ b/go/vt/vttablet/onlineddl/executor_test.go
@@ -93,7 +93,7 @@ func TestValidateAndEditCreateTableStatement(t *testing.T) {
 			}, createTable)
 			assert.NoError(t, err)
 			assert.Equal(t, tc.countConstraints, len(uniqueConstraintNames))
-			assert.Equal(t, tc.countConstraints, len(constraintMap))
+			assert.Equalf(t, tc.countConstraints, len(constraintMap), "got contraints: %v", constraintMap)
 		})
 	}
 }
@@ -120,6 +120,18 @@ func TestValidateAndEditAlterTableStatement(t *testing.T) {
 			alter:  "alter table t add fulltext key name0_ft (name0), add column i int, add fulltext key name1_ft (name1), add fulltext key name2_ft (name2)",
 			expect: []string{"alter table t add fulltext key name0_ft (name0), add column i int", "alter table t add fulltext key name1_ft (name1)", "alter table t add fulltext key name2_ft (name2)"},
 		},
+		{
+			alter:  "alter table t add constraint check (id != 1)",
+			expect: []string{"alter table t add constraint chk_aulpn7bjeortljhguy86phdn9 check (id != 1)"},
+		},
+		{
+			alter:  "alter table t add constraint t_chk_1 check (id != 1)",
+			expect: []string{"alter table t add constraint chk_1_aulpn7bjeortljhguy86phdn9 check (id != 1)"},
+		},
+		{
+			alter:  "alter table t add constraint some_check check (id != 1)",
+			expect: []string{"alter table t add constraint some_check_aulpn7bjeortljhguy86phdn9 check (id != 1)"},
+		},
 	}
 	for _, tc := range tt {
 		t.Run(tc.alter, func(t *testing.T) {
@@ -129,7 +141,8 @@ func TestValidateAndEditAlterTableStatement(t *testing.T) {
 			require.True(t, ok)
 
 			m := map[string]string{}
-			alters, err := e.validateAndEditAlterTableStatement(context.Background(), alterTable, m)
+			onlineDDL := &schema.OnlineDDL{UUID: "a5a563da_dc1a_11ec_a416_0a43f95f28a3", Table: "t"}
+			alters, err := e.validateAndEditAlterTableStatement(context.Background(), onlineDDL, alterTable, m)
 			assert.NoError(t, err)
 			altersStrings := []string{}
 			for _, alter := range alters {
diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go
index 7476d5bba8..5c6fbda247 100644
--- a/test/ci_workflow_gen.go
+++ b/test/ci_workflow_gen.go
@@ -73,13 +73,12 @@ var (
 		"ers_prs_newfeatures_heavy",
 		"15",
 		"vtgate_general_heavy",
-		"vtbackup_transform",
+		"vtbackup",
 		"18",
 		"xb_backup",
 		"21",
 		"22",
 		"mysql_server_vault",
-		"26",
 		"vstream_failover",
 		"vstream_stoponreshard_true",
 		"vstream_stoponreshard_false",
diff --git a/test/config.json b/test/config.json
index b2be584d6c..7b0b8245f1 100644
--- a/test/config.json
+++ b/test/config.json
@@ -114,28 +114,10 @@
 			"Args": ["vitess.io/vitess/go/test/endtoend/backup/vtbackup", "-timeout", "20m"],
 			"Command": [],
 			"Manual": false,
-			"Shard": "vtbackup_transform",
+			"Shard": "vtbackup",
 			"RetryMax": 1,
 			"Tags": ["upgrade_downgrade_backups"]
 		},
-		"backup_transform": {
-			"File": "unused.go",
-			"Args": ["vitess.io/vitess/go/test/endtoend/backup/transform", "-timeout", "15m"],
-			"Command": [],
-			"Manual": false,
-			"Shard": "vtbackup_transform",
-			"RetryMax": 1,
-			"Tags": ["upgrade_downgrade_backups"]
-		},
-		"backup_transform_mysqlctld": {
-			"File": "unused.go",
-			"Args": ["vitess.io/vitess/go/test/endtoend/backup/transform/mysqlctld"],
-			"Command": [],
-			"Manual": false,
-			"Shard": "21", 
-			"RetryMax": 1,
-			"Tags": []
-		},
 		"backup_xtrabackup": {
 			"File": "unused.go",
 			"Args": ["vitess.io/vitess/go/test/endtoend/backup/xtrabackup"],
@@ -369,17 +351,6 @@
 				"site_test"
 			]
 		},
-		"pitrtls": {
-			"File": "unused.go",
-			"Args": ["vitess.io/vitess/go/test/endtoend/recovery/pitrtls"],
-			"Command": [],
-			"Manual": false,
-			"Shard": "26",
-			"RetryMax": 1,
-			"Tags": [
-				"site_test"
-			]
-		},
 		"recovery": {
 			"File": "unused.go",
 			"Args": ["vitess.io/vitess/go/test/endtoend/recovery/unshardedrecovery"],