Skip to content

Commit 36bcc03

Browse files
author
Shlomi Noach
authored
Merge branch 'master' into fix-variables-spelling
2 parents 0243e76 + 340a93c commit 36bcc03

23 files changed

+368
-25
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,4 @@ This PR [briefly explain what is does]
1616
> In case this PR introduced Go code changes:
1717
1818
- [ ] contributed code is using same conventions as original code
19-
- [ ] code is formatted via `gofmt` (please avoid `goimports`)
20-
- [ ] code is built via `./build.sh`
21-
- [ ] code is tested via `./test.sh`
19+
- [ ] `script/cibuild` returns with no formatting errors, build errors or unit test errors.

.travis.yml

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1+
# http://docs.travis-ci.com/user/languages/go/
12
language: go
23

3-
go:
4-
- 1.6
5-
- tip
4+
go: 1.8
65

7-
script: ./test.sh
6+
os:
7+
- linux
8+
9+
env:
10+
- MYSQL_USER=root
11+
12+
before_install:
13+
- mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
14+
15+
install: true
16+
17+
script: script/cibuild
18+
19+
notifications:
20+
email: false

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# gh-ost
22

3+
[![build status](https://travis-ci.org/github/gh-ost.svg)](https://travis-ci.org/github/gh-ost) [![downloads](https://img.shields.io/github/downloads/github/gh-ost/total.svg)](https://github.com/github/gh-ost/releases) [![release](https://img.shields.io/github/release/github/gh-ost.svg)](https://github.com/github/gh-ost/releases)
4+
35
#### GitHub's online schema migration for MySQL <img src="doc/images/gh-ost-logo-light-160.png" align="right">
46

57
`gh-ost` is a triggerless online schema migration solution for MySQL. It is testable and provides pausability, dynamic control/reconfiguration, auditing, and many operational perks.
@@ -62,6 +64,7 @@ Also see:
6264
- [what if?](doc/what-if.md)
6365
- [the fine print](doc/the-fine-print.md)
6466
- [Community questions](https://github.com/github/gh-ost/issues?q=label%3Aquestion)
67+
- [Using `gh-ost` on AWS RDS](doc/rds.md)
6568

6669
## What's in a name?
6770

@@ -81,6 +84,8 @@ But then a rare genetic mutation happened, and the `c` transformed into `t`. And
8184

8285
We develop `gh-ost` at GitHub and for the community. We may have different priorities than others. From time to time we may suggest a contribution that is not on our immediate roadmap but which may appeal to others.
8386

87+
Please see [Coding gh-ost](https://github.com/github/gh-ost/blob/develdocs/doc/coding-ghost.md) for a guide to getting started developing with gh-ost.
88+
8489
## Download/binaries/source
8590

8691
`gh-ost` is now GA and stable.
@@ -89,7 +94,9 @@ We develop `gh-ost` at GitHub and for the community. We may have different prior
8994

9095
[Download latest release here](https://github.com/github/gh-ost/releases/latest)
9196

92-
`gh-ost` is a Go project; it is built with Go 1.5 with "experimental vendor". Soon to migrate to Go 1.6. See and use [build file](https://github.com/github/gh-ost/blob/master/build.sh) for compiling it on your own.
97+
`gh-ost` is a Go project; it is built with Go `1.8` (though `1.7` should work as well). To build on your own, use either:
98+
- [script/build](https://github.com/github/gh-ost/blob/master/script/build) - this is the same build script used by CI hence the authoritative; artifact is `./bin/gh-ost` binary.
99+
- [build.sh](https://github.com/github/gh-ost/blob/master/build.sh) for building `tar.gz` artifacts in `/tmp/gh-ost`
93100

94101
Generally speaking, `master` branch is stable, but only [releases](https://github.com/github/gh-ost/releases) are to be used in production.
95102

RELEASE_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.35
1+
1.0.36

doc/coding-ghost.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Getting started with gh-ost development.
2+
3+
## Overview
4+
5+
Getting started with gh-ost development is simple!
6+
7+
- First obtain the repository with `git clone` or `go get`.
8+
- From inside of the repository run `script/cibuild`
9+
- This will bootstrap the environment if needed, format the code, build the code, and then run the unit test.
10+
11+
## CI build workflow
12+
13+
`script/cibuild` performs the following actions will bootstrap the environment to build `gh-ost` correctly, build, perform syntax checks and run unit tests.
14+
15+
If additional steps are needed, please add them into this workflow so that the workflow remains simple.
16+
17+
## Notes:
18+
19+
Currently, `script/ensure-go-installed` will install `go` for Mac OS X and Linux. We welcome PR's to add other platforms.

doc/command-line-flags.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ See `approve-renamed-columns`
131131

132132
Issue the migration on a replica; do not modify data on master. Useful for validating, testing and benchmarking. See [testing-on-replica](testing-on-replica.md)
133133

134+
### throttle-control-replicas
135+
136+
Provide a command delimited list of replicas; `gh-ost` will throttle when any of the given replicas lag beyond `--max-lag-millis`. The list can be queried and updated dynamically via [interactive commands](interactive-commands.md)
137+
138+
### throttle-http
139+
140+
Provide a HTTP endpoint; `gh-ost` will issue `HEAD` requests on given URL and throttle whenever response status code is not `200`. The URL can be queried and updated dynamically via [interactive commands](interactive-commands.md). Empty URL disables the HTTP check.
141+
134142
### timestamp-old-table
135143

136144
Makes the _old_ table include a timestamp value. The _old_ table is what the original table is renamed to at the end of a successful migration. For example, if the table is `gh_ost_test`, then the _old_ table would normally be `_gh_ost_test_del`. With `--timestamp-old-table` it would be, for example, `_gh_ost_test_20170221103147_del`.

doc/interactive-commands.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Both interfaces may serve at the same time. Both respond to simple text command,
1717
- `help`: shows a brief list of available commands
1818
- `status`: returns a detailed status summary of migration progress and configuration
1919
- `sup`: returns a brief status summary of migration progress
20+
- `coordinates`: returns recent (though not exactly up to date) binary log coordinates of the inspected server
2021
- `chunk-size=<newsize>`: modify the `chunk-size`; applies on next running copy-iteration
2122
- `max-lag-millis=<max-lag>`: modify the maximum replication lag threshold (milliseconds, minimum value is `100`, i.e. `0.1` second)
2223
- `max-load=<max-load-thresholds>`: modify the `max-load` config; applies on next running copy-iteration
@@ -31,6 +32,7 @@ Both interfaces may serve at the same time. Both respond to simple text command,
3132
- `nice-ratio=0.5` will cause `gh-ost` to sleep for `50ms` immediately following.
3233
- `nice-ratio=1` will cause `gh-ost` to sleep for `100ms`, effectively doubling runtime
3334
- value of `2` will effectively triple the runtime; etc.
35+
- `throttle-http`: change throttle HTTP endpoint
3436
- `throttle-query`: change throttle query
3537
- `throttle-control-replicas='replica1,replica2'`: change list of throttle-control replicas, these are replicas `gh-ost` will check. This takes a comma separated list of replica's to check and replaces the previous list.
3638
- `throttle`: force migration suspend

doc/rds.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
`gh-ost` has been updated to work with Amazon RDS however due to GitHub not relying using AWS for databases, this documentation is community driven so if you find a bug please [open an issue][new_issue]!
2+
3+
# Amazon RDS
4+
5+
## Limitations
6+
7+
- No `SUPER` privileges.
8+
- `gh-ost` runs should be setup use [`--assume-rbr`][assume_rbr_docs] and use `binlog_format=ROW`.
9+
- Aurora does not allow editing of the `read_only` parameter. While it is defined as `{TrueIfReplica}`, the parameter is non-modifiable field.
10+
11+
## Aurora
12+
13+
#### Replication
14+
15+
In Aurora replication, you have separate reader and writer endpoints however because the cluster shares the underlying storage layer, `gh-ost` will detect it is running on the master. This becomes an issue when you wish to use [migrate/test on replica][migrate_test_on_replica_docs] because you won't be able to use a single cluster in the same way you would with MySQL RDS.
16+
17+
To work around this, you can follow along the [AWS replication between clusters documentation][aws_replication_docs] for Aurora with one small caveat. For the "Create a Snapshot of Your Replication Master" step, the binlog position is not available in the AWS console. You will need to issue the SQL query `SHOW SLAVE STATUS` or `aws rds describe-events` API call to get the correct position.
18+
19+
#### Percona Toolkit
20+
21+
If you use `pt-table-checksum` as a part of your data integrity checks, you might want to check out [this patch][percona_toolkit_patch] which will enable you to run `pt-table-checksum` with the `--no-binlog-format-check` flag and prevent errors like the following:
22+
23+
```
24+
03-24T12:51:06 Failed to /*!50108 SET @@binlog_format := 'STATEMENT'*/: DBD::mysql::db do failed: Access denied; you need (at least one of) the SUPER privilege(s) for this operation [for Statement "/*!50108 SET @@binlog_format := 'STATEMENT'*/"] at pt-table-checksum line 9292.
25+
26+
This tool requires binlog_format=STATEMENT, but the current binlog_format is set to ROW and an error occurred while attempting to change it. If running MySQL 5.1.29 or newer, setting binlog_format requires the SUPER privilege. You will need to manually set binlog_format to 'STATEMENT' before running this tool.
27+
```
28+
29+
#### Preflight checklist
30+
31+
Before trying to run any `gh-ost` migrations you will want to confirm the following:
32+
33+
- [ ] You have a secondary cluster available that will act as a replica. Rule of thumb here has been a 1 instance per cluster to mimic MySQL-style replication as opposed to Aurora style.
34+
- [ ] The database instance parameters and database cluster parameters are consistent between your master and replicas
35+
- [ ] Executing `SHOW SLAVE STATUS\G` on your replica cluster displays the correct master host, binlog position, etc.
36+
- [ ] Database backup retention is greater than 1 day to enable binlogs
37+
- [ ] You have setup [`hooks`][ghost_hooks] to issue RDS procedures for stopping and starting replication. (see [github/gh-ost#163][ghost_rds_issue_tracking] for examples)
38+
39+
[new_issue]: https://github.com/github/gh-ost/issues/new
40+
[assume_rbr_docs]: https://github.com/github/gh-ost/blob/master/doc/command-line-flags.md#assume-rbr
41+
[migrate_test_on_replica_docs]: https://github.com/github/gh-ost/blob/master/doc/cheatsheet.md#c-migratetest-on-replica
42+
[aws_replication_docs]: http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Aurora.Overview.Replication.MySQLReplication.html
43+
[percona_toolkit_patch]: https://github.com/jacobbednarz/percona-toolkit/commit/0271ba6a094da446a5e5bb8d99b5c26f1777f2b9
44+
[ghost_hooks]: https://github.com/github/gh-ost/blob/master/doc/hooks.md
45+
[ghost_rds_issue_tracking]: https://github.com/github/gh-ost/issues/163

doc/requirements-and-limitations.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ The `SUPER` privilege is required for `STOP SLAVE`, `START SLAVE` operations. Th
4040
- It is not allowed to migrate a table where another table exists with same name and different upper/lower case.
4141
- For example, you may not migrate `MyTable` if another table called `MYtable` exists in the same schema.
4242

43-
- Amazon RDS and Google Cloud SQL are currently not supported
44-
- We began working towards removing this limitation. See tracking issue: https://github.com/github/gh-ost/issues/163
43+
- Amazon RDS works, but has it's own [limitations](rds.md).
44+
- Google Cloud SQL is currently not supported
4545

4646
- Multisource is not supported when migrating via replica. It _should_ work (but never tested) when connecting directly to master (`--allow-on-master`)
4747

go/base/context.go

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ const (
4040
type ThrottleReasonHint string
4141

4242
const (
43-
NoThrottleReasonHint ThrottleReasonHint = "NoThrottleReasonHint"
44-
UserCommandThrottleReasonHint = "UserCommandThrottleReasonHint"
43+
NoThrottleReasonHint ThrottleReasonHint = "NoThrottleReasonHint"
44+
UserCommandThrottleReasonHint = "UserCommandThrottleReasonHint"
45+
LeavingHibernationThrottleReasonHint = "LeavingHibernationThrottleReasonHint"
46+
)
47+
48+
const (
49+
HTTPStatusOK = 200
4550
)
4651

4752
var (
@@ -99,10 +104,13 @@ type MigrationContext struct {
99104
ThrottleFlagFile string
100105
ThrottleAdditionalFlagFile string
101106
throttleQuery string
107+
throttleHTTP string
102108
ThrottleCommandedByUser int64
109+
HibernateUntil int64
103110
maxLoad LoadMap
104111
criticalLoad LoadMap
105112
CriticalLoadIntervalMilliseconds int64
113+
CriticalLoadHibernateSeconds int64
106114
PostponeCutOverFlagFile string
107115
CutOverLockTimeoutSeconds int64
108116
ForceNamedCutOverCommand bool
@@ -148,6 +156,7 @@ type MigrationContext struct {
148156
pointOfInterestTime time.Time
149157
pointOfInterestTimeMutex *sync.Mutex
150158
CurrentLag int64
159+
ThrottleHTTPStatusCode int64
151160
controlReplicasLagResult mysql.ReplicationLagResult
152161
TotalRowsCopied int64
153162
TotalDMLEventsApplied int64
@@ -157,6 +166,7 @@ type MigrationContext struct {
157166
throttleReasonHint ThrottleReasonHint
158167
throttleGeneralCheckResult ThrottleCheckResult
159168
throttleMutex *sync.Mutex
169+
throttleHTTPMutex *sync.Mutex
160170
IsPostponingCutOver int64
161171
CountingRowsFlag int64
162172
AllEventsUpToLockProcessedInjectedFlag int64
@@ -174,13 +184,16 @@ type MigrationContext struct {
174184
UniqueKey *sql.UniqueKey
175185
SharedColumns *sql.ColumnList
176186
ColumnRenameMap map[string]string
187+
DroppedColumnsMap map[string]bool
177188
MappedSharedColumns *sql.ColumnList
178189
MigrationRangeMinValues *sql.ColumnValues
179190
MigrationRangeMaxValues *sql.ColumnValues
180191
Iteration int64
181192
MigrationIterationRangeMinValues *sql.ColumnValues
182193
MigrationIterationRangeMaxValues *sql.ColumnValues
183194

195+
recentBinlogCoordinates mysql.BinlogCoordinates
196+
184197
CanStopStreaming func() bool
185198
}
186199

@@ -215,6 +228,7 @@ func newMigrationContext() *MigrationContext {
215228
maxLoad: NewLoadMap(),
216229
criticalLoad: NewLoadMap(),
217230
throttleMutex: &sync.Mutex{},
231+
throttleHTTPMutex: &sync.Mutex{},
218232
throttleControlReplicaKeys: mysql.NewInstanceKeyMap(),
219233
configMutex: &sync.Mutex{},
220234
pointOfInterestTimeMutex: &sync.Mutex{},
@@ -472,12 +486,10 @@ func (this *MigrationContext) IsThrottled() (bool, string, ThrottleReasonHint) {
472486
}
473487

474488
func (this *MigrationContext) GetThrottleQuery() string {
475-
var query string
476-
477489
this.throttleMutex.Lock()
478490
defer this.throttleMutex.Unlock()
479491

480-
query = this.throttleQuery
492+
var query = this.throttleQuery
481493
return query
482494
}
483495

@@ -488,6 +500,21 @@ func (this *MigrationContext) SetThrottleQuery(newQuery string) {
488500
this.throttleQuery = newQuery
489501
}
490502

503+
func (this *MigrationContext) GetThrottleHTTP() string {
504+
this.throttleHTTPMutex.Lock()
505+
defer this.throttleHTTPMutex.Unlock()
506+
507+
var throttleHTTP = this.throttleHTTP
508+
return throttleHTTP
509+
}
510+
511+
func (this *MigrationContext) SetThrottleHTTP(throttleHTTP string) {
512+
this.throttleHTTPMutex.Lock()
513+
defer this.throttleHTTPMutex.Unlock()
514+
515+
this.throttleHTTP = throttleHTTP
516+
}
517+
491518
func (this *MigrationContext) GetMaxLoad() LoadMap {
492519
this.throttleMutex.Lock()
493520
defer this.throttleMutex.Unlock()
@@ -522,6 +549,19 @@ func (this *MigrationContext) SetNiceRatio(newRatio float64) {
522549
this.niceRatio = newRatio
523550
}
524551

552+
func (this *MigrationContext) GetRecentBinlogCoordinates() mysql.BinlogCoordinates {
553+
this.throttleMutex.Lock()
554+
defer this.throttleMutex.Unlock()
555+
556+
return this.recentBinlogCoordinates
557+
}
558+
559+
func (this *MigrationContext) SetRecentBinlogCoordinates(coordinates mysql.BinlogCoordinates) {
560+
this.throttleMutex.Lock()
561+
defer this.throttleMutex.Unlock()
562+
this.recentBinlogCoordinates = coordinates
563+
}
564+
525565
// ReadMaxLoad parses the `--max-load` flag, which is in multiple key-value format,
526566
// such as: 'Threads_running=100,Threads_connected=500'
527567
// It only applies changes in case there's no parsing error.

0 commit comments

Comments
 (0)