Archive for the ‘install’ Category

Install and configure MySQL on EC2 with RedHat Linux

Май 23rd, 2012

Recently I had to turn a few EC2 instances into MySQL database servers. The third time I had to do it, I grabbed the list of steps from my previous sessions and just replayed it. Later I thought maybe polishing information a little bit and publishing a step-by-step walkthrough on the blog may help a few people. So here it is.

Before you begin.

For my MySQL instances I used the following:

  • Extra Large, High-Memory, and High-CPU instances. Although the instruction should work on any type of instance.
  • RedHat Enterprise Linux 6.2 64-bit AMI
  • For MySQL data storage, multiple identical EBS devices attached to each instance

The configuration template provided in this post assumes the new MySQL instance only needs InnoDB storage engine.

Grab the packages.

Download the appropriate packages from MySQL web page. You will need client, shared-compat, and server. For example:

MySQL-client-5.5.24-1.el6.x86_64.rpm
MySQL-server-5.5.24-1.el6.x86_64.rpm
MySQL-shared-compat-5.5.24-1.el6.x86_64.rpm

Make sure the packages you downloaded are for a 64-bit architecture. You could of course choose packages from other vendors as the change should not affect the process in any relevant way.

Install MySQL

Remove the MySQL libraries that have been shipped with the system and install the new client and library packages:

[root@ip-10-238-234-26 ~]# rpm -e --nodeps mysql-libs
[root@ip-10-238-234-26 ~]# rpm -ihv MySQL-client-5.5.24-1.el6.x86_64.rpm MySQL-shared-compat-5.5.24-1.el6.x86_64.rpm
Preparing...                ########################################### [100%]
   1:MySQL-shared-compat    ########################################### [ 50%]
   2:MySQL-client           ########################################### [100%]

Then install the server package:

[root@ip-10-238-234-26 ~]# rpm -ihv MySQL-server-5.5.24-1.el6.x86_64.rpm
Preparing...                ########################################### [100%]
   1:MySQL-server           ########################################### [100%]
Search for EBS volumes.

Examine system to find the EBS volumes you will use for MySQL storage.

[root@ip-10-32-2-145 ~]# dmesg | grep 'unknown partition'
 xvds: unknown partition table
 xvdt: unknown partition table
 xvds: unknown partition table
 xvdt: unknown partition table

Please keep in mind some of the disks reported may be EC2 ephemeral storage, which you typically do not want to use for MySQL data, so make sure to only use EBS volumes in the following steps. If you are uncertain what is what, you can call fdisk -l and check the disk sizes:

[root@ip-10-32-2-145 ~]# fdisk -l

Disk /dev/xvde1: 6442 MB, 6442450944 bytes
255 heads, 63 sectors/track, 783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
[..]
Create partitions.

Create a new partition on the first disk.

[root@ip-10-32-2-145 ~]# fdisk /dev/xvds
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x3774dc60.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-54823, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-54823, default 54823):
Using default value 54823

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Command (m for help): wq
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Assuming you created several identical EBS volumes, duplicate the partition table onto each.

[root@ip-10-32-2-145 ~]# sfdisk -d /dev/xvds |  sfdisk /dev/xvdt
Checking that no-one is using this disk right now ...
OK

Disk /dev/xvdt: 54823 cylinders, 255 heads, 63 sectors/track

sfdisk: ERROR: sector 0 does not have an msdos signature
 /dev/xvdt: unrecognized partition table type
Old situation:
No partitions found
New situation:
Units = sectors of 512 bytes, counting from 0

   Device Boot    Start       End   #sectors  Id  System
/dev/xvdt1            63 880731494  880731432  fd  Linux raid autodetect
/dev/xvdt2             0         -          0   0  Empty
/dev/xvdt3             0         -          0   0  Empty
/dev/xvdt4             0         -          0   0  Empty
Warning: no primary partition is marked bootable (active)
This does not matter for LILO, but the DOS MBR will not boot this disk.
Successfully wrote the new partition table

Re-reading the partition table ...

If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1
(See fdisk(8).)
Verify partitions.
[root@ip-10-32-2-145 ~]# fdisk -l | grep -E '^/dev/xvd'
[..]
/dev/xvds1               1       54823   440365716   fd  Linux raid autodetect
/dev/xvdt1               1       54823   440365716   fd  Linux raid autodetect
Create RAID volume.

Create a new RAID level 0 volume over all EBS partitions. Use relatively large chunk size – 128KB or 256KB should be good choices.

