Chapter 6 Extending MySQL Utilities

Table of Contents

6.1 Introduction to extending the MySQL Utilities
6.2 MySQL Utilities copy_server.py sample
6.3 Specialized Operations
6.3.1 mysql.utilities.command.grep — Search Databases for Objects
6.3.2 mysql.utilities.command.proc — Search Processes on Servers
6.4 Parsers
6.4.1 mysql.utilities.parser — Parse MySQL Log Files

This chapter introduces the architecture for the MySQL Utilities library and demonstrates how to get started building your own utilities.

6.1 Introduction to extending the MySQL Utilities

Administration and maintenance on the MySQL server can at times be complicated. Sometimes tasks require tedious or even repetitive operations that can be time consuming to type and re-type. For these reasons and more, the MySQL Utilities were created to help both beginners and experienced database administrators perform common tasks.

What are the internals of the MySQL Utilities?

MySQL Utilities are designed as a collection of easy to use Python scripts that can be combined to provide more powerful features. Internally, the scripts use the mysql.utilities module library to perform its various tasks. Since a library of common functions is available, it is easy for a database administrator to create scripts for common tasks. These utilities are located in the /scripts folder of the installation or source tree.

If you have a task that is not met by these utilities or one that can be met by combining one or more of the utilities or even parts of the utilities, you can easily form your own custom solution. The following sections present an example of a custom utility, discussing first the anatomy of a utility and then what the mysql.utilities module library has available.

Anatomy of a MySQL Utility

MySQL Utilities use a three-tier module organization. At the top is the command script, which resides in the /scripts folder of the installation or source tree. Included in the script is a command module designed to encapsulate and isolate the bulk of the work performed by the utility. The command module resides in the /mysql/utilities/command folder of the source tree. Command modules have names similar to the script. A command module includes classes and methods from one or more common modules where the abstract objects and method groups are kept. The common modules reside in the /mysql/utilities/common folder of the source tree. The following illustrates this arrangement using the mysqlserverinfo utility:

/scripts/mysqlserverinfo.py
    |
    +--- /mysql/utilities/command/serverinfo.py
            |
            +--- /mysql/utilities/common/options.py
            |
            +--- /mysql/utilities/common/server.py
            |
            +--- /mysql/utilities/common/tools.py
            |
            +--- /mysql/utilities/common/format.py

Each utility script is designed to process the user input and option settings and pass them on to the command module. Thus, the script contains only such logic for managing and validating options. The work of the operation resides in the command module.

Command modules are designed to be used from other Python applications. For example, one could call the methods in the serverinfo.py module from another Python script. This enables developers to create their own interfaces to the utilities. It also permits developers to combine several utilities to form a macro-level utility tailored to a specified need. For example, if there is a need to gather server information as well as disk usage, it is possible to import the serverinfo.py and diskusage.py modules and create a new utility that performs both operations.

Common modules are the heart of the MySQL Utilities library. These modules contain classes that abstract MySQL objects, devices, and mechanisms. For example, there is a server class that contains operations to be performed on servers, such as connecting (logging in) and running queries.

The MySQL Utilities Library

Although the library is growing, the following lists the current common modules and the major classes and methods as of the 1.0.1 release:

Module     Class/Method              Description
---------- ------------------------- ----------------------------------------
database   Database                  Perform database-level operations
dbcompare  get_create_object         Retrieve object create statement
           diff_objects              Diff definitions of two objects
           check_consistency         Check data consistency of two tables
format     format_tabular_list       Format list in either GRID or
                                     delimited format to a file
           format_vertical_list      Format list in a vertical format to
                                     a file
           print_list                Print list based on format (CSV,
                                     GRID, TAB, or VERTICAL)
options    setup_common_options      Set up option parser and options common
                                     to all MySQL Utilities
           add_skip_options          Add common --skip options
           check_skip_options        Check skip options for validity
           check_format_option       Check format option for validity
           add_verbosity             Add verbosity and quiet options
           check_verbosity           Check whether both verbosity and quiet
                                     options are being used
           add_difftype              Add difftype option
           add_engines               Add engine, default-storage-engine
                                     options
           check_engine_options      Check whether storage engines listed
                                     in options exist
           parse_connection          Parse connection values
rpl        Replication               Establish replication connection
                                     between a master and a slave
           get_replication_tests     Return list of replication test function
                                     pointers
