ITPub博客

首页 > 数据库 > > 8.12 优化MYSQL 服务器

8.12 优化MYSQL 服务器

作者:飘絮絮絮丶 时间:2020-05-12 11:31:20 0 删除 编辑

参考官方文档:

dev.mysql.com/doc/refma


本节讨论数据库服务器的优化技术,主要处理系统配置而不是调整SQL语句。 本节中的信息适用于想要确保他们管理的服务器的性能和可扩展性的DBA; 对于构建包括设置数据库的安装脚本的开发人员; 以及那些希望最大限度提高自身生产力的开发,测试等人员自己运行MySQL。



8.12.1 系统因素


一些系统级因素可能会以主要方式影响性能:


  • 如果有足够的RAM,则可以删除所有交换设备。 某些操作系统在某些情况下使用交换设备,即使您拥有可用内存。
  • 避免MyISAM表的外部锁定。 默认值是禁用外部锁定。 - external-locking和--skip-external-locking选项显式启用和禁用外部锁定。



只要您只运行一台服务器,禁用外部锁定不会影响MySQL的功能。 请记住在运行myisamchk之前关闭服务器(或者锁定并冲洗相关表格)。 在某些系统中,强制禁用外部锁定是因为它无法工作。


唯一不能禁用外部锁定的情况是在同一数据上运行多个MySQL服务器(而不是客户端),或者如果您运行myisamchk检查(而不是修复)表而不告知服务器先刷新和锁定表。 请注意,除了使用NDB群集时,通常不建议使用多个MySQL服务器同时访问相同的数据。



LOCK TABLES和UNLOCK TABLES语句使用内部锁定,所以即使外部锁定被禁用,也可以使用它们。



注意:

MySQL Cluster目前在MySQL 5.7中不受支持。 希望从MySQL 5.0或5.1升级MySQL簇的用户应迁移到MySQL Cluster NDB 7.0或7.1; 这些都基于MySQL 5.1,但包含NDB的最新改进和修复。




8.12.2 优化mysql服务器参数



MySQL使用非常具有伸缩性的算法,因此通常可以使用很少的内存运行。 但是,通常情况下,您通过为MySQL提供更多内存来获得更好的性能



MySQL使用非常具有伸缩性的算法,因此通常可以使用很少的内存运行。 但是,通常情况下,您通过为MySQL提供更多内存来获得更好的性能


调整MySQL服务器时,要配置的两个最重要的变量是key_buffer_size和table_open_cache。 在尝试更改任何其他变量之前,您应该先确信自己已经设置了这些设置。


以下示例显示了不同运行时配置的一些典型变量值。


  • 如果你有至少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的值以加快排序操作后行的读取速度。



如果您在命令行上为mysqld或mysqld_safe指定了一个选项,则它仅在调用服务器时才有效。 要在每次运行服务器时使用该选项,请将其放入选项文件中。



要查看参数更改的效果,请执行以下操作:



shell> mysqld --key_buffer_size=32M --verbose --help



变量值列在输出结尾附近。 确保--verbose和--help选项是最后一个。 否则,在命令行上列出的任何选项的效果都不会反映在输出中。




8.12.3 优化磁盘I/O



本节介绍如何在您将更多更快的存储硬件投入数据库服务器时配置存储设备。



  • 磁盘寻道是一个巨大的性能瓶颈。 当数据量开始变得如此之大以至于不能有效缓存时,这个问题就会变得更加明显。 对于您可以随意访问数据的大型数据库,您可以确保至少需要一次磁盘查找以及一些磁盘写入操作。 为了尽量减少这个问题,请使用低寻道时间的磁盘。


  • 通过将文件符号链接到不同的磁盘或剥离磁盘来增加可用磁盘主轴的数量(从而减少查找开销):
    • 使用symbolic 链接


这意味着,对于MyISAM表,您可以将索引文件和数据文件从其在数据目录中的常用位置符号链接到另一个磁盘(也可以是条带化的)。 这使得查找和读取时间更好,假设磁盘也不用于其他目的 (现在条带化已经交给高速存储做了)

InnoDB表不支持符号链接。 但是,可以将InnoDB数据和日志文件放置在不同的物理磁盘上。

  • 条带化


条带化意味着您有许多磁盘,并将第一个磁盘块,第二个磁盘上的第二个块和(N MOD number_of_disks)磁盘上的第N个块,依此类推。 这意味着如果您的正常数据大小小于条带大小(或完全对齐),则可以获得更好的性能。 分条非常依赖操作系统和条带大小,因此可以使用不同的条带大小对应用程序进行基准测试。



