Some hardware/operating system architectures support memory pages greater than the default (usually 4KB). The actual implementation of this support depends on the underlying hardware and operating system. Applications that perform a lot of memory accesses may obtain performance improvements by using large pages due to reduced Translation Lookaside Buffer (TLB) misses.
In MySQL, large pages can be used by InnoDB, to allocate memory for its buffer pool and additional memory pool.
Standard use of large pages in MySQL attempts to use the
largest size supported, up to 4MB. Under Solaris, a
“super large pages” feature enables uses of pages
up to 256MB. This feature is available for recent SPARC
platforms. It can be enabled or disabled by using the
--super-large-pages or
--skip-super-large-pages
option.
MySQL also supports the Linux implementation of large page support (which is called HugeTLB in Linux).
Before large pages can be used on Linux, the kernel must be
enabled to support them and it is necessary to configure the
HugeTLB memory pool. For reference, the HugeTBL API is
documented in the
Documentation/vm/hugetlbpage.txt file of
your Linux sources.
The kernel for some recent systems such as Red Hat Enterprise Linux appear to have the large pages feature enabled by default. To check whether this is true for your kernel, use the following command and look for output lines containing “huge”:
shell> cat /proc/meminfo | grep -i huge
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 4096 kB
The nonempty command output indicates that large page support is present, but the zero values indicate that no pages are configured for use.
If your kernel needs to be reconfigured to support large
pages, consult the hugetlbpage.txt file
for instructions.
Assuming that your Linux kernel has large page support
enabled, configure it for use by MySQL using the following
commands. Normally, you put these in an
rc file or equivalent startup file that
is executed during the system boot sequence, so that the
commands execute each time the system starts. The commands
should execute early in the boot sequence, before the MySQL
server starts. Be sure to change the allocation numbers and
the group number as appropriate for your system.
# Set the number of pages to be used. # Each page is normally 2MB, so a value of 20 = 40MB. # This command actually allocates memory, so this much # memory must be available. echo 20 > /proc/sys/vm/nr_hugepages # Set the group number that is permitted to access this # memory (102 in this case). The mysql user must be a # member of this group. echo 102 > /proc/sys/vm/hugetlb_shm_group # Increase the amount of shmem permitted per segment # (12G in this case). echo 1560281088 > /proc/sys/kernel/shmmax # Increase total amount of shared memory. The value # is the number of pages. At 4KB/page, 4194304 = 16GB. echo 4194304 > /proc/sys/kernel/shmall
For MySQL usage, you normally want the value of
shmmax to be close to the value of
shmall.
To verify the large page configuration, check
/proc/meminfo again as described
previously. Now you should see some nonzero values:
shell> cat /proc/meminfo | grep -i huge
HugePages_Total: 20
HugePages_Free: 20
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 4096 kB
The final step to make use of the
hugetlb_shm_group is to give the
mysql user an “unlimited”
value for the memlock limit. This can by done either by
editing /etc/security/limits.conf or by
adding the following command to your
mysqld_safe script:
ulimit -l unlimited
Adding the ulimit command to
mysqld_safe causes the
root user to set the memlock limit to
unlimited before switching to the
mysql user. (This assumes that
mysqld_safe is started by
root.)
Large page support in MySQL is disabled by default. To enable
it, start the server with the
--large-pages option. For
example, you can use the following lines in your server's
my.cnf file:
[mysqld] large-pages
With this option, InnoDB uses large pages
automatically for its buffer pool and additional memory pool.
If InnoDB cannot do this, it falls back to
use of traditional memory and writes a warning to the error
log: Warning: Using conventional memory
pool
To verify that large pages are being used, check
/proc/meminfo again:
shell> cat /proc/meminfo | grep -i huge
HugePages_Total: 20
HugePages_Free: 20
HugePages_Rsvd: 2
HugePages_Surp: 0
Hugepagesize: 4096 kB

User Comments
An error will always generate on initial startup of mysqld since the 'mysql_install_db' script is run necessarily prior to 'mysqld_safe' in the daemon startup script. In order to allow the initialization of the database using huge page support, ease the memlock limit by typing 'ulimit -l unlimited' as root at the command prompt before either starting mysqld or executing mysql_install_db. This is in addition to adding it to the mysqld_safe script.
Also, choose values wisely since I believe that the 'nr_hugepages' parameter will actually reserve physical memory. At 2MB per page that means a value of 512 will reserve 1GB.
If you are getting the error 22 or 12 at initialization, both of the above tips should help immensely. (See also http://time.to.pullthepl.ug/story/2008/11/18/9/-MySQL-Large-Pages-errors .)
I had an issue where large pages were enabled however mysql was not using the whole chunk of large page memory allocated (approx 23 GB) so the server was swapping constantly. This was MySQL 5.1.49 using the new innodb plugin 1.0.10 (also applies to MySQL 5.5 and above most likely). The solution: the amount of large page memory you allocate should be > innodb_buffer_pool size.
I allocated 13,500 large pages for a 24 GB buffer pool and it works fine now.
Hi,
following system:
Debian 6 4CPU 20Gbyte RAM dedicated MySQL server
my.cnf:
...
innodb_buffer_pool_size = 12000M
innodb_additional_mem_pool_size = 16M
...
Therefore the following /etc/sysctl.d/mysql.conf
----
# Set the number of pages to be used:
# Add innodb_buffer_pool_size and
# innodb_additional_mem_pool_size
# and divide by Hugepagesize.
# Each page is normally 2MB, so a value of 6100 = 12200MB.
# This command actually allocates memory, so this much
# memory must be available.
# Important:
# ulimit -l unlimited
# and set in my.cnf:
# ...
# [mysqld]
# large-pages
# ...
vm.nr_hugepages = 6100
# Set the group number that is permitted to access this
# memory (110 in this case). The mysql user must be a
# member of this group.
vm.hugetlb_shm_group = 110
# Set the amount of shmem permitted per segment in bytes
# (12199Mb in this case).
kernel.shmmax = 12791578624
# Set the total amount of shared memory. The value
# is the size in pages. At 4KB/page, 3122944 = 12199MB.
kernel.shmall = 3122944
----
I added the ulimit to the startup script and added the large-pages in the mysqld section.
But I get the following error:
....
110823 13:41:00 mysqld_safe Starting mysqld daemon with databases from /mnt/mysql/data
110823 13:41:00 [Warning] '--log_slow_queries' is deprecated and will be removed in a future release. Please use ''--slow_query_log'/'--slow_query_log_file'' instead.
110823 13:41:00 [Note] Plugin 'FEDERATED' is disabled.
InnoDB: HugeTLB: Warning: Failed to allocate 12582928384 bytes. errno 28
InnoDB HugeTLB: Warning: Using conventional memory pool
...
The existing samples are not very clear - I would like to know if my example is right and clear enough for calculation the size correctly.
Got it to work:
Instead of using the calculated 12200MB I used 15GB.
root@mysql04.dc1:~# ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x6c1009eb 0 zabbix 600 693504 8
0x00000000 32769 mysql 600 1279262720 1 dest
0x00000000 65538 mysql 600 12585009152 1 dest
root@mysql04.dc1:~# grep -i huge /proc/meminfo
HugePages_Total: 7680
HugePages_Free: 7394
HugePages_Rsvd: 6325
HugePages_Surp: 0
Hugepagesize: 2048 kB
root@mysql04.dc1:~#
So the calculation seeems somehow to be wrong...
Add your own comment.