Simple $wpdb error handling

For my own copy and paste pleasures, here are some wpdb error handling examples. It will grow over time:

A very simple non-failing method for in a function:


if ($wpdb->query($query) === FALSE) {
	return FALSE;
} else {
	return $wpdb->get_results($query);
}

A more complex method for in a function. It uses WordPress’s built in WP_Error class:


if ( false === $wpdb->query($sql)) {
	if ( $wp_error ) {
		return new WP_Error( 'db_query_error', 
			__( 'Could not execute query' ), $wpdb->last_error );
	} else {
		return 0;
	}
}

A very simple flow breaking method, in-line procedural:


if ($wpdb->query($query) === FALSE) {
	wp_die( __('Crap! well that’s screwed up: ' . $wpdb->last_error) ); 
}

Story line of the Amazon EC2 and RDS failure and recovery

I wanted to read the timeline of the Amazon “Networking Event”.  So I’ve taken the logs of the EC2 and RDS status updates and put them together for a post.

If you want to learn about how to make a more robust Amazon Web Services (AWS) configuration, read my article on the WebDevStudios blog.

RDS Apr 21, 1:48 AM PDT We are currently investigating connectivity and latency issues with RDS database instances in the US-EAST-1 region.

RDS Apr 21, 2:16 AM PDT We can confirm connectivity issues impacting RDS database instances across multiple availability zones in the US-EAST-1 region.

RDS Apr 21, 3:05 AM PDT We are continuing to see connectivity issues impacting some RDS database instances in multiple availability zones in the US-EAST-1 region. Some Multi AZ failovers are taking longer than expected. We continue to work towards resolution.

RDS Apr 21, 4:03 AM PDT We are making progress on failovers for Multi AZ instances and restore access to them. This event is also impacting RDS instance creation times in a single Availability Zone. We continue to work towards the resolution.

RDS Apr 21, 5:06 AM PDT IO latency issues have recovered in one of the two impacted Availability Zones in US-EAST-1. We continue to make progress on restoring access and resolving IO latency issues for remaining affected RDS database instances.

RDS Apr 21, 6:29 AM PDT We continue to work on restoring access to the affected Multi AZ instances and resolving the IO latency issues impacting RDS instances in the single availability zone.

RDS Apr 21, 8:12 AM PDT Despite the continued effort from the team to resolve the issue we have not made any meaningful progress for the affected database instances since the last update. Create and Restore requests for RDS database instances are not succeeding in US-EAST-1 region.

RDS Apr 21,10:35 AM PDT We are making progress on restoring access and IO latencies for affected RDS instances. We recommend that you do not attempt to recover using Reboot or Restore database instance APIs or try to create a new user snapshot for your RDS instance – currently those requests are not being processed.

RDS Apr 21, 2:35 PM PDT We have restored access to the majority of RDS Multi AZ instances and continue to work on the remaining affected instances. A single Availability Zone in the US-EAST-1 region continues to experience problems for launching new RDS database instances. All other Availability Zones are operating normally. Customers with snapshots/backups of their instances in the affected Availability zone can restore them into another zone. We recommend that customers do not target a specific Availability Zone when creating or restoring new RDS database instances. We have updated our service to avoid placing any RDS instances in the impaired zone for untargeted requests.

RDS Apr 21, 2:41 11:42 PM PDT In line with the most recent Amazon EC2 update, we wanted to let you know that the team continues to be all-hands on deck working on the remaining database instances in the single affected Availability Zone. It’s taking us longer than we anticipated. When we have an updated ETA or meaningful new update, we will make sure to post it here. But, we can assure you that the team is working this hard and will do so as long as it takes to get this resolved.

RDS Apr 22, 2:41 7:08 AM PDT In line with the most recent Amazon EC2 update, we are making steady progress in restoring the remaining affected RDS instances. We expect this progress to continue over the next few hours and we’ll keep folks posted.

RDS Apr 22, 2:41 2:43 PM PDT We are continuing to make progress in restoring access to the remaining affected RDS instances. We expect this progress to continue over the next few hours and we’ll keep folks posted.