server     get_connection_dictionary Get connection dictionary
           find_running_servers      Check whether any servers are
                                     running on the local host
           connect_servers           Connect to source and destination server
           Server                    Connect to running MySQL server
                                     and perform server-level operations
table      Index                     Encapsulate index for a given table
                                     as defined by SHOW INDEXES
           Table                     Encapsulate table for given database
                                     to perform table-level operations
tools      get_tool_path             Search for MySQL tool and return its
                                     full path
           delete_directory          Remove directory (folder) and contents
user       parse_user_host           Parse user, passwd, host, port from
                                     user:passwd@host
           User                      Clone user and its grants to another
                                     user and perform user-level operations

General Interface Specifications and Code Practices

The MySQL Utilities are designed and coded using mainstream coding practices and techniques common to the Python community. Effort has been made to adhere to the most widely accepted specifications and techniques. This includes limiting the choice of libraries used to the default libraries found in the Python distributions. This ensures easier installation, enhanced portability, and fewer problems with missing libraries. Similarly, external libraries that resort to platform-specific native code are also not used.

The class method and function signatures are designed to make use of a small number of required parameters and all optional parameters as a single dictionary. Consider the following method:

def do_something_wonderful(position, obj1, obj2, options={}):
    """Does something wonderful

    A fictional method that does something to object 2 based on the
    location of something in object 1.

    position[in]   Position in obj1
    obj1[in]       First object to manipulate
    obj2[in]       Second object to manipulate
    options[in]    Option dictionary
      width        width of printout (default 75)
      iter         max iterations (default 2)
      ok_to_fail   if True, do not throw exception
                   (default True)

    Returns bool - True = success, Fail = failed
    """

This example is typical of the methods and classes in the library. Notice that this method has three required parameters and a dictionary of options that may exist.

Each method and function that uses this mechanism defines its own default values for the items in the dictionary. A quick look at the method documentation shows the key names for the dictionary. This can be seen in the preceding example where the dictionary contains three keys and the documentation lists their defaults.

To call this method and pass different values for one or more of the options, the code may look like this:

opt_dictionary = {
  'width'      : 100,
  'iter'       : 10,
  'ok_to_fail' : False,
}
result = do_something_wonderful(1, obj_1, obj_2, opt_dictionary)

The documentation block for the preceding method is the style used throughout the library.

Example

Now that you are familiar with the MySQL utilities and the supporting library modules, let us take a look at an example that combines some of these modules to solve a problem.

Suppose that you want to develop a new database solution and need to use real world data and user accounts for testing. The mysqlserverclone MySQL utility looks like a possibility but it makes only an instance of a running server. It does not copy data. However, mysqldbcopy makes a copy of the data and mysqluserclone clones the users. You could run each of these utilities in sequence, and that would work, but we are lazy at heart and want something that not only copies everything but also finds it for us. That is, we want a one-command solution.

The good news is that this is indeed possible and very easy to do. Let us start by breaking the problem down into its smaller components. In a nutshell, we must perform these tasks:

  • Connect to the original server

  • Find all of the databases

  • Find all of the users

  • Make a clone of the original server

  • Copy all of the databases

  • Copy all of the users

If you look at the utilities and the modules just listed, you see that we have solutions and primitives for each of these operations. So you need not even call the MySQL utilities directly (although you could). Now let us dive into the code for this example.

The first task is to connect to the original server. We use the same connection mechanism as the other MySQL utilities by specifying a --server option like this:

parser.add_option("--server", action="store", dest="server",
                  type="string", default="root@localhost:3306",
                  help="connection information for original server in " + \
                  "the form: user:password@host:port:socket")

Once we process the options and arguments, connecting to the server is easy: Use the parse_connection method to take the server option values and get a dictionary with the connection values. All of the heavy diagnosis and error handling is done for us, so we just need to check for exceptions:

from mysql.utilities.common.options import parse_connection

try:
    conn = parse_connection(opt.server)
except:
    parser.error("Server connection values invalid or cannot be parsed.")

Now that we have the connection parameters, we create a class instance of the server using the Server class from the server module and then connect. Once again, we check for exceptions:

from mysql.utilities.common.server import Server

server_options = {
    'conn_info' : conn,
    'role'      : "source",
}
server1 = Server(server_options)
try:
    server1.connect()
except UtilError, e:
    print "ERROR:", e.errmsg

