This document is about PowerDNS 4.X. If you have PowerDNS 3.X, please see the PowerDNS 3.X documentation

Generic MySQL backend

Native Yes
Master Yes
Slave Yes
Superslave Yes
Autoserial Yes (v3.1 and up)
Case All lower
DNSSEC Yes (set gmysql-dnssec)
Disabled data Yes (v3.4.0 and up)
Comments Yes (v3.4.0 and up)
Module name gmysql
Launch name gmysql

warning: If using MySQL with 'slave' support enabled in PowerDNS you must run MySQL with a table engine that supports transactions. In practice, great results are achieved with the 'InnoDB' tables. PowerDNS will silently function with non-transaction aware MySQLs but at one point this is going to harm your database, for example when an incoming zone transfer fails.

The default schema is included at the bottom of this page. zone2sql with the --gmysql flag also assumes this layout is in place. For full migration notes, please see Migration. This schema contains all elements needed for master, slave and superslave operation.

When using the InnoDB storage engine, we suggest adding the following lines to the 'create table records' command above:

CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains`

Or, if you have already created the tables, execute:

ALTER TABLE `records` ADD CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`)

This automates deletion of records on deletion of a domain from the domains table.

Using MySQL replication

To support NATIVE domains, the binlog_format for the MySQL replication must be set to MIXED or ROW to prevent differences in data between replicated servers. See ", Setting The Binary Log Format" for more information.



Host (ip address) to connect to. Mutually exclusive with gmysql-socket.

WARNING: When specified as a hostname a chicken/egg situation might arise where the database is needed to resolve the IP address of the database. It is best to supply an IP address of the database here.


The port to connect to on gmysql-host. Default: 3306


Connect to the UNIX socket at this path. Mutually exclusive with gmysql-host.


Name of the database to connect to. Default: "pdns".


User to connect as. Default: "powerdns".


Group to connect as. Default: "client".


The password to for gmysql-user.


Enable DNSSEC processing for this backend. Default=no.


Use the InnoDB READ-COMMITTED transaction isolation level. Default=yes.


The timeout in seconds for each attempt to read from, or write to the server. A value of 0 will disable the timeout. Default: 10

Default Schema

CREATE TABLE domains (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255) NOT NULL,
  master                VARCHAR(128) DEFAULT NULL,
  last_check            INT DEFAULT NULL,
  type                  VARCHAR(6) NOT NULL,
  notified_serial       INT DEFAULT NULL,
  account               VARCHAR(40) DEFAULT NULL,
) Engine=InnoDB;

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
  id                    INT AUTO_INCREMENT,
  domain_id             INT DEFAULT NULL,
  name                  VARCHAR(255) DEFAULT NULL,
  type                  VARCHAR(10) DEFAULT NULL,
  content               VARCHAR(64000) DEFAULT NULL,
  ttl                   INT DEFAULT NULL,
  prio                  INT DEFAULT NULL,
  change_date           INT DEFAULT NULL,
  disabled              TINYINT(1) DEFAULT 0,
  ordername             VARCHAR(255) BINARY DEFAULT NULL,
  auth                  TINYINT(1) DEFAULT 1,
) Engine=InnoDB;

CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE INDEX recordorder ON records (domain_id, ordername);

CREATE TABLE supermasters (
  ip                    VARCHAR(64) NOT NULL,
  nameserver            VARCHAR(255) NOT NULL,
  account               VARCHAR(40) NOT NULL,
  PRIMARY KEY (ip, nameserver)
) Engine=InnoDB;

CREATE TABLE comments (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  name                  VARCHAR(255) NOT NULL,
  type                  VARCHAR(10) NOT NULL,
  modified_at           INT NOT NULL,
  account               VARCHAR(40) NOT NULL,
  comment               VARCHAR(64000) NOT NULL,
) Engine=InnoDB;

CREATE INDEX comments_domain_id_idx ON comments (domain_id);
CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);

CREATE TABLE domainmetadata (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  kind                  VARCHAR(32),
  content               TEXT,
) Engine=InnoDB;

CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);

CREATE TABLE cryptokeys (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  flags                 INT NOT NULL,
  active                BOOL,
  content               TEXT,
) Engine=InnoDB;

CREATE INDEX domainidindex ON cryptokeys(domain_id);

CREATE TABLE tsigkeys (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255),
  algorithm             VARCHAR(50),
  secret                VARCHAR(255),
) Engine=InnoDB;

CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);