diff --git a/config-templates/config.php b/config-templates/config.php
index 418504084d3ff6433e92aa1c8957e3c70b6fa9b2..e21bcd8b476651c9800794de3abe1257210e3268 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -197,6 +197,61 @@ $config = array(
     ),
 
 
+
+    /*
+     * Database
+     *
+     * This database configuration is optional. If you are not using
+     * core funcationlity or modules that require a database, you can
+     * skip this configuration.
+     */
+
+    /*
+     * Database connection string.
+     * Ensure that you have the required PDO database drive installed
+     * for your connection string.
+     */
+    'database.dsn' => 'mysql:host=localhost;dbname=saml',
+
+    /*
+     * SQL database credentials
+     */
+    'database.username' => 'simplesamlphp',
+    'database.password' => 'secret',
+
+    /*
+     * (Optional) Table prefix
+     */
+    'database.prefix' => '',
+
+    /*
+     * True or false if you would like a persisent datata connection
+     */
+    'database.persistent' => false,
+
+    /*
+     * Database slave configuration is optional as well. If you are only
+     * running a single database server, leave this blank. If you have
+     * a master/slave conifguration, you can define as many slave servers
+     * as you want here. Slaves will be picked at random to be queried from.
+     *
+     * Configuration options in the salve array are exactly the same as the
+     * options for the master (shown above) with the exception of the table
+     * prefix.
+     */
+    'database.slaves' => array(
+        /*
+        array(
+            'dsn' => 'mysql:host=myslave;dbname=saml',
+            'username' => 'simplesamlphp',
+            'password' => 'secret',
+            'persistent' => false,
+        ),
+        */
+    ),
+
+
+
     /*
      * Enable
      *
@@ -572,13 +627,13 @@ $config = array(
      *                  hours (86400 seconds). Optional.
      *
      * PDO metadata handler:
-     * This metadata handler looks up for the metadata of an entity stored in a database.
+     * This metadata handler looks up metadata of an entity stored in a database.
+     *
+     * Note: If you are using the PDO metadata handler, you must configure the database
+     * options in this configuration file.
+     *
      * The PDO metadata handler defines the following options:
      * - 'type': This is always 'pdo'.
-     * - 'dsn': The database connection string. Mandatory.
-     * - 'username': Database username
-     * - 'cachedir': Database password
-     * - 'usePersistentConnection': Enable/Disable persistent database connection. Default is false.
      *
      *
      * Examples:
@@ -604,7 +659,7 @@ $config = array(
      *
      * This example defines an pdo source.
      * 'metadata.sources' => array(
-     *     array('type' => 'pdo', server => 'mysql:host=localhost;dbname=saml', 'username' => 'simplesamlphp', 'password' => 'SuperSecretPassword')
+     *     array('type' => 'pdo')
      *     ),
      *
      * Default:
diff --git a/lib/SimpleSAML/Database.php b/lib/SimpleSAML/Database.php
new file mode 100644
index 0000000000000000000000000000000000000000..16df90f5daee5c770c4e9081ec84a5f011f1e521
--- /dev/null
+++ b/lib/SimpleSAML/Database.php
@@ -0,0 +1,202 @@
+<?php
+
+/**
+ * This file implements functions to read and write to a group of database
+ * servers.
+ *
+ * This database class supports a single database, or a master/slave
+ * configuration with as many defined slaves as a user would like.
+ * 
+ * The goal of this class is to provide a single mechanism to connect to a database
+ * that can be reused by any component within SimpleSAMLphp including modules.
+ * When using this class, the global configuration should be passed here, but
+ * in the case of a module that has a good reason to use a different database,
+ * such as sqlauth, an alternative config file can be provided.
+ *
+ * @author Tyler Antonio, University of Alberta. <tantonio@ualberta.ca>
+ * @package simpleSAMLphp
+ */
+
+class SimpleSAML_Database {
+
+	/**
+	 * This variable holds the instance of the session - Singleton approach.
+	 */
+	private static $instance = array();
+
+	/**
+	 * PDO Object for the Master database server
+	 */
+	private $dbMaster;
+
+	/**
+	 * Array of PDO Objects for configured database
+	 * slaves
+	 */
+	private $dbSlaves = array();
+
+	/**
+	 * Prefix to apply to the tables
+	 */
+	private $tablePrefix;
+
+    /**
+	 * Retrieves the current database instance. Will create a new one if there isn't an existing connection.
+	 *
+	 * @param object $altConfig Optional: Instance of a SimpleSAML_Configruation class
+	 * @return SimpleSAML_Database The shared database connection.
+	 */
+	public static function getInstance($altConfig = null) {
+		$config = ($altConfig)? $altConfig : SimpleSAML_Configuration::getInstance();
+		$instanceId = spl_object_hash($config);
+
+		/* Check if we already have initialized the session. */
+		if (isset(self::$instance[$instanceId])) {
+			return self::$instance[$instanceId];
+		}
+
+		/* Create a new session. */
+		self::$instance[$instanceId] = new SimpleSAML_Database($config);
+		return self::$instance[$instanceId];
+	}
+
+	/**
+	 * Private constructor that restricts instantiation to getInstance().
+	 *
+	 * @param object $config Instance of the SimpleSAML_Configruation class
+	 */
+	private function __construct($config) {
+		$driverOptions = array();
+		if ($config->getBoolean('database.persistent', TRUE)) {
+			$driverOptions = array(PDO::ATTR_PERSISTENT => TRUE);
+		}
+
+		// Connect to the master
+		$this->dbMaster = $this->connect($config->getValue('database.dsn'), $config->getValue('database.username'), $config->getValue('database.password'), $driverOptions);
+
+		// Connect to any configured slaves
+		$slaves = $config->getValue('database.slaves');
+		if (count($slaves >= 1)) {
+			foreach ($slaves as $slave) {
+				array_push($this->dbSlaves, $this->connect($slave['dsn'], $slave['username'], $slave['password'], $driverOptions));
+			}
+		}
+
+		$this->tablePrefix = $config->getString('database.prefix', '');
+	}
+
+	/**
+	 * This function connects to a dabase.
+	 *
+	 * @param $dsn 			Database connection string
+	 * @param $username 	SQL user
+	 * @param $password 	SQL password
+	 * @param $options 		PDO options
+	 *
+	 * @return PDO object
+	 */
+	private function connect($dsn, $username, $password, $options){
+		try{
+			$db = new PDO($dsn, $username, $password, $options);
+			$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+			return $db;
+		} catch(PDOException $e){
+			throw new Exception("Database error: ". $e->getMessage());
+		}
+	}
+
+	/**
+	 * This function randomly selects a slave database server
+	 * to query. In the event no slaves are configured, it
+	 * will return the master.
+	 *
+	 * @return PDO object
+	 */
+	private function getSlave(){
+		if (count($this->dbSlaves) > 0) {
+			$slaveId = rand(0,count($this->dbSlaves)-1);
+			return $this->dbSlaves[$slaveId];
+		} else {
+			return $this->dbMaster;
+		}
+	}
+
+	/**
+	 * This function simply applies the table prefix to
+	 * a suppled table name.
+	 *
+	 * @param $table Table to apply prefix,if configured
+	 * @return string Table with configured prefix
+	 */
+	public function applyPrefix($table){
+		return $this->tablePrefix . $table;
+	}
+
+	/**
+	 * This function queries the database
+	 *
+	 * @param $db 			PDO object to use
+	 * @param $stmt 		Prepared SQL statement
+	 * @param $params 		Parameters
+	 *
+	 * @return PDO statement object
+	 */
+	private function query($db, $stmt, $params){
+		assert('is_object($db)');
+		assert('is_string($stmt)');
+		assert('is_array($params)');
+
+		try{
+			$query = $db->prepare($stmt);
+
+			foreach ($params as $param => $value) {
+				if(is_array($value)){
+					$query->bindValue(":$param", $value[0], ($value[1])? $value[1] : PDO::PARAM_STR);
+				}
+				else{
+					$query->bindValue(":$param", $value, PDO::PARAM_STR);	
+				}
+			}
+
+			$query->execute();
+
+			if ($query->execute() === FALSE) {
+				throw new Exception("Database error: " . var_export($this->pdo->errorInfo(), TRUE));
+			}
+
+			return $query;
+		} catch (PDOException $e){
+			throw new Exception("Database error: ". $e->getMessage());
+		}
+	}
+
+	/**
+	 * This executes queries directly on the master.
+	 *
+	 * @param $stmt 		Prepared SQL statement
+	 * @param $params 		Parameters
+	 *
+	 * @return PDO statement object
+	 */
+	public function write($stmt, $params = array()){
+		$db = $this->dbMaster;
+
+		return $this->query($db, $stmt, $params);
+	}
+
+	/**
+	 * This executes queries on a database server
+	 * that is determined by this::getSlave()
+	 *
+	 * @param $stmt 		Prepared SQL statement
+	 * @param $params 		Parameters
+	 *
+	 * @return PDO statement object
+	 */
+	public function read($stmt, $params = array()){
+		$db = $this->getSlave();
+
+		return $this->query($db, $stmt, $params);
+	}
+}
diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
index 7bde1847a464c36749d9f0c3e87b6974e407b5bb..3a0030a697ae8e925addf498ce0524434613f5db 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerPdo.php
@@ -20,7 +20,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
 	/**
 	 * The PDO object
 	 */
