These step by step instructions describe how to install Plone on Ubuntu with RelStorage connected to MySQL as the main database. Familiarity with Linux systems administration is expected. Update: These instructions were revised in August 2009 for Plone 3.2.3 and RelStorage 1.2.0.
Server Preparation
Start with a minimal installation of Ubuntu 8.04 LTS. It will be easiest if you start with a server (or virtual server) that provides no public services yet. Otherwise, make a backup of everything important on the server, especially any MySQL databases, before proceeding.
Most of these commands should be performed with root privileges. You might need to type sudo su -
to get root privileges. In these instructions, commands you should type are preceded with the character $
to represent the prompt, but you should not type the $
.
Ensure the main
and universe
repositories are configured and that the system is fully up to date. See below. Use a mirror appropriate for your location.
$ cd /etc/apt $ cat sources.list deb http://us.archive.ubuntu.com/ubuntu hardy main universe deb http://us.archive.ubuntu.com/ubuntu hardy-updates main universe deb http://us.archive.ubuntu.com/ubuntu hardy-security main universe $ apt-get update $ apt-get upgrade
Restart the server if major packages were upgraded.
Install Ubuntu Packages
Install all of the following packages. During the installation process, the system will prompt you for a MySQL administration password. Make up a good but memorable password.
$ apt-get install build-essential mysql-client mysql-server libmysqlclient15-dev $ apt-get install wget libjpeg62-dev
Don’t forget to install your favorite text editor. One good choice is nano
.
Configure MySQL
It is important to configure MySQL before starting Plone or creating any database, because these MySQL configuration changes will affect the layout of the database.
With root privileges, edit /etc/mysql/my.cnf
. Change it as follows:
- In the
[mysqld]
section, find the line that configuresmax_allowed_packet
. Change the line to read:max_allowed_packet = 32M
This changes the maximum size of a ZODB object. 32 megabytes is probably sufficient for most sites.
- Find the commented line that contains
skip-innodb
. Remove that line or leave it commented. Add the following lines below it:innodb_data_file_path = ibdata1:10M:autoextend innodb_buffer_pool_size=64M innodb_log_file_size=16M innodb_log_buffer_size=8M innodb_flush_log_at_trx_commit=1 innodb_file_per_table
These lines improve the performance of RelStorage over the default configuration. The values are intended for a server with about 256 MB of RAM, running both MySQL and some Zope processes. Feel free to adjust these values now, but avoid touching them once your database has been created.
Since we changed the innodb_log_file_size
parameter, we need to stop MySQL, delete the log files, and start MySQL again:
$ /etc/init.d/mysql stop $ rm /var/lib/mysql/ib_logfile* $ /etc/init.d/mysql start
Create the Databases and Grant Access
Start the MySQL command line client. The client will prompt you for the administration password you typed earlier. (If you chose not to set an administration password, leave out the -p
option.)
$ mysql -p
At the MySQL prompt, type (copy and paste) the following commands to create two databases in MySQL: one for testing RelStorage, the other for storing Plone data; then grant access to these databases. Replace PASSWORD
with a new password of your choosing. This password does not need to be memorized by humans, so you can make it ugly and strong, but write it down somewhere.
mysql> create database relstoragetest; mysql> create database plone; mysql> grant all on relstoragetest.* to 'relstoragetest'@'localhost' identified by 'relstoragetest'; mysql> grant all on plone.* to 'plone'@'localhost' identified by 'PASSWORD'; mysql> flush privileges; mysql> quit
Install Plone
Type the commands below to download and unpack Plone. Version 3.2.3
was the most current release when these instructions were written.
$ cd /root $ wget 'http://launchpad.net/plone/3.2/3.2.3/+download/Plone-3.2.3-UnifiedInstaller.tgz' $ tar xvzf Plone-3.2.3-UnifiedInstaller.tgz
Type the commands below to install Plone in standalone mode, not cluster mode. Plone’s cluster installation mode installs a ZEO server, but RelStorage does not need a ZEO server. The standalone installation mode provides everything we need to build an installation of Plone that supports clustering with RelStorage.
$ cd Plone-3.2.3-UnifiedInstaller $ ./install.sh standalone
The install script compiles Plone and its dependencies, then installs at /usr/local/Plone
. Note that the Plone installer will generate a password for you to use later. The generated password is stored in the file /usr/local/Plone/zinstance/adminPassword.txt
.
Patch ZODB
After Plone is installed, you need to patch its installed copy of ZODB to support RelStorage. This is all you need to do:
$ cd /usr/local/Plone/Zope-2.10.7-final-py2.4/lib/python/ZODB $ wget 'http://svn.zope.org/*checkout*/relstorage/trunk/poll-invalidation-1-zodb-3-7-1.patch' $ patch -p0 < poll-invalidation-1-zodb-3-7-1.patch
The patch command should generate the following output to confirm that the patch was successful:
patching file Connection.py patching file DB.py
Modify the Buildout
We are going to install RelStorage by enhancing the buildout configuration in Plone. Edit the file /usr/local/Plone/zinstance/buildout.cfg
, changing it as follows:
- Add RelStorage and MySQL-python to the list of eggs to install. Do this by finding the
eggs
option in the[buildout]
section and appendingRelStorage
andMySQL-python
to it. Note that each egg must be listed on a separate line, so make the option look like this:eggs = Plone RelStorage MySQL-python
- Add ZODB3 to the list of “additional fake eggs”. Plone is using a concept called fake eggs to aid in the transition from the old monolithic Zope installation method to Python egg installation. Find the
additional-fake-eggs
option in the[zope2]
section and addZODB3 = 3.7.1
to the end. After your edit, the option should look like this:additional-fake-eggs = ZConfig pytz ZODB3 = 3.7.1
- Add zodbconvert to the list of scripts to generate in the [zopepy] section.
scripts = zopepy zodbconvert
- Configure Plone to use RelStorage by adding the following to the [instance] section. Replace PASSWORD with the strong password you set for the MySQL user named
plone
.rel-storage = type mysql db plone user plone passwd PASSWORD
We also need to add a line to versions.cfg
to solve a version dependency issue. Type the following command (be sure to type “>>”, which means to append to the file, rather than just “>”, which means to overwrite the file):
$ echo zc.recipe.testrunner = 1.1.0 >> /usr/local/Plone/zinstance/versions.cfg
Run Buildout
Execute the buildout
command to install RelStorage:
$ cd /usr/local/Plone/zinstance $ bin/buildout
You should get output similar to the following.
Uninstalling zopepy. Uninstalling instance. Uninstalling zope2. Installing zope2. Creating fake eggs Updating productdistros. Installing instance. Getting distribution for 'RelStorage'. Got RelStorage 1.2.0b2. Getting distribution for 'MySQL-python'. zip_safe flag not set; analyzing archive contents... Got MySQL-python 1.2.3c1. Generated script '/usr/local/Plone/zinstance/bin/instance'. Installing zopepy. Generated script '/usr/local/Plone/zinstance/bin/zodbconvert'. Generated interpreter '/usr/local/Plone/zinstance/bin/zopepy'. Updating zopeskel. Updating chown. chown: Running chmod 600 .installed.cfg find /usr/local/Plone/zinstance -type d -name var -exec chown -R plone \{\} \; find /usr/local/Plone/buildout-cache/eggs -type d -name LC_MESSAGES -exec chown -R plone \{\} \; find /usr/local/Plone/zinstance -name runzope -exec chown plone \{\} \; Updating unifiedinstaller. Updating precompile. precompiling python scripts in /usr/local/Plone/zinstance/products precompiling python scripts in /usr/local/Plone/zinstance/parts/productdistros
If the Buildout command did not work, please feel free to ask questions. Buildout is an excellent tool, but when something goes wrong, its error messages are often cryptic.
Test RelStorage on MySQL
Now it’s time to test RelStorage and MySQL together. It only takes a moment and could prevent a lot of frustration. The tests will detect various bad configurations of MySQL.
Type the following to run the tests:
$ cd /usr/local/Plone/zinstance $ bin/instance test -m mysql -p
If everything is configured properly, there should be no test failures or errors. The output should look similar to this:
Running unit tests: Running: Ran 113 tests with 0 failures and 0 errors in 24.016 seconds.
Some troubleshooting tips:
- If you set up MySQL on a different server (a procedure not covered by these instructions), synchronize the clocks of the server and client using
ntp
. The MySQL adapter for RelStorage requires the clocks on the server and client to be within 60 seconds of each other. - If the connection isolation test fails, it most likely means that MySQL created MyISAM tables instead of InnoDB tables, which can happen if the InnoDB engine failed to initialize when MySQL started. InnoDB is required for RelStorage.
Run Plone
Type this to start Plone without putting the process in the background:
$ /usr/local/Plone/zinstance/bin/instance fg
The first time Plone runs, RelStorage should create the database tables automatically. If everything goes well, at this point you can point your web browser at http://localhost:8080/manage, log in (see /usr/local/Plone/zinstance/adminPassword.txt
for the password), and add a Plone Site
to the root folder. The new Plone site will be stored entirely in MySQL.
Clustering
RelStorage supports clustering with no additional software. ZEO is not needed. Just set up more Plone instances with the same software (use rsync
, nfs
, or some other method to keep the software in sync) and point all of the clients at the same database. Furthermore, RelStorage has several options designed to improve cluster performance, such as memcached integration. If you are setting up a cluster, you are welcome to contact the author about the best way to set it up for your site.
Great article. I’ve recently created a Plone / Relstorage / Mysql instance. Our plan is to get our sites production ready and then clone it over to our production server. I didn’t set any of the following settings – is it too late to introduce them now? What about on the production database when we clone? What’s the impact of not using them?
max_allowed_packet = 32M
innodb_data_file_path = ibdata1:10M:autoextend
innodb_buffer_pool_size=64M
innodb_log_file_size=16M
innodb_log_buffer_size=8M
innodb_flush_log_at_trx_commit=1
innodb_file_per_table
Hi Anthony. Here are my thoughts on these settings:
– I think you can change max_allowed_packet, innodb_buffer_pool_size, and innodb_flush_log_at_trx_commit anytime.
– innodb_data_file_path can change. It simply has to point at the database file.
– Either innodb_log_buffer_size or innodb_log_file_size (maybe both) reacts badly to a change. It disables InnoDB sometimes. Be careful.
– You have to dump and re-create the database in order to activate changes of innodb_file_per_table.
I would also like to quote two emails from Russell Quick. When I have some time, I’ll update this howto to use Russell’s method instead of mine.
“””
We have one small issue and were wondering if you knew what to do with this: Each time we change and run buildout it wipes out the zope.conf file and we have to copy over the database configuration section. Is there a way to set up buildout so that it will set the relstorage zodb_main section automatically or not rewrite the file?
“””
“””
We’ve discovered how to set the zope.conf file from the buidout so it doesn’t have to be changed manually. You can add the following section to the [instance] section of the buildout.cfg, adjusting your parameters for your specific database settings (we used postgresql):
“””
Thanks for your help, Russell!
Anthony, to answer the rest of your question, the default configuration of MySQL:
– will not pass the tests (max_allowed_packet must be larger than 16M),
– bottlenecks RelStorage write performance, and
– puts all the important data in one big file without providing tools to manage that big file.
We’ve managed to get buildout working using a different mount point and database for temp and the plone folder. No editing of zope.conf is required after running the buildout. We adopted this configuration with the idea we’d be running multiple plone instances – we’d have one database for each Plone instance.
rel-storage =
type mysql
db zope
host 127.0.0.1
user zope
passwd xxxxx
zodb-temporary-storage =
mount-point /temp_folder
db zope_temp
host 127.0.0.1
user zope
passwd xxxxx
zope-conf-additional =
mount-point /plone
db plone
host 127.0.0.1
user zope
passwd xxxxx
Sorry my formatting was tags were eaten. Not sure how to post with them intact.
Well I am at a bit of a bump in the road. Following these above instructions I run bin/buildout and it appears to run correctly, however when I run the bin/instance test -m mysql -p command I get the following error message:
Running tests at level 1
Test-module import failures:
Module: relstorage.tests.testmysql
Traceback (most recent call last):
File “/usr/local/Plone/buildout-cache/eggs/RelStorage-1.2.0b2-py2.4.egg/relstorage/tests/testmysql.py”, line 20, in ?
from relstorage.adapters.mysql import MySQLAdapter
File “/usr/local/Plone/buildout-cache/eggs/RelStorage-1.2.0b2-py2.4.egg/relstorage/adapters/mysql.py”, line 52, in ?
import MySQLdb
ImportError: No module named MySQLdb
Total: 0 tests, 0 failures, 0 errors
Test-modules with import problems:
relstorage.tests.testmysql
When I do dpkg -l python-mysqldb I get:
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name Version Description
+++-===========================-===========================-======================================================================
ii python-mysqldb 1.2.2-7ubuntu1 A Python interface to MySQL
Does anyone have any ideas of what I need to do to get this test to work?
PFiero
I’ve got things running. A couple things to note:
a) Where the document says “at least version 8.04 LTS” for the Ubuntu version, it appears to me (not being REALLY all that Ubuntu literate) that it should read “only use version 8.04 LTS”.
b) When putting in the mysql statements instead of:
grant all on relstoragetest.* to ”@’localhost’;
it should read:
grant all on relstoragetest.* to ‘relstoragetest’@’localhost’ identified by ‘relstoragetest’;
My instance test now passes. Yay.
I updated the instructions today based on feedback. Thanks guys!
I try to build Plone 4 with RelStorage.
I added RelStorage and psycopg2 to the eggs section and the rel-storage configuration in base.cfg. buildout works fine and i am able to add a plone site in my postgresql db.
The only issue i have is that zodbconvert is not built. I added
zodbconvert to the zopepy section in my base.cfg:
[zopepy]
# installs a zopepy python interpreter that runs with your
# full Zope environment
recipe = zc.recipe.egg
eggs = ${buildout:eggs}
interpreter = zopepy
scripts = zopepy zodbconvert
Any pointers what might cause the zodbconvert script not to be built?
Shane,
Thanks for this excellent write up. I realize it is a few years old, just curious how RelStorage has worked out for you in that time?
I’ve been very pleased with RelStorage. I have used it for small sites with no problems at all. I’ve helped people set it up for large sites and while they have had some problems, none of them have been showstoppers.