I’ve posted a recipe for chrooting MySQL on Debian sarge a while ago. These instructions no longer work out of the box for newer MySQL packages from Debian and Ubuntu. The main problem is that the startup script added a few extra checks and script invocations that don’t understand the chroot environment. So here’s an updated plan:
- Prepare the chroot directory. It’s recommended to use an extra partition/filesystem for it. I will use
/srv/mysql
(which is an LVM2 partition with an ext3 filesystem on my system) for the rest of the text. - Stop MySQL:
/etc/init.d/mysql stop
- Copy the databases to new location:
mkdir -p /srv/mysql/var/lib cp -a /var/lib/mysql /srv/mysql/var/lib
- Copy this script to
/etc/default/mysql-chroot
- Edit
/etc/init.d/mysql
:- Source the
mysql-chroot
script somewhere at the top:… test -x /usr/sbin/mysqld || exit 0 . /etc/default/mysql-chroot SELF=$(cd $(dirname $0); pwd -P)/$(basename $0) …
- Fix the disk space check:
… # check for diskspace shortage datadir=`mysqld_get_param datadir` if LC_ALL=C BLOCKSIZE= df --portability $CHROOT_DIR$datadir/. | tail -n 1 | awk '{ exit ($4>4096) }'; then log_failure_msg "$0: ERROR: The partition with $datadir is too full!" …
- Run
setup_chroot
right in the start section:… if mysqld_status check_alive nowarn; then echo "...already running." else setup_chroot /usr/bin/mysqld_safe > /dev/null 2>&1 & …
- Somehow
/var/run/mysqld/mysqld.pid
disappears after each start. We have to create it each time, otherwise thestop
command won’t work properly:… if mysqld_status check_alive warn; then log_end_msg 0 ln -sf $CHROOT_DIR/var/run/mysqld/mysqld.pid \ /var/run/mysqld # Now start mysqlcheck or whatever the admin wants. output=$(/etc/mysql/debian-start) …
- Source the
- In
/etc/mysql/debian.cnf
, change the twosocket
lines to:socket = /srv/mysql/var/run/mysqld/mysqld.sock
- In
/etc/mysql/my.cnf
:- Change the
socket
line in the[client]
section to:socket = /srv/mysql/var/run/mysqld/mysqld.sock
Don’t change the
socket
lines in the other sections! - Add
chroot = /srv/mysql
to the
[mysqld]
section.
- Change the
- Prepend
/srv/mysql
to the log files listed in/etc/logrotate.d/mysql-server
- Make
/usr/bin/mysql_upgrade_shell
use the chrooted socket. Note: Currently these changes must be made each time mysql gets upgraded because upgrades override this file!… --password=*) password=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --socket=*) socket=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --ldata=*|--data=*|--datadir=*) DATADIR=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; … fi $bindir/mysql_fix_privilege_tables --silent --user=$user --password=$password --socket=$socket $args exit 0 … check_args="--check-upgrade --all-databases --auto-repair --user=$user --password=$password --socket=$socket" … $bindir/mysql_fix_privilege_tables --silent --user=$user --password=$password --socket=$socket $args …
- Start MySQL:
/etc/init.d/mysql start
- Check
/var/log/syslog
for errors ;-)
Bummer, i just see copying the ‘−−’ from the article doesn’t work. You have to delete the copied ‘−−’ and type them manually. I’ll correct that tomorrow.
hi hi…
thanks for that great doc, it really helped me out. there seems to be no other usable howto for chrooting mysql on debian on the net…
sadly I have some problems when starting the mysql daemon via the init script. the daemon itself comes up, but the ‘debian-start’ util within the ‘upgrade_system_tables_if_necessary’ function:
/etc/mysql/debian-start[17223]: Can’t find data directory. Please restart with –datadir=path-to-writable-data-dir
I didn’t change the datadir option in ‘/etc/mysql/my.cnf’ and the directory and files in it are writeable to the ‘mysql’ user.
any hints on that problem?
my current version is ‘5.0.32-7etch1’
thanks ollie
Hi ollie, try retyping all the ‘--’ you inserted. It should work then.
There still were some problems with the script text on this page (see the first comment). I hope I’ve fixed all now.
The text on this site contained some − (−) entities, they looked like a normal ‘-‘ signs but it’s quite different for scripts.
Hi!
I’m having the same problem as ollie.. I have double checked the ‘–‘ characters and they are correct. I think something else is causing this.
Would really appreciate some help here!
Cheers,
Tom
ollie fixed his problem by adding ‘--datadir=<CHROOT_DIR>/var/lib/mysql’ to
the MYUPGRADE variable in ‘/etc/mysql/debian-start’.
I have to check with a fresh install if this is needed now.
woo-hoo great howto! keep updating it!
have you had a chance to see if its needed in fresh installs?
Not yet. But stay tuned!
Thanks! Seems to work just fine with Debian Etch 4.0r1! No need to use the fix Ollie had to use.
Thanks Teppo!
Also, I just did a fresh install on Ubuntu Gutsy. It worked fine like described above.
You da man, Juergen.
Great script + great instruction = no problems.
Working beautifully. Thanks 10^6.
Hi
I had to add an / to your chrootdir in my.cnf
-> “chroot = /srv/mysql/”
Thanks for your recipe !
Greets,
Dieter
Hi!
Great HowTo !!
I had a problem with php and mysql.sock i sloved it by adding:
ln -sf $CHROOT_DIR/var/run/mysqld/mysqld.sock /var/run/mysqld
after:
ln -sf $CHROOT_DIR/var/run/mysqld/mysqld.pid /var/run/mysqld
Greets,
Bieniu
Thanks for the tip on adding “–datadir” to /etc/mysql/debian-start, that solved a non-chroot issue I’ve been having for an hour now.
I would advice to put the “datadir” configuration parameter inside /etc/mysql/debian.cnf instead, thus removing the need of fiddling with init-scripts.
Just my €.02… Thanks for a great blog for us Debian techies ;-)
Great tutorial – I used it many times.
Just a small reflection: above you have use the ‘ln’ command to create a symlink to pidfle, but many programs searches the socket under /var/run/mysqld. I think the bind mount better than use ‘ln’, just simply put this line to fstab:
/srv/mysql/var/run/mysqld /var/run/mysqld none bind 0 2
Thank you again.
a.
Good idea!
[…] Årsaken til dette er at scriptet ikke er optimalisert for et chrootet miljø. Jeg fant denne guiden, den virket ikke for meg men gjorde meg i stand til å bedre skjønne prosessen (noe utdatert). For […]
Still works great on Lenny with MySQL 5!!
Thanks for this!!
I have a debian squeeze 64 bit system running, and I need to create a 32 bit chroot to run 32 bit mysql and other apps. I have the chroot working (lenny), but apt-get won’t install mysql in the chroot, and there are no error messages. This recipe copies an existing mysl to the chroot, but I need to create a new 32 bit mysql. Any suggestions or hints would be greatly appreciated!
Thanks!
Mark
[…] but for the MySQL DB server, both methods are not working in the “chrooted” environment. I then start it like this /usr/bin/mysqld_safe & You can have a look to solve that problem: Chrooting Recent MySQL Versions on Debian and Ubuntu by Juergen Kreileder. […]
thanks for this nice tutorial, it worked fine for me the last years.
the current mysql includes a chroot-function (as of 5.1 at least), so squeeze is much easier to setup the chroot-environment:
you do not need the script any more and also an edit of /etc/init.d/mysql is not necessary any more.
only the changes to /etc/mysql/debian.cnf and /etc/mysql/my.cnf are needed to setup the chroot.
Hi,
I confirm that using “/usr/bin/mysqld_safe &” is good enough to start MySQL from a chroot environment under Ubuntu 11.10
No other changes are needed. Just start up your web server and then MySQL to get minimal services running. Good luck and thank you for this tutorial along with helpful comments from other admins.
thanks for the tutorial,it worked for me
As freaker said you do not need the script and an edit of /etc/init.d.mysql
I have one doubt
How to start and stop mysql service from inside the chroot jail
If any one knows please update
Thank u advance and also thanks for the tutorial……
thanks for the tutorial,it worked for me
As freaker said you do not need the script and an edit of /etc/init.d/mysql
I have one doubt
How to start and stop mysql service from inside the chroot jail
If any one knows please update
Thank u advance and also thanks for the tutorial……