条纹的速度差异很大程度上取决于参数。 根据您设置条带参数和磁盘数量的方式,您可能会得到数量级差异。 您必须选择针对随机或顺序访问进行优化。



  • 为了保证可靠性,您可能希望使用RAID 0 + 1(分条加镜像),但在这种情况下,需要2×N个驱动器来容纳N个数据驱动器。 如果你有钱,这可能是最好的选择。 但是,您可能还必须投资一些卷管理软件来有效处理它。


  • 一个好的选择是根据数据类型的重要性来改变RAID级别。 例如,存储可在RAID 0磁盘上重新生成的半重要数据,但存储真正重要的数据,例如主机信息和日志记录在RAID 0 + 1或RAID N磁盘上。 由于更新奇偶校验位所需的时间,如果您有很多写操作,则RAID N可能会成为问题。
  • 您还可以设置数据库使用的文件系统的

如果您不需要知道上次访问文件的时间(这在数据库服务器上并不真正有用),则可以使用-o noatime选项装入文件系统。 这会跳过对文件系统inode中最后一次访问时间的更新,从而避免一些磁盘搜索。


在许多操作系统上,可以通过将文件系统与-o async选项挂载来设置文件系统以异步更新。 如果您的计算机相当稳定,这应该可以提供更好的性能而不会牺牲太多的可靠性。 (这个标志在Linux上默认打开。)




在MYSQL 上使用NFS



建议在考虑使用NFS与MySQL时谨慎。 潜在问题因操作系统和NFS版本而异,其中包括:



  • 放置在NFS卷上的MySQL数据和日志文件被锁定并无法使用。 例如,如果多个MySQL实例访问相同的数据目录,或者由于停电导致MySQL不正确关闭,则可能会发生锁定问题。 NFS版本4通过引入基于咨询和基于租约的锁定来解决潜在的锁定问题。 但是,不建议在MySQL实例中共享数据目录。
  • 由于收到的消息乱序或网络流量丢失而导致数据不一致。 为避免此问题,请将TCP与硬核和内核装入选项一起使用。
  • 最大文件大小限制。 NFS版本2客户端只能访问文件的最低2GB(带符号32位偏移量)。 NFS版本3客户端支持较大的文件(最多64位偏移量)。 支持的最大文件大小还取决于NFS服务器的本地文件系统。


在专业SAN环境或其他存储系统中使用NFS往往比在这种环境之外使用NFS提供更高的可靠性。 但是,SAN环境中的NFS可能比直接连接或总线连接的非循环存储要慢。


如果您选择使用NFS,建议使用NFS版本4或更高版本,与在部署到生产环境之前彻底测试NFS设置一样。




8.12.4 使用符号链接


您可以将数据库或表从数据库目录移动到其他位置,并用符号链接替换它们到新的位置。 例如,您可能希望这样做,即将数据库移动到具有更多可用空间的文件系统,或者通过将表分布到不同的磁盘来提高系统的速度。



对于InnoDB表,使用CREATE TABLE语句中的DATA DIRECTORY子句而不是符号链接,如第14.7.5节“在数据目录之外创建文件 - 每个表空间表空间”中所述。 这项新功能是支持的跨平台技术。



推荐的方法是将整个数据库目录符号链接到不同的磁盘。 Symlink MyISAM表仅作为最后的手段。



要确定数据目录的位置,请使用以下语句:


SHOW VARIABLES LIKE 'datadir';



---具体操作省略。。。



8.12.5 优化内存使用



8.12.4.1 Mysql 如何使用内存

MySQL分配缓冲区和缓存以提高数据库操作的性能。 默认配置旨在允许MySQL服务器在具有大约512MB内存的虚拟机上启动。 您可以通过增加某些缓存和缓冲区相关系统变量的值来提高MySQL的性能。 您还可以修改默认配置以在内存有限的系统上运行MySQL。


以下列表描述了MySQL使用内存的一些方式。 在适用的情况下,引用相关的系统变量。 有些项目是存储引擎或功能特定的。



  • InnoDB缓冲池是一个内存区域,用于保存表,索引和其他辅助缓冲区的缓存InnoDB数据。 为了提高高容量读取操作的效率,缓冲池分为可能包含多行的页面。 为了高速缓存管理的效率,缓冲池被实现为页面的链接列表; 很少使用的数据使用LRU算法的变体超时缓存。