[root@ip-10-32-2-145 ~]# mdadm -C /dev/md0 --chunk=256 -n 2 -l 0 /dev/xvds1 /dev/xvdt1
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
Save the md array configuration.
[root@ip-10-32-2-145 ~]# echo 'DEVICE /dev/xvds1 /dev/xvdt1' >> /etc/mdadm.conf
[root@ip-10-32-2-145 ~]# mdadm --examine --scan >> /etc/mdadm.conf

Here is what the file should look like

[root@ip-10-32-2-145 ~]# cat /etc/mdadm.conf
DEVICE /dev/xvds1 /dev/xvdt1
ARRAY /dev/md/0 metadata=1.2 UUID=f7d5b2e7:495efeb3:26297d34:7be87159 name=ip-10-32-2-145:0
Rebuild the initramfs image.

If this is not done, system won’t see the new /etc/mdadm.conf contents during boot and md device may be renamed to something else.

[root@ip-10-32-2-145 ~]# mkinitrd --force /boot/initramfs-2.6.32-220.el6.x86_64.img 2.6.32-220.el6.x86_64

You have to use the initramfs file and kernel version that are appropriate for your system. You can list /boot directory contents to figure this out:

[root@ip-10-226-155-162 ~]# ls -1 /boot/
config-2.6.32-220.el6.x86_64
efi
grub
initramfs-2.6.32-220.el6.x86_64.img
symvers-2.6.32-220.el6.x86_64.gz
System.map-2.6.32-220.el6.x86_64
vmlinuz-2.6.32-220.el6.x86_64
Create filesystem.

This part may take a while depending on the volume size.

[root@ip-10-32-2-145 ~]# mkfs.ext4 /dev/md0
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=64 blocks, Stripe width=128 blocks
55050240 inodes, 220182272 blocks
11009113 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
6720 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000, 214990848

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 36 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
Create a mount point.

I do not like mounting to /var/lib/mysql directly. Typically I create a new directory inside /vol, or /mnt, or /data.

[root@ip-10-32-2-145 ~]# mkdir -p /vol/mysql
Store the filesystem information.

Always use noauto option during installation. It skips automatic filesystem mounting during system init, which can save you from a lot of trouble if something does not work for any reason and when the boot process hangs on this step. EC2 does not come with a system console that would allow rescuing a system from such state.

[root@ip-10-32-2-145 ~]# echo '/dev/md0   /vol/mysql   ext4   rw,nobarrier,noatime,nodiratime,noauto   0 0' >> /etc/fstab

It may actually be very reasonable to keep noauto there forever and either mount the database volume manually each time the server reboots (it implies you also have to start MySQL manually) or implement volume mounting in a way that does not block the instance in case of some errors.

Mount the new volume.

This command can now use the configuration from /etc/fstab.

[root@ip-10-32-2-145 ~]# mount /vol/mysql

The command should not return anything, but to make sure it worked, just run a quick check whether the volume was acutally mounted or not:

[root@ip-10-32-2-145 ~]# df -h /vol/mysql
Filesystem            Size  Used Avail Use% Mounted on
/dev/md0              827G  201M  785G   1% /vol/mysql

Mounted on should point the new mount point and not to / for example.

Move the default data directory.

Move into the new location the default MySQL data directory created by the MySQL-server package installtion. Also create a directory for MySQL logs.

[root@ip-10-32-2-145 ~]# mv /var/lib/mysql /vol/mysql/
[root@ip-10-32-2-145 ~]# ln -s /vol/mysql/mysql /var/lib/mysql
[root@ip-10-32-2-145 ~]# mkdir /vol/mysql/log
[root@ip-10-32-2-145 ~]# chown mysql:mysql /vol/mysql/log
Set swappiness to prevent unnecessary swapping.

You can refer to this article for more details on swappiness.

[root@ip-10-32-2-145 ~]# echo 'vm.swappiness = 0' >> /etc/sysctl.conf
[root@ip-10-32-2-145 ~]# sysctl -p /etc/sysctl.conf
Configure time synchronization.

Create a new file called ntpdate in /etc/cron.daily with the following contents:

#!/bin/sh

/usr/sbin/ntpdate pool.ntp.org 1> /dev/null 2>&1

Then set the file permissions:

[root@ip-10-32-2-145 ~]# chmod +x /etc/cron.daily/ntpdate
Disable or configure SELinux.

