diff --git a/includes/backup.inc b/includes/backup.inc
new file mode 100644
index 0000000..e48f591
--- /dev/null
+++ b/includes/backup.inc
@@ -0,0 +1,77 @@
+<?php
+
+/**
+ * Import a backup generated by the export.
+ * 
+ * @param $filename
+ *   The filename of the backup.
+ */
+function backup_import($filename) {
+  $connection = Database::getConnection();
+
+  // MySQL and derivatives needs a special mode to retain zeros in autoincrement
+  // columns.
+  if (Database::getConnection()->databaseType() == 'mysql') {
+    $connection->query("SET sql_mode='ANSI,TRADITIONAL,NO_AUTO_VALUE_ON_ZERO'");
+  }
+
+  $handle = fopen($filename, 'r');
+  if (!$handle) {
+    return FALSE;
+  }
+  $insert = NULL;
+  while (($line = fgets($handle, 4096)) !== FALSE) {
+    $command = json_decode($line, TRUE);
+    if (isset($command['table'])) {
+      $insert->execute();
+      $connection->schema()->dropTable($command['table']);
+      $connection->schema()->createTable($command['table'], $command['data']);
+      $insert = $connection->insert($command['table'])->fields($command['data']['fields']);
+    }
+    else {
+      $insert->values($command['data']);
+    }
+  }
+  $insert->execute();
+}
+
+/**
+ * Export a backup to a file.
+ * 
+ * @param $filename
+ *   The filename of the backup.
+ */
+function backup_export($filename) {
+  $directory = dirname($filename);
+  if (!file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
+    return FALSE;
+  }
+
+  if (!$handle = fopen($filename, 'wb')) {
+    return FALSE;
+  }
+
+  // Get the current schema, order it by table name.
+  $schema = drupal_get_schema();
+  ksort($schema);
+
+  $last_table = end(array_keys($schema));
+  // Export all the tables in the schema.
+  foreach ($schema as $table => $data) {
+    // Dump the table structure.
+    fwrite($handle, json_encode(array('table' => $table, 'data' => $data)) . "\n");
+
+    if (isset($data['backup data']) && !$data['backup data']) {
+      continue;
+    }
+
+    // Prepare the export of values.
+    $result = db_select($table, NULL, array('fetch' => PDO::FETCH_ASSOC))
+      ->fields($table);
+    $total = $result->countQuery()->execute()->fetchCol();
+    foreach ($result->execute() as $record) {
+      fwrite($handle, json_encode(array('data' => $record)) . "\n");
+    }
+  }
+  fclose($handle);
+}
diff --git a/modules/dblog/dblog.install b/modules/dblog/dblog.install
index 23f85ba..97baa6a 100644
--- a/modules/dblog/dblog.install
+++ b/modules/dblog/dblog.install
@@ -86,6 +86,7 @@ function dblog_schema() {
       'type' => array('type'),
       'uid' => array('uid'),
     ),
+    'backup data' => FALSE,
   );
 
   return $schema;
diff --git a/modules/system/system.install b/modules/system/system.install
index 6d2fc80..74eb00e 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -687,6 +687,7 @@ function system_schema() {
       'expire' => array('expire'),
     ),
     'primary key' => array('cid'),
+    'backup data' => FALSE,
   );
   $schema['cache_bootstrap'] = $schema['cache'];
   $schema['cache_bootstrap']['description'] = 'Cache table for data required to bootstrap Drupal, may be routed to a shared memory cache.';
