Skip to content

Commit da4f1e9

Browse files
authored
Merge branch 'master' into update-codeql
2 parents 412de7c + 6b676f1 commit da4f1e9

11 files changed

Lines changed: 398 additions & 238 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
- uses: actions/checkout@v4
1212

1313
- name: Set up Go
14-
uses: actions/setup-go@v5
14+
uses: actions/setup-go@v6
1515
with:
1616
go-version-file: go.mod
1717

.github/workflows/golangci-lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v4
17-
- uses: actions/setup-go@v5
17+
- uses: actions/setup-go@v6
1818
with:
1919
go-version-file: go.mod
2020
- name: golangci-lint

.github/workflows/replica-tests.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ jobs:
1515
steps:
1616
- uses: actions/checkout@v4
1717

18+
- name: Install sysbench
19+
run: |
20+
sudo apt-get update
21+
sudo apt-get install -y sysbench
22+
1823
- name: Setup environment
1924
run: script/docker-gh-ost-replica-tests up
2025

doc/command-line-flags.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ See also: [`skip-foreign-key-checks`](#skip-foreign-key-checks)
119119

120120
`gh-ost` reads event from the binary log and applies them onto the _ghost_ table. It does so in batched writes: grouping multiple events to apply in a single transaction. This gives better write throughput as we don't need to sync the transaction log to disk for each event.
121121

122-
The `--dml-batch-size` flag controls the size of the batched write. Allowed values are `1 - 100`, where `1` means no batching (every event from the binary log is applied onto the _ghost_ table on its own transaction). Default value is `10`.
122+
The `--dml-batch-size` flag controls the size of the batched write. Allowed values are `1 - 1000`, where `1` means no batching (every event from the binary log is applied onto the _ghost_ table on its own transaction). Default value is `10`.
123123

124124
Why is this behavior configurable? Different workloads have different characteristics. Some workloads have very large writes, such that aggregating even `50` writes into a transaction makes for a significant transaction size. On other workloads write rate is high such that one just can't allow for a hundred more syncs to disk per second. The default value of `10` is a modest compromise that should probably work very well for most workloads. Your mileage may vary.
125125

doc/local-tests.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,11 @@ TEST_MYSQL_IMAGE="mysql-server:8.0.16" ./script/docker-gh-ost-replica-tests up
3434
# cleanup containers
3535
./script/docker-gh-ost-replica-tests down
3636
```
37+
38+
Pass the `-t` flag to run the tests with a toxiproxy between gh-ost and the MySQL replica. This simulates network conditions where MySQL connections are closed unexpectedly.
39+
40+
```shell
41+
# run tests with toxiproxy
42+
./script/docker-gh-ost-replica-tests up -t
43+
./script/docker-gh-ost-replica-tests run -t
44+
```

go/cmd/gh-ost/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func main() {
106106
flag.BoolVar(&migrationContext.CutOverExponentialBackoff, "cut-over-exponential-backoff", false, "Wait exponentially longer intervals between failed cut-over attempts. Wait intervals obey a maximum configurable with 'exponential-backoff-max-interval').")
107107
exponentialBackoffMaxInterval := flag.Int64("exponential-backoff-max-interval", 64, "Maximum number of seconds to wait between attempts when performing various operations with exponential backoff.")
108108
chunkSize := flag.Int64("chunk-size", 1000, "amount of rows to handle in each iteration (allowed range: 10-100,000)")
109-
dmlBatchSize := flag.Int64("dml-batch-size", 10, "batch size for DML events to apply in a single transaction (range 1-100)")
109+
dmlBatchSize := flag.Int64("dml-batch-size", 10, "batch size for DML events to apply in a single transaction (range 1-1000)")
110110
defaultRetries := flag.Int64("default-retries", 60, "Default number of retries for various operations before panicking")
111111
flag.BoolVar(&migrationContext.PanicOnWarnings, "panic-on-warnings", false, "Panic when SQL warnings are encountered when copying a batch indicating data loss")
112112
cutOverLockTimeoutSeconds := flag.Int64("cut-over-lock-timeout-seconds", 3, "Max number of seconds to hold locks on tables while attempting to cut-over (retry attempted when lock exceeds timeout) or attempting instant DDL")
@@ -143,6 +143,7 @@ func main() {
143143
flag.BoolVar(&migrationContext.IncludeTriggers, "include-triggers", false, "When true, the triggers (if exist) will be created on the new table")
144144
flag.StringVar(&migrationContext.TriggerSuffix, "trigger-suffix", "", "Add a suffix to the trigger name (i.e '_v2'). Requires '--include-triggers'")
145145
flag.BoolVar(&migrationContext.RemoveTriggerSuffix, "remove-trigger-suffix-if-exists", false, "Remove given suffix from name of trigger. Requires '--include-triggers' and '--trigger-suffix'")
146+
flag.BoolVar(&migrationContext.SkipPortValidation, "skip-port-validation", false, "Skip port validation for MySQL connections")
146147

147148
maxLoad := flag.String("max-load", "", "Comma delimited status-name=threshold. e.g: 'Threads_running=100,Threads_connected=500'. When status exceeds threshold, app throttles writes")
148149
criticalLoad := flag.String("critical-load", "", "Comma delimited status-name=threshold, same format as --max-load. When status exceeds threshold, app panics and quits")

go/logic/applier.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package logic
88
import (
99
gosql "database/sql"
1010
"fmt"
11+
"reflect"
1112
"regexp"
1213
"strings"
1314
"sync/atomic"
@@ -1298,7 +1299,8 @@ func (this *Applier) updateModifiesUniqueKeyColumns(dmlEvent *binlog.BinlogDMLEv
12981299
tableOrdinal := this.migrationContext.OriginalTableColumns.Ordinals[column.Name]
12991300
whereColumnValue := dmlEvent.WhereColumnValues.AbstractValues()[tableOrdinal]
13001301
newColumnValue := dmlEvent.NewColumnValues.AbstractValues()[tableOrdinal]
1301-
if newColumnValue != whereColumnValue {
1302+
1303+
if !reflect.DeepEqual(whereColumnValue, newColumnValue) {
13021304
return column.Name, true
13031305
}
13041306
}

go/logic/applier_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ func TestApplierGenerateSqlModeQuery(t *testing.T) {
6262
}
6363

6464
func TestApplierUpdateModifiesUniqueKeyColumns(t *testing.T) {
65-
columns := sql.NewColumnList([]string{"id", "item_id"})
66-
columnValues := sql.ToColumnValues([]interface{}{123456, 42})
65+
columns := sql.NewColumnList([]string{"id", "item_id", "item_text"})
66+
columnValues := sql.ToColumnValues([]interface{}{123456, 42, []uint8{116, 101, 115, 116}})
6767

6868
migrationContext := base.NewMigrationContext()
6969
migrationContext.OriginalTableColumns = columns

localtests/sysbench/create.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* This table will get created by `sysbench prepare` */
2+
/*
3+
CREATE TABLE `sbtest1` (
4+
`id` int NOT NULL AUTO_INCREMENT,
5+
`k` int NOT NULL DEFAULT '0',
6+
`c` char(120) NOT NULL DEFAULT '',
7+
`pad` char(60) NOT NULL DEFAULT '',
8+
PRIMARY KEY (`id`),
9+
KEY `k_1` (`k`)
10+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
11+
*/
12+
13+
DROP TABLE IF EXISTS `sbtest1`;

0 commit comments

Comments
 (0)