Browse Source

[2042] Initial MySQL implementation (WIP)

Tomek Mrugalski 12 years ago
parent
commit
1db0c25926

+ 7 - 0
tests/tools/dhcp-ubench/Makefile

@@ -0,0 +1,7 @@
+MYSQL_CFLAGS=`mysql_config --cflags`
+MYSQL_LDFLAGS=`mysql_config --libs`
+
+all: mysql_ubench
+
+mysql_ubench: mysql_ubench.cc
+	$(CXX) $< -o mysql_ubench $(MYSQL_CFLAGS) $(MYSQL_LDFLAGS)

+ 45 - 0
tests/tools/dhcp-ubench/README

@@ -0,0 +1,45 @@
+
+ DHCP micro-benchmarks
+-----------------------
+
+This directory contains simplified prototypes for various DB back-ends
+that are planned or considered as a backend engine for BIND10 DHCP.
+Athough trivial now, they are expected to evolve into useful tools
+that will allow users to measure performance in their specific environment.
+
+Currently the following benchmarks are planned:
+- in memory+flat file
+- SQLite
+- MySQL
+
+As they require additional (sometimes heavy) dependencies, they are not
+built by default. Actually, their build system completely separated.
+It will be eventually merged with the main BIND10 makefile system, but
+that is a low priority for now.
+
+
+ MySQL backend
+---------------
+
+MySQL backend requires MySQL client development libraries. It uses
+mysql_config tool (that works similar to pkg-config) to discover
+required compilation and linking options. To install required packages
+on Ubuntu, use the following command:
+
+sudo apt-get install mysql-client mysql-server libmysqlclient-dev
+
+Running MySQL server is required. Make sure that you have your setup
+configured so there is a user that is able to create databases.
+
+Before running tests, you need to initialize your database. You can
+use mysql-init.sql script for that purpose.
+
+WARNING: It will drop existing Kea database. Do not run this on
+your production server. Assuming your MySQL user is kea, you can
+initialize your test database by:
+
+mysql -u kea -p < mysql-init.sql
+
+After that step, you are ready to run the test:
+
+./mysql_ubench

+ 86 - 0
tests/tools/dhcp-ubench/mysql-init.sql

@@ -0,0 +1,86 @@
+DROP DATABASE kea;
+CREATE DATABASE kea;
+
+CONNECT kea;
+
+CREATE TABLE lease4 (
+
+    # Primary key (serial = BININT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE)
+    lease_id SERIAL,
+    addr INT UNSIGNED UNIQUE,
+
+    # The largest hardware address is for Infiniband (20 bytes)
+    hwaddr VARCHAR(20),
+
+    # The largest client-id is DUID in DHCPv6 - up to 128 bytes
+    client_id VARCHAR(128),
+
+    # Expressed in seconds
+    valid_lft INT,
+
+    # Expressed in seconds,
+    recycle_time INT DEFAULT 0,
+
+    cltt TIMESTAMP,
+
+    pool_id int,
+
+    fixed BOOL,
+
+    # DDNS stuff
+    hostname VARCHAR(255),
+    fqdn_fwd BOOL DEFAULT false,
+    fqdn_rev BOOL DEFAULT false,
+
+    options TEXT,
+    comments TEXT
+);
+
+CREATE TABLE lease6 (
+
+    # Primary key (serial = BININT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE)
+    lease_id SERIAL,
+    addr CHAR(16) BYTE UNIQUE,
+
+    # The largest hardware address is for Infiniband (20 bytes)
+    hwaddr VARCHAR(20),
+
+    # The largest client-id is DUID in DHCPv6 - up to 128 bytes
+    client_id VARCHAR(128),
+
+    iaid int unsigned,
+
+    # Used for IA_PD only (tinyint = 0..255)
+    prefix_len TINYINT unsigned,
+
+    # Expressed in seconds
+    preferred_lft INT,
+
+    # Expressed in seconds
+    valid_lft INT,
+
+    # Expressed in seconds,
+    recycle_time INT DEFAULT 0,
+
+    cltt TIMESTAMP,
+
+    pool_id int,
+
+    fixed BOOL DEFAULT false,
+
+    hostname VARCHAR(255),
+    fqdn_fwd BOOL DEFAULT false,
+    fqdn_rev BOOL DEFAULT false,
+
+    options TEXT,
+    comments TEXT
+);
+
+CREATE TABLE host (
+    address BIGINT NULL,
+    address6 BIGINT NULL,
+    prefix6 BIGINT NULL,
+    hostname VARCHAR(255),
+    options TEXT,
+    comments TEXT
+);

+ 148 - 0
tests/tools/dhcp-ubench/mysql_ubench.cc