缓冲池的大小对系统性能很重要:

  • InnoDB使用malloc()操作在服务器启动时为整个缓冲池分配内存。 innodb_buffer_pool_size系统变量定义了缓冲池的大小。 通常,推荐的innodb_buffer_pool_size值是系统内存的50%到75%。 innodb_buffer_pool_size可以在服务器运行时动态配置。


    • 在具有大量内存的系统上,可以通过将缓冲池分为多个缓冲池实例来提高并发性。 innodb_buffer_pool_instances系统变量定义了缓冲池实例的数量。
    • 缓冲池太小可能会导致过度搅动,因为页面仅从缓冲池刷新到短时间内再次需要。
    • 由于竞争内存,缓冲池太大可能会导致交换。
  • 所有线程共享MyISAM密钥缓冲区。 key_buffer_size系统变量决定了它的大小。



对于服务器打开的每个MyISAM表,索引文件将打开一次; 对于每个访问表的并发运行线程,数据文件都会打开一次。 对于每个并发线程,分配表结构,每列的列结构和大小为3 * N的缓冲区(其中N是最大行长度,不计算BLOB列)。 BLOB列需要5到8个字节加上BLOB数据的长度。 MyISAM存储引擎维护一个额外的行缓冲区供内部使用。



  • 可以将myisam_use_mmap系统变量设置为1,以便为所有MyISAM表启用内存映射。
  • 如果内部内存临时表变得太大(使用tmp_table_size和max_heap_table_size系统变量确定),MySQL会自动将表从内存转换为磁盘格式。 磁盘上的临时表使用由internal_tmp_disk_storage_engine系统变量定义的存储引擎。


对于使用CREATE TABLE显式创建的MEMORY表,只有max_heap_table_size系统变量决定了表允许增长的大小,并且没有转换为磁盘格式。



  • MySQL性能方案是一个用于在低级别监视MySQL服务器执行情况的功能。 性能方案以增量方式动态分配内存,将其内存使用扩展到实际的服务器负载,而不是在服务器启动期间分配所需的内存。 一旦分配了内存,在服务器重新启动之前它不会被释放。
  • 服务器用于管理客户端连接的每个线程都需要一些线程特定的空间。 以下列表指示这些以及哪些系统变量控制其大小:


连接缓冲区和结果缓冲区中的每一个都以等于net_buffer_length个字节的大小开始,但根据需要动态扩展到max_allowed_packet个字节。 在每个SQL语句之后,结果缓冲区缩小为net_buffer_length个字节。 当语句正在运行时,还会分配当前语句字符串的副本。

每个连接线程都使用内存来计算语句摘要。 服务器为每个会话分配max_digest_length字节。


  • 所有线程共享相同的基本内存。
  • 当不再需要线程时,除非线程回到线程缓存中,分配给它的内存被释放并返回到系统 。 在这种情况下,内存仍然分配。
  • 每个执行表的顺序扫描的请求都会分配一个读取缓冲区。 read_buffer_size系统变量确定缓冲区大小。
  • 在以任意顺序读取行时(例如,在排序后),可能会分配一个随机读取缓冲区以避免磁盘搜索。 read_rnd_buffer_size系统变量确定缓冲区大小。
  • 所有连接都在一次执行中执行,大多数连接都可以在不使用临时表的情况下完成。 大多数临时表是基于内存的哈希表。 具有较大行长度(以所有列长度的总和计算)的临时表或包含BLOB列的临时表存储在磁盘上。
  • 大多数执行排序的请求会根据结果集大小分配排序缓冲区和零到两个临时文件。
  • 几乎所有的解析和计算都是在线程本地和可重用的内存池中完成的。 小项目不需要内存开销,从而避免了正常的慢速内存分配和释放。 内存仅分配给意外大的字符串。
  • 对于每个具有BLOB列的表,都会动态放大一个缓冲区以读取较大的BLOB值。 如果您扫描一个表,缓冲区会增长到最大的BLOB值。
  • MySQL需要表缓存的内存和描述符。 所有使用中表格的处理程序结构都保存在表格缓存中,并作为“先进先出”(FIFO)进行管理。 table_open_cache系统变量定义了初始表缓存大小;




MySQL还需要用于表定义缓存的内存。 table_definition_cache系统变量定义了可以存储在表定义缓存中的表定义数(来自.frm文件)。 如果您使用大量表,则可以创建大型表格定义缓存以加快表格的打开速度。 与表缓存不同,表定义缓存占用更少的空间,并且不使用文件描述符。



  • 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使用大量内存。 这可能是由不同内存地址上的线程堆栈引起的。 例如,Solaris的ps版本将堆栈之间未使用的内存计为已用内存。 要验证这一点,请检查swap -s的可用交换。 我们用几个内存泄漏检测器(商业和开源)测试mysqld,所以应该没有内存泄漏。