The next item is to get a list of all of the databases on the server. We use the new server class instance to retrieve all of the databases on the server:

db_list = []
for db in server1.get_all_databases():
    db_list.append((db[0], None))

If you wanted to supply your own list of databases, you could use an option like the following. You could also add an else clause which would enable you to either get all of the databases by omitting the --databases option or supply your own list of databases (for example, --databases=db1,db2,db3):

parser.add_option("-d", "--databases", action="store", dest="dbs_to_copy",
                  type="string", help="comma-separated list of databases "
                  "to include in the copy (omit for all databases)",
                  default=None)

if opt.dbs_to_copy is None:
    for db in server1.get_all_databases():
        db_list.append((db[0], None))
else:
    for db in opt.dbs_to_copy.split(","):
        db_list.append((db, None))

Notice we are creating a list of tuples. This is because the dbcopy module uses a list of tuples in the form (old_db, new_db) to enable you to copy a database to a new name. For our purposes, we do not want a rename so we leave the new name value set to None.

Next, we want a list of all of the users. Once again, you could construct the new solution to be flexible by permitting the user to specify the users to copy. We leave this as an exercise.

In this case, we do not have a primitive for getting all users created on a server. But we do have the ability to run a query and process the results. Fortunately, there is a simple SQL statement that can retrieve all of the users on a server. For our purposes, we get all of the users except the root and anonymous users, then add each to a list for processing later:

users = server1.exec_query("SELECT user, host "
                           "FROM mysql.user "
                           "WHERE user != 'root' and user != ''")
for user in users:
    user_list.append(user[0]+'@'+user[1])

Now we must clone the original server and create a viable running instance. When you examine the mysqlserverclone utility code, you see that it calls another module located in the /mysql/utilities/command sub folder. These modules are where all of the work done by the utilities take place. This enables you to create new combinations of the utilities by calling the actual operations directly. Let's do that now to clone the server.

The first thing you notice in examining the serverclone module is that it takes a number of parameters for the new server instance. We supply those in a similar way as options:

parser.add_option("--new-data", action="store", dest="new_data",
                  type="string", help="the full path to the location "
                  "of the data directory for the new instance")
parser.add_option("--new-port", action="store", dest="new_port",
                  type="string", default="3307", help="the new port "
                       "for the new instance - default=%default")
parser.add_option("--new-id", action="store", dest="new_id",
                  type="string", default="2", help="the server_id for "
                       "the new instance - default=%default")

from mysql.utilities.command import serverclone

try:
    res = serverclone.clone_server(conn, opt.new_data, opt.new_port,
                                    opt.new_id, "root", None, False, True)
except exception.UtilError, e:
    print "ERROR:", e.errmsg
    sys.exit()

As you can see, the operation is very simple. We just added a few options we needed like --new-data, --new-port, and --new-id (much like mysqlserverclone) and supplied some default values for the other parameters.

Next, we need to copy the databases. Once again, we use the command module for mysqldbcopy to do all of the work for us. First, we need the connection parameters for the new instance. This is provided in the form of a dictionary. We know the instance is a clone, so some of the values are going to be the same and we use a default root password, so that is also known. Likewise, we specified the data directory and, since we are running on a Linux machine, we know what the socket path is. (For Windows machines, you can leave the socket value None.) We pass this dictionary to the copy method:

dest_values = {
    "user"   : conn.get("user"),
    "passwd" : "root",
    "host"   : conn.get("host"),
    "port"   : opt.new_port,
    "unix_socket" : os.path.join(opt.new_data, "mysql.sock")
}

In this case, a number of options are needed to control how the copy works (for example, if any objects are skipped). For our purposes, we want all objects to be copied so we supply only the minimal settings and let the library use the defaults. This example shows how you can 'fine tune' the scripts to meet your specific needs without having to specify a lot of additional options in your script. We enable the quiet option on so as not to clutter the screen with messages, and tell the copy to skip databases that do not exist (in case we supply the --databases option and provide a database that does not exist):

options = {
    "quiet" : True,
    "force" : True
}

The actual copy of the databases is easy. Just call the method and supply the list of databases:

from mysql.utilities.command import dbcopy

try:
    dbcopy.copy_db(conn, dest_values, db_list, options)
except exception.UtilError, e:
    print "ERROR:", e.errmsg
    sys.exit()

