Archive for the ‘automation’ Category

Severalnines releases ClusterControl™ for MySQL Replication v. 1.1.9

Октябрь 4th, 2011
Stockholm - October 4th 2011

Severalnines, provider of automation and management software for easily usable, highly available and auto-scalable cloud database platforms, today announces the latest release of its flagship product ClusterControl™ for MySQL Replication.

Introducing ClusterControl™ for MySQL Replication v.1.1.9

ClusterControl™ for MySQL Replication enables customers to Deploy, Manage, Monitor and Scale a clustered database platform based on the standard MySQL Replication.

Developers and DBAs now have access to all of the features of Severalnines' flagship product ClusterControl™ specifically adapted to MySQL Replication.

Designed to address issues and needs of MySQL users relying on MySQL Replication, ClusterControl™ for MySQL Replication offers a complete set of tools to assist developers and administrators of all skill levels to deploy, manage, monitor and scale their replicated MySQL databases.

Features and benefits

Config wizard
- Generates individual configurations based on application needs
- Creates deployment packages
- Deploys a Replication cluster in minutes
Config manager
- Sanity checks changes to configuration parameters
- Rolls out configuration changes to all servers and automates rolling restarts
Upgrade advisor
- Keeps users up-to-date by performing upgrades
- Applies minor patches or major upgrades
- Allows roll-back to previous versions
Availability manager
- Clusterware that detects process failures
- Automates MySQL master fail-over
- Performs recovery of failed database processes
Backup manager
- Schedule backups or allow users to start an immediate backup
- Monitor and browse existing backups
- Define retention policies
- No proprietary data formats
Monitor
- Granular end-to-end transaction and database operation monitoring
Query analyzer
- Analysis on cluster-wide running queries
- Global MySQL processlist
- Deep real-time and historical visibility into individual nodes
Alarms and notifications
Scale
- Add new Slaves (or remove) to the cluster without any downtime
- Easily specify hostnames of Slaves to be added

View all of the features here.

Automated fail-over with ClusterControl™

Standard MySQL Replication is easy to set up, and is probably the most widely used mechanism to provide high availability for MySQL. Unfortunately, it is somewhat fragile. There is no support for fail-over. Slaves can easily end up with different data from the master. Diverging datasets can cause replication to stop. Crashing masters can corrupt binary logs, which means replication is not possible any more.

ClusterControl™ addresses the problems associated with master fail-over and resynchronizations, and avoids data loss by taking advantage of semi-sync replication in MySQL 5.5.

ClusterControl™ automates fail-over and reconfiguration of the replication setup to keep the Replication cluster stable and running. This online tutorial explains the MySQL Replication architecture, and how different types of failures are handled.

Users can try it now by generating their deployment package.

Reources related to this release


Configurator for MySQL Replication
Tutorial: ClusterControl for MySQL Replication
Videos: Online Demos on MySQL Replication
Book a demo

Please do reach out to us with your feedback on Facebook, LinkedIn, XING or directly via these contact details for fruitful and interactive discussions on this latest release. For 'instant' communication, feel free to follow us on Twitter!

About Severalnines

Severalnines provides automation and management software for easily usable, highly available and auto-scalable cloud database platforms. ClusterControl™, the company’s flagship product, used by developers and administrators of all skill levels, addresses the full deploy-manage-monitor-scale cycle. Severalnines has enabled over 7,000 deployments to date via its popular online configurator for clustered MySQL databases.

To see who is using Severalnines today, please visit our references page.

PlanetMySQL Voting: Vote UP / Vote DOWN

A simple load test script in Python

Ноябрь 3rd, 2010

Lately I’ve had to do some environment load testing so I wrote this quick script. It can be modified as needed but the basic idea is that it spawns $x threads (–threads) and then sends two connections (or however many you want with –per-connection=) per thread to the URL (–url=). You can have it wait a configurable time between connections as well (–wait=).

The url is appended with a 32 character randomized string so that any database/caching on the backend of the site isn’t serving data from a warm cache. You can hunt down the string length for 32 and change it to whatever you want. Feel free to change and use as needed, just keep my info at top.

#!/usr/bin/python
################################################################################
## DATE: 2010-10-26
## AUTHOR: Matt Reid
## MAIL: mreid@kontrollsoft.com
## SITE: http://kontrollsoft.com
## LICENSE: BSD http://www.opensource.org/licenses/bsd-license.php
################################################################################

from __future__ import division
import threading
import sys
import urllib2
import select
import random
import string
import getopt
import time

class threader(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        global url
        global per
        global u
        for i in range(per):
            if wait > 0:
                time.sleep(wait)
            str = randstr(32)
            # IMPORTANT: this is where we append the search string to the main URL
            # you might need to change this for your site.
            url = "%s/search/%s"%(u,str)
            print "polling url: %s"%(url)
            urllib2.urlopen(url)

def randstr(length):
    global url
    twoletters = [c+d for c in string.letters for d in string.letters]
    r = random.random
    n = len(twoletters)
    l2 = length//2
    lst = [None] * l2
    for i in xrange(l2):
        lst[i] = twoletters[int(r() * n)]
        if length & 1:
            lst.append(random.choice(string.letters))

    return "".join(lst)

def init_thread():
    backgrounds = []
    for thread in range(threads):
        print "Spawning thread: %s"%(thread)
        background = threader()
        background.start()
        backgrounds.append(background)
    for background in backgrounds:
        background.join()

def print_help():
    print '''loader.py - URL load test script
==================================================
Date: 2010-08-26
Website: http://themattreid.com
Author: Matt Reid
Email: themattreid@gmail.com
License: new BSD license
==================================================
Use the following flags to change default behavior

   Option                 Description
   --url=                 URL to test
   --per-connection=      Number of sequential reqests per connection (default 2)
   --threads=             Number of threads for url connections (default 50)
   --wait=                Time to wait in-between requests
   --help                 Print this message

   -u                     Same as --url
   -p                     Same as --per-connection
   -t                     Same as --threads
   -w                     Same as --wait
   -h                     Same as --help
   '''

def main():
    init_thread()
    sys.exit(0)

if __name__ == "__main__":
    global threads #num threads/connections to open
    global u #url to hit
    global per #per connection url hits
    try:
        options, remainder = getopt.getopt(
            sys.argv[1:], 'ptuw', ['per-connection=',
                                   'threads=',
                                   'url=',
                                   'wait=',
                                   'help'])
    except getopt.GetoptError, err:
        print str(err)
        sys.exit(2)

    for opt, arg in options:
        if opt in ('--per-connection'):
            per = int(arg)
        elif opt in ('--threads'):
            threads = int(arg)
        elif opt in ('--url'):
            u = arg
        elif opt in ('--wait'):
            wait = int(arg)
        elif opt in ('--help'):
            print_help()
            sys.exit(2)

    try:
        threads
    except NameError:
        print "No thread quantity specified."
        print_help()
        sys.exit(2)
    try:
        per
    except NameError:
        per = 2
    try:
        u
    except NameError:
        print "No URL Specified"
        print_help()
        sys.exit(2)
    try:
        wait
    except NameError:
        wait=0

    main()

PlanetMySQL Voting: Vote UP / Vote DOWN

A simple load test script in Python

Ноябрь 3rd, 2010

Lately I’ve had to do some environment load testing so I wrote this quick script. It can be modified as needed but the basic idea is that it spawns $x threads (–threads) and then sends two connections (or however many you want with –per-connection=) per thread to the URL (–url=). You can have it wait a configurable time between connections as well (–wait=).

The url is appended with a 32 character randomized string so that any database/caching on the backend of the site isn’t serving data from a warm cache. You can hunt down the string length for 32 and change it to whatever you want. Feel free to change and use as needed, just keep my info at top.

#!/usr/bin/python
################################################################################
## DATE: 2010-10-26
## AUTHOR: Matt Reid
## MAIL: mreid@kontrollsoft.com
## SITE: http://kontrollsoft.com
## LICENSE: BSD http://www.opensource.org/licenses/bsd-license.php
################################################################################

from __future__ import division
import threading
import sys
import urllib2
import select
import random
import string
import getopt
import time

class threader(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        global url
        global per
        global u
        for i in range(per):
            if wait > 0:
                time.sleep(wait)
            str = randstr(32)
            # IMPORTANT: this is where we append the search string to the main URL
            # you might need to change this for your site.
            url = "%s/search/%s"%(u,str)
            print "polling url: %s"%(url)
            urllib2.urlopen(url)

def randstr(length):
    global url
    twoletters = [c+d for c in string.letters for d in string.letters]
    r = random.random
    n = len(twoletters)
    l2 = length//2
    lst = [None] * l2
    for i in xrange(l2):
        lst[i] = twoletters[int(r() * n)]
        if length & 1:
            lst.append(random.choice(string.letters))

    return "".join(lst)

def init_thread():
    backgrounds = []
    for thread in range(threads):
        print "Spawning thread: %s"%(thread)
        background = threader()
        background.start()
        backgrounds.append(background)
    for background in backgrounds:
        background.join()

def print_help():
    print '''loader.py - URL load test script
==================================================
Date: 2010-08-26
Website: http://themattreid.com
Author: Matt Reid
Email: themattreid@gmail.com
License: new BSD license
==================================================
Use the following flags to change default behavior

   Option                 Description
   --url=                 URL to test
   --per-connection=      Number of sequential reqests per connection (default 2)
   --threads=             Number of threads for url connections (default 50)
   --wait=                Time to wait in-between requests
   --help                 Print this message

   -u                     Same as --url
   -p                     Same as --per-connection
   -t                     Same as --threads
   -w                     Same as --wait
   -h                     Same as --help
   '''

def main():
    init_thread()
    sys.exit(0)

if __name__ == "__main__":
    global threads #num threads/connections to open
    global u #url to hit
    global per #per connection url hits
    try:
        options, remainder = getopt.getopt(
            sys.argv[1:], 'ptuw', ['per-connection=',
                                   'threads=',
                                   'url=',
                                   'wait=',
                                   'help'])
    except getopt.GetoptError, err:
        print str(err)
        sys.exit(2)

    for opt, arg in options:
        if opt in ('--per-connection'):
            per = int(arg)
        elif opt in ('--threads'):
            threads = int(arg)
        elif opt in ('--url'):
            u = arg
        elif opt in ('--wait'):
            wait = int(arg)
        elif opt in ('--help'):
            print_help()
            sys.exit(2)

    try:
        threads
    except NameError:
        print "No thread quantity specified."
        print_help()
        sys.exit(2)
    try:
        per
    except NameError:
        per = 2
    try:
        u
    except NameError:
        print "No URL Specified"
        print_help()
        sys.exit(2)
    try:
        wait
    except NameError:
        wait=0

    main()

PlanetMySQL Voting: Vote UP / Vote DOWN

How to: rotate wordpress posts into headline/feature status

Август 8th, 2010

If you’re using the new Arthemia theme for WordPress you might notice that there are two areas of the theme that can have articles promoted to; namely Headline and Featured sections. This is controlled by category association. Basically you have a post and if you want it in the Headline area of the theme you attach the category “headline” to it, similarly for the featured section. Now, let’s say you don’t want to manually change this all the time since it can be time consuming to promote posts to those categories if you want rotating content.

Here’s a simple solution. In this bash script I connect to MySQL and remove the current associations from posts and then randomly choose posts to be promoted to the Headline and Featured categories. This can be modified for other ideas you might have involving categories/posts/randomized associations in WordPress. You can also find the script here: http://pastebin.com/1QqiM5rh – wordpress is clobbering my line breaks so use the Pastebin version if you want to copy/paste the content.

The queries contain IDs for the Headline and Featured categories. In my installation, which will be different than yours, has the Headline category as ID=’103′ and Featured as ID=’104′ – replace as needed. I’m also doing some matching (see the WHERE sections) so that I don’t promote posts with certain IDs that are specific to the site for this script. You’ll want to customize the queries as needed for your site.

#!/bin/bash
#wordpress connection settings
USER="wordpress"
PASSWORD="password"
HOST="mysql.mysite.com"
DB="wordpress"
MYSQL="/usr/bin/mysql"
#remove current relationship for headline/post, set random post as headline
HEADLINE0="DELETE FROM wp_term_relationships WHERE term_taxonomy_id='103'; INSERT INTO wp_term_relationships (object_id,term_taxonomy_id,term_order) VALUES ((select ID from wp_posts where post_name NOT LIKE '%autosave%' AND post_name != '' and post_name !='hello-world' AND ID !='2' AND ID !='16' AND ID !='35' AND ID !='44' ORDER BY RAND() LIMIT 1),'103','0');"
#select current headline post - for reference, we never use this in the script
HEADLINE1="select * from wp_term_relationships where term_taxonomy_id = '103';"
#remove current relationship for featured/post, set random post as featured
FEATURED0="DELETE FROM wp_term_relationships WHERE term_taxonomy_id='104'; INSERT INTO wp_term_relationships (object_id,term_taxonomy_id,term_order) VALUES
((select ID from wp_posts where post_name NOT LIKE '%autosave%' AND post_name != '' and post_name !='hello-world' AND ID !='2' AND ID !='16' AND ID !='35' AND ID !='44' ORDER BY RAND() LIMIT 1),'104','0'),
((select ID from wp_posts where post_name NOT LIKE '%autosave%' AND post_name != '' and post_name !='hello-world' AND ID !='2' AND ID !='16' AND ID !='35' AND ID !='44' ORDER BY RAND() LIMIT 1),'104','0'),
((select ID from wp_posts where post_name NOT LIKE '%autosave%' AND post_name != '' and post_name !='hello-world' AND ID !='2' AND ID !='16' AND ID !='35' AND ID !='44' ORDER BY RAND() LIMIT 1),'104','0'),
((select ID from wp_posts where post_name NOT LIKE '%autosave%' AND post_name != '' and post_name !='hello-world' AND ID !='2' AND ID !='16' AND ID !='35' AND ID !='44' ORDER BY RAND() LIMIT 1),'104','0'),
((select ID from wp_posts where post_name NOT LIKE '%autosave%' AND post_name != '' and post_name !='hello-world' AND ID !='2' AND ID !='16' AND ID !='35' AND ID !='44' ORDER BY RAND() LIMIT 1),'104','0');"
#execute queries
echo -n "Updating headline: "
until $MYSQL --user="$USER" --password="$PASSWORD" --host="$HOST" "$DB" -e "$HEADLINE0"; do
echo "[FAILED]"
echo -n "Running again: "
done
echo "[OK]"
echo -n "Updating featured: "
until $MYSQL --user="$USER" --password="$PASSWORD" --host="$HOST" "$DB" -e "$FEATURED0"; do
echo "[FAILED]"
echo -n "Running again: "
done
echo "[OK]"


PlanetMySQL Voting: Vote UP / Vote DOWN

Kontrollcomm – remote database and system command execution webapp

Март 22nd, 2010
I’m pleased to announce the first release of Kontrollcomm – “The Server Command Automation Interface” is a web-based application that automates remote command execution on linux and unix based servers. There are three main areas of the application: Hosts, Templates, and Commands. The use is very simple: all of your hosts are setup in the [...]
PlanetMySQL Voting: Vote UP / Vote DOWN

Automating MySQL access with expect and bash scripting

Февраль 8th, 2010

If you have multiple database servers with strange names, or if you have to hop over multiple machines to connect to any mysql database server, then you know what a pain it can be to administer such a setup. Thanks to some scripting, you can automate such tasks as follows:

Create an expect script:
/path/to/sshmysql.exp

#!/usr/bin/expect -f
#script by darren cassar
#mysqlpreacher.com

set machine [lindex $argv 0]

set timeout -1

spawn ssh username@$machine
match_max 100000
expect -exact “assword: ”
send — “password\r”
send — “sudo -k; sudo su – mysql\r”
expect -exact “sudo -k; sudo su – mysql”
expect -exact “assword:”
send — “password\r”
interact

# you should change the word password in ’send — “password\r”‘ to your login password
# if you have the same password for each environment you could also script logging into mysql directly from the same expect script BUT that is not recommended.

Create a bash script:
/path/to/login.sh

#!/bin/bash
#script by darren cassar
#mysqlpreacher.com

sm=’/path/to/sshmysql.exp’

menu() {
echo ” 101 – dev.databaseserver1 ”
echo ” 102 – dev.databaseserver2 ”
echo ” 103 – dev.databaseserver3 ”
echo ” 201 – qa.databaseserver1 ”
echo ” 301 – uat.databaseserver1 ”
echo ” 302 – uat.databaseserver2 ”
echo ” 401 – prod.databaseserver1 ”
echo ” ”
}

ARGUMENT=notmenu

if [ -z "$1" ]
then
ARGUMENT=menu
else
choice=$1
fi

if [ $ARGUMENT = "menu" ]
then
menu
else
case “$choice” in
101|dev.databaseserver1 ) $sm dev.databaseserver1;;
102|dev.databaseserver2 ) $sm dev.databaseserver2;;
103|dev.databaseserver3 ) $sm dev.databaseserver3;;
201|qa.databaseserver1 ) $sm qa.databaseserver1;;
301|uat.databaseserver1 ) $sm uat.databaseserver1;;
302|uat.databaseserver2 ) $sm uat.databaseserver2;;
401|prod.databaseserver1 ) $sm prod.databaseserver1;;
* ) echo “Wrong value passed to script”
menu ;;
esac
fi

alias l=’/path/to/login.sh’

Output:

[darrencassar@mymachine ~ ]$ l
101 – dev.databaseserver1
102 – dev.databaseserver2
103 – dev.databaseserver3
201 – qa.databaseserver1
301 – uat.databaseserver1
302 – uat.databaseserver2
401 – prod.databaseserver1

Output:
The below command would log you into the first development database server as mysql user.

[darrencassar@mymachine ~ ]$ l 101

On each machine place aliases for each instance in the .profile

alias use3306=’mysql -u root -p -h 127.0.0.1 -P 3306 –prompt=”mysql \D> “‘

The above setup can be used using any client/server OS: Linux, Solaris, MAC OS or Windows(running Cygwin)

NOTE: If you store the password in clear text inside the expect script, you should at least save the scripts inside an encrypted partition on your machine and make sure that folder is not shared or accessible by anyone. Another way of doing it would be to use either SSHKeys OR save the password inside a file and encrypt it using OpenSSL

Enjoy!


PlanetMySQL Voting: Vote UP / Vote DOWN