-	private $pdo;
+	private $db;
 
 	/**
 	 * Prefix to apply to the metadata table
@@ -69,20 +69,9 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
 		assert('is_array($config)');
 
 		$globalConfig = SimpleSAML_Configuration::getInstance();
+		$this->db = SimpleSAML_Database::getInstance();
 
 		$cfgHelp = SimpleSAML_Configuration::loadFromArray($config, 'pdo metadata source');
-
-		// determine the table prefix if one was set
-		$this->tablePrefix = $cfgHelp->getString('tablePrefix', '');
-		$this->dsn = $cfgHelp->getString('dsn');
-
-		$driverOptions = array();
-		if ($cfgHelp->getBoolean('usePersistentConnection', TRUE)) {
-			$driverOptions = array(PDO::ATTR_PERSISTENT => TRUE);
-		}
-
-		$this->pdo = new PDO($this->dsn, $cfgHelp->getValue('username', NULL), $cfgHelp->getValue('password', NULL), $driverOptions);
-		$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 	}
 
 
@@ -102,7 +91,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
 			return NULL;
 		}
 
-		$stmt = $this->pdo->prepare("SELECT entity_id, entity_data FROM $tableName");
+		$stmt = $this->db->read("SELECT entity_id, entity_data FROM $tableName");
 		if($stmt->execute()) {
 			$metadata = array();
 
@@ -189,24 +178,24 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
 
 		$tableName = $this->getTableName($set);
 
-		$metadata = $this->pdo->prepare("SELECT entity_id, entity_data FROM $tableName WHERE entity_id = :entity_id");
-		$metadata->bindValue(":entity_id", $index, PDO::PARAM_STR);
-		$metadata->execute();
+		$metadata = $this->db->read("SELECT entity_id, entity_data FROM $tableName WHERE entity_id = :entity_id", array(
+			'entity_id' => $index,
+		));
+
 		$retrivedEntityIDs = $metadata->fetch();
 
+		$params = array(
+			'entity_id' => $index,
+			'entity_data' => json_encode($entityData),
+		);
+
 		if($retrivedEntityIDs !== FALSE && count($retrivedEntityIDs) > 0){
-			$stmt = $this->pdo->prepare("UPDATE $tableName SET entity_data = :entity_data WHERE entity_id = :entity_id");
+			$stmt = $this->db->write("UPDATE $tableName SET entity_data = :entity_data WHERE entity_id = :entity_id", $params);
 		}
 		else{
-			$stmt = $this->pdo->prepare("INSERT INTO $tableName (entity_id, entity_data) VALUES (:entity_id, :entity_data)");
+			$stmt = $this->db->write("INSERT INTO $tableName (entity_id, entity_data) VALUES (:entity_id, :entity_data)", $params);
 		}
 
-		$stmt->bindValue(":entity_id", $index, PDO::PARAM_STR);
-		$stmt->bindValue(":entity_data", json_encode($entityData), PDO::PARAM_STR);
-		
-		if ($stmt->execute() === FALSE) {
-			throw new Exception("PDO metadata handler: Database error: " . var_export($this->pdo->errorInfo(), TRUE));
-		}
 		return 1 === $stmt->rowCount();
 	}
 
@@ -220,7 +209,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
 	private function getTableName($table) {
 		assert('is_string($table)');
 
-		return str_replace("-", "_", $this->tablePrefix . $table);
+		return $this->db->applyPrefix(str_replace("-", "_", $this->tablePrefix . $table));
 	}
 
 	/**
@@ -229,11 +218,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerPdo extends SimpleSAML_Metadata_
 	public function initDatabase() {
 		foreach ($this->supportedSets as $set) {
 			$tableName = $this->getTableName($set);
-			$result = $this->pdo->exec("CREATE TABLE IF NOT EXISTS $tableName (entity_id VARCHAR(255) PRIMARY KEY NOT NULL, entity_data TEXT NOT NULL)");
-			if ($result === FALSE) {
-			    throw new Exception("PDO metadata handler: Database error: " . var_export($this->pdo->errorInfo(), TRUE));
-			}
+			$this->db->write("CREATE TABLE IF NOT EXISTS $tableName (entity_id VARCHAR(255) PRIMARY KEY NOT NULL, entity_data TEXT NOT NULL)");
 		}
 	}
 
-}
+}
\ No newline at end of file