Support Azure Database for MySQL.
This commit is contained in:
parent
ea339b6023
commit
ae762694fb
@ -65,6 +65,7 @@ Also see:
|
|||||||
- [the fine print](doc/the-fine-print.md)
|
- [the fine print](doc/the-fine-print.md)
|
||||||
- [Community questions](https://github.com/github/gh-ost/issues?q=label%3Aquestion)
|
- [Community questions](https://github.com/github/gh-ost/issues?q=label%3Aquestion)
|
||||||
- [Using `gh-ost` on AWS RDS](doc/rds.md)
|
- [Using `gh-ost` on AWS RDS](doc/rds.md)
|
||||||
|
- [Using `gh-ost` on Azure Database for MySQL](doc/azure.md)
|
||||||
|
|
||||||
## What's in a name?
|
## What's in a name?
|
||||||
|
|
||||||
|
26
doc/azure.md
Normal file
26
doc/azure.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
`gh-ost` has been updated to work with Azure Database for MySQL however due to GitHub does not use it, this documentation is community driven so if you find a bug please [open an issue][new_issue]!
|
||||||
|
|
||||||
|
# Azure Database for MySQL
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- `gh-ost` runs should be setup use [`--assume-rbr`][assume_rbr_docs] and use `binlog_row_image=FULL`.
|
||||||
|
- Azure Database for MySQL does not use same user name suffix for master and replica, so master host, user and password need to be pointed out.
|
||||||
|
|
||||||
|
## Step
|
||||||
|
1. Change the replica server's `binlog_row_image` from `MINIMAL` to `FULL`. See [guide](https://docs.microsoft.com/en-us/azure/mysql/howto-server-parameters) on Azure document.
|
||||||
|
2. Use your `gh-ost` always with additional 5 parameter
|
||||||
|
```{bash}
|
||||||
|
gh-ost \
|
||||||
|
--azure \
|
||||||
|
--assume-master-host=master-server-dns-name \
|
||||||
|
--master-user="master-user-name" \
|
||||||
|
--master-password="master-password" \
|
||||||
|
--assume-rbr \
|
||||||
|
[-- other paramters you need]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
[new_issue]: https://github.com/github/gh-ost/issues/new
|
||||||
|
[assume_rbr_docs]: https://github.com/github/gh-ost/blob/master/doc/command-line-flags.md#assume-rbr
|
||||||
|
[migrate_test_on_replica_docs]: https://github.com/github/gh-ost/blob/master/doc/cheatsheet.md#c-migratetest-on-replica
|
@ -6,6 +6,10 @@ A more in-depth discussion of various `gh-ost` command line flags: implementatio
|
|||||||
|
|
||||||
Add this flag when executing on Aliyun RDS.
|
Add this flag when executing on Aliyun RDS.
|
||||||
|
|
||||||
|
### azure
|
||||||
|
|
||||||
|
Add this flag when executing on Azure Database for MySQL.
|
||||||
|
|
||||||
### allow-master-master
|
### allow-master-master
|
||||||
|
|
||||||
See [`--assume-master-host`](#assume-master-host).
|
See [`--assume-master-host`](#assume-master-host).
|
||||||
|
@ -41,6 +41,7 @@ The `SUPER` privilege is required for `STOP SLAVE`, `START SLAVE` operations. Th
|
|||||||
- Amazon RDS works, but has its own [limitations](rds.md).
|
- Amazon RDS works, but has its own [limitations](rds.md).
|
||||||
- Google Cloud SQL works, `--gcp` flag required.
|
- Google Cloud SQL works, `--gcp` flag required.
|
||||||
- Aliyun RDS works, `--aliyun-rds` flag required.
|
- Aliyun RDS works, `--aliyun-rds` flag required.
|
||||||
|
- Azure Database for MySQL works, `--azure` flag required, and have detailed document about it. (azure.md)
|
||||||
|
|
||||||
- Multisource is not supported when migrating via replica. It _should_ work (but never tested) when connecting directly to master (`--allow-on-master`)
|
- Multisource is not supported when migrating via replica. It _should_ work (but never tested) when connecting directly to master (`--allow-on-master`)
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ type MigrationContext struct {
|
|||||||
DiscardForeignKeys bool
|
DiscardForeignKeys bool
|
||||||
AliyunRDS bool
|
AliyunRDS bool
|
||||||
GoogleCloudPlatform bool
|
GoogleCloudPlatform bool
|
||||||
|
AzureMySQL bool
|
||||||
|
|
||||||
config ContextConfig
|
config ContextConfig
|
||||||
configMutex *sync.Mutex
|
configMutex *sync.Mutex
|
||||||
|
@ -76,7 +76,8 @@ func ValidateConnection(db *gosql.DB, connectionConfig *mysql.ConnectionConfig,
|
|||||||
}
|
}
|
||||||
// AliyunRDS set users port to "NULL", replace it by gh-ost param
|
// AliyunRDS set users port to "NULL", replace it by gh-ost param
|
||||||
// GCP set users port to "NULL", replace it by gh-ost param
|
// GCP set users port to "NULL", replace it by gh-ost param
|
||||||
if migrationContext.AliyunRDS || migrationContext.GoogleCloudPlatform {
|
// Azure MySQL set users port to a different value by design, replace it by gh-ost para
|
||||||
|
if migrationContext.AliyunRDS || migrationContext.GoogleCloudPlatform || migrationContext.AzureMySQL {
|
||||||
port = connectionConfig.Key.Port
|
port = connectionConfig.Key.Port
|
||||||
} else {
|
} else {
|
||||||
portQuery := `select @@global.port`
|
portQuery := `select @@global.port`
|
||||||
|
@ -77,6 +77,7 @@ func main() {
|
|||||||
flag.BoolVar(&migrationContext.SkipStrictMode, "skip-strict-mode", false, "explicitly tell gh-ost binlog applier not to enforce strict sql mode")
|
flag.BoolVar(&migrationContext.SkipStrictMode, "skip-strict-mode", false, "explicitly tell gh-ost binlog applier not to enforce strict sql mode")
|
||||||
flag.BoolVar(&migrationContext.AliyunRDS, "aliyun-rds", false, "set to 'true' when you execute on Aliyun RDS.")
|
flag.BoolVar(&migrationContext.AliyunRDS, "aliyun-rds", false, "set to 'true' when you execute on Aliyun RDS.")
|
||||||
flag.BoolVar(&migrationContext.GoogleCloudPlatform, "gcp", false, "set to 'true' when you execute on a 1st generation Google Cloud Platform (GCP).")
|
flag.BoolVar(&migrationContext.GoogleCloudPlatform, "gcp", false, "set to 'true' when you execute on a 1st generation Google Cloud Platform (GCP).")
|
||||||
|
flag.BoolVar(&migrationContext.AzureMySQL, "azure", false, "set to 'true' when you execute on Azure Database on MySQL.")
|
||||||
|
|
||||||
executeFlag := flag.Bool("execute", false, "actually execute the alter & migrate the table. Default is noop: do some tests and exit")
|
executeFlag := flag.Bool("execute", false, "actually execute the alter & migrate the table. Default is noop: do some tests and exit")
|
||||||
flag.BoolVar(&migrationContext.TestOnReplica, "test-on-replica", false, "Have the migration run on a replica, not on the master. At the end of migration replication is stopped, and tables are swapped and immediately swap-revert. Replication remains stopped and you can compare the two tables for building trust")
|
flag.BoolVar(&migrationContext.TestOnReplica, "test-on-replica", false, "Have the migration run on a replica, not on the master. At the end of migration replication is stopped, and tables are swapped and immediately swap-revert. Replication remains stopped and you can compare the two tables for building trust")
|
||||||
|
@ -89,7 +89,7 @@ func (this *Applier) InitDBConnections() (err error) {
|
|||||||
if err := this.validateAndReadTimeZone(); err != nil {
|
if err := this.validateAndReadTimeZone(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !this.migrationContext.AliyunRDS && !this.migrationContext.GoogleCloudPlatform {
|
if !this.migrationContext.AliyunRDS && !this.migrationContext.GoogleCloudPlatform && !this.migrationContext.AzureMySQL {
|
||||||
if impliedKey, err := mysql.GetInstanceKey(this.db); err != nil {
|
if impliedKey, err := mysql.GetInstanceKey(this.db); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,7 +53,7 @@ func (this *Inspector) InitDBConnections() (err error) {
|
|||||||
if err := this.validateConnection(); err != nil {
|
if err := this.validateConnection(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !this.migrationContext.AliyunRDS && !this.migrationContext.GoogleCloudPlatform {
|
if !this.migrationContext.AliyunRDS && !this.migrationContext.GoogleCloudPlatform && !this.migrationContext.AzureMySQL {
|
||||||
if impliedKey, err := mysql.GetInstanceKey(this.db); err != nil {
|
if impliedKey, err := mysql.GetInstanceKey(this.db); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,5 +116,5 @@ func (this *ConnectionConfig) GetDBUri(databaseName string) string {
|
|||||||
if this.tlsConfig != nil {
|
if this.tlsConfig != nil {
|
||||||
tlsOption = TLS_CONFIG_KEY
|
tlsOption = TLS_CONFIG_KEY
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?interpolateParams=%t&autocommit=true&charset=utf8mb4,utf8,latin1&tls=%s", this.User, this.Password, hostname, this.Key.Port, databaseName, interpolateParams, tlsOption)
|
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?interpolateParams=%t&autocommit=true&charset=utf8mb4,utf8,latin1&tls=%s&allowNativePasswords=true", this.User, this.Password, hostname, this.Key.Port, databaseName, interpolateParams, tlsOption)
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ func TestGetDBUri(t *testing.T) {
|
|||||||
c.Password = "penguin"
|
c.Password = "penguin"
|
||||||
|
|
||||||
uri := c.GetDBUri("test")
|
uri := c.GetDBUri("test")
|
||||||
test.S(t).ExpectEquals(uri, "gromit:penguin@tcp(myhost:3306)/test?interpolateParams=true&autocommit=true&charset=utf8mb4,utf8,latin1&tls=false")
|
test.S(t).ExpectEquals(uri, "gromit:penguin@tcp(myhost:3306)/test?interpolateParams=true&autocommit=true&charset=utf8mb4,utf8,latin1&tls=false&allowNativePasswords=true")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetDBUriWithTLSSetup(t *testing.T) {
|
func TestGetDBUriWithTLSSetup(t *testing.T) {
|
||||||
@ -80,5 +80,5 @@ func TestGetDBUriWithTLSSetup(t *testing.T) {
|
|||||||
c.tlsConfig = &tls.Config{}
|
c.tlsConfig = &tls.Config{}
|
||||||
|
|
||||||
uri := c.GetDBUri("test")
|
uri := c.GetDBUri("test")
|
||||||
test.S(t).ExpectEquals(uri, "gromit:penguin@tcp(myhost:3306)/test?interpolateParams=true&autocommit=true&charset=utf8mb4,utf8,latin1&tls=ghost")
|
test.S(t).ExpectEquals(uri, "gromit:penguin@tcp(myhost:3306)/test?interpolateParams=true&autocommit=true&charset=utf8mb4,utf8,latin1&tls=ghost&allowNativePasswords=true")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user