Lastly, we copy the user accounts. Once again, we must provide a dictionary of options and call the command module directly. In this case, the userclone module provides a method that clones one user to one or more users so we must loop through the users and clone them one at a time:

from mysql.utilities.command import userclone

options = {
    "overwrite" : True,
    "quiet"     : True,
    "globals"   : True
}

for user in user_list:
    try:
        res = userclone.clone_user(conn, dest_values, user,
                                   (user,), options)
    except exception.UtilError, e:
        print "ERROR:", e.errmsg
        sys.exit()

We are done. As you can see, constructing new solutions from the MySQL utility command and common modules is easy and is limited only by your imagination.

Enhancing the Example

A complete solution for the example named copy_server.py is located in the appendix. It is complete in so far as this document explains, but it can be enhanced in a number of ways. The following briefly lists some of the things to consider adding to make this example utility more robust.

  • Table locking: Currently, databases are not locked when copied. To achieve a consistent copy of the data on an active server, you may want to add table locking or use transactions (for example, if you are using InnoDB) for a more consistent copy.

  • Skip users not associated with the databases being copied.

  • Do not copy users with only global privileges.

  • Start replication after all of the users are copied (makes this example a clone and replicate scale out solution).

  • Stop new client connections to the server during the copy.

Conclusion

If you find some primitives missing or would like to see more specific functionality in the library or scripts, please contact us with your ideas or better still, write them yourselves! We welcome all suggestions in code or text. To file a feature request or bug report, visit http://bugs.mysql.com. For discussions, visit http://forums.mysql.com/list.php?155.

6.2 MySQL Utilities copy_server.py sample


#
# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#

"""
This file contains an example of how to build a customized utility using
the MySQL Utilities scripts and libraries.
"""

import optparse
import os
import sys

from mysql.utilities import VERSION_FRM
from mysql.utilities.command import dbcopy
from mysql.utilities.command import serverclone
from mysql.utilities.command import userclone
from mysql.utilities.common.server import Server
from mysql.utilities.common.options import parse_connection
from mysql.utilities.exception import UtilError

# Constants
NAME = "example - copy_server "
DESCRIPTION = "copy_server - copy an existing server"
USAGE = "%prog --server=user:pass@host:port:socket " \
        "--new-dir=<path> --new-id=<server_id> " \
        "--new-port=<port> --databases=<db list> " \
        "--users=<user list>"

# Setup the command parser
parser = optparse.OptionParser(
    version=VERSION_FRM.format(program=os.path.basename(sys.argv[0])),
    description=DESCRIPTION,
    usage=USAGE,
    add_help_option=False)
parser.add_option("--help", action="help")

# Setup utility-specific options:

# Connection information for the source server
parser.add_option("--server", action="store", dest="server",
                  type="string", default="root@localhost:3306",
                  help="connection information for original server in " + \
                  "the form: <user>:<password>@<host>:<port>:<socket>")

# Data directory for new instance
parser.add_option("--new-data", action="store", dest="new_data",
                  type="string", help="the full path to the location "
                  "of the data directory for the new instance")

# Port for the new instance
parser.add_option("--new-port", action="store", dest="new_port",
                  type="string", default="3307", help="the new port "
                       "for the new instance - default=%default")

# Server id for the new instance
parser.add_option("--new-id", action="store", dest="new_id",
                  type="string", default="2", help="the server_id for "
                       "the new instance - default=%default")

# List of databases
parser.add_option("-d", "--databases", action="store", dest="dbs_to_copy",
                  type="string", help="comma-separated list of databases "
                  "to include in the copy (omit for all databases)",
                  default=None)

# List of users
parser.add_option("-u", "--users", action="store", dest="users_to_copy",
                  type="string", help="comma-separated list of users "
                  "to include in the copy (omit for all users)",
                  default=None)

# Now we process the rest of the arguments.
opt, args = parser.parse_args()

# Parse source connection values
try:
    conn = parse_connection(opt.server)
except:
    parser.error("Server connection values invalid or cannot be parsed.")

# Get a server class instance
print "# Connecting to server..."
server_options = {
    'conn_info' : conn,
    'role'      : "source",
}
server1 = Server(server_options)
try:
    server1.connect()
except UtilError, e:
    print "ERROR:", e.errmsg

# Get list of databases from the server if not specified in options
print "# Getting databases..."
db_list = []
if opt.dbs_to_copy is None:
    for db in server1.get_all_databases():
        db_list.append((db[0], None))