EC2 Apr 22, 2:41 AM PDT We continue to make progress in restoring volumes but don’t yet have an estimated time of recovery for the remainder of the affected volumes. We will continue to update this status and provide a time frame when available.
EC2 Apr 22, 6:18 AM PDT We’re starting to see more meaningful progress in restoring volumes (many have been restored in the last few hours) and expect this progress to continue over the next few hours. We expect that well reach a point where a minority of these stuck volumes will need to be restored with a more time consuming process, using backups made to S3 yesterday (these will have longer recovery times for the affected volumes). When we get to that point, we’ll let folks know. As volumes are restored, they become available to running instances, however they will not be able to be detached until we enable the API commands in the affected Availability Zone.

EC2 Apr 22, 8:49 AM PDT We continue to see progress in recovering volumes, and have heard many additional customers confirm that they’re recovering. Our current estimate is that the majority of volumes will be recovered over the next 5 to 6 hours. As we mentioned in our last post, a smaller number of volumes will require a more time consuming process to recover, and we anticipate that those will take longer to recover. We will continue to keep everyone updated as we have additional information.

EC2 Apr 22, 2:15 PM PDT In our last post at 8:49am PDT, we said that we anticipated that the majority of volumes “will be recovered over the next 5 to 6 hours.” These volumes were recovered by ~1:30pm PDT. We mentioned that a “smaller number of volumes will require a more time consuming process to recover, and we anticipate that those will take longer to recover.” We’re now starting to work on those. We’re also now working to enable customers to be able to launch EBS backed instances and create, delete, attach and detach EBS volumes in the affected Availability Zone. Our current estimate is that this will take 3-4 hours until full access is restored. We will continue to keep everyone updated as we have additional information.

EC2 Apr 22, 6:27 PM PDT We’re continuing to work on restoring the remaining affected volumes. The work we’re doing to enable customers to be able to launch EBS backed instances and create, delete, attach and detach EBS volumes in the affected Availability Zone is taking considerably more time than we anticipated. The team is in the midst of troubleshooting a bottleneck in this process and we’ll report back when we have more information to share on the timing of this functionality being fully restored.

EC2 Apr 22, 9:11 PM PDT We wanted to give a more detailed update on the state of our recovery. At this point, we have recovered a large number of the stuck volumes and are in the process of recovering the remainder. We have added significant storage capacity to the cluster, and storage capacity is no longer a bottleneck to recovery. Some portion of these volumes have lost the connection to their instance, and are waiting to be connected before normal operations can resume. In order to re-establish this connection, we need to allow the instances in the affected Availability Zone to access the EC2 control plane service. There are a large number of control plane requests being generated by the system as we re-introduce instances and volumes. The load on our control plane is higher than we anticipated. We are re-introducing these instances slowly in order to moderate the load on the control plane and prevent it from becoming overloaded and affecting other functions. We are currently investigating several avenues EC2 to unblock this bottleneck and significantly increase the rate at which we can restore control plane access to volumes and instances– and move toward a full recovery. The team has been completely focused on restoring access to all customers, and as such has not yet been able to focus on performing a complete post mortem. Once our customers have been taken care of and are fully back up and running, we will post a detailed account of what happened, along with the corrective actions we are undertaking to ensure this doesn’t happen again. Once we have additional information on the progress that is being made, we will post additional updates.

RDS Apr 23, 12:00 AM PDT We are continuing to work on restoring access to the remaining affected RDS instances. We expect the restoration process to continue over the next several hours and we’ll update folks as we have new information.


EC2 Apr 23, 1:55 AM PDT We are continuing to work on unblocking the bottleneck that is limiting the speed with which we can re-establish connections between volumes and their instances. We will continue to keep everyone updated as we have additional information.

RDS Apr 23, 8:45 AM PDT We have made significant progress in resolving stuck IO issues and restoring access to RDS database instances and now have the vast majority of them back operational again. We continue to work on restoring access to the small number of remaining affected instances and we’ll update folks as we have new information.