RedHat comes with SELinux enabled, but often SELinux will be disabled during a database server installation process. To disable, perform the following:

[root@ip-10-32-2-145 ~]# cd /etc/sysconfig/
[root@ip-10-32-2-145 sysconfig]# replace 'SELINUX=enforcing' 'SELINUX=disabled' -- selinux
selinux converted
Restart the system.

It is time to restart the system. You should do this for two reasons:

  • You want to verify if the RAID volume loads correctly after a restart and that MySQL data volume can be mounted again without any problems.
  • You disabled SELinux and it is also the only way to make the change effective.
Verify md array stats and SELinux status.

Once the system boots again, verify the md array status.

[root@ip-10-32-2-145 ~]# cat /proc/mdstat
Personalities : [raid0]
md0 : active raid0 xvds1[0] xvdt1[1]
      880729088 blocks super 1.2 256k chunks

unused devices: 

It should still say md0 if you regenerated the initramfs image.

If you disabled SELinux, verify that as well.

[root@ip-10-32-2-145 ~]# selinuxenabled
[root@ip-10-32-2-145 ~]# echo $?
1

selinuxenabled indicates whether SELinux is enabled or disabled. It returns 0 if SELinux is enabled and 1 if it is not enabled.

Mount data volume.
[root@ip-10-32-2-145 ~]# mount /vol/mysql
[root@ip-10-32-2-145 ~]# df -h /vol/mysql
Filesystem            Size  Used Avail Use% Mounted on
/dev/md0              827G  201M  785G   1% /vol/mysql

If you want, now you can remove noauto from /etc/fstab.

Create MySQL configuration file.

I sometimes use this simple script that writes a good default configuration into /etc/my.cnf. It auto-tunes a few parameters that commonly need customization. You could just copy-paste it into the command line and run.

(cat <<EOF
[mysqld_safe]
log-error = /vol/mysql/log/mysql-error.log

[mysqld]
user = mysql
port = 3306
socket = /vol/mysql/mysql/mysql.sock

datadir = /vol/mysql/mysql
tmpdir = /tmp
pid-file = /vol/mysql/mysql/mysql.pid

character-set-server = utf8

slow-query-log
slow_query_log_file = /vol/mysql/log/mysql-slow.log
long_query_time = 10

log-bin = /vol/mysql/log/mysql-bin
relay-log = /vol/mysql/log/mysql-relay
server-id = $(/bin/hostname | /usr/bin/md5sum | /usr/bin/awk --non-decimal-data '{ hex=substr($1, 24, 8); printf ("0x"hex)+0 }')

back_log = 50
max_connections = 500
max_connect_errors = 100
skip-name-resolve

key_buffer_size = 8M
sort_buffer_size = 2M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 8M
max_allowed_packet = 16M
max_heap_table_size = 64M
tmp_table_size = 64M

table_open_cache = 2048
thread_cache_size = 16

innodb_file_per_table
innodb_data_file_path = ibdata1:128M:autoextend
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_log_buffer_size = 16M
innodb_buffer_pool_size = $(/usr/bin/awk '/MemTotal:/ { printf "%.0fM\n", ($2*0.70)/1024 }' /proc/meminfo)
innodb_log_file_size = 512M
innodb_log_files_in_group = 2
innodb_read_io_threads = $(($(/bin/grep -E 'md[0-9]+ : active raid0' /proc/mdstat | wc -w) - 2))
innodb_write_io_threads = $(($(/bin/grep -E 'md[0-9]+ : active raid0' /proc/mdstat | wc -w) - 2))
innodb_io_capacity = $((($(/bin/grep -E 'md[0-9]+ : active raid0' /proc/mdstat | wc -w) - 4 ) * 130))
innodb_thread_concurrency = 0

[mysql]
no-auto-rehash
socket=/vol/mysql/mysql/mysql.sock

[client]
socket=/vol/mysql/mysql/mysql.sock

EOF
) > /etc/my.cnf

Remember this is just a template. Each server may need individual adjustments to database configuration.

It’s done.

You can now start MySQL.

[root@ip-10-32-2-145 ~]# /etc/init.d/mysql start
Starting MySQL (Percona Server)........................     [OK]

PlanetMySQL Voting: Vote UP / Vote DOWN

How to install and configure a Linux server for MySQL?

Апрель 12th, 2012

Have you ever spent a lot of time thinking about how to install and configure a Linux server for MySQL database? I will try to highlight all the critical steps and some of the decisions you may need to make.

Linux distribution.

