Scripted Database Management Using pynuoadmin

This section is intended as a companion to Database Management - A Working Example, showing how to programmatically accomplish the same tasks in python.

Prerequisites

This guide assumes that the pynuoadmin library is installed (for setup instructions, see pynuoadmin Management Client Package Setup). It also assumes that NuoDB Admin API is already running and available with URL http://server0:8888.

Connect to an Admin Server

To run commands, first connect to one of the admin servers.

import pynuoadmin.nuodb_mgmt as nuodb_mgmt

admin_url = 'https://server0:8888'
client_key_pem = '/etc/nuodb/keys/nuocmd.pem'
admin_cert = '/etc/nuodb/keys/ca.cert'

# Get a client connection
conn = nuodb_mgmt.AdminConnection(url_base=admin_url,
                                  client_key=client_key_pem,
                                  verify=admin_cert)

# Check that the server is up
conn.check_server(check_active=True)

# Check that all the servers in the domain are healthy
conn.check_servers(check_active=True, check_connected=True)

Create a New Database

To create a new database, first create one or more archive objects for that database and then create a database object on the server.

NuoDB Community Edition is limited to a single Storage Manager and does not support databases with two or more archives. In order to deploy a two archive database, make sure that you have an Enterprise Edition license installed. For more information, see Obtaining and Installing an Enterprise Edition License.
db_name = 'db'
server_id = 'server0'
archive_path = '/var/opt/nuodb/archive/db'

# Create 2 archives
archive_ids = []
for i in range(2):
    archive = conn.create_archive(db_name=db_name,
                                  server_id=server_id,
                                  archive_path=archive_path + str(i))
    archive_ids.append(archive.id)

# Create the database
conn.create_database(db_name, dba_user='user', dba_password='secret')
Save the Archive IDs of the archives. They will be needed later when starting Storage Managers (SMs) to serve the archives.

Start Storage Managers (SMs)

Start SM processes to serve the archives just created. Once there are RUNNING SMs serving the archives, the database will be transitioned into the RUNNING state. For more information about database state transitions, see Database State Lifecycle.

# Start SM processes
for archive in archive_ids:
    conn.start_process(db_name=db_name,
                       server_id=server_id,
                       engine_type="SM",
                       archive_id=archive)

# Check that there is a process for each of the archives and
# that the database is now in a RUNNING state
conn.check_database(db_name, check_running=True,
                    num_processes=len(archive_ids),
                    timeout=60)

Start Transaction Engines (TEs)

Though the database is running, it is not able to accept queries. For that, a TE process needs to be started.

# Start TE process
te = conn.start_process(db_name=db_name, server_id=server_id, engine_type="TE")
te_sid = te.start_id

# Wait for the TE to start
conn.check_process(te_sid, check_running=True, timeout=60)

Start a Database Using a Start Plan

To avoid keeping track of archive IDs manually, NuoDB Admin can generate a start plan. A start plan is a list of processes to start so that every archive is served by an SM. A list of hosts on which a new TE should be started can also be provided to the method.

# Optionally, kill any processes previously started for the database
conn.shutdown_database(db_name)
conn.check_database(db_name, num_processes=0, timeout=60)

te_hosts = [server_id]  # Hosts on which to start a new TE

# Generate a start plan
# By setting reusable to False, only archives that are not currently running are included
start_plan = conn.get_database_startplan(db_name, te_server_ids=te_hosts, reusable=False)

# TEs should not start until the database is RUNNING
num_sms = 0
for process in start_plan['processes']:
    if process['engineType'] in ('SM', 'SSM'):
        conn.start_process(db_name=process['dbName'],
                           server_id=process['host'],
                           engine_type=process['engineType'],
                           archive_id=process['archiveId'])
        num_sms += 1

conn.check_database(db_name, check_running=True, num_processes=num_sms, timeout=60)

for process in start_plan['processes']:
    if process['engineType'] == 'TE':
        conn.start_process(db_name=process['dbName'],
                           server_id=process['host'],
                           engine_type=process['engineType'])

# Make sure that the database is running again with the correct number of processes
conn.check_database(db_name,
                    check_running=True,
                    num_processes=len(start_plan['processes']),
                    timeout=60)

Cleanup

To remove the database created, first shut down all running processes then delete the database from the domain.

conn.shutdown_database(db_name)

# Wait for database processes to exit
conn.check_database(db_name, num_processes=0, timeout=60)

conn.delete_database(db_name)