else:
    for db in opt.dbs_to_copy.split(","):
        db_list.append((db, None))

# Get list of all users from the server
print "# Getting users..."
user_list=[]
if opt.users_to_copy is None:
    users = server1.exec_query("SELECT user, host "
                               "FROM mysql.user "
                               "WHERE user != 'root' and user != ''")
    for user in users:
        user_list.append(user[0]+'@'+user[1])
else:
    for user in opt.users_to_copy.split(","):
        user_list.append(user)

# Build options
options = {
    'new_data'       : opt.new_data,
    'new_port'       : opt.new_port,
    'new_id'         : opt.new_id,
    'root_pass'      : 'root',
    'mysqld_options' : '--report-host=localhost --report-port=%s' % opt.new_port,
}

# Clone the server
print "# Cloning server instance..."
try:
    res = serverclone.clone_server(conn, options)
except UtilError, e:
    print "ERROR:", e.errmsg
    sys.exit()

# Set connection values
dest_values = {
    "user"   : conn.get("user"),
    "passwd" : "root",
    "host"   : conn.get("host"),
    "port"   : opt.new_port,
    "unix_socket" : os.path.join(opt.new_data, "mysql.sock")
}

# Build dictionary of options
options = {
    "quiet" : True,
    "force" : True
}

print "# Copying databases..."
try:
    dbcopy.copy_db(conn, dest_values, db_list, options)
except UtilError, e:
    print "ERROR:", e.errmsg
    sys.exit()

# Build dictionary of options
options = {
    "overwrite" : True,
    "quiet"     : True,
    "globals"   : True
}

print "# Cloning the users..."
for user in user_list:
    try:
        res = userclone.clone_user(conn, dest_values, user,
                                   (user,), options)
    except UtilError, e:
        print "ERROR:", e.errmsg
        sys.exit()

print "# ...done."

  

6.3 Specialized Operations

6.3.1 mysql.utilities.command.grep — Search Databases for Objects

This module provides utilities to search for objects on a server. The module defines a set of object types to be searched. Searches target the fields of each object. The notion of an object field is very loosely defined and means any names occurring as part of the object definition. For example, the fields of a table include the table name, the column names, and the partition names (if it is a partitioned table).

Constants

The following constants denote the object types that can be searched.

  • mysql.utilities.command.grep.ROUTINE

  • mysql.utilities.command.grep.EVENT

  • mysql.utilities.command.grep.TRIGGER

  • mysql.utilities.command.grep.TABLE

  • mysql.utilities.command.grep.DATABASE

  • mysql.utilities.command.grep.VIEW

  • mysql.utilities.command.grep.USER

The following constant is a sequence of all the object types that are available. It can be used to generate a version-independent list of object types that can be searched; for example, options and help texts.

  • mysql.utilities.command.grep.OBJECT_TYPES

Classes

class mysql.utilities.command.grep.ObjectGrep(pattern[, database_pattern=None, types=OBJECT_TYPES, check_body=False, use_regexp=False])

Search MySQL server instances for objects where the name (or content, for routines, triggers, or events) matches a given pattern.

sql() - string

Return the SQL code for executing the search in the form of a SELECT statement.

Returns:SQL code for executing the operation specified by the options.
Return type:string

execute(connections[, output=sys.output, connector=mysql.connector])

Execute the search on each of the connections in turn and print an aggregate of the result as a grid table.

Parameters:
  • connections Sequence of connection specifiers to send the query to

  • output File object to use for writing the result

  • connector Connector to use for connecting to the servers

6.3.2 mysql.utilities.command.proc — Search Processes on Servers

This module searches processes on a server and optionally kills either the query or the connection for all matches.

Processes are matched by searching the fields of the INFORMATION_SCHEMA.PROCESSLIST table (which is available only for servers from MySQL 5.1.7 and later). Internally, the module operates by constructing a SELECT statement for finding matching processes, and then sending it to the server. Instead of performing the search, the module can return the SQL code that performs the query. This can be useful if you want to execute the query later or feed it to some other program that processes SQL queries further.

Constants

The following constants correspond to fields in the INFORMATION_SCHEMA.PROCESSLIST table. They indicate which columns to examine when searching for processes matching the search conditions.

  • mysql.utilities.command.proc.ID

  • mysql.utilities.command.proc.USER

  • mysql.utilities.command.proc.HOST

  • mysql.utilities.command.proc.DB

  • mysql.utilities.command.proc.COMMAND

  • mysql.utilities.command.proc.TIME

  • mysql.utilities.command.proc.STATE

  • mysql.utilities.command.proc.INFO