Unless you have a really good experience in systems administration, choose a widely supported Linux distribution. The best choices usually are RedHat or its free cousin called CentOS. Compatible alternatives you could also consider are Scientific Linux and Oracle Linux. Make sure you will be installing a 64-bit version, unless you have a very good reason not to.

Storage.

If you have multiple disks available in the server, create a single array from all disks. Choose RAID level that offers better performance rather than more disk space, so either RAID 1 or RAID 10 depending on the number of disks (“Should RAID 5 be used in a MySQL server?”). Use stripe (chunk) size of at least 128KB.

LVM.

You may skip it if database carries InnoDB tables only (other than system tables). Otherwise, or if unsure, LVM should be configured as it may help in creating consistent and lock-free MySQL backups. Make sure to leave some free space in the volume group where MySQL logical volume will be. 10% of the logical volume size could be a good default. An example of what you should see after installation:

garfield ~ # vgdisplay <your volume group name>
  --- Volume group ---
  VG Name               <your volume group name>
  System ID
  Format                lvm2
[..]
  VG Size               1,58 TiB
  PE Size               4,00 MiB
  Total PE              413626
  Alloc PE / Size       394426 / 1,51 TiB
  Free  PE / Size       19200 / 75,00 GiB
  VG UUID               aZcyWM-B1mc-5PEc-VeNf-W0fw-hLvV-12w29x

Partitioning.

For a dedicated database server, it is commonly enough to create four partitions:

  • /boot – tiny, to hold boot files – please refer to the system documentation for details
  • / – 20GB or 30GB for the system files and logs
  • swap – nothing larger than a few gigabytes makes sense
  • /mnt/db – all remaining space for MySQL data and binary logs

Filesystem.

Use whatever you want for system partitions. For MySQL partition, ext3 or ext4 are fine, but if you need to squeeze that last ounce of performance out of the system, go with xfs. It can deal much better with concurrent I/O.

Time synchronization.

All your servers should have their clocks updated periodically. Install NTP client and make sure it updates time daily. How to check whether clock is out of sync or not? Once you install ntpdate package, try the following:

garfield ~ # ntpdate -q pool.ntp.org
server 77.65.7.58, stratum 2, offset -29.763656, delay 0.04489
server 91.217.142.1, stratum 2, offset -29.776960, delay 0.08609
server 195.8.52.8, stratum 2, offset -29.761839, delay 0.04979
12 Apr 12:21:25 ntpdate[8676]: step time server 77.65.7.58 offset -29.763656 sec

The clock in my computer was clearly not synchronized :-)

Swap.

Prevent needless swap activity. Add vm.swappiness = 0 into /etc/sysctl.conf. Please refer to “How to prevent swapping on a MySQL server?” for details.

I/O scheduler.

By default any Linux uses CFQ algorithm for I/O scheduling. CFQ does not really care about I/O latency and may serialize requests, which means it can work against database performance. This is why it should be replaced with deadline, or even noop when server has a good hardware RAID controller, on physical volumes where MySQL data files will be stored.

In order to change the I/O scheduler at run time, simply write into a special pseudo-file /sys/block/<block device>/queue/scheduler, for example:

echo "noop" > /sys/block/sda/queue/scheduler

The change can be made permanent by adding such line into an init script such as /etc/rc.local or other that is appropriate.

MySQL configuration.

  1. Create MySQL data directory inside the volume mount point (e.g. /mnt/db/mysql). Do not use the mount point directly or you may be seeing the annoying lost+found database inside MySQL.
  2. Create a directory for binary logs (e.g. /mnt/db/binlog).

Alternatively, instead of making new /mnt/db/mysql, you may simply move the data directory created by the install script from a MySQL package (e.g. mv /var/lib/mysql /mnt/db/).

And do not forget about changing these directories ownership to mysql user!

In my.cnf, set the following:

  1. datadir to /mnt/db/mysql
  2. log-bin to /mnt/db/binlog/mysql-bin
  3. relay-log to /mnt/db/binlog/mysql-relay

Done.

At this point the server is ready for use and you can begin taking care of setting up privileges and tuning the MySQL configuration.


PlanetMySQL Voting: Vote UP / Vote DOWN

dbbenchmark.com – configuring OpenBSD for MySQL benchmarking

Сентябрь 3rd, 2010

Here are some quick commands for installing the proper packages and requirements for the MySQL dbbenchmark program.

