Back Up Rails

An important aspect of delivering an application to end users, that is easily over-looked, is back up. If our application is to be used regularly, users need to be assured that should disaster strike, we will be able to restore the application. More importantly we can restore their data that they have stored within the application. Therefore, backup is an important part of any production environment.

In this section, I will briefly outline a couple of systems that we can use to more easily back up a Rails application.

Backing Up the Code Repository

One strategy that could be used to back up our application code is simply to back up the files in the application folder. There are two issues with this. It is difficult to backup files that are in use, and therefore unless we shutdown our application during backup, it is likely that not all of the files will be backed up. Second, backing up the application folder only backs up the most recent version of an application. Previous versions would be lost unless we keep an extensive set of back ups.

There is a simple solution to both problems and that is to back up the Subversion repository. This contains not only the current version of the application, but also the earlier versions and newer development versions. Subversion has a facility to export its contents to a file. This file can be easily restored to a new instance of Subversion.

To create an export file from the repository use svnadmin's dump option:

$ svnadmin dump path_to_repository > dump_filename

For example, on a Windows system we could use the following command to create a dump file.

$ svnadmin dump c:
epository > dumpfile.dump

We can use a svnadmin dump to export only parts of the repository. We can also make incremental backups (the default is a full backup. An incremental backup will contain only the files that have changed since the last full backup). The following shows the syntax for an incremental backup of revisions 100 to 104 of a repository.

$ svnadmin dump incremental revision 100:104 path_to_repository > dump_filename

To recover the Subversion repository, you would use the svnadmin load option after first recreating a blank repository. The syntax of the commands would be:

$ svnadmin create repository_name
$ svnadmin load repository_name < dump_filename

To create a scheduled automatic backup, we could run the svnadmin dump command within a batch file and then use a cron or scheduled task to run the batch file at an appropriate time. This would create a simple file that can be easily incorporated into our standard backup routine.

However, we could also use Ruby to run a backup dump. The example below shows the contents of a file called BackupSVN.rb and will backup a repository at "c: epository" on a Windows system.

filename = "svn_output#{Time.new.strftime('%Hh%Mm%Ss%a%d%b%Y')}.dump"
repository_location = 'c:
epository'
exec "svnadmin dump #{repository_location} > #{filename}"

Running the program will create a dump file. The Time.new.strftime('%Hh%Mm%Ss%a%d%b%Y') element causes the filename to include a simple time stamp. As with a batch file, such a batch process could be scheduled with cron or a scheduled task.

Back Up the Database

A number of ways for backing up a MySQL database are documented at http://dev.mysql.com/doc/refman/5.1/en/backup.html.

On a Windows system the easiest method is via MySQL Administrator. This is an administration utility that can be downloaded from http://www.mysql.com. This application provides recovery and scheduled backup facilities and is cross platform. The backups generate files that can be easily incorporated into a standard backup to tape or network storage.

Back Up the Database

However, it is possible to use a Ruby script to generate MySQL backups too.

For example, we could use MySQL's mysqldump utility, which acts in a very similar way to svnadmin's dump option. In its default mode, mysqldump not only outputs the data, but also the SQL code needed to recreate the tables and then insert the data into the new tables. The dump, therefore, automatically saves the data with the code required to recreate the table structures as they were at the time. Restoring the dump data will not require us to run a migration, and therefore we do not need to track the migration version with each data dump.

Like svnadmin, mysqldump is accessible from the command line and can get a full listing of the options available by entering:

$ mysqldump -help

The command to create a dump file of all tables in the database is:

$ mysqldump --all-databases -u root -p > dump.sql

The -p switch will force the system to prompt for the root password. In a script we will need to replace the -p switch with the --password switch. This longer switch allows us to specify a password. So, if the root password was PASSWORD, we could add the following line to our Ruby backup script to generate a backup dump file for the MySQL database.

filename = "mysql_output#{Time.new.strftime('%Hh%Mm%Ss%a%d%b%Y')}.sql"
exec "mysqldump --all-databases -u root --password=PASSWORD > #{filename}"

On a Windows system, you may need to provide a path to the MySQL bin folder, but once that is done, the script works as it is given above.

Combining Your Backup Scripts

Unfortunately, exec terminates the Ruby instance. Therefore, an exec call has to be the last line of a backup script. We cannot simply paste the MySql backup script onto the end of the Subversion backup script to combine the two into one script, as only the first exec call will trigger. However, there is another way to execute shell commands within Ruby, and that is to use popen. Below is an example of Ruby code that will execute both backup commands:

def run(command)
IO.popen(command, 'r+') do |io|
io.close_write
output = io.readlines
for line in output
puts line
end
end
end
filename = "svn_output#{Time.new.strftime('%Hh%Mm%Ss%a%d%b%Y')}.dump"
repository_location = 'c:
epository'
run("svnadmin dump #{repository_location} > #{filename}")
filename = "mysql_output#{Time.new.strftime('%Hh%Mm%Ss%a%d%b%Y')}.sql"
run("mysqldump --all-databases -u root --password=PASSWORD > #{filename}")

The run method defined in the first half of that code can be used to execute other shell commands. Therefore, you can add additional maintenance tasks to this script as required.

The "for line in output" loop, prints out the lines returned by the shell command. As the outputs of the two backup processes are piped to files, the combined backup code will return nothing to the console. If you were to add this to the end of the code:

run('ping 127.0.0.1')

...the output of the ping command would be output to the console after the two backup processes had completed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.19.243