监控mysql 内存使用



以下示例演示如何使用Performance Schema和sys方案来监视MySQL内存使用情况。



大多数性能架构内存工具默认情况下处于禁用状态。 可以通过更新性能方案setup_instruments表的ENABLED列来启用仪器。 内存仪器具有 memory/code_area/instrument_name形式的名称,其中code_area是诸如sql或innodb之类的值,instrument_name是仪器详细信息。


1.要查看可用的MySQL内存工具,请查询Performance Schema setup_instruments表。 以下查询返回所有代码区域的数百个内存工具。


mysql> SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%memory%';



您可以通过指定代码区域来缩小结果。 例如,通过将innodb指定为代码区域,可以将结果限制为InnoDB内存仪器。

SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%memory/innodb%';


取决于您的MySQL安装,代码区可能包括performance_schema,sql, client, innodb, myisam, csv, memory, blackhole, archive, partition等。


2.要启用内存工具,请将性能架构工具规则添加到您的MySQL配置文件中。 例如,要启用所有内存工具,请将此规则添加到您的配置文件并重新启动服务器:



performance-schema-instrument='memory/%=COUNTED'


注意:

在启动时启用内存工具可确保启动时发生的内存分配计数。



重新启动服务器后,Performance Schema setup_instruments表的ENABLED列应为您启用的内存仪器报告YES。 对于内存工具,setup_instruments表中的TIMED列会被忽略,因为内存操作没有timed。

SELECT * FROM performance_schema.setup_instruments WHERENAME LIKE '%memory/innodb%';


3.查询内存仪器数据。 在此示例中,内存仪器数据在Performance Schema memory_summary_global_by_event_name表中查询,该表总结EVENT_NAME的数据。 EVENT_NAME是乐器的名称。

SELECT * FROMperformance_schema.memory_summary_global_by_event_nameWHERE EVENT_NAME LIKE 'memory/innodb/buf_buf_pool'\G


可以使用sys schema memory_global_by_current_bytes表查询相同的底层数据,该表显示全局服务器当前的内存使用情况,按分配类型细分。


SELECT * FROM sys.memory_global_by_current_bytes WHEREevent_name LIKE 'memory/innodb/buf_buf_pool'\G


此sys方案查询通过代码区域聚合当前分配的内存(current_alloc):


SELECT SUBSTRING_INDEX(event_name,'/',2) AS code_area,sys.format_bytes(SUM(current_alloc)) AS current_alloc FROMsys.x$memory_global_by_current_bytes GROUP BYSUBSTRING_INDEX(event_name,'/',2) ORDER BYSUM(current_alloc) DESC;






8.15.4.2 启用大页面支持



某些硬件/操作系统体系结构支持的内存页面大于默认值(通常为4KB)。 这种支持的实际实施取决于底层硬件和操作系统。 执行大量内存访问的应用程序可能通过使用大页面来获得性能改进,原因是减少了 Translation Lookaside Buffer(TLB)未命中。


在MySQL中,InnoDB可以使用大页面为其缓冲池和额外的内存池分配内存。


标准使用MySQL中的大页面将尝试使用支持的最大大小,最大为4MB。 在Solaris下,“超大页面”功能可以使用最多256MB的页面。 此功能适用于最新的SPARC平台。 可以使用--super-large-pages或--skip-super-large-pages选项启用或禁用它。


MySQL还支持大型页面支持的Linux实现(在Linux中称为HugeTLB)。



在Linux上可以使用大页面之前,必须启用内核来支持它们,并且需要配置HugeTLB内存池。 作为参考,HugeTBL API记录在Linux源代码的Documentation / 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使用。 通常情况下,您将这些文件放入系统启动序列期间执行的rc文件或等效启动文件中,以便每次系统启动时执行这些命令。 在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。 现在你应该看到一些非零值:


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用户提供一个“无限制”的memlock限制值。 这可以通过编辑/etc/security/limits.conf或将以下命令添加到mysqld_safe脚本来完成:


ulimit -l unlimited


