Skip to main content

C

Dependencies

  • C compiler (e.g. gcc)

  • pthreads library (present on most Linux distributions)

  • mysqlclient library, available from the libmysqlclient-dev package on Debian-based distributions.

Code

/* Compile with:
 *
 * cc multi_threaded_inserts.c -lmysqlclient -pthread -o mti
 */

#include <stdlib.h>
#include <stdio.h>

#include <mysql/mysql.h>

const static char *host = "127.0.0.1";
const static char *user = "root";
const static char *passwd = "";
const static size_t port = 3306;

#define NUM_WORKERS 20

static volatile int keep_going = 1;

void *insert_worker(void *worker_id);

int main()
{
    my_init();

    MYSQL conn;
    mysql_init(&conn);

    printf("Connecting to SingleStoreDB...\n");
    if (mysql_real_connect(&conn, host, user, passwd, NULL, port, NULL, 0) != &conn)
    {
        printf("Could not connect to the SingleStoreDB database!\n");
        goto failure;
    }

    printf("Creating database 'test'...\n");
    if (mysql_query(&conn, "create database test") || mysql_query(&conn, "use test"))
    {
        printf("Could not create 'test' database!\n");
        goto failure;
    }

    printf("Creating table 'tbl' in database 'test'...\n");
    if (mysql_query(&conn, "create table tbl (id bigint auto_increment primary key)"))
    {
        printf("Could not create 'tbl' table in the 'test' database!\n");
        goto failure;
    }

    printf("Launching %lu insert workers...\n", NUM_WORKERS);

    pthread_t workers[NUM_WORKERS];

    size_t i;
    for (i = 0; i < NUM_WORKERS; ++i)
    {
        pthread_create(&workers[i], NULL, &insert_worker, (void *)i);
    }

    printf("Running inserts for %lu seconds...\n", 10);
    sleep(10);
    keep_going = 0;

    size_t rows_inserted = 0;
    for (i = 0; i < NUM_WORKERS; ++i)
    {
        size_t rows_i;
        pthread_join(workers[i], &rows_i);
        rows_inserted += rows_i;
    }

    printf("Inserted %lu rows. Cleaning up...\n", rows_inserted);

    if (mysql_query(&conn, "drop database test"))
    {
        printf("Could not drop the testing database 'test'!\n");
    }
    mysql_close(&conn);

    return 0;

failure:
    mysql_close(&conn);
    return 1;
}

void *insert_worker(void *worker_id)
{
    size_t id = (size_t) worker_id;

    MYSQL conn;
    mysql_init(&conn);
    if (mysql_real_connect(&conn, host, user, passwd, "test", port, NULL, 0) != &conn)
    {
        printf("Worker %lu could not connect to the SingleStoreDB database! Aborting...\n", id);
        exit(1);
    }

    size_t i;
    for (i = 0; keep_going; i += 8)
    {
        if (mysql_query(&conn, "insert into tbl values (null), (null), (null),"
                        "(null), (null), (null), (null), (null)"))
        {
            printf("Worker %lu failed to insert data, aborting...\n", id);
            exit(1);
        }
    }

    mysql_close(&conn);

    return (void *)i;
}