-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"pq: transaction error" when pointing migrate to redshift #90
Comments
What happens when you run your migration SQL statement manually using lib/pq? |
thanks @dhui, I am able to execute that query via lib/pq directly within a transaction with same redshift connection info db, err := sql.Open("postgres", ds.DataSourceName())
if err != nil {
panic(fmt.Sprintf("open %v", err))
}
defer db.Close()
fmt.Println("# creating table in tx")
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
panic(fmt.Sprintf("transaction %v", err))
}
if _, err = tx.Exec("update schema_migrations set dirty = true where version = 1"); err != nil {
panic(fmt.Sprintf("insert %v", err))
}
if _, err = tx.Exec("create table cities( cityid integer not null, city varchar(100) not null, state char(2) not null)"); err != nil {
panic(fmt.Sprintf("create %v", err))
}
if _, err = tx.Exec("update schema_migrations set dirty = false where version = 1"); err != nil {
panic(fmt.Sprintf("insert %v", err))
}
if err = tx.Commit(); err != nil {
panic(fmt.Sprintf("commit %v", err))
} |
@dhui I tried running migrate cli again on an empty schema_migrations table and no other tables. It fails with the 'unexpected transaction status idle' error but there is a value in schema_migrations with version and dirty = true. Only that value is committed. The error might be coming from here (based on simple grep on error message in lib/pq). it seems like redshift might be thinking transaction is in bad state as trying the same migration on postgres 9.5 works ok. Only semi-related issue on pq is this one If you can point me to where in go-migrate the migration is applied and where/how transactions are managed, I can try to connect dots |
See the Run() receiver function in the postgres db driver. The redshift db driver uses the postgres DB driver. To see how the DB driver is used, see the runMigrations() receiver function. When the I don't know the extent to which lib/pq supports redshift and how much of the Postgres network protocol Redshift supports.
|
thanks @dhui, those pointers help me reproduce the error in my script. the SetVersion method on postgres driver first truncates schema_migrations table. I added a truncate in my list of commands and was able to get the same transaction status idle error message sequence of sqls executed are now tx, err := db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
panic(fmt.Sprintf("transaction %v", err))
}
if _, err = tx.Exec("truncate schema_migrations"); err != nil {
panic(fmt.Sprintf("truncate %v", err))
}
if _, err = tx.Exec("update schema_migrations set dirty = true where version = 1"); err != nil {
panic(fmt.Sprintf("insert %v", err))
}
if _, err = tx.Exec("create table cities( cityid integer not null, city varchar(100) not null, state char(2) not null)"); err != nil {
panic(fmt.Sprintf("create %v", err))
}
if _, err = tx.Exec("update schema_migrations set dirty = false where version = 1"); err != nil {
panic(fmt.Sprintf("insert %v", err))
}
if err = tx.Commit(); err != nil {
panic(fmt.Sprintf("commit %v", err))
} Problem - Redshift's Truncate commits the transaction in which it is run, so the next commit call errors out from pq. This is different from Postgres where Truncate is transaction safe. Few notes/question,
|
Good find @sumits !
Feel free to open a PR fixing the redshift driver to use |
sounds good @dhui, will make the change and try out in couple of days |
@dhui - finally got to this one and started with implementing Redshift's own SetVersion() that would do a Before going too far with those changes, wanted to discuss the other option of using |
Thanks for taking the time to fix this issue. The I'm all for using It looks like redshift forked from postgres 8 and had diverged due to different goals, so it makes sense to maintain a separate redshift db driver for migrate. e.g. re-write the redshift db driver to not depend on the postgres db driver. If the redesigned DB driver supports composability, then we can refactor the redshift driver to use some shared logic/functionality of the postgres driver. A similar albeit different example is CockroachDB, which uses the postgres wire protocol but has a different query language, hence a different and independent db driver. |
@dhui, I agree that keeping Redshift separate is the cleanest as redshift is not keeping up with all postgres developments and doesn't make sense to call them same. I will take a look at the cockroach driver and see what writing a new driver takes. I also saw guidelines somewhere in this repo while browsing, so that should help too |
See the comments in database/driver.go for info about implementing a db driver. For starters, I'd:
|
TRUNCATE commits the current transaction, which breaks the expection of the 'Commit()' that follows. See: golang-migrate#90 https://docs.aws.amazon.com/redshift/latest/dg/r_TRUNCATE.html
This addresses golang-migrate#90 . The exported Redshift object no longer exports an embedde 'Driver' however, so some more work is needed to make this backwards compatible.
TRUNCATE commits the current transaction, which breaks the expection of the 'Commit()' that follows. See: golang-migrate/migrate#90 https://docs.aws.amazon.com/redshift/latest/dg/r_TRUNCATE.html
This addresses golang-migrate/migrate#90 . The exported Redshift object no longer exports an embedde 'Driver' however, so some more work is needed to make this backwards compatible.
Thanks for all the work for this migration tool, we are really hoping to add to our tools chest. I am trying to us migrate with redshift database and getting a strange error "pq: unexpected transaction status idle" when trying to run the simplest migration. I have tried running the SQL in my migrations file directly on redshift and that works fine. I have also tried pointing go-migrate to postgres database and that works well too. any pointers to make progress on this issue are greatly appreciated.
DROP TABLE cities
)CREATE TABLE cities( cityid integer not null, city varchar(100) not null, state char(2) not null)
)please let me know if any more info is needed
The text was updated successfully, but these errors were encountered: