You've probably heard the announcement: Martin Pitt's PPA is being deprecated. This is in an effort to push folks towards the new official apt.postgresql.org.
See the announcement here: http://www.postgresql.org/about/news/1432/
Also, see the deprecation notice on Martin's PPA:
https://launchpad.net/~pitti/+archive/postgresql
Since we have quite a few customers using Martin's PPA for PostgreSQL packages under Ubuntu, I wrote a little shell script to switch repositories if you're using Martin's PPA and just install the apt.postgresql.org repository if you are not.
You can find it here: https://github.com/pgexperts/add-pgdg-apt-repo
Frosty PostgreSQL
Wednesday, February 27, 2013
Thursday, February 14, 2013
Finding unreplicated tables and sequences in slony with check_postgres and nagios
Since slony doesn't automatically add tables to replication for you, sometimes it's handy to double check that everything is being replicated. If your slony cluster is named "sample" then you would have a slony schema named "_sample". As such, you can query against the sl_table and sl_sequence tables to find unreplicated tables like so:
Those queries are a bit unpleasant to remember, so I like to make them into views like so:
Now, that's a little handier because we can just select straight out of the view. Now that we have these easy to use views, we can use check_postgres.pl's custom_query check to setup a nagios alert whenever there are unreplicated tables or sequences.
First we need to create the check commands like so:
Now that we have the commands defined, we use them in a service definition:
SELECT pg_class.OID::regclass as table_name FROM pg_class JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.OID WHERE relkind = 'r' AND pg_class.OID NOT IN (SELECT tab_reloid FROM _sample.sl_table) AND pg_namespace.nspname NOT IN ('information_schema', 'pg_catalog', '_sample')
SELECT pg_class.OID::regclass as sequence_name FROM pg_class JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.OID WHERE relkind = 'S' AND pg_class.OID NOT IN (SELECT seq_reloid FROM _sample.sl_sequence) AND pg_namespace.nspname NOT IN ('information_schema', 'pg_catalog', '_sample');
Those queries are a bit unpleasant to remember, so I like to make them into views like so:
CREATE OR REPLACE VIEW public.unreplicated_tables AS SELECT pg_class.OID::regclass as table_name FROM pg_class JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.OID WHERE relkind = 'r' AND pg_class.OID NOT IN (SELECT tab_reloid FROM _sample.sl_table) AND pg_namespace.nspname NOT IN ('information_schema', 'pg_catalog', '_sample') AND pg_class.relname <> 'fwd_epc_map';
CREATE OR REPLACE VIEW public.unreplicated_sequences AS SELECT pg_class.OID::regclass as sequence_name FROM pg_class JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.OID WHERE relkind = 'S' AND pg_class.OID NOT IN (SELECT seq_reloid FROM _sample.sl_sequence) AND pg_namespace.nspname NOT IN ('information_schema', 'pg_catalog', '_sample');
Now, that's a little handier because we can just select straight out of the view. Now that we have these easy to use views, we can use check_postgres.pl's custom_query check to setup a nagios alert whenever there are unreplicated tables or sequences.
First we need to create the check commands like so:
define command{I apologize for all the wrapping there.
command_name check_pgsql_slony_unreplicated_tables
command_line /usr/lib64/nagios/plugins/check_postgres.pl --host $HOSTADDRESS$ --port=5432 --dbuser nagios --dbname mydb --action=custom_query --query="SELECT count(table_name) AS result FROM public.unreplicated_tables" --valtype=integer --warn=1 --critical=5
}
define command{
command_name check_pgsql_slony_unreplicated_sequences
command_line /usr/lib64/nagios/plugins/check_postgres.pl --host $HOSTADDRESS$ --port=5432 --dbuser nagios --dbname mydb --action=custom_query --query="SELECT count(sequence_name) AS result FROM public.unreplicated_sequences" --valtype=integer --warn=1 --critical=5
}
Now that we have the commands defined, we use them in a service definition:
define service {And that's it! Now we'll receive an alert whenever an unreplicated table or sequence exists on the servers in hostgroup slony_primary.
use postgres-service
notifications_enabled 1
hostgroup_name slony_primary
service_description Slony Unreplicated Tables
check_command check_pgsql_slony_unreplicated_tables
contact_groups pgexperts
}
define service {
use postgres-service
notifications_enabled 1
hostgroup_name slony_primary
service_description Slony Unreplicated Sequences
check_command check_pgsql_slony_unreplicated_sequences
contact_groups pgexperts
}
Labels:
nagios,
postgresql,
slony
Tuesday, February 12, 2013
Russian Doll Syndrome / Please Monitor Your RAID Volumes
As part of setting up nagios monitoring for customers, I always make sure that the RAID volumes are being monitored on the DB servers. More often than not, I have to tell the customer there are bad disks in one or more of the RAID volumes. Don't be one of those customers, make sure you monitor the RAID volumes on your PostgreSQL (and other) servers!
So, today I was setting up some of this same monitoring for LSI RAID controllers in a Dell server using the check_sasraid_megaraid nagios plugin. This plugin requires the LSI SNMP installer as well as net-snmp and a few other miscellaneous packages.
This brings us to the Russian Doll Syndrome. I download the zip file from the LSI support site and unzip it to find a zip full of zips:
Ok, fine, they have a zip for each architecture, so let's unzip the Linux_x64 one and get on with this:
Oh, sweet, another zip file!
And inside that, we find a tarball:
And finally an RPM. Yeesh LSI, why couldn't we just have the RPM right inside the SAS_SNMP_Linux_x64_Installer.zip file or even just in the top level zip file?
So, all kidding aside, please make sure you're monitoring the RAID volumes on your PostgreSQL servers!
So, today I was setting up some of this same monitoring for LSI RAID controllers in a Dell server using the check_sasraid_megaraid nagios plugin. This plugin requires the LSI SNMP installer as well as net-snmp and a few other miscellaneous packages.
This brings us to the Russian Doll Syndrome. I download the zip file from the LSI support site and unzip it to find a zip full of zips:
$ unzip 12.10.03.01_MegaRAID_SNMP_Installers.zip
Archive: 12.10.03.01_MegaRAID_SNMP_Installers.zip
extracting: SAS_SNMP_Win_Installer.zip
extracting: SAS_SNMP_Linux_Installer.zip
extracting: SAS_SNMP_Linux_x64_Installer.zip
extracting: SAS_SNMP_Solaris_Installer.zip
extracting: SAS_SNMP_Solaris11x86_Installer.zip
inflating: 12.10.03.01_MegaRAID_SNMP_Installers.txt
Ok, fine, they have a zip for each architecture, so let's unzip the Linux_x64 one and get on with this:
$ unzip SAS_SNMP_Linux_x64_Installer.zip
Archive: SAS_SNMP_Linux_x64_Installer.zip
inflating: MD5CheckSum.txt
extracting: SAS_SNMP_Linux_x64_Installer-12.10-0301.zip
Oh, sweet, another zip file!
$ unzip SAS_SNMP_Linux_x64_Installer-12.10-0301.zip
Archive: SAS_SNMP_Linux_x64_Installer-12.10-0301.zip
inflating: readme.txt
extracting: sas_snmp_64bit.tar.gz
And inside that, we find a tarball:
$ tar xvfz sas_snmp_64bit.tar.gz
sas_snmp-12.10-0301.x86_64.rpm
And finally an RPM. Yeesh LSI, why couldn't we just have the RPM right inside the SAS_SNMP_Linux_x64_Installer.zip file or even just in the top level zip file?
So, all kidding aside, please make sure you're monitoring the RAID volumes on your PostgreSQL servers!
Labels:
monitoring,
nagios,
postgresql,
raid
Thursday, August 23, 2012
PostgreSQL, NUMA and zone reclaim mode on linux
Lately we've been seeing issues with zone reclaim mode on large memory multi processor NUMA linux systems.
What's NUMA? It's just an acronym for Non-Uniform Memory Access. This means that some memory in your system is more expensive for a particular CPU to access than its "local" memory.
You can see how much more distant the kernel considers the different zones by using the numactl command like so:
Here we see a distance of 10 for node 0 to access node 0 memory and 21 for node 0 to access node 1 memory. What does distance really mean? It's a cost parameter based on number of "hops" or buses that separate the node from the distant memory.
Now, what's zone reclaim mode?
From the linux kernel docs:
I highlighted the text above because PostgreSQL depends heavily on the filesystem cache and disabling zone reclaim mode is desirable in this situation.
There's been a bit of discussion about this on the pgsql-performance mailing list here: http://archives.postgresql.org/pgsql-performance/2012-07/msg00215.php
If you've got a modern multi-socket system, odds are good that zone reclaim mode is enabled automatically on boot. You can check this by looking at /proc/sys/vm/zone_reclaim_mode.
The biggest issue we've seen with zone reclaim mode enabled on customer multi-socket systems is the filesystem cache never filling up even when the database is much larger than RAM. That's because the system is trying to keep some "local" memory available. After disabling zone_reclaim_mode, the filesystem cache fills up and performance improves.
So, how to disable zone_reclaim_mode? The best way to do this is via sysctl. Just add:
vm.zone_reclaim_mode = 0
to /etc/sysctl.conf, save it and execute sysctl -p to load the new settings into the kernel.
Other interesting non PostgreSQL pages on NUMA/zone_reclaim_mode:
What's NUMA? It's just an acronym for Non-Uniform Memory Access. This means that some memory in your system is more expensive for a particular CPU to access than its "local" memory.
You can see how much more distant the kernel considers the different zones by using the numactl command like so:
numactl --hardwareIf you've got a modern multiprocessor system, you'll probably see something like this:
available: 2 nodes (0-1)
node 0 size: 48417 MB
node 0 free: 219 MB
node 1 size: 48480 MB
node 1 free: 135 MB
node distances:
node 0 1
0: 10 21
1: 21 10
Here we see a distance of 10 for node 0 to access node 0 memory and 21 for node 0 to access node 1 memory. What does distance really mean? It's a cost parameter based on number of "hops" or buses that separate the node from the distant memory.
Now, what's zone reclaim mode?
From the linux kernel docs:
zone_reclaim_mode:
Zone_reclaim_mode allows someone to set more or less aggressive approaches to
reclaim memory when a zone runs out of memory. If it is set to zero then no
zone reclaim occurs. Allocations will be satisfied from other zones / nodes
in the system.
This is value ORed together of
1 = Zone reclaim on
2 = Zone reclaim writes dirty pages out
4 = Zone reclaim swaps pages
zone_reclaim_mode is set during bootup to 1 if it is determined that pages
from remote zones will cause a measurable performance reduction. The
page allocator will then reclaim easily reusable pages (those page
cache pages that are currently not used) before allocating off node pages.
It may be beneficial to switch off zone reclaim if the system is
used for a file server and all of memory should be used for caching files
from disk. In that case the caching effect is more important than
data locality.
Allowing zone reclaim to write out pages stops processes that are
writing large amounts of data from dirtying pages on other nodes. Zone
reclaim will write out dirty pages if a zone fills up and so effectively
throttle the process. This may decrease the performance of a single process
since it cannot use all of system memory to buffer the outgoing writes
anymore but it preserve the memory on other nodes so that the performance
of other processes running on other nodes will not be affected.
Allowing regular swap effectively restricts allocations to the local
node unless explicitly overridden by memory policies or cpuset
configurations.
I highlighted the text above because PostgreSQL depends heavily on the filesystem cache and disabling zone reclaim mode is desirable in this situation.
There's been a bit of discussion about this on the pgsql-performance mailing list here: http://archives.postgresql.org/pgsql-performance/2012-07/msg00215.php
If you've got a modern multi-socket system, odds are good that zone reclaim mode is enabled automatically on boot. You can check this by looking at /proc/sys/vm/zone_reclaim_mode.
The biggest issue we've seen with zone reclaim mode enabled on customer multi-socket systems is the filesystem cache never filling up even when the database is much larger than RAM. That's because the system is trying to keep some "local" memory available. After disabling zone_reclaim_mode, the filesystem cache fills up and performance improves.
So, how to disable zone_reclaim_mode? The best way to do this is via sysctl. Just add:
vm.zone_reclaim_mode = 0
to /etc/sysctl.conf, save it and execute sysctl -p to load the new settings into the kernel.
Other interesting non PostgreSQL pages on NUMA/zone_reclaim_mode:
Labels:
linux,
numa,
postgresql
Thursday, August 2, 2012
Finding non-UTF8 data in a dump
Recently I was tasked with identifying all rows in a PostgreSQL database that contained non UTF8 data for migrating from SQL_ASCII encoding to UTF8. Because of the database's size, just using iconv and diff on a dump file wouldn't work.
I started with this perl script from Jon Jensen: http://blog.endpoint.com/2010/03/postgresql-utf-8-conversion.html
It got me a little way down the road, but what I really wanted was to know which table had the bad row and better yet, be able to easily import the bad rows with a COPY command for cleanup and eventual use as temporary tables that we can be used with UPDATE statements to fix the production DB.
So, I turned to Python. I found a isUTF8(text) definition here: http://www.haypocalc.com/wiki/Python_Unicode#isUTF8.28.29
I took that and wrote pg_find_bad_utf8.py which outputs COPY commands with only the non-UTF8 rows to STDOUT and also outputs a schema-only dump command to STDERR which only dumps the tables with bad data for ease of creating a temporary DB.
You can find the script on github here: https://github.com/pgexperts/pg_find_bad_utf8
What other methods do you folks use?
I started with this perl script from Jon Jensen: http://blog.endpoint.com/2010/03/postgresql-utf-8-conversion.html
It got me a little way down the road, but what I really wanted was to know which table had the bad row and better yet, be able to easily import the bad rows with a COPY command for cleanup and eventual use as temporary tables that we can be used with UPDATE statements to fix the production DB.
So, I turned to Python. I found a isUTF8(text) definition here: http://www.haypocalc.com/wiki/Python_Unicode#isUTF8.28.29
I took that and wrote pg_find_bad_utf8.py which outputs COPY commands with only the non-UTF8 rows to STDOUT and also outputs a schema-only dump command to STDERR which only dumps the tables with bad data for ease of creating a temporary DB.
You can find the script on github here: https://github.com/pgexperts/pg_find_bad_utf8
What other methods do you folks use?
Labels:
postgresql,
python,
utf8
Wednesday, May 23, 2012
pgbackup.py script to dump all PostgreSQL DBs
For a long time, I've written all my automation scripts in bourne shell and bash with occasional forays into perl. I really like bash because you're always guaranteed to have bash installed on a modern linux system and so don't need to install perl and 15 modules to get the job done.
That said, I've recently begun using python for more automation. As an exercise, I've rewritten my dbbackup.sh script for python 2.7 trying to use only the standard library.
The script pg_dumps all the databases in a PostgreSQL cluster in the custom format allowing you to specify the compression level. (See this blog post regarding pg_dump compression level performance.) It also dumps the globals to a bzip2'd SQL file and then removes files in the dump destination directory that are older than the --keep value (default 7 days). Finally, if it had any errors during the run, it sends the error log file to the specified email address. It also picks up libpq environment variables, but will override those with anything specified on the command line.
You can find it here: https://github.com/pgexperts/pgbackup
That said, I've recently begun using python for more automation. As an exercise, I've rewritten my dbbackup.sh script for python 2.7 trying to use only the standard library.
The script pg_dumps all the databases in a PostgreSQL cluster in the custom format allowing you to specify the compression level. (See this blog post regarding pg_dump compression level performance.) It also dumps the globals to a bzip2'd SQL file and then removes files in the dump destination directory that are older than the --keep value (default 7 days). Finally, if it had any errors during the run, it sends the error log file to the specified email address. It also picks up libpq environment variables, but will override those with anything specified on the command line.
You can find it here: https://github.com/pgexperts/pgbackup
Labels:
pg_dump,
postgresql
Tuesday, May 15, 2012
Slony Upstart Script for Ubuntu 10.04 LTS
Since Ubuntu is moving towards using upstart instead of SysV init scripts, I thought I'd write a quick upstart script for starting slony compiled and installed in /usr/local/slony. Upstart 1.4+ supports setuid, but the version of upstart included with Ubuntu 10.04LTS is only 0.6.5 and even on Ubuntu 11.10, it's only 1.3, so instead I use start-stop-daemon's --chuid switch. The script should be installed as /etc/init/slony.conf. Here's the script:
---cut here---
# slony - slon daemon
#
# slon is the slony replication daemon
description "slony slon daemon"
start on net-device-up
stop on runlevel [06]
# can't use setuid until upstart 1.4
#setuid slony
# which is why we use start-stop-daemon with the --chuid switch
respawn
script
exec start-stop-daemon --start --chuid slony --exec /usr/local/slony/bin/slon -- -f /etc/slon.conf >> /var/log/slony/slony.log 2>&1
end script
---cut here---
This will have the slon daemon run as the slony user and log to /var/log/slony/slony.log. You'll also need a valid slony config file in /etc/slon.conf.
You can also find the script in the pgexperts upstart-scripts git repo:
https://github.com/pgexperts/upstart-scripts
---cut here---
# slony - slon daemon
#
# slon is the slony replication daemon
description "slony slon daemon"
start on net-device-up
stop on runlevel [06]
# can't use setuid until upstart 1.4
#setuid slony
# which is why we use start-stop-daemon with the --chuid switch
respawn
script
exec start-stop-daemon --start --chuid slony --exec /usr/local/slony/bin/slon -- -f /etc/slon.conf >> /var/log/slony/slony.log 2>&1
end script
---cut here---
This will have the slon daemon run as the slony user and log to /var/log/slony/slony.log. You'll also need a valid slony config file in /etc/slon.conf.
You can also find the script in the pgexperts upstart-scripts git repo:
https://github.com/pgexperts/upstart-scripts
Subscribe to:
Posts (Atom)