将ulimit命令添加到mysqld_safe会导致root用户在切换到mysql用户之前将memlock限制设置为unlimited。 (这假定mysqld_safe是由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



8.12.6 优化 网络使用



8.12.6.1 mysql 使用线程的客户端连接



连接管理器线程处理服务器侦听的网络接口上的客户端连接请求。 在所有平台上,一个管理器线程处理TCP / IP连接请求。 在Unix上,这个管理器线程还处理Unix套接字文件连接请求。 在Windows上,管理器线程处理共享内存连接请求,另一个处理命名管道连接请求。 服务器不会创建线程来处理它不会听的接口。 例如,不支持命名管道连接的Windows服务器不会创建线程来处理它们。


连接管理器线程将每个客户端连接与专用于它的线程关联,以处理该连接的身份验证和请求处理。 管理器线程在必要时创建一个新线程,但尝试通过首先查询线程缓存来查看它是否包含可用于连接的线程来避免这样做。 当连接结束时,如果缓存未满,则其线程返回到线程缓存。



在这种连接线程模型中,线程数量与当前连接的客户端数量一样多,当服务器工作负载必须按比例扩展以处理大量连接时,会存在一些缺点。 例如,线程创建和处理变得昂贵。 另外,每个线程都需要服务器和内核资源,例如堆栈空间。 为了容纳大量的同时连接,每个线程的堆栈大小必须保持很小,导致它或者太小或者服务器消耗大量内存。 其他资源也可能耗尽,调度开销可能会变得很大。


要控制和监视服务器如何管理处理客户端连接的线程,几个系统和状态变量是相关的。


线程缓存的大小由thread_cache_size系统变量确定。 默认值为0(不缓存),这会导致为每个新连接设置线程,并在连接终止时处理线程。 将thread_cache_size设置为N以启用缓存N个不活动的连接线程。 thread_cache_size可以在服务器启动时设置,也可以在服务器运行时更改。 连接线程在与其关联的客户端连接终止时变为非活动状态。



要监视高速缓存中的线程数以及创建了多少线程,因为无法从高速缓存中获取线程,请监视Threads_cached和Threads_created状态变量。


您可以在服务器启动时或运行时设置max_connections,以控制可同时连接的最大客户端数量。



当线程堆栈太小时,这会限制服务器可以处理的SQL语句的复杂性,存储过程的递归深度以及其他耗费内存的操作。 要为每个线程设置N字节的堆栈大小,请使用--thread_stack = N启动服务器。




8.12.6.2 DNS lookup 优化器和 主机缓存



MySQL服务器在内存中维护一个包含客户端信息的主机缓存:IP地址,主机名和错误信息。 服务器为非本地TCP连接使用此缓存。 它不使用用于使用回环接口地址(127.0.0.1或 ::1)建立的TCP连接的缓存,也不使用使用Unix套接字文件,命名管道或共享内存建立的连接。



对于每个新的客户端连接,服务器都使用客户端IP地址来检查客户端主机名是否在主机缓存中。 如果没有,则服务器尝试解析主机名。 首先,它将IP地址解析为主机名,并将该主机名解析为IP地址。 然后将结果与原始IP地址进行比较,以确保它们相同。 服务器将有关此操作结果的信息存储在主机缓存中。 如果缓存已满,则丢弃最近最少使用的条目。



host_cache性能架构表公开了主机高速缓存的内容,以便可以使用SELECT语句进行检查。 这可以帮助您诊断连接问题的原因。




服务器像这样处理主机高速缓存中的条目:

  1. 当第一个TCP客户端连接从给定IP地址到达服务器时,会创建一个新条目来记录客户端IP,主机名和客户端查找验证标志。最初,主机名被设置为NULL,并且该标志为false。此条目也用于来自同一始发IP的后续客户端连接。
  2. 如果客户端IP条目的验证标志为false,则服务器将尝试IP到主机名称的DNS解析。如果成功,则使用解析的主机名更新主机名,并将验证标志设置为true。如果解决不成功,则采取的行动取决于错误是永久性的还是暂时性的。对于永久性故障,主机名保持为NULL并且验证标志设置为true。对于瞬态故障,主机名和验证标志保持不变。 (下一次客户端从此IP连接时,将发生另一个DNS解析尝试。)
  3. 如果在处理来自给定IP地址的传入客户端连接时发生错误,则服务器将更新该IP项的相应错误计数器。



如果操作系统支持,则服务器使用线程安全gethostbyaddr_r()和gethostbyname_r()调用执行主机名解析。 否则,执行查找的线程将锁定一个互斥锁,并调用gethostbyaddr()和gethostbyname()。 在这种情况下,除非拥有互斥锁的线程释放它,否则其他线程无法解析主机缓存中未包含的主机名。


服务器使用主机缓存有以下几个目的:


  • 通过缓存IP到主机名称查找的结果,服务器可避免为每个客户端连接执行DNS查找。 相反,对于给定的主机,它只需要对来自该主机的第一个连接执行查找。
  • 缓存包含有关在连接过程中发生的错误的信息。 有些错误被认为是“阻塞”。如果连续发生的这些错误中没有成功连接,则服务器将阻止来自该主机的进一步连接。 max_connect_errors系统变量决定发生阻塞之前允许的错误数量。


要取消阻塞阻止的主机,请发出FLUSH HOSTS语句或执行mysqladmin flush-hosts命令来刷新主机缓存。



如果阻止的主机在最后一次连接尝试之后发生其他主机的活动,即使没有FLUSH HOSTS,阻止的主机也可能被解除阻塞。 发生这种情况的原因可能是服务器放弃了最近最少使用的高速缓存条目,以便在连接从不在高速缓存中的客户端IP到达,高速缓存已满的时候,为新条目腾出空间。 如果放弃的条目用于阻止的主机,则该主机将变为未阻止状态。


主机缓存默认启用。 要禁用它,请在服务器启动时或运行时将host_cache_size系统变量设置为0。


要禁用DNS主机名查找,请使用--skip-name-resolve选项启动服务器。 在这种情况下,服务器仅使用IP地址,而不使用主机名将连接主机与MySQL授权表中的行匹配。 只能使用那些使用IP地址的表中指定的帐户。 (请确保存在指定IP地址的帐户,否则您可能无法连接。)


如果您的DNS和主机速度非常慢,则可以通过使用--skip-name-resolve禁用DNS查找或通过增大host_cache_size的值以使主机缓存更大来提高性能。


要完全禁止TCP / IP连接,请使用--skip-networking选项启动服务器。


某些连接错误与TCP连接无关,在连接过程中很早(即使在知道IP地址之前),或者并非特定于任何特定IP地址(例如内存不足条件)。 有关这些错误的信息,请检查Connection_errors_xxx状态变量


8.12.7 线程池插件



注意:

MySQL线程池是包含在MySQL企业版中的一个扩展,这是一个商业产品。 要了解有关商业产品的更多信息,请访问mysql.com/products/。



从MySQL 5.7.9开始,MySQL企业版包含MySQL线程池,使用服务器插件实现。 MySQL服务器中的默认线程处理模型执行每个客户机连接使用一个线程的语句。 随着更多客户端连接到服务器并执行语句,整体性能下降。 线程池插件提供了另一种线程处理模型,旨在减少开销并提高性能。 该插件实现了一个线程池,该线程池通过高效地管理大量客户端连接的语句执行线程来提高服务器性能



线程池解决了每个连接模型的一个线程的一些问题:

  • 线程堆栈过多使得CPU高速缓存在高度并行执行工作负载中几乎无用。 线程池促进线程堆栈重用以最小化CPU高速缓存占用空间。
  • 由于太多的线程并行执行,上下文切换开销很高。 这也给操作系统调度程序带来了具有挑战性的任务。 线程池控制活动线程的数量,以将MySQL服务器内的并行性保持在可以处理的级别,并且适用于执行MySQL的服务器主机。
  • 并行执行的事务太多会增加资源争用。 在InnoDB中,这增加了中央互斥锁的时间。 线程池控制事务何时开始,以确保并行执行不太多。


线程池插件仅包含在MySQL企业版中。它不包含在MySQL社区分发版中。


在Windows上,线程池插件需要Windows Vista或更高版本。在Linux中,该插件需要内核2.6.9或更高版本。


8.12.7.1 线程池组件和安装


线程池功能包含以下组件:

  • 插件库目标文件包含用于多个INFORMATION_SCHEMA表的线程池代码和插件的插件。

INFORMATION_SCHEMA表被命名为TP_THREAD_STATE,TP_THREAD_GROUP_STATE和TP_THREAD_GROUP_STATS。


  • 几个系统变量与线程池相关。 当服务器成功加载线程池插件时,thread_handling系统变量具有一个动态加载的值。

其他相关变量由线程池插件实现; 除非启用,否则它们不可用:


---这部分暂时不介绍了,因为本来使用mysql 就是看中的开源,免费。如果还需要商业组件,那就违背了选着mysql的初衷了。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3165701/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-09

  • 博文量
    2646
  • 访问量
    42295