@@ -0,0 +1,148 @@
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <mysql/mysql.h>
+
+using namespace std;
+
+const char * hostname ="localhost";
+const char * user = "root";
+const char * passwd = "foobletch";
+
+void failure(MYSQL* conn, const char* operation) {
+    stringstream tmp;
+    tmp << "Error " << mysql_errno(conn) << " during " << operation
+        << ": " << mysql_error(conn);
+    throw tmp.str();
+}
+
+MYSQL * connect() {
+    MYSQL *conn = NULL;
+
+    conn = mysql_init(NULL);
+    if (!conn) {
+        failure(conn, "initializing MySQL library");
+    } else {
+        cout << "MySQL library init successful." << endl;
+    }
+
+    if (!mysql_real_connect(conn, hostname, user, passwd, NULL, 0, NULL, 0)) {
+        failure(conn, "connecting to MySQL server");
+    } else {
+        cout << "MySQL connection established." << endl;
+    }
+
+    return (conn);
+}
+
+bool disconnect(MYSQL * conn) {
+    if (!conn) {
+        throw "NULL MySQL connection pointer.";
+    }
+    mysql_close(conn);
+}
+
+
+
+bool createLease4Test(MYSQL * conn, uint32_t num) {
+    if (!conn) {
+        throw "NULL MySQL connection pointer.";
+    }
+
+    uint32_t addr = 0x01000000; // Let's start with 1.0.0.0 address
+    char hwaddr[20];
+    uint8_t hwaddr_len = 20; // not a real field
+    char client_id[128];
+    uint8_t client_id_len = 128;
+    uint32_t valid_lft = 1000;  // we can use the same value for all leases
+    uint32_t recycle_time = 0;  // not supported in any foresable future,
+                                // so keep this as 0
+    string cltt = "now()"; // timestamp
+    uint32_t pool_id = 0; // let's use pools 0-99
+    bool fixed = false;   //
+    string hostname("foo");      // will generate it dynamically
+    bool fqdn_fwd = true; // let's pretend to do AAAA update
+    bool fqdn_rev = true; // let's pretend to do PTR update
+
+    for (uint8_t i = 0; i < 20; i++) {
+        hwaddr[i] = 65 + i;
+    }
+
+    for (uint8_t i = 0; i < 128; i++) {
+        client_id[i] = 33 + i;
+    }
+
+    for (uint32_t i = 0; i < num; i++) {
+
+        stringstream cltt;
+        cltt << "2012-07-11 15:43:" << (i % 60);
+
+        // the first address is 1.0.0.0.
+        char query[2000], * end;
+        strcpy(query, "INSERT INTO lease4(addr,hwaddr,client_id,"
+               "valid_lft,recycle_time,cltt,pool_id,fixed,hostname,"
+               "fqdn_fwd,fqdn_rev) VALUES(");
+        end = query + strlen(query);
+        end += sprintf(end, "%u,\'", addr);
+        end += mysql_real_escape_string(conn, end, hwaddr, hwaddr_len);
+        end += sprintf(end,"\',\'");
+        end += mysql_real_escape_string(conn, end, client_id, client_id_len);
+        end += sprintf(end, "\',%d,%d,'%s',%d,%s,\'%s\',%s,%s);",
+                       valid_lft, recycle_time, cltt.str().c_str(),
+                       pool_id, (fixed?"true":"false"), hostname.c_str(),
+                       (fqdn_fwd?"true":"false"), (fqdn_rev?"true":"false"));
+        // lease_id field is set automatically
+        // options and comments fields are not set
+
+        cout << "QUERY=[" << query << "]" << endl;
+
+        unsigned int len = end - query;
+        if (mysql_real_query(conn, query, len)) {
+            // something failed.
+        }
+    }
+}
+
+bool searchLease4Test(MYSQL * conn, uint32_t num) {
+    if (!conn) {
+        throw "NULL MySQL connection pointer.";
+    }
+}
+
+bool updateLease4Test(MYSQL* conn, uint32_t num) {
+    if (!conn) {
+        throw "NULL MySQL connection pointer.";
+    }
+}
+
+bool deleteLease4Test(MYSQL* conn, uint32_t num) {
+    if (!conn) {
+        throw "NULL MySQL connection pointer.";
+    }
+}
+
+int main(int argc, const char * argv[]) {
+
+    cout << "MySQL client version is " << mysql_get_client_info() << endl;
+
+    uint32_t num = 1;
+
+    try {
+        MYSQL *conn = connect();
+
+        createLease4Test(conn, num);
+        searchLease4Test(conn, num);
+        updateLease4Test(conn, num);
+        deleteLease4Test(conn, num);
+
+        disconnect(conn);
+
+    } catch (const std::string& e) {
+        cout << "Failed: " << e << endl;
+        return (-1);
+    }
+
+    return (0);
+}