The following constants indicate actions to perform on processes that match the search conditions.

  • mysql.utilities.command.proc.KILL_QUERY

    Kill the process query

  • mysql.utilities.command.proc.KILL_CONNECTION

    Kill the process connection

  • mysql.utilities.command.proc.PRINT_PROCESS

    Print the processes

Classes

class mysql.utilities.command.proc.ProcessGrep(matches, actions=[], use_regexp=False)

This class searches the INFORMATION_SCHEMA.PROCESSLIST table for processes on MySQL servers and optionally kills them. It can be used to perform a search (and optionally kill), or to generate the SQL statement for doing the same.

For example, to kill all queries with user 'mats', use the following code:

>>> from mysql.utilities.command.proc import *
>>> grep = ProcessGrep(matches=[(USER, "mats")], actions=[KILL_QUERY])
>>> grep.execute("root@server-1.example.com", "root@server-2.example.com")
Parameters:
  • matches (List of (var, pat) pairs) Sequence of field comparison conditions. In each condition, var is one of the constants listed earlier that specify PROCESSLIST table fields and pat is a pattern. For a process to match, all field conditions must match.

sql([only_body=False])

Return the SQL code for executing the search (and optionally, the kill).

If only_body is True, only the body of the function is shown. This is useful if the SQL code is to be used with other utilities that generate the routine declaration. If only_body is False, a complete procedure is generated if there is any kill action supplied, and just a SELECT statement if it is a plain search.

Parameters:
  • only_body (boolean) Show only the body of the procedure. If this is False, a complete procedure is returned.

Returns:

SQL code for executing the operation specified by the options.

Return type:

string

execute(connections, ...[, output=sys.stdout, connector=mysql.connector])

Execute the search on each of the connections supplied. If output is not None, the value is treated as a file object and the result of the execution is printed on that stream. Note that the output and connector arguments must be supplied as keyword arguments. All other arguments are treated as connection specifiers.

Parameters:
  • connections Sequence of connection specifiers to send the search to

  • output File object to use for writing the result

  • connector Connector to use for connecting to the servers

6.4 Parsers

6.4.1 mysql.utilities.parser — Parse MySQL Log Files

This module provides classes for parsing MySQL log files. Currently, Slow Query Log and General Query Log are supported.

Classes

class mysql.utilities.parser.GeneralQueryLog(stream)

This class parses the MySQL General Query Log. Instances support iteration, but the class does not provide multiple independent iterators.

For example, to read the log and print the entries:

>>> general_log = open("/var/lib/mysql/mysql.log")
>>> log = GeneralQueryLog(general_log)
>>> for entry in log:
...     print entry
Parameters:
  • stream (file type) – a valid file type; for example, the result of the built-in Python function open()

version

Returns:Version of the MySQL server that produced the log
Return type:tuple

program

Returns:Full path of the MySQL server executable
Return type:str

port

Returns:TCP/IP port on which the MySQL server was listening
Return type:int

socket

Returns:Full path of the MySQL server Unix socket
Return type:str

start_datetime

Returns:Date and time of the first read log entry
Return type:datetime.datetime

lastseen_datetime

Returns:Date and time of the last read log entry
Return type:datetime.datetime

class mysql.utilities.parser.SlowQueryLog(stream)

This class parses the MySQL Slow Query Log. Instances support iteration, but the class does not provide multiple independent iterators.

For example, to read the log and print the entries:

>>> slow_log = open("/var/lib/mysql/mysql-slow.log")
>>> log = SlowQueryLog(slow_log)
>>> for entry in log:
...     print entry
Parameters:
  • stream (file type) – a valid file type; for example, the result of the built-in Python function open()

version

Returns:Version of the MySQL server that produced the log
Return type:tuple

program

Returns:Full path of the MySQL server executable
Return type:str

port

Returns:TCP/IP port on which the MySQL server was listening
Return type:int

socket

Returns:Full path of the MySQL server Unix socket
Return type:str

start_datetime

Returns:Date and time of the first read log entry
Return type:datetime.datetime

lastseen_datetime

Returns:Date and time of the last read log entry
Return type:datetime.datetime