{"id":26484,"date":"2015-10-12T08:30:48","date_gmt":"2015-10-12T03:00:48","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=26484"},"modified":"2016-01-19T13:29:53","modified_gmt":"2016-01-19T07:59:53","slug":"postgresql-on-linux-migration-to-aws-postgresql-rds-using-londiste-daemon-no-downtime","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/postgresql-on-linux-migration-to-aws-postgresql-rds-using-londiste-daemon-no-downtime\/","title":{"rendered":"Migrate PostgreSQL on Linux server to AWS PostgreSQL RDS using Londiste (Skytools 2)"},"content":{"rendered":"<p>PostgreSQL is another SQL. It is the second most popular Structured Query Language after MySQL. The steps discussed in the blog can be used for any kind of migration of PostgreSQL. From on-premise to cloud or on-premise to on-premise or cloud to on-premise.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-27930 aligncenter\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/09\/postgresql-logo.png\" alt=\"postgresql-logo\" width=\"610\" height=\"280\" \/><\/p>\n<h3><\/h3>\n<h3><span style=\"color: #800000\">Use-case<\/span><\/h3>\n<p>I had to migrate my PostgreSQL running on an EC2 server to RDS PostgreSQL for production environment with NO to minimal downtime &amp; NO data loss which occurs when we usually make a dump, restore it and change the DB host. I read about Londiste &#8211; A tool that makes that happen easily. So, you can follow these steps to migrate running\u00a0PostgreSQL. in any environment. The thing to remember here is you don&#8217;t get a bash shell for AWS RDS. We\u00a0will achieve this by connecting the production PosgreSQL to the AWS RDS PostgreSQL which is production live and then starting the replication. Once the production DB is in sync with AWS RDS DB we make the DB host change in our application.<\/p>\n<h3><span style=\"color: #993300\">Prerequisites<\/span><\/h3>\n<p>All steps are basically for Ubuntu but just with minimal changes it will work on any other OS. The postgreSQL version is 9.1 in my case. The packages you would need to download are:<\/p>\n<ol>\n<li><strong>skytools<\/strong> &#8211; skytools-2.1.12.tar.gz &#8212; http:\/\/pgfoundry.org\/frs\/download.php\/2872\/skytools-2.1.12.tar.gz<\/li>\n<li><strong>psgcpy<\/strong> &#8211;\u00a0https:\/\/pypi.python.org\/packages\/source\/p\/psycopg2\/psycopg2-2.6.1.tar.gz<\/li>\n<li>You can get the latest packages from\u00a0pgfoundry.org<\/li>\n<\/ol>\n<h3><span style=\"color: #993300\">STEPS<\/span><\/h3>\n<h4><span style=\"color: #993300\">1. Install Skytools\u00a0by running the following commands:<\/span><\/h4>\n<p>[js]tar -xvf skytools-2.1.12.tar.gz<\/p>\n<p>cd \/usr\/local\/src\/skytools-2.1.12<\/p>\n<p>.\/configure &#8211;prefix=\/opt\/skytools-2.1.12 &#8211;with\u00a0pgconfig=\/usr\/lib\/postgresql\/9.1\/bin\/pg_config<\/p>\n<p>(\/usr\/lib\/postgresql\/9.1\/bin\/pg_config is the directory of postgreSQL config file and you can\u00a0locate the file by using\u00a0&lt;strong&gt;locate&lt;\/strong&gt; bash command)<\/p>\n<p>make<\/p>\n<p>make install [\/js]<\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #993300\">2. Install psycopg2 by running the following commands:<\/span><\/h4>\n<p>[js]tar -xvf psycopg2-2.4.2.tar.gz<\/p>\n<p>cd psycopg2-2.4.2<\/p>\n<p>python setup.py install &#8211;prefix=\/usr\/local<\/p>\n<p>python setup.py build_ext &#8211;pg-config \/usr\/lib\/postgresql\/9.1\/bin\/pg_config[\/js]<\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #993300\">3. Now, change file permissions<\/span>:<\/h4>\n<p>Give the <strong>postgres<\/strong> user (the user which automatically gets created when you install postgreSQL)<\/p>\n<p>[js]chown -R postgres:postgres \/opt\/skytools-2.1.12<\/p>\n<p>chown -R postgres:postgres \/usr\/lib\/postgresql\/9.1\/ [\/js]<\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #993300\">4. Set paths:<\/span><\/h4>\n<p>Set the LD_LIBRARY_PATH &amp; PYTHONPATH and start the two newly created clusters.<\/p>\n<p>[js]export PYTHONPATH=\/opt\/skytools-2.1.12\/lib\/python2.6\/site-packages\/<\/p>\n<p>export LD_LIBRARY_PATH=\/usr\/lib\/postgresql\/9.1\/lib\/:\/usr\/lib:\/opt\/perlbrew\/perls\/perl-<br \/>\n5.14.2\/lib\/5.14.2\/x86_64-linux-gnu\/CORE: [\/js]<\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #993300\">5. Edit the londiste.ini &amp; pgqadm.ini\u00a0Files in the below directory cd \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf&#8221;<\/span><\/h4>\n<p>Londiste provides us with some default docs and files. So, for ease of use we will edit the example file itself and use it. Londiste.ini should look something like below:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27905\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/09\/Screenshot-from-2015-10-09-194811.png\" alt=\"Screenshot from 2015-10-09 19:48:11\" width=\"957\" height=\"369\" \/>In <strong>provider<\/strong>(source) line: Enter <strong>provider_db<\/strong> details:<br \/>\n<strong>dbname<\/strong>=<br \/>\n<strong>port<\/strong>=5432 (For PostgreSQL)<br \/>\n<strong>host<\/strong>= (hostname of EC2 PostgreSQL server)<br \/>\nI have not entered the username and password for this DB server since the credentials are in the PostgreSQL conf file.<\/p>\n<p>In <strong>subscriber<\/strong>(destination) line: Enter same set of details for <strong>subscriber_db.<br \/>\n<\/strong>Then enter log file locations of your choice. Make sure postgres user has access to the directory.<\/p>\n<p>Now, lets edit pgqadm.ini in the same directory:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27907\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/09\/Screenshot-from-2015-10-09-194958.png\" alt=\"Screenshot from 2015-10-09 19:49:58\" width=\"747\" height=\"309\" \/><br \/>\nIn this, enter details of<strong> source DB<\/strong>. I have kept the <strong>maint_delay_min<\/strong> to 5 minutes. <strong>Loop_delay<\/strong> should be least. It checks what has changed in the master in that interval of time and replicates onto the RDS Instance. \u00a0You can reduce it.<\/p>\n<p>One log &amp; pid file will be in \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf<br \/>\nfor Londiste.ini &amp; the other set in \/var\/lib\/postgresql\/ \/log &amp; \/pid folders. I\u00a0Have kept 2 sets of log &amp; pid files different data in both.<\/p>\n<h4><span style=\"color: #993300\">6. Now, install the ini file and for that cd into \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/ directory<\/span><\/h4>\n<p>Also, just before that go to \/opt\/skytools-2.1.12\/lib\/python2.6\/site-packages\/skytools and increase the timeout in the file <strong>psycopgwrapper.py\u00a0<\/strong>so that connection does not break if the host machine&#8217;s DB takes time to reply.<\/p>\n<p>Install londiste.ini and install provider DB &amp; subscriber DB( go to \/opt\/skytools-2.1.12\/bin\/)<br \/>\nWe need londiste.ini file to validate the provider DB &amp; the suscriber DB i.e. the destination DB, whether it is accessible or not.<\/p>\n<p>[js]londiste.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/londiste.ini provider install<\/p>\n<p>londiste.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/londiste.ini subscriber install[\/js]<\/p>\n<h5>Note: Error may occur if the current server you are working on has no access to the provider DB host or\u00a0subscriber host. So, first ensure connectivity using telnet from the server on host and port.<\/h5>\n<p><strong>pgqadm.ini install and enable ticker:<\/strong><\/p>\n<p>[js]pgqadm.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/pgqadm.ini install<br \/>\npgqadm.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/pgqadm.ini ticker -d<br \/>\nlondiste.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/londiste.ini replay -d<br \/>\npgqadm.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/pgqadm.ini status[\/js]<\/p>\n<h5>Note: &#8220;-d&#8221; option is to run the londiste\/PgQ daemons in background.<br \/>\nStatus can be checked using the last command the status one.<\/h5>\n<p>The daemon can be <strong>stopped<\/strong> using:<\/p>\n<p>[js]londiste.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/londiste.ini replay\u00a0-s[\/js]<\/p>\n<p>and started again using -d switch in place of <strong>-s<\/strong><br \/>\n(But if you kill the daemon process &amp;\u00a0If this throws error In-case you stop\/start\/restart the server or process\u00a0you might need to delete the pid files before starting the ticker &amp;\u00a0replay daemon again.\u00a0Delete the pid file in \/var\/lib\/postgresql\/pid\/myfisrtreplication.pid)<\/p>\n<p>Also, you will have to Repeat step 2 &amp; step 4.<\/p>\n<h4><span style=\"color: #993300\">7. Initiating Replication<\/span><\/h4>\n<p>Add tables and start replication, for example in the following command table name family_nicknames is added:<\/p>\n<p>[js]londiste.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/londiste.ini provider add<br \/>\nfamily_nicknames<\/p>\n<p>londiste.py \/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf\/londiste.ini subscriber add<br \/>\nfamily_nicknames[\/js]<\/p>\n<p>Once a table is added, the table will be copied and also all future changes made will automatically replicate in the RDS from the\u00a0master DB. To replicate all use:<\/p>\n<p>[js]londiste.py \/etc\/skytools\/conf.ini provider add &#8211;all (adding all tables on provider for replication)<\/p>\n<p>londiste.py \/etc\/skytools\/conf.ini subscriber add &#8211;all (adding all tables on subscriber for replication) [\/js]<\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #993300\">8. The replication starts. You can check the logs at:<\/span><\/h4>\n<p>\/opt\/skytools-2.1.12\/share\/doc\/skytools\/conf then\u00a0tailf myfisrtpgreplication.log<br \/>\nand<br \/>\n\/var\/lib\/postgresql\/log\/myfisrtpgreplication.log<\/p>\n<h4><span style=\"color: #993300\">9. You can check the replication by logging in to RDS:<\/span><\/h4>\n<p>[js]psql &#8211;host abcd-postgres.xyz1234567.us-east-1.rds.amazonaws.com &#8211;username=dev[\/js]<\/p>\n<p>To test, you can make a few changes to a table in the master or provider DB &amp; then add the table for replication &amp; then go\u00a0to the RDS PostgreSQL and check if the changes are replicated or not. Later once all the replication is complete (check logs) you just need to change the DB endpoint to AWS RDS endpoint<\/p>\n<p>This is very useful when it comes to migration of on-premise applications with DB to AWS as a matter of fact any cloud platform. Hope this has been useful to you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PostgreSQL is another SQL. It is the second most popular Structured Query Language after MySQL. The steps discussed in the blog can be used for any kind of migration of PostgreSQL. From on-premise to cloud or on-premise to on-premise or cloud to on-premise. Use-case I had to migrate my PostgreSQL running on an EC2 server [&hellip;]<\/p>\n","protected":false},"author":174,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":11},"categories":[1174,2348],"tags":[248,2547,2548,260,2545,986,1703,2549,942,1442,2546],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/26484"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/174"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=26484"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/26484\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=26484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=26484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=26484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}