本节讨论的优化技术为数据库服务器,主要是与系统配置的处理,而不是调优SQL语句。本节中的信息适用于谁想要确保在他们所管理的服务器的性能和可扩展性;对于开发人员构建的安装脚本,包括建立数据库;和人员运行MySQL本身的开发,测试等,谁想要最大限度地提高自己的工作效率。
1. 系统因素和启动参数的调节(System Factors and Startup Parameter Tuning)
我们先从系统层面的因素,因为有些决策必须很早做出决定才能实现巨大的性能提升。
要使用的操作系统是非常重要的。要获得多CPU机器的最佳使用,你应该使用Solaris(因为它的线程执行效果较好)或Linux(因为2.4和以后的内核 具有良好的SMP支持)。需要注意的是老版本的Linux内核有一个默认的2GB文件大小限制。如果你有这样的内核和需要大于2GB的文件,让大文件支持(LFS)补丁ext2文件系统。其它文件系统如ReiserFS和XFS没有这个2GB限制。
在生产中使用MySQL之前,我们建议您在您的目标平台上进行测试。
其他提示:
-
如果你有足够的内存,你可以删除所有交换设备。一些操作系统在某些情况下即使有空闲的内存也会使用交换设备。
-
避免MyISAM表外部锁。从MySQL4.0中,默认在所有系统上禁用外部锁。该--external-locking和--skip-external-locking选项明确地启用和禁用外部锁定。
请注意,禁用外部锁定,不影响MySQL的功能只要你只运行一个服务。只需记住在运行myisamchk之前关闭服务器(或锁定并刷新相关表格)。在一些系统上它是强制性禁用外部锁。
在LOCK TABLES并UNLOCK TABLES语句中使用内部锁定,因此可以使用它们,即使外部锁定被禁用。
2.调节服务器参数(Tuning Server Parameters)
可确定使用此命令mysqld服务器缺省缓冲区大小:
shell> mysqld --verbose --help
此命令产生的所有的mysqld选项和可配置的系统变量列表。输出包括默认的变量值,看起来像这样:
…………………………
对于当前正在运行的mysqld服务器,可以通过连接到它,并发出该语句看它的系统变量的当前值:
mysql> SHOW VARIABLES;
也可以看到正在运行的服务器的一些统计数据和状态指示发出以下声明:
mysql> SHOW STATUS;
系统变量和状态信息,也可使用mysqladmin可以得到:
shell> mysqladmin variables
shell> mysqladmin extended-status
MySQL使用的算法是非常可扩展性,因此通常可以用很少的内存运行。不过,通常给予MySQL更多的内存获得更好的性能。
当调整MySQL服务器,可以配置的两个最重要的变量是的key_buffer_size[520]和table_open_cache[584]。
下面的例子显示了不同的运行时配置一些典型的变量值。
-
如果至少有256MB的内存和很多表,并希望与客户的中等数量最大的性能,使用这样的:
shell> mysqld_safe --key_buffer_size=64M --table_open_cache=256 \
--sort_buffer_size=4M --read_buffer_size=1M &
-
如果你只有128MB的内存,只有一些表,但你还是做了很多的排序,你可以使用像这样:
shell> mysqld_safe --key_buffer_size=16M --sort_buffer_size=1M
如果有非常多的并发连接,可能会情况之外mysqld的已配置为使用很少的内存为每个连接交换问题。如果你有足够的内存mysqld的所有连接性能更好。
-
用很少的内存和大量的连接,使用像这样:
shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=100K \
--read_buffer_size=100K &
或者这样
shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=16K \
--table_open_cache=32 --read_buffer_size=8K \
--net_buffer_length=1K &
如果对表,比可用内存大得多执行GROUP BY或ORDER BY操作,提高read_rnd_buffer_size的[565]的值,以加快排序如下操作行的读取。
如果指定的mysqld或mysqld_safe的命令行选项,它仍然只对服务器该调用。在每次服务器运行时使用的选项,把它放在选项文件。
看参数变化的影响,做这样的事情:
shell> mysqld --key_buffer_size=32M --verbose --help
变量值如下附列的输出。确保--verbose[471]和--help[436]选项是最后一个。否则,在命令行后它们列出的任何选项的效果是
未反映在输出中。
3.优化磁盘I/O(Optimizing Disk I/O)
-
磁盘寻道是一个巨大的性能瓶颈。当数据量开始增长加大,以致有效的缓存变得不可能应付,这个问题变得更加明显。对于大型数据库存取数据或多或少随机,可以肯定需要的至少一个磁盘寻道来读取和几个磁盘搜索来写东西。为了尽量减少此问题,使用具有低寻道时间磁盘。
-
增加可用磁盘轴的数量(和从而减少寻道开销),要么通过符号链接文件,以不同的磁盘或条带化磁盘:
-
使用符号链接
这意味着,对于MyISAM表,符号链接从数据目录的位置通常在索引文件和数据文件到另一个磁盘(即也可以条带化)。这使得无论在寻找和读取时间更好,假设磁盘不用于其他目的。
-
条带化
条带意味着必须许多磁盘并把第一块中的第一盘,第二盘上的第二块,和在(NMOD number_of_disks)的第N个块的磁盘上,等。这意味着如果正常的数据大小比磁条大小少(或完全一致),你会得到更好的性能。条带化是非常依赖于操作系统和条带大小,所以基准用不同的条带大小应用程序。
对于条带的速度差是非常依赖于参数。这取决于如何设置的条带化参数和磁盘数量,可能会得到不同的测量数量级。必须选择随机或顺序访问从而优化。
-
为保证可靠性,您可能需要使用RAID0+1(条带化加镜像),但在这种情况下,需要2×N个驱动器来保存数据n驱动器。如果有钱这可能是最好的选项。但是,可能还需要投资一些卷管理软件有效地处理它。
-
一个好的选择是根据关键不同类型的数据如何选择RAID级别。例如,存储半重要的数据,可以在RAID0磁盘再生,但存储非常重要的数据,如在RAID0+1或RAID n磁盘主机信息和日志。如果你有许多写入,由于需要更新奇偶校验位的时间,RAID N可能是一个问题。
-
在Linux上,你可以通过使用hdparm的配置磁盘的接口获得更好的性能(在负载下高达100%的情况并不少见)。下面hdparm的选项应该是MySQL的相当不错,而且很可能在许多其他应用:
hdparm -m 16 -d 1
在使用该命令时需要注意的是性能和可靠性,取决于您的硬件,因此我们强烈建议您在使用hdparm的后彻底测试你的系统。参考hdparm的手册页获取更多信息。如果hdparm的没有合理利用,可能会导致文件系统损坏,所以试验之前备份!
-
还可以设置数据库使用的文件系统的参数:
如果不需要知道什么时候文件上次访问(这是不是在数据库服务器上真的很有用),你可以使用-o noatime选项挂载文件系统。这跳过的文件系统上的inode更新的最后访问时间从而避免一些磁盘寻道。
在许多操作系统中,你可以通过与-o asyncoption安装它设置一个文件系统,异步更新。
3.1使用符号链接(Using Symbolic Links)
可以移动数据库或表从数据库目录到其他地方,并与符号链接到新位置取代。可能要做到这一点,例如,一个数据库移动到文件系统有更多的自由空间,或通过传播你的表不同的提高系统的运行速度磁盘。
对于InnoDB表,使用CREATE TABLE语句数据创建,而不是符号链接 详见5.4.1.2, “Specifying the Location of a Tablespace”。这个新功能是支持跨平台的技术。
推荐的方法是符号链接整个数据库目录到不同的磁盘。符号链接MyISAM表只能作为最后的手段。
要确定您的数据目录的位置,请使用下面的语句:
SHOW VARIABLES LIKE 'datadir';
3.1.1在Unix上使用数据库的符号链接 (Using Symbolic Links for Databases on Unix)
在Unix中,符号链接数据库的方式是先有的磁盘,你有自由的空间,然后创建MySQL数据目录到它的软链接上创建一个目录。
shell> mkdir /dr1/databases/test
shell> ln -s /dr1/databases/test /path/to/datadir
MySQL不支持多个数据库连接一个目录.一个符号链接工作只要你不让数据库之间的链接符号替换数据库目录。假设你有一个数据库DB1 MySQL数据目录下,然后做一个链接指向DB1DB2:
shell> cd /path/to/datadir
shell> ln -s db1 db2
结果表明,或任何表tbl_a DB1中,似乎也在DB2表tbl_a。如果一个客户端更新db1.tbl_a和另一个客户端更新db2.tbl_a,有可能发生的问题。
3.1.2. 在UNIX使用MyISAM符号链接(Using Symbolic Links for MyISAM Tables on Unix)
符号链接是完全只支持MyISAM表。通过对其他存储引擎的表使用的文件,你可能如果你试图使用符号链接得到奇怪问题。
不链接表上没有一个完整的操作调用realpath()。(Linux和Solaris支持的realpath())要确定您的系统是否支持符号链接,检查的值 have_symlink[515]系统变量使用下面的语句:
SHOW VARIABLES LIKE 'have_symlink';
符号链接的MyISAM表处理的工作原理如下:
-
在数据目录中,你总是有表格式(.FRM)文件,数据(.MYD)文件,索引(.MYI)文件.数据文件和索引文件可以去其他地方移动,并通过符号链接替换的数据目录。该格式文件不能。
-
可以单独符号链接的数据文件和索引文件不同的目录中。
-
指示正在运行的MySQL服务器进行符号链接,使用DATA DIRECTORY和INDEX DIRECTORY选项CREATE TABLE.另外,如果mysqld没有运行,符号链接,可以手动使用ln -s命令行来实现。
注意:在数据目录和索引中的一个或两个中使用的路径目录选项可能不包括MySQL数据目录. (Bug #32167)
-
使用myisamchk不会替换为数据文件或索引文件中的符号链接。它可以直接对文件的符号连接点。任何临时文件的目录中创建在数据文件或索引文件所在。这同样适用于使用ALTER TABLE,OPTIMIZE TABLE和REPAIR TABLE语句。
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
注意:当删除正在使用符号链接的表,无论是符号链接和文件 其符号链接指向都将被删除。这是一个非常好的理由不 mysqld的运行为系统根目录或许可证制度用户有写权限的MySQL数据库目录。
-
如果重命名表使用ALTER TABLE...RENAME或RENAME TABLE并且不表移动到另一个数据库,在数据库目录中的符号链接被重命名为新的名称和数据文件和索引文件也相应更名。
-
如果你使用ALTER TABLE... RENAME或RENAME TABLE到表移动到另一个数据库,表移动到其他数据库目录中。如果表名变了,在新的数据库目录中的符号链接被重命名为新的名称和数据文件和索引文件也相应更名。
-
如果不使用符号链接,启动mysqld --skip-symbolic-links[465]选项,以确保没有人可以使用mysqld的删除或重命名文件的数据目录之外。
不支持这些表的符号链接的操作:
-
ALTER TABLE忽略DATA DIRECTORY和INDEX DIRECTORY表选项。
-
如前面所指出的,只有数据文件和索引文件可以是符号链接。.frm文件绝不能是一个符号链接。试图执行此操作(例如,使一个表名的代名词另一个) 会产生不正确的结果。假设你有MySQL数据目录下的数据库DB1,在这个数据库中的表TBL,并在DB1目录中你做一个符号链接TBL2指向TBL1:
shell> cd /path/to/datadir/db1
shell> ln -s tbl1.frm tbl2.frm
shell> ln -s tbl1.MYD tbl2.MYD
shell> ln -s tbl1.MYI tbl2.MYI
问题导致如果一个线程读取db1.tbl1而另一个线程更新db1.tbl2:
-
查询缓存被“fooled”(它没有办法知道tbl1has没有更新,所以它返回过时的结果)。...
-
ALTER语句上TBL2失败
3.1.3 在Windows使用符号链接的数据库( Using Symbolic Links for Databases on Windows)
在Windows中,符号链接可用于数据库目录.这使您能够把数据库目录在不同的位置(例如,在不同的磁盘上)通过符号链接设置。在Windows上使用数据库的符号链接的是类似于其在Unix使用,虽然对于建立链接的过程是不同的。
假设你要放置在指定的数据库mydbat 中的数据库目录D:\ DATA\ mydb。要做到这一点,创建一个指向D:\ DATA\ mydb的MySQL数据目录的符号链接。但是,创建符号链接之前,请确保D:\ DATA\ mydb的目录是否存在,如果有必要创建它。如果你已经有一个名为mydbin数据目录的数据库目录,将其移动到D:\DATA。否则,符号链接是无效的。为了避免出现问题,确保当您移动数据库目录时服务没有运行。
用于创建数据库的符号链接的过程取决于您的Windows版本。
Windows Vista中的Windows Server 2008或更新的有本地符号链接的支持,让你可以使用MKLINK命令创建一个符号链接。此命令需要管理员权限。
-
改变位置到数据目录:
C:\> cd \path\to\datadir
-
在数据目录中创建符号链接名为mydb的指向数据库目录的位置:
C:\> mklink /d mydb D:\data\mydb
在此之后,在mydb数据库中创建的所有表中都在D:\ DATA\ mydb生成。
另外,由MySQL支持的所有版本的Windows,你可以通过创建数据目录中的.SYM文件,其中包含的路径到目标目录中创建一个MySQL数据库的符号链接。该文件应命名为db_name.sym,其中db_name是数据库名称。
支持使用.SYM文件在Windows数据库符号链接默认情况下启用。如果你不需要.SYM文件的符号链接,你可以通过启动mysqld使用--skip-symbolic-links[465]选项来禁用对他们的支持。要确定您的系统是否支持.SYM文件的符号链接,请使用此语句的have_symlink[515]系统变量的值:
SHOW VARIABLES LIKE 'have_symlink';
要创建一个.SYM文件的符号连接,使用这个程序:
-
改变位置到数据目录:
C:\> cd \path\to\datadir
-
在数据目录下,创建一个包含该路径名名为mydb的.SYM的文本文件:D:\ DATA\ mydb\
在此之后,在D:\ DATA\ mydb中创建的数据库mydbare创建的所有表。
以下限制适用于使用.SYM文件在Windows数据库的符号链接。这些限制不适用于使用MKLINK创建符号链接。
-
如果存在于MySQL数据目录名称相同的数据库目录中的符号链接并不使用。
-
不能使用的--innodb_file_per_table[1818]选项。
-
如果您运行的mysqld作为一种服务,则不能使用映射的驱动器到远程服务器作为符号链接的目标。作为一种变通方法,您可以使用完整路径。(\\servername\path\)
4.优化内存使用(Optimizing Memory Use)
4.1 MySQL如何使用内存(How MySQL Uses Memory)
下面的列表显示了一些mysqld服务器使用内存的方法。在适用情况下,相关的存储器使用的系统变量的名称被给出:
-
所有线程共享的MyISAM键缓存;它的大小是由的key_buffer_size[520]变量确定。服务器使用的其他缓冲区根据需要分配
-
用来管理客户端连接的每个线程使用了一些特定于线程的空间。下面的列表显示这些和哪些变量控制它们的大小:
-
堆栈(thread_stack参数)
-
一个连接缓冲区(net_buffer_length参数)
-
一个结果缓冲区(net_buffer_length参数)
。 连接缓冲区和结果缓冲区各以一个大小等于为net_buffer_length[544]个字节,但动态地被扩大直到max_allowed_packet[530]为所需的字节。结果缓冲区缩小为net_buffer_length字节每个SQL语句之后。虽然声明中运行,当前语句的字符串的副本也划分
-
所有线程共享相同的基本内存。
-
当线程不再需要分配给它的内存被释放并返回到系统中,除非该线程返回到线程缓存。在这种情况下,该内存保持分配。
-
该myisam_use_mmap系统变量可以被设置为1,使内存映射所有的MyISAM表。
-
执行表的顺序扫描每个请求分配一个读缓冲区(变量 read_buffer_size[563])。
-
当读取任意顺序列(例如,下面的排序),随机读缓存(可变read_rnd_buffer_size[565])可以被分配,以避免磁盘寻道。
-
所有joins单次执行,大部分联接甚至无需使用临时表来完成.大多数临时表是基于内存的哈希表。与大排的长度(按所有列长度之和)或包含BLOB列临时表存储在磁盘上。
如果内部内存临时表变得太大时,MySQL通过改变表从内存到磁盘上的格式,由MyISAM存储引擎来处理自动处理的。
-
执行一种最请求分配一个排序缓冲区和零至两个临时文件根据结果集的大小。
-
几乎所有的分析和计算在本地线程和可重复使用的内存池进行。没有内存开销是需要的,所以避免正常缓慢的内存分配和释放。
内存只分配给出乎意料的大字符串。
-
对于每被打开一个MyISAM表,索引文件被打开一次;该数据文件被打开一次为每个并发运行的线程。对于每个并发线程,一个表结构列结构为每一列和大小3* N的缓冲区分配(其中尼什的最大行长度,不包括BLOB列)。BLOB列需要五个八个字节加上BLOB数据的长度。MyISAM存储引擎维护一个额外的行缓冲区供内部使用。
-
对于每个表有BLOB列,一个缓冲区动态地被扩大读取在更大的BLOB值。如果扫描的表,一个缓冲区一样大的大BLOB值分配。
-
处理器结构全部使用表都保存在缓存中,并作为一个FIFO管理。最初的高速缓存大小是从table_open_cache[584]系统变量的值。如果一个表在同一时间被用于由两个运行的线程,高速缓存包含该表中的两个条目。
-
一个FLUSH TABLES语句或mysqladmin flush-tables命令关闭不在使用一次都在使用的表要在当前正在执行的线程结束时,关闭所有表和标记。这有效地释放大部分使用的内存。FLUSH TABLES不会返回,直到所有的表都被关闭。
-
服务器缓存在内存中信息GRANT,CREATE USER,CREATE SERVER,和 INSTALL PLUGIN 的语句。该内存不释放相应的REVOKE,DROP USER,DROP SERVER和UNINSTALL PLUGIN语句,因此对于服务器执行许多这种导致高速缓存缓慢的语句的情况下,就会增加的内存使用。这个缓存的内存可以被FLUSH PRIVILEGES释放。
ps和其他系统状态的程序可能会报告mysqld使用了大量的内存。这可以通过在不同的内存地址线程堆栈所引起。例如,PS的Solaris版本计算堆栈所使用内存的未使用的内存。
4.2 启动大页面支持(Enabling Large Page Support)
一些硬件/操作系统体系结构支持的内存页大于默认值(通常是4KB)。这种支持的实际实现取决于底层硬件和操作系统。执行了大量的内存访问可以通过使用由于减少了转换后备缓冲器(TLB)的遗漏大页面获得性能提升的应用程序。
在MySQL中,大页面可以使用InnoDB中,分配内存的缓冲池和额外的内存池。
规范使用大页面在MySQL中尝试使用的最大尺寸的支持,高达4MB。在Solaris上,“超级大页”功能使页使用最多256MB。此功能适用于最近的SPARC平台。它可以启用或使用 --super-large-pages[465]或--skip-super-large-pages[465]选项禁用。
MySQL还支持Linux实现的大页面支持(即所谓HugeTLB在Linux中)。
在大页面可以在Linux上使用,内核必须能够支持它们,这是必要的配置HugeTLB内存池。作为参考,HugeTBL API被记录在您的Linux源文档/vm/hugetlbpage.txt文件。
该内核最近的一些系统,如红帽企业Linux似乎有大页面功能默认情况下启用。要检查这是否是真正的内核,可以使用下面的命令,并查找包含“huge”的输出线:
shell> cat /proc/meminfo | grep -i huge
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 4096 kB
非空命令的输出表明,大页面支持是存在的,但零值表示没有页面配置使用。
如果你的内核需要重新配置,以支持大页面,查阅有关hugetlbpage.txt文件说明。
假设你的Linux内核中启用了大页面支持,通过MySQL的使用以下命令将其配置为使用。通常情况下,在被系统引导顺序中执行,从而使命令执行在系统每次启动时的rcfile或等价的启动文件中把这些。这些命令应该执行在引导过程的早期,MySQL服务器启动之前。一定要改变分配数和组号以适合您的系统。
# 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
对于MySQL的使用,通常要SHMMAX的值接近SHMALL的值。
为了验证大页面的配置,检查/ proc/ meminfo中再次如前所述。现在,你应该可以看到一些非零的值:
shell> cat /proc/meminfo | grep -i huge
HugePages_Total: 20
HugePages_Free: 20
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 4096 kB
最后一步要利用hugetlb_shm_group的是给mysql用户的“unlimited”值MEMLOCK限制。这可以通过完成编辑/etc/security/limits.conf或通过添加 下面的命令来你mysqld_safe的脚本:
ulimit -l unlimited
添加ulimit命令来mysqld_safe的使root用户切换到mysqluser之前设置MEMLOCK限制无限(这是假定mysqld_safeis开始由root)。
在MySQL中大页面支持默认是关闭的。要启用它,启动服务器的--large-pages选项。例如,您可以使用您的服务器的my.cnf文件下面几行:
[mysqld]
large-pages
使用此选项时,InnoDB会自动使用大页面的缓冲池和额外的内存池。如果InnoDB中无法做到这一点,回退到使用传统的内存,并写入一个警告,错误日志:
Warning: Using conventional memory pool
为了验证大页的使用情况,再次检查/ proc/ meminfo:
shell> cat /proc/meminfo | grep -i huge
HugePages_Total: 20
HugePages_Free: 20
HugePages_Rsvd: 2
HugePages_Surp: 0
Hugepagesize: 4096 kB
5.优化网络使用(Optimizing Network Use)
5.1 MySQL如何使用线程的客户端连接(How MySQL Uses Threads for Client Connections)
连接管理器线程处理上,该服务器监听到网络接口的客户端的连接请求。在所有平台上,一位管理线程处理的TCP / IP连接请求。在Unix中,这个管理线程同时处理Unix套接字文件连接请求。在Windows中,一个管理者线程处理共享内存的连接请求,另一个句柄命名管道连接请求。服务器不创建线程来处理它不会监听接口。例如,不具有命名管道连接支持Windows服务器启用不创建一个线程来处理它们。
连接管理器关联的线程与线程专门给它来处理身份验证和请求处理该连接的每个客户端连接。管理线程创建一个新的线程在必要时,但尽量避免先咨询线程缓存,看它是否包含可用于连接一个线程这样做。当一个连接结束,它的线程被返回到线程缓存,如果缓存中没有满。
在这方面的线程模型,还有因为目前有连接的客户端,它具有在服务器工作负载必须扩展以处理大量连接的一些缺点尽可能多的线程。例如,线程的创建和处理变得昂贵。另外,每个线程都需要服务器和内核资源,如堆栈空间。以容纳大量的并发连接,每个线程的堆栈大小必须保持较小,从而导致一种情况,它是太小或服务器消耗大量的内存。其他资源耗尽可能会出现为好,调度开销可以成为显著。
在MySQL5.6.10中,MySQL的5.6的商业发行版包括了一个线程池的插件,提供设计,以减少开销,提高性能的其他线程的处理模式。它实现了通过有效地管理语句的执行线程为大量的客户端连接,从而提高服务器性能的一个线程池。
控制和监视服务器如何管理用于处理客户端连接,多个系统和状态变量相关的线程。
线程缓存由thread_cache_size的[585]系统变量确定的尺寸所述。缺省值是0(没有缓存),这将导致一个线程被设置为每一个新的连接和设置在连接终止时的。设置thread_cache_size的[585]为N,使?活动连接线程被缓存。thread_cache_size[585]可设置在服务器启动时或在服务器运行时改变。一个连接线程变为无效时,与它相关联的客户端连接终止。
要监控,因为一个线程不能取自缓存在缓存线程和多少个线程被创建的数量,监控Threads_cached[637]和Threads_Created的[637]的状态变量。
可以在服务器启动时设置的max_connections[532]或在运行时控制的客户端,可以同时连接的最大数目。
当线程堆栈太小,这限制了对SQL语句的服务器能够处理的复杂性,存储过程的递归深度,以及其它内存耗时的操作。要设置N个字节的堆栈大小为每个线程,启动服务器--thread_stack= N。
5.2 DNS查询优化与缓存主机(DNS Lookup Optimization and the Host Cache)
MySQL服务器维护,其中包含有关客户端的信息在内存中缓存主机:IP地址,主机名和错误信息。服务器使用该缓存的非本地TCP连接。它不使用高速缓存为使用loopback接口的地址(127.0.0.1or::1)建立的TCP连接,或者使用Unix套接字文件,命名管道或共享内存建立的连接。
对于每一个新的客户端连接,服务器使用客户端的IP地址,以检查是否在客户端的主机名是在主机缓存。如果没有,则服务器尝试解析主机名。首先,它解析IP地址的主机名和解析主机名返回一个IP地址。然后将结果与原来的IP地址,以确保它们是相同的。服务器存储有关该操作在主机高速缓存的结果信息。如果高速缓存已满,最近最少使用的条目将被丢弃。
该host_cache性能架构表暴露了主机缓存中的内容,以便它可以使用SELECT语句来检查。这可能会帮助您诊断连接问题的原因。详见 20.9.9.1, “The host_cacheTable”.
该服务器在句柄这样的主机缓存条目:
-
当第一个TCP客户端连接到达一个给定IP地址的服务器,创建新条目来记录客户端IP,主机名和客户端查询验证标志。最初,主机名设置为NULL,该标志是假的。本条目也可用于从相同的原始IP随后的客户端的连接。
-
如果验证标志为客户端IP条目是假的,服务器将尝试一个IP地址和主机名的DNS解析。如果成功,该主机名与所解析的主机名和更新 验证标志被设置为真。如果分辨是不成功的,所采取的行动取决于错误是永久的还是暂时的。对于永久性故障,主机名称保持空和验证标志设置为true。对于暂时故障,主机名和验证标志保持不变。(另一个DNS解析的尝试发生在下次客户端从该IP连接。)
-
如果在处理来自指定IP地址的传入客户端连接时发生错误,则服务器更新相应的错误计数器在该IP的条目。对于记录错误的描述,祥看20.9.9.1, “The host_cacheTable”.
服务器执行使用线程安全gethostbyaddr_r()的主机名称解析和如果操作系统支持他们gethostbyname_r()调用。否则,在执行查询的线程锁定一个互斥体,并调用gethostbyaddr()和的gethostbyname()来代替。在这种情况下,没有其他线程可以解析主机名不是在主机缓存中,直到该线程持有的互斥锁释放它。
服务器用于多个目的主机的缓存:
-
通过缓存的IP到Host查找的结果,服务器避免做每个客户端连接的DNS查找。相反,对于给定的主机,它需要仅用于从该主机的第一连接执行查找。
-
缓存包含有关在连接过程中发生的错误的信息。有些错误被认为是“blocking”。如果从给定主机太多这类相继发生没有成功 连接时,服务器会阻止主机进一步的连接。max_connect_errors[531]的系统变量决定阻塞发生之前允许的错误的数目。
要解除封锁的主机,通过发出一个FLUSH HOSTS语句或执行mysqladmin flush-hosts命令清空主机缓存。
这是可能的阻塞主机甚至成为畅通无需FLUSH HOSTS如果从其他主机的活动,因为从封锁主机的最后一个连接尝试发生。这可能是因为服务器丢弃最近最少使用的缓存条目,以腾出空间给新的项目,如果缓存满的时候从客户端的IP不在缓存中的连接到达。如果丢弃项是阻塞主机,该主机变得畅通。
主机缓存是默认启用的。要禁用它,设置host_cache_size[515]系统变量为0时,无论是在服务器启动时或运行时。
要禁用DNS主机名查找,用--skip-name-resolve[464]选项启动服务器。在这种情况下,服务器只使用IP地址而不是主机名匹配的主机连接到MySQL授权表中的行。仅帐户使用的IP地址的那些表中指定的都可以使用。
如果你有一个非常缓慢的DNS和多台主机,你也许可以或者通过禁用DNS查找与--skip-name-resolve[464]或通过增加host_cache_size的值来提高性能[515],使主机缓存更大。
要完全禁止TCP / IP连接,启动服务器的--skip-networking[464]选项。
一些错误连接不与TCP连接相关联的,发生在连接过程(一个IP地址是已知的,甚至之前)很早,或者不针对任何特定的IP地址(如里面出来内存不足的情况)。有关这些错误的信息,请查看Connection_errors_xxx[622] 状态变量
6.线程池插件(The Thread Pool Plugin)
**********************************************************************************************************************************
注意:MySQL的线程池是一个商业推广。要了解更多关于商业产品(MySQL企业版)查看
**********************************************************************************************************************************