EC2 Apr 22, 8:54 AM PDT We have made significant progress during the night in manually restoring the remaining stuck volumes, and are continuing to work through the remainder. Additionally we have removed some of the bottlenecks that were preventing us from allowing more instances to re-establish their connection with the stuck volumes, and the majority of those instances and volumes are now connected. We’ve encountered an additional issue that’s preventing the recovery of the remainder of the connections from being established, but are making progress. Once we solve for this bottleneck, we will work on restoring full access for customers to the control plane.

EC2 Apr 22, 11:54 AM PDT Quick update. We’ve tried a couple of ideas to remove the bottleneck in opening up the APIs, each time we’ve learned more but haven’t yet solved the problem. We are making progress, but much more slowly than we’d hoped. Right now we’re setting up more control plane components that should be capable of working through the backlog of attach/detach state changes for EBS volumes. These are coming online, and we’ve been seeing progress on the backlog, but it’s still too early to tell how much this will accelerate the process for us. For customers who are still waiting for restoration of the EBS control plane capability in the impacted AZ, or waiting for recovery of the remaining volumes, we understand that no information for hours at a time is difficult for you. We’ve been operating under the assumption that people prefer us to post only when we have new information. Think enough people have told us that they prefer to hear from us hourly (even if we don’t have meaningful new information) that we’re going to change our cadence and try to update hourly from here on out.

EC2 Apr 22, 12:46 PM PDT We have completed setting up the additional control plane components and we are seeing good scaling of the system. We are now processing through the backlog of state changes and customer requests at a very quick rate. Barring any setbacks, we anticipate getting through the remainder of the backlog in the next hour. We will be in a brief hold after that, assessing whether we can proceed with reactivating the APIs.

RDS Apr 23, 12:54 PM PDT As we mentioned in our last update at 8:45 AM, we now have the vast majority of affected RDS instances back operational again. Since that post, we have continued to work on restoring access to the small number of remaining affected instances. RDS uses EBS, and as such, our pace of recovery is dependent on EBS’s recovery. As mentioned in the most recent EC2 post, EBSs recovery has gone a bit slower than anticipated in the last few hours. This has slowed down RDS recovery as well. We understand how significant this service interruption is for our affected customers and we are working feverishly to address the impact. We’ll update folks as we have new information. Additionally we have heard from customers that you prefer more frequent updates, even if there has been no meaningful progress. We have heard that feedback, and will try to post hourly updates here. Some of these updates will point to EC2’s updates (as they continue to recover the rest of EBS volumes), but we’ll post nonetheless.

HOW TO: Installing MySQL on RedHat/CentOS/Amazon Linux in 5 easy steps.

This seems like it should be a really complicated tasks, but once you have done a few it sinks in that this is really simple…

 

Just run each of the following 5 steps as root.  Answer any questions with the common sense response, and you are done

yum groupinstall “MySQL Database”
/usr/bin/mysql_install_db –user=mysql
service mysqld start
/usr/bin/mysql_secure_installation
chkconfig mysqld on

Details

Step 1 uses the groupinstall  command to install all of the most common mysql daemons.  This one line eliminates perhaps half a dozen steps.

Step 2 does the initial DB configuration for the software.  You can select the defaults for all most all options, but when it asks about security, say no because we are gonna do it in the next two lines.

Step 3 starts the MySQL server for the first time

Step 4 when run with all the defaults secures your server nicely.

Step 5 is one that lots of  the tutorials miss.  When you reboot your DB server, it would be nice if MySQL ran right? Well this line does that.

 

If you want to change your server configuration from the default, run this line:

nano /etc/my.cnf

After saving, if you are done restart the MySQL daemon:

service mysqld start

Simple as that, you are done… Any Questions?

HOW TO: How do you redirect all https traffic to http?

There are LOTS of ways to do this.

 

This is what I do so that I can use the same code in any site’s .htaccess

RewriteEngine On
RewriteBase /
Options +FollowSymlinks
RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ http://%{SERVER_NAME}/$1 [R=301,L]

 

I like this better than checking for port 443 because sometimes load balancers handle the certificate and encryption then send the information to port 80.   This works in that situation. Of course you can adjust this code to redirect to www.%{SERVER_NAME} if that is your preference.

 

Of course redirecting all https traffic to http is equally simple by adding a ! or not to the https check and adjusting your target.

