@@ -0,0 +1,195 @@
+diff -ru pdns-3.4.3_orig/modules/gmysqlbackend/gmysqlbackend.cc pdns-3.4.3/modules/gmysqlbackend/gmysqlbackend.cc
+--- pdns-3.4.3_orig/modules/gmysqlbackend/gmysqlbackend.cc 2015-04-23 10:32:01.101345245 +0200
++++ pdns-3.4.3/modules/gmysqlbackend/gmysqlbackend.cc 2015-04-23 10:34:14.696465950 +0200
+@@ -30,6 +30,30 @@
+ throw PDNSException("Unable to launch "+mode+" connection: "+e.txtReason());
+ }
+ L<<Logger::Info<<mode<<" Connection successful. Connected to database '"<<getArg("dbname")<<"' on '"<<(getArg("host").empty() ? getArg("socket") : getArg("host"))<<"'."<<endl;
++
++ if(!getArg("slave-socket").empty() || !getArg("slave-host").empty())
++ {
++ try
++ {
++ setDBReadonly(new SMySQL(getArg("slave-dbname"),
++ getArg("slave-host"),
++ getArgAsNum("slave-port"),
++ getArg("slave-socket"),
++ getArg("slave-user"),
++ getArg("slave-password")));
++ L<<Logger::Warning<<mode<<" Slave connection successful."<<endl;
++ }
++ catch(ArgException &e)
++ {
++ // Ignore exception, slave not
++ L<<Logger::Warning<<mode<<" Slave configuration."<<endl;
++ }
++ catch(SSqlException &e)
++ {
++ // Ignore exception, slave not
++ L<<Logger::Warning<<mode<<" Unable to connect to slave."<<endl;
++ }
++ }
+ }
+
+ class gMySQLFactory : public BackendFactory
+@@ -49,6 +73,13 @@
+ declare(suffix,"innodb-read-committed","Use InnoDB READ-COMMITTED transaction isolation level","yes");
+
+ declare(suffix,"dnssec","Enable DNSSEC processing","no");
++
++ declare(suffix,"slave-dbname","Pdns backend database name to connect to","");
++ declare(suffix,"slave-user","Database backend user to connect as","");
++ declare(suffix,"slave-host","Database backend host to connect to","");
++ declare(suffix,"slave-port","Database backend port to connect to","0");
++ declare(suffix,"slave-socket","Pdns backend socket to connect to","");
++ declare(suffix,"slave-password","Pdns backend password to connect with","");
+
+ string record_query = "SELECT content,ttl,prio,type,domain_id,disabled,name,auth FROM records WHERE";
+
+diff -ru pdns-3.4.3_orig/pdns/backends/gsql/gsqlbackend.cc pdns-3.4.3/pdns/backends/gsql/gsqlbackend.cc
+--- pdns-3.4.3_orig/pdns/backends/gsql/gsqlbackend.cc 2015-04-23 10:32:01.121345114 +0200
++++ pdns-3.4.3/pdns/backends/gsql/gsqlbackend.cc 2015-04-23 11:01:09.597837000 +0200
+@@ -77,7 +77,7 @@
+ string query = (GSQLformat(d_MasterOfDomainsZoneQuery) % sqlEscape(domain)).str();
+
+ try {
+- d_db->doQuery(query, d_result);
++ getDBReadonly()->doQuery(query, d_result);
+ }
+ catch (SSqlException &e) {
+ throw PDNSException("GSQLBackend unable to retrieve list of master domains: "+e.txtReason());
+@@ -148,7 +148,7 @@
+ snprintf(output,sizeof(output)-1,d_InfoOfDomainsZoneQuery.c_str(),
+ sqlEscape(domain).c_str());
+ try {
+- d_db->doQuery(output,d_result);
++ getDBReadonly()->doQuery(output,d_result);
+ }
+ catch(SSqlException &e) {
+ throw PDNSException("GSQLBackend unable to retrieve information about a domain: "+e.txtReason());
+@@ -189,7 +189,7 @@
+ /* list all domains that need refreshing for which we are slave, and insert into SlaveDomain:
+ id,name,master IP,serial */
+ try {
+- d_db->doQuery(d_InfoOfAllSlaveDomainsQuery, d_result);
++ getDBReadonly()->doQuery(d_InfoOfAllSlaveDomainsQuery, d_result);
+ }
+ catch (SSqlException &e) {
+ throw PDNSException("GSQLBackend unable to retrieve list of slave domains: "+e.txtReason());
+@@ -225,7 +225,7 @@
+ /* list all domains that need notifications for which we are master, and insert into updatedDomains
+ id,name,master IP,serial */
+ try {
+- d_db->doQuery(d_InfoOfAllMasterDomainsQuery,d_result);
++ getDBReadonly()->doQuery(d_InfoOfAllMasterDomainsQuery,d_result);
+ }
+ catch(SSqlException &e) {
+ throw PDNSException("GSQLBackend unable to retrieve list of master domains: "+e.txtReason());
+@@ -276,6 +276,7 @@
+ {
+ setArgPrefix(mode+suffix);
+ d_db=0;
++ d_db_slave=NULL;
+ d_logprefix="["+mode+"Backend"+suffix+"] ";
+
+ try
+@@ -739,7 +740,7 @@
+ snprintf(output,sizeof(output)-1,d_GetAllDomainMetadataQuery.c_str(), sqlEscape(name).c_str());
+
+ try {
+- d_db->doQuery(output);
++ getDBReadonly()->doQuery(output);
+ }
+ catch (SSqlException &e) {
+ throw PDNSException("GSQLBackend unable to list metadata: "+e.txtReason());
+@@ -765,7 +766,7 @@
+ snprintf(output,sizeof(output)-1,d_GetDomainMetadataQuery.c_str(), sqlEscape(toLower(name)).c_str(), sqlEscape(kind).c_str());
+
+ try {
+- d_db->doQuery(output);
++ getDBReadonly()->doQuery(output);
+ }
+ catch (SSqlException &e) {
+ throw PDNSException("GSQLBackend unable to list metadata: "+e.txtReason());
+@@ -856,7 +857,7 @@
+ ).str();
+
+ try {
+- d_db->doQuery(query);
++ getDBReadonly()->doQuery(query);
+ }
+ catch(SSqlException &e) {
+ throw PDNSException("GSQLBackend list query: "+e.txtReason());
+@@ -874,7 +875,7 @@
+ % domain_id
+ ).str();
+ try {
+- d_db->doQuery(query);
++ getDBReadonly()->doQuery(query);
+ }
+ catch(SSqlException &e) {
+ throw PDNSException("GSQLBackend listSubZone query: "+e.txtReason());
+@@ -894,7 +895,7 @@
+ for(vector<DNSResourceRecord>::const_iterator i=nsset.begin();i!=nsset.end();++i) {
+ try {
+ snprintf(output,sizeof(output)-1,format.c_str(),sqlEscape(ip).c_str(),sqlEscape(i->content).c_str());
+- d_db->doQuery(output, d_result);
++ getDBReadonly()->doQuery(output, d_result);
+ }
+ catch (SSqlException &e) {
+ throw PDNSException("GSQLBackend unable to search for a domain: "+e.txtReason());
+@@ -993,7 +994,7 @@
+ string query = (GSQLformat(d_getAllDomainsQuery) % (int)include_disabled).str();
+
+ try {
+- d_db->doQuery(query);
++ getDBReadonly()->doQuery(query);
+ }
+ catch (SSqlException &e) {
+ throw PDNSException("Database error trying to retrieve all domains:" + e.txtReason());
+@@ -1254,7 +1255,7 @@
+ sd.domain_id);
+
+ try {
+- d_db->doQuery(output, d_result);
++ getDBReadonly()->doQuery(output, d_result);
+ }
+ catch (const SSqlException& e) {
+ //DLOG(L<<"GSQLBackend unable to calculate SOA serial: " << e.txtReason()<<endl);
+diff -ru pdns-3.4.3_orig/pdns/backends/gsql/gsqlbackend.hh pdns-3.4.3/pdns/backends/gsql/gsqlbackend.hh
+--- pdns-3.4.3_orig/pdns/backends/gsql/gsqlbackend.hh 2015-04-23 10:32:01.121345114 +0200
++++ pdns-3.4.3/pdns/backends/gsql/gsqlbackend.hh 2015-04-23 10:57:42.927197264 +0200
+@@ -18,6 +18,8 @@
+ {
+ if(d_db)
+ delete d_db;
++ if(d_db_slave)
++ delete d_db_slave;
+ }
+
+ void setDB(SSql *db)
+@@ -28,6 +30,16 @@
+ }
+ }
+
++ void setDBReadonly(SSql *db)
++ {
++ d_db_slave=db;
++ }
++
++ SSql *getDBReadonly()
++ {
++ return d_db_slave != NULL ? d_db_slave : d_db;
++ }
++
+ virtual string sqlEscape(const string &name);
+ void lookup(const QType &, const string &qdomain, DNSPacket *p=0, int zoneId=-1);
+ bool list(const string &target, int domain_id, bool include_disabled=false);
+@@ -91,6 +103,7 @@
+ private:
+ string d_qname;
+ SSql *d_db;
++ SSql *d_db_slave;
+ SSql::result_t d_result;
+
+ string d_NoIdQuery;
|