Skip to content

Instantly share code, notes, and snippets.

@eedeep
Last active December 17, 2015 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eedeep/5565631 to your computer and use it in GitHub Desktop.
Save eedeep/5565631 to your computer and use it in GitHub Desktop.

mysqldumped --forever

Perhaps you've read some of the much tweeted [PHP hate] (http://www.codinghorror.com/blog/2012/06/the-php-singularity.html) from recent years. I used to write PHP and it is true that it works, you can get things done. The same goes for MySQL - it works and you can definitely use it to build and run successful applications. Facebook uses it. But the ["fractal of bad design"] (http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/) assessment of PHP could equally be applied to MySQL. Just take a look at [this screencast] (http://www.youtube.com/watch?v=1PoFIohBSM4) for a whole bunch of concrete examples. Don't get me wrong, over the years MySQL and I have had our fair share of late nights partying together till dawn, our intimate mornings nestled amongst the features of the INFORMATION_SCHEMA, timeless moments on that shitty official MySQL forum site (yes you know the one) but I'm afraid the time has come to truncate my losses and move on. You could say I've mysqldumped my old friend forever. Now, [WHO'S COMIN WITH ME?!] (http://www.youtube.com/watch?v=r7ObPFtGijw)

But where are we going I hear you ask? Well, if you're currently a still running MySQL why not give Postgres a go, especially if you're starting a new project. Why not even use it on existing projects that are running on MySQL? Maybe because you have existing MySQL databases full of important data and tables that you'd need to convert over to Postgres? Fear not, conversion of your existing MySQL databases (schema and data) to Postgres is relatively easy. That said, none of the methods and/or tools which I found via The Google - and I tried a few including SQLFairy and mysql-postgresql-converter - actually worked. Note that [py-mysql2postgres] (https://pypi.python.org/pypi/py-mysql2pgsql) - preferable for me since written in python - may well work but I could not induce success with it. With all of these I either ran into unexpected exceptions or ran out of memory (I was trying to convert a reasonably sized 500Mb+ database). With a minor struggle or two I did get there in the end though, so I thought I'd share how.

Big thanks to [maxlapshin] (https://github.com/maxlapshin/), who wrote [mysql2postgres] (https://github.com/maxlapshin/mysql2postgres) which more or less worked apart from a small patch I wrote to ensure index names don't exceed the 63 character limit for Postgres schema object names.

This is all based on running Ubuntu 12.04, it might be different on different releases of Ubuntu or different platforms. I'd love to hear from you if you try it under different conditions (eg, Mac OSX or even Windows). Anyway, here's what worked for me:

  1. Install ruby bundler gem:

     sudo apt-get install rubygems bundler
    
  2. Then upgrade your ruby environment to version 1.9 as the mysql2postgres gem requires it. To do that you can follow the steps here: http://lenni.info/blog/2012/05/installing-ruby-1-9-3-on-ubuntu-12-04-precise-pengolin/

  3. And uninstall old ruby stuff by following these steps: http://lenni.info/blog/2011/12/installing-ruby-1-9-2-on-ubuntu-11-10-oneric-ocelot-without-using-rvm/#uninstall

  4. Install postgres and the pg ruby gem:

     sudo apt-get install postgresql-9.1 postgresql-server-dev-9.1
     sudo gem install pg
    
  5. Install the mysql2postgres gem but do it from github source to get my patch for dealing with illegally long index names (pull request to maxshalpin in the works):

     cd  /var/lib/gems/1.9.1
     git clone git@github.com:eedeep/mysql2postgres.git
     gem build mysql-to-postgres.gemspec
     gem install mysql-to-postgres-0.2.12.gem
    
  6. Stick the config file for mysql2postgres here for now...it would be nice if the location of this config file were configurable

     sudo mkdir /var/lib/gems/1.9.1/mysql-to-postgres-0.2.12/config
     sudo vi /var/lib/gems/1.9.1/mysql-to-postgres-0.2.12/config/database.yml
    
  7. Populate the config file. Note that this assumes you've got two databases both named myamazingapp, one in MySQL and one in Postgres. Also users with passwords, which are again, all myamazingapp. The Postgres database should be empty, the MySQL database should be full. If you don't know how to create your Postgres database and user have a read of [this] (http://stackoverflow.com/questions/12890018/how-to-get-started-with-postgressql-similar-to-mysql) and then the official Postgres docs, which are good. Then put this in the database.yml file from step 6:

     mysql2psql:
         mysql:
             hostname: localhost
             port: 3306
             username: myamazingdb
             password: myamazingdb
             database: myamazingdb
         destination:
             development:
                 adapter: jdbcpostgresql
                 encoding: unicode
                 pool: 4
                 username: myamazingdb
                 password: myamazingdb
                 hostname: 127.0.0.1
                 port: 5432
                 socket: ""
    
         tables:
    
         # if suppress_data is true, only the schema definition will be exported/migrated, and not the data
         suppress_data: false
    
         # if suppress_ddl is true, only the data will be exported/imported, and not the schema
         suppress_ddl: false
    
         # if force_truncate is true, forces a table truncate before table loading
         force_truncate: false
    
         preserve_order: false
    
         remove_dump_file: false
    
         report_status:  json    # false, json, xml
    
  8. Run the mysql2postgres command (actually named mysql-to-postgres, just to confuse you). The dump file should remain on your file system so you can open it up and have a look at how all your schema objects and data will get created afresh in your Postgres database. Do it like:

     cd /var/lib/gems/1.9.1/gems/mysql-to-postgres-0.2.12
     sudo mysql-to-postgres
    
  9. I don't really know why but you are likely to encounter an error during the Postgres import phase of the above command. If you look inside your Postgres database at this stage with \d though, you should see that at this point it is still completely empty. So ignore the error and import the dump file to your empty Postgres database directly like so (your dump file will be similarly named but not identical):

     psql -U myamazingdb -W myamazingdb myamazingdb -f 20130514154231+1000_output.sql
    
  10. Verify it worked. You should, at the end of that (fingers crossed) have a functioning Postgres database so that you're on step closer to being able dump MySQL forever. To connect to your newly populated Postgres database try:

    psql -Umyamazingdb -Wmyamazingdb myamazingdb
    # NB: Will show results from select statement etc here to compare and contrast
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment