Archive for December, 2007

Got an error reading communication packets

If you look at your error log file for MySQL you’ll inevitably see the warning: “got an error reading communication packets”. The common solution is to increase the max_allowed_packet size.

I’ve seen this set as high as 1GB but typically the problem is alleviated by running it as max_allowed_packet=64M. If you set this higher – either by issuing a `set global max_allowed_packet=64M;` or by editing the cnf and restarting the mysqld process – and the error persists, I’d recommend reading the following links. Very informative.

http://dev.mysql.com/doc/refman/5.0/en/communication-errors.html
http://dev.mysql.com/doc/refman/5.0/en/making-trace-files.html

Perl Parallel Processing for data collection 2

Figured I’d update and say that I solved the issue with threading. (Thanks Steve). The agent.pl script is now using the Proc::Queue module to automatically manage the number of spawned processes via forking. Here’s the run down.

use Proc::Queue;
Proc::Queue::size(10); # changing limit to 10 concurrent processes
Proc::Queue::trace(0); # trace mode off
Proc::Queue::debug(0); # debug is off
Proc::Queue::delay(0.5); # set 500 miliseconds as minimum
# delay between fork calls

…..

$count = @Array;
# loop throuhg the results and spawn processes with Proc::Queue
while($i < $count) {
my $f=fork;
if(defined ($f) and $f==0) {
thread_exec(); #call the poller kickoff function
exit(0)
}
$i++;
}

Monolith 1.2 Update

Lots of changes coming down the pipe for the upcoming release.

Changes as follows.

1. Name change – from Monolith MySQL – Backup Manager to Monolith – MySQL DBA Console [pending]

2. Performance auditing, Security Auditing, OLAP tools, Backup management [complete]

3. Parallel server polling for large cluster support [complete]

4. Trigger support [complete]

5. Backup file consistency checking [complete]

6. Versioning support – variable checks and reporting for 4.1, 5.x, 5.1 [pending]

7. Local backup script + remote backup reporting [complete - needs web interface]

8. Graph reporting for Query Rate + Data growth (predictive analysis), Query Cache utilization, Uptime, Query Cache hits/insert, Queries in cache/Queries not cached, + more [complete]

9. Utilizes two local databases for 1) backup, 2) reporting. [complete]

10. Connection gathering. (count(show processlist)) [complete]

Perl Parallel Processing for data collection

I’ve been wanting to change the Monolith polling (poller.pl) script for a while. It’s written in perl and is called by the agent.pl script. This ideally runs from Cron on hourly or daily intervals – depending on how often you want to collect DB statistics for OLAP needs.

Problem:
I am currently polling >80 servers and the original script runs those checks in serial. Some DBs take longer to poll than others given the load on the server and the number of schemas that need information gathered from them. For example most servers poll in a matter of seconds, but one server has over 300 schemas running on it and the data+index size gathering takes over 10 minutes to poll.

Solution:
migrate the agent.pl script to utilize the threads library that is included in Perl 5.8 (possibly older versions as well but that’s what I’m running).

Method:
I have the agent.pl pull down a list of hostnames to poll, push the various variables for database connection into a array, and send that nested array to a thread_execution function. It spawns a thread for each connection and the time for polling is decreased.

Code:
the important parts, some code left out here. Also the code tag on wordpress sucks and isn’t formatting my tabs.

push(@Array , ([ "$ip_address", "$username", "$pass", "$port", "$host_id" ]));}
while($i < $count) {
my $thr = new threads \&
thread_exec, @Array, $i;
my $id=threads->tid;
$thr->detach;
threads->
yield();
threads->
list();$i++;}}
sub thread_exec {
my $id=threads->tid;
my $ip_address = $Array["$i"]->[0];
my $username = $Array["$i"]->[1];
my $pass = $Array["$i"]->[2];
my $port = $Array["$i"]->[3];
my $host_id = $Array["$i"]->[4];
print "THREAD ID: $id , IP: $ip_address, USR: $username, PASS: $pass, PORT: $port, HOST: $host_id\n";go_poller($ip_address,$username,$pass,$port,$host_id)

Solution:
While this is still a bit buggy I have the following results.

Single Thread Timings

real 47m49.729s
user 0m21.100s
sys 0m5.870s

Multi-Threaded Timings

real 0m35.318
suser 0m23.560s
sys 0m8.270s

So as you see, quite a bit of savings there. Now I just need to figure out why this keeps popping up….
Attempt to free unreferenced scalar during global destruction.

OLAP Begins

Just downloaded this guy here: Mondrian

Over the years I’ve been writing my own OLAP scripts in Perl and PHP. It’s not that I’m tired of doing that – since it’s nice to have complete control over the process, but I just don’t have the time to commit to that right now. So perhaps this can streamline things.

Updates to come once it is online and working.

Standard Issue

Some common issues I run into.

1. Disk space usage – usually a result of binary logs hogging up space. Usually alleviated by setting expire_logs_day=n but in some cases the server sees so much traffic it can fill up before n days is reached. Hence the usual method of “mysql> purge master logs to ‘log-name.xxx’;”

2. Replication issues: seconds behind master too high, duplicate key errors, local data infile associated errors

3. Users need more accounts and don’t have grant options to create new ones. Trivial but menial labor. Meh.

4. Connection limits – someone decides not to use connection pooling or persistent connections, therefore we see some stale connections just hanging out and using up the max_connections variable. Please use connection pooling / persistence.

5. Latency – usually comes into play with MySQL Cluster setups where the management node misses heartbeats from the data/storage nodes. Solution: faster interconnects and vlans that separate traffic – or bonded NICs to aggregate bandwidth. Easier said than done depending on who runs the network.

6. RAM: please get as much ram as you can afford, then you can complain to your DBA about performance.

7. Using MyISAM when you should be using InnoDB. Sure your application may not use transactions but in many cases, almost all, InnoDB will perform better – especially if you have lots of RAM. Crash recovery? Yes, InnoDB is better at that as well.

8. Backup  processes taking too long. I need to have alternate scripts that make use of mysql-parallel-dump. End of story.

CNF files

I have some preconfigured cnf files for the following RAM sizes. These are for dedicated servers so if you’re running Tomcat or Apache on the box as well – you’ll want to drop the buffer sizes accordingly so that MySQL isn’t hogging the resources.

2GB RAM
4GB RAM
8GB RAM
16GB RAM

Connection Logging

Ever wonder how to track the number of active connections without using Cacti or some other monitoring system?

Yep, this does it. Script

New Backup Scripts

Features:

1. Email reporting
2. File consistency checking
3. Retention period file pruning
4. Daily/Weekly/Monthly scripts for Cron execution

Files
Daily backup
Weekly backup
Monthly backup