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 Installing pynuoadmin). 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

Before creating a database, ensure a NuoDB license file is installed in the domain. The NuoDB Limited Use License allows only one Storage Manager (SM).

The NuoDB Limited Use License supports creating only one Storage Manager (SM). To deploy a database with two or more SMs, install a NuoDB Enterprise License. For more information, see Obtain and Install a Product License.

First create one or more archive objects for the new database, then create a database object:

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)