export PKG_PATH="ftp://openbsd.mirrors.tds.net/pub/OpenBSD/4.7/packages/amd64/"
pkg_add -i -v wget
wget http://dbbenchmark.googlecode.com/files/dbbenchmark-version-0.1.beta_rev26.tar.gz
pkg_add -i -v python
Ambiguous: choose package for python
 a       0:
         1: python-2.4.6p2
         2: python-2.5.4p3
         3: python-2.6.3p1
Your choice: 2

pkg_add -i -v py-mysql
pkg_add -i -v mysql
pkg_add -i -v mysql-server
ln -s /usr/local/bin/python2.5 /usr/bin/python
gzip -d dbbenchmark-version-0.1.beta_rev26.tar.gz
tar -xvf dbbenchmark-version-0.1.beta_rev26.tar
cd dbbenchmark-version-0.1.beta_rev26
./dbbenchmark.py --print-sql
 - login to mysql and execute sql commands
./dbbenchmark.py

PlanetMySQL Voting: Vote UP / Vote DOWN

Sure-fire MySQL Install on Windows

Июнь 25th, 2010

Due to firewalls, virus scans, corporate security restrictions, or just plain bad luck; there are times when MySQL just won’t install on a specific Windows server.  Here’s a sure-fire install method.   Relax, I won’t have you run the msi installer again.

The first step is to remove directories from your previous install attempts.  Uninstall from the control panel.  Manually, rename or delete “C:\Program Files\MySQL\MySQL Server 5.1″.  Next, delete (or rename) the data directory.  Warning! If you have previously entered data into MySQL, deleting the data directory will delete data.  The directory is located at “C:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.1\data”.   You may need to unhide the data directory.

Let’s get started.

#1.  Download the no-install MySQL Version for Windows.  Choose either “Windows (x86, 32-bit) ZIP Archive” or “Windows (x86, 64-bit) ZIP Archive” based on whether your system is 64 or 32-bit .

#2.  Unzip the files to “C:\Program Files\MySQL\MySQL Server 5.1″.

#3.  Use notepad or wordpad to create a my.ini file and save the file in the MySQL directory, “C:\Program Files\MySQL\MySQL Server 5.1″   Be careful that notepad doesn’t add a default “.txt” extension to the my.ini file ( http://support.microsoft.com/kb/253688 )

Add the following following to your my.ini file and save.

[mysqld]
##update basedir if you move the install location
basedir="C:/Program Files/MySQL/MySQL Server 5.1"

##update datadir if you move the data directory
datadir="C:/Program Files/MySQL/MySQL Server 5.1/data"

## increase to 40% of RAM if using MyISAM
key_buffer_size=32MB

## increase to 80% of available RAM for production usage
innodb_buffer_pool_size = 128MB

## may want to increase if write intensive
innodb_log_file_size = 64MB
innodb_log_buffer_size=8MB
table_cache=1024
thread_cache=16
query_cache_size=32M

Note the basedir and the datadir variables.  If you wish to install in a different location or put the data in a different location, update these values accordingly.

#3.  Create and start the service.    Open a command prompt, and enter the following:

"C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld"  --install "MySQL 5.1" --defaults-file="C:\Program Files\MySQL\MySQL Server 5.1\my.ini"

This installs the server.  To start the service, type

net start "MySQL 5.1"

or start the service from the control panel.

You should be up and running.  If not, check your err log in “C:\Program Files\MySQL\MySQL Server 5.1\Data”

#4.  Connect from your client application and update your user accounts.  By default, there are 3 accounts: root@localhost, root@127.0.0.1 and an anonymous account.

The following commands log in with the mysql command-line client, remove the anonymous account and set the password for the root accounts.

At a command prompt, enter the following:

"c:\program files\mysql\mysql 5.1 server\bin\mysql" -uroot

This will log you into MySQL and you should have a mysql command prompt like mysql>

Here are the commands to delete your anonymous account and set passwords for your two root accounts.  When setting the password, substitute your desired password for “mypassword”.


mysql> DROP USER ""@localhost;
mysql> Set PASSWORD FOR "root"@"localhost" = password("mypassword");
mysql> Set PASSWORD FOR "root"@"127.0.0.1" = password("mypassword");
mysql> flush privileges;
mysql> exit

Feel free to post any questions/comments or issues to the comment section of this blog.  For more comprehensive instructions see http://dev.mysql.com/doc/refman/5.1/en/windows-install-archive.html



PlanetMySQL Voting: Vote UP / Vote DOWN