RewriteEngine On
RewriteBase /
Options +FollowSymlinks
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1 [R=301,L]

 

 

HOW TO: Determine which flavor or version of Linux is installed

If you are working with a Linux or Unix server, you may not even know which operating system release is on the server or even if it is a 32 bit or 64 bit machine. How do you even tell if your server is 32bit or 64bit? Usually this is not too terribly important. Most of the commands just work. However, it can become important when you want to install or upgrade the server software.

Fortunately, getting the OS version and machine information is JUST as simple..

cat /etc/*-release

That one line will work all versions that anyone who needs to read this article will ever run into.*

Debian: /etc/debian_version, /etc/debian_release (rare)
Fedora Core: /etc/fedora-release
Gentoo Linux: /etc/gentoo-release
Mandrake: /etc/mandrake-release
Mandriva/Mandrake Linux: /etc/mandriva-release, /etc/mandrake-release, /etc/mandakelinux-release
Novell Linux Desktop: /etc/nld-release
Red Hat: /etc/redhat-release
Solaris SPARC: /etc/release
Sun JDS: /etc/sun-release
SUSE Linux: /etc/SuSE-release, /etc/novell-release
SUSE Linux ES9: /etc/sles-release
Ubuntu Linux: /etc/lsb-release

This will produce results like:

CentOS release 5.5 (Final)

or

Red Hat Enterprise Linux Server release 5.4 (Tikanga)

 

The next thing you need to know is if the kernel you have installed is 64 bit ot 32 bit. You can do that via this command

cat /proc/cpuinfo

 

 

Here is an example of a 32bit kernel: (Notice the x86)

Linux version 2.6.18-164.el5PAE (mockbuild@x86-002.build.bos.redhat.com) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Tue Aug 18 15:59:11 EDT 2009

Here is an example of a 64bit kernel:(Notice the x64)

Linux version 2.6.18-028stab070.5 (root@rhel5-build-x64) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Fri Sep 17 15:37:23 MSD 2010

I hope this helps!

 

 

* NOTE:

If you have built your own server, there is a possility you have to run a slightly different command line as some version use *_version as the file name.

These flavours include:

Red Hat: /etc/redhat_version
Slackware: /etc/slackware-version
Knoppix: knoppix_version

So if the above line produced no results try:

cat /etc/*version

See more examples of these files here on Linux Mafia

HOW TO: Take a quick glance at errors from a project.

PHP records all errors to a file named error_log

I needed to look at the status of a project on two servers to see what errors were being thrown.

This command line shows the top 20 errors and how often they occurred within the last 1000 errors..
tail -1000 error_log | awk -F ‘]’ ‘{print $4}’| sort | uniq -c | sort -nr | head -20

Depending upon the load on your server, that could report on the errors in the last half hour, or across several days. In either case, it will give you a quick idea on where you should clean your code of warnings and notices and where you need to do some fixing… Just remember there’s no time line involved in the report. So the error messages could be from something already fixed.

HOW TO: Find the IP address of a domain from the local server before propagation

Have you ever wanted to know the ip address assigned to a domain according to your local server? I had this problem. I needed to get an IP address of a domain before the domain propagated. I was writing a custom cpanel postwwwacct script. For some very, very odd reason, cpanel will tell you IF you have a dedicated ip address for the domain, but not what it is. Fortunately postwwwacct occurs after the bind of the ip address.

I thought I would have to use a grep and awk to parse the IP address out of the .db file in /var/named but fortunately it occurred to me that I could just do a simple dig call within my script and get the value back. That’s straight forward and returns only the information I want to have.

So here is a perl script that does this:

#!/usr/bin/perl
$ns='ns1.example.com';
$domain='wahoo.com';
$ip=`dig \@$ns $domain A +short`;
if ( $ip == -1 )
{
  print "command failed: $!\n";
}
else
{
  printf "The result is: " . $ip;
}

 

You will of course have to replace ns1.example.com with the url for the name server running on your server.
The backticks (“) indicate you need to run a command line and return the stdout results. (And yes, I think backticks sound gross but that’s what they are called.)

Also note the @ is a special character and must be escaped with a \.

Hope this helps!

Getting Started With BackPress

This summer I took the opportunity to write my first BackPress application.  It was an educational experience that came with a number of surprises. I thought I would share my experience with you, along with some tips to get you out of the gates with a BackPress project of your own.

My Project

In 2008, the comedic duo Rhett and Link created a YouTube contest called SuperNote. I created a PHP app to support this project. It created its own user database, collected videos from YouTube via the API and allowed users to login to and review the video and record, among other things, how long the video’s creator was able to hold a vocal note without interruption. It also allowed different levels of user interaction with different fields visible for each user role.  Everything about this project was written from scratch, with the exception of using WordPress 2.6’s wp-db.php for database access.  It worked alright. I used sessions for logging in and that was always somewhat flakey.

In 2010, the guys decided this project would be a bi-annual event. Since we would roll out this code every two years, it was worth an investment in its stability.  Enter BackPress,  stage right.  Because the code in BackPress makes up the core of projects such as BuddyPress and in some ways WordPress itself, I knew it would have undergone much more rigorous testing than my own home brewed code had.

Additionally the project was expanding in scope.  We wanted to have the project integrated the WordPress blog, which was in turn integrated with Ning and the same password could be used on each.  A requirement was that only active members of the community could have access to the tool and that this access was granted or denied via the WordPress user interface.

 

What BackPress IS and what it ISN’T.

When I started this project, I was thinking of BackPress as a very small white labeled WordPress.  I expected that I could put BackPress on a website and it would do SOMETHING. I wasn’t expecting anything pretty, but I was expecting to at least be able to visit the site and get a mostly blank “Hello World” screen created by BackPress.  I expected to be able to login and maybe see a profile page with my login info and nothing more.

I was expecting WAAAAAAAY too much.

Here is what the BackPress.org website says:

BackPress is a PHP library of core functionality for web applications. It grew out of the immensely popular WordPress project, and is also the core of the bbPress and GlotPress sister-projects.

It includes a variety of the foundations you need to build robust, scalable web applications including (amongst other things):

  • Logging,
  • User Roles and Capabilities (Permission systems),
  • Database connections (across multiple servers and multiple datacenters),
  • HTTP Transactions,
  • XML-RPC Server and Client,
  • Object caching,
  • Formatting,
  • XSS and SQL injection protection, including a variety of powerful escaping functions,
  • Taxonomies and
  • Options management

And the best part? It’s all licensed under a generous GPL2 license, so you can use it in your own free or commercial projects.

That is all completely true, but the word that should be underscored, bolded and blink tagged is “LIBRARY”. (Ok so I couldn’t bring myself to <blink> it…).

You need to think of BackPress like a C library.  You won’t have a working program of any kind until you write it.  In BackPress, there is no UI for any of the code.  If you want to have your users login, you need to write that.  If you want to actually display something to the screen via index.php, you have to build it and integrate the parts of BackPress you need.  BackPress does EVERYTHING listed on the .org site, but only provides the frameworks.

One of the things that surprised me the most was the basic nature of both the Option and Role management APIs.  For example, you can set options, retrieve options and all of that across a single WordPress “session” or visit.  It all works great – but if you want the values to be persistent and the options to be available the next time the site is visited, you will need to include a storage mechanism.  You could use a database or memcache or flat files, but without connecting your options and roles system to SOMETHING, everything you set goes away.

Plan Ahead

Because I’d written a large amount of my project in 2008, I was able to do a conversion to BackPress in one all night coding session and other than the surprise of no persistent storage of options, it all worked.  However, you should plan on doing a full UX design and data structure design for your project.

You should have answers to the following – not necessarily in any order:

  • Are you creating a single use project or do you need to consider other installations?  This will help you decide whether or not you need routines to create the database tables and default options, or if you want to hand create them and just have your BackPress site use them.
  • Do you need to store options? How will you store them?
  • Do you need to check user roles and if so what do you want them to be? Where/how will you store them?
  • If you are connecting with WordPress, will your tables, used to store options, users and etc, be located in the same WordPress database? If so, will your tables have a unique prefix or will you use pre-existing WordPress tables? Or if not will you access your tables from your own database?  Where will the database access information be stored?
  • Do you need to provide profile editing?
  • Do you need a link to login from the home page? Or do you want to only display a login prompt only when the user is not logged in?
  • Do you need a log out link?
  • Do you need a UI to allow administration of the site itself?  Do you have a role for that?
  • etc etc etc

How to get started

The best thing that you can do to get started is to look at an existing project.  There aren’t a lot of them out there.  Because so much of the code is custom purposed, not everyone thinks their code is ready to be shared.  Additionally, you want to protect the client’s IP and still release a working project. Since I’ve not yet shared the SuperNote code, I’m going to give you the link that I found that provided the most useful launch point.  

SupportPress: https://supportpress.svn.wordpress.org/trunk/

Browsing the code of SupportPress, I was finally able to realize what BackPress was and what it wasn’t.  SupportPress is a neat project that has only been released via SVN (and maybe even that much of a release is Google’s fault as I only found reference to it in search results.).  I don’t think it is yet code complete, but it has all the basic functionality you would need and can help guide you as to what you will need to create.  It also contains code from BuddyPress (which also can be examined for how BuddyPress used BackPress) and you may not want to use the same solutions that SupportPress chose.  So I would advise using it as a guide only.

When I release the source code for the SuperNote Review Tool (Hmmm “SNoRT” I like it!!!!) I will include a link here:

I hope this helps.  I’ll do my best to answer any questions raised in the comments.  Also if there is interest I’ll create some posts with code examples from my project.  It’s been a few months since it was written and it is all getting to be a bit fuzzy in my memory. So, if you want more articles on the subject, let me know soon!

How do you set the local timezone on a CentOS Linux server?

Though installations will vary, this is usually done via a file named timezone in the /etc directory.

By default, there’s probably already a file there set to the utc timezone.

So if you do a

cat /etc/timezone

you will see

TZif2UTCTZif2UTC
UTC0

Fortunately you don’t have to decipher all that. Your install probably has files for every timezone imaginable in the /usr/share/zoneinfo directory. You just have to create a symbolic link to one of those files. Then when Linux asks for the timezone, it returns the file you’ve linked to.

For example for the eastern time zone, EST, you could get away with something like this:

ln -sf /usr/share/zoneinfo/EST localtime

However, what would be even better is if you could specify a city near you that shares your timezone.

For example, I would chose cities from the America directory. Specifically I would choose New_York. So my timezone files link with

ln -sf /usr/share/zoneinfo/America/New_York localtime

The directories can be very specific… as we have some very specific people – like those crazy Indianans. People in the state of Indiana can be really whacky about timezones. So you can be even more specific like:

ln -sf /usr/share/zoneinfo/America/Indiana/Winamac localtime

In the end, you look around, chose the file that is best, remove the existing localtime file and create a link. Pretty simple really.

HOW TO: Dump or Backup all MySQL databases to separate files

I needed to transfer about 40 databases from a new clients server over to my hosting platform.

When doing a couple database exports, I might use PHPMyAdmin to do the export. Heck, it’s convenient because I usually want to look around at the same time. For doing a straight export, mysqldump is a great program that is even easier than phpmyadmin. There’s really nothing to it! (NOTE: For large databases with a LARGE number of tables you need to add –skip-lock-tables)

mysqldump –all-databases > dbdump.sql

If you want to get fancy, you can even compress the file

mysqldump –all-databases | gzip -9 > dbdump.sql.gz

But I wanted to go one step further. I wanted every database to have a separate file, compressed and correctly named.

I was shocked how simple it was to write. First I had to ask mysql for a list of the databases. Then I needed extract just the database name, removing the table borders. Then I needed to tell mysqldump to use each database name in the export source and destination.

In no time I had a 3 line script that was incredibly powerful.

I give you backupdbs.sh

#!/bin/bash
for database in $(mysql -e "show databases"|awk -F " " '{print $1}'); do
  mysqldump $database | gzip -9 > $database.sql.gz
done

 

 

Note that you may need to provide the -u and -p parameters (username and password).

That’s all there is to it!