Today we are going to talk about a topic that many people are afraid of. We know that MySQL is open-source, but there are some steps from the code until we have the database binary running in our server. Many may ask why doing this since there are packages available, but it wouldn’t be funny if we didn’t know how to do it, correct?
Jokes aside, it might be interesting to compile MySQL because it is possible to add certain flags to enable additional libraries that are very useful to investigate certain parts of the code.
Let’s compile MySQL for Ubuntu 20.04 (Focal Fossa):
First, we are going to create our directories. We will create a directory that will have the source code, another one to place the compiled binaries, and the latest one is where we are going to place the boost library.
1 2 3 4 5 6 7 8 |
cd / mkdir compile cd compile/ mkdir build mkdir source mkdir boost mkdir basedir mkdir /var/lib/mysql |
Next, we need to install the additional Linux packages required to compile MySQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
apt-get -y install dirmngr apt-get update -y apt-get -y install cmake apt-get install build-essential -y apt-get -y install dirmngr || true apt-get -y install lsb-release wget apt-get -y purge eatmydata || true apt-get -y install psmisc pkg-config apt-get -y install libsasl2-dev libsasl2-modules libsasl2-modules-ldap || apt-get -y install libsasl2-modules libsasl2-modules-ldap libsasl2-dev apt-get -y install dh-systemd || true apt-get -y install curl bison cmake perl libssl-dev gcc g++ libaio-dev libldap2-dev libwrap0-dev gdb unzip gawk apt-get -y install lsb-release libmecab-dev libncurses5-dev libreadline-dev libpam-dev zlib1g-dev apt-get -y install libldap2-dev libnuma-dev libjemalloc-dev libeatmydata libc6-dbg valgrind libjson-perl libsasl2-dev apt-get -y install libmecab2 mecab mecab-ipadic apt-get -y install build-essential devscripts libnuma-dev apt-get -y install cmake autotools-dev autoconf automake build-essential devscripts debconf debhelper fakeroot apt-get -y install libcurl4-openssl-dev patchelf apt-get -y install libeatmydata1 apt-get install libmysqlclient-dev -y apt-get install valgrind -y |
Next, we will download the source code. For this, we will use the MySQL repository in GitHub:
1 2 |
cd source git clone https://github.com/mysql/mysql-server.git |
Next, we will go to our build directory and we will run CMAKE with our chosen flags:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
cd /compile/build cmake ../source/mysql-server/ -DBUILD_CONFIG=mysql_release \ -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-RelWithDebInfo} \ -DWITH_DEBUG=1 \ -DFEATURE_SET=community \ -DENABLE_DTRACE=OFF \ -DWITH_SSL=system \ -DWITH_ZLIB=system \ -DCMAKE_INSTALL_PREFIX="/compile/basedir/" \ -DINSTALL_LIBDIR="lib/" \ -DINSTALL_SBINDIR="bin/" \ -DWITH_INNODB_MEMCACHED=ON \ -DDOWNLOAD_BOOST=1 \ -DWITH_VALGRIND=1 \ -DINSTALL_PLUGINDIR="plugin/" \ -DMYSQL_DATADIR="/var/lib/mysql/"\ -DWITH_BOOST="/compile/boost/" |
After we run CMAKE, we are going to compile MySQL de facto, using the make command. To optimize the compiling process, we will use the -j option. The -j indicates how many threads we are going to use to compile MySQL.
1 2 |
make -j 15 make install |
Note that we will not find a mysqld binary in the /compile/build/bin/, but instead, we will see a mysqld-debug. This is because of the DWITH_DEBUG option we set previously.
Now, we can test our binary. For this, we are going to manually create the directories, configure the permission and the my.cnf:
1 2 3 4 |
mkdir /var/log/mysql/ mkdir /var/run/mysqld/ chown ubuntu: /var/log/mysql/ chown ubuntu: /var/run/mysqld/ |
And add these settings to the /etc/my.cnf:
1 2 3 4 5 |
[mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql log-error = /var/log/mysql/error.log |
Next step , we are going to initialize MySQL data dictionary:
1 |
/compile/basedir/bin/mysqld-debug --defaults-file=/etc/my.cnf --initialize --user ubuntu |
And now, MySQL is ready to be started:
1 |
/compile/basedir/bin/mysqld-debug --defaults-file=/etc/my.cnf --user ubuntu & |
A temporary password will be created and we can extract from the error log:
1 |
grep "A temporary password" /var/log/mysql/error.log |
Now we can validate connecting using the MySQL client of our preference:
1 2 3 4 5 |
# mysql -uroot -p'JuggJZagt2;+' mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 8.0.23-debug-valgrind |
And we did it! We have our own custom MySQL running. Our next adventure will be changing a little the source code to start getting familiar with it!
This topic will be present in the book that my colleague and I are writing about MySQL. The book is called Learning MySQL. Stay tuned!
See ya!