17.高性能MySQL --- MySQL 分支与变种

原文链接:https://book.douban.com/subject/3766465/

 

1.系统参数
	mysql 通过 show variables sql 命令暴露了许多系统变量。或者通过命令行 mysqladmin variables。
  这些变量反映了一系列配置信息,如服务器的默认存储引擎,可用时区等。

2.show status
	show status 命令会显示每个服务器变量的名字和值。和上面讲的服务器参数不一样,状态变量是只读的。可以在mysql
  客户端里运行show status 或者在命令行里运行mysqladmin extended-status 来查看这些变量。如果用sql命令,可以
  使用 like 或者 where 来限制。可以用 like 对变量名做标准模式匹配。命令将返回一个表,但不能对它进行排序,与另外
  一个表进行联合操作。在mysql 5.1 中,可以直接从 information_schema.global_status 和 information_schema.session_status 
  表中查询值。
  	show global status; //全局变量
  	show status; //会话变量

  	有上百个变量。大部分要么是计数器,要么是包含某些状态指标的当前值。每次mysql做一些事情都会导致计数器的增长,比如开始初始化一个全表
  扫描(Select_scan)。度量值,例如打开的到服务器的连接数(Threads_connected),可能增长或者减少。有时候几个变量貌似指向相同的事情,如
  Connections(尝试连接到服务器的连接数量)和Threads_connected。变量是关联的,但类似的名字并不总是隐含某种关系。
    变量采用无符号整形存储。它们在32位编译系统上是4个字节,而在64位环境上用8个字节,并且当达到最大后重新从0开始。如果你增量的监测这些
  变量,可能需要观察并修正这个绕回处理。你也需要意识到如果服务器已经运行了很长一段时间,可能会有比预期更小的值,这是因为这些变量值已经被
  重置为0.
    如果想对服务器的工作负载有一个大体的了解,可以将相关的一组变量放在一起查看和对比---例如,一起查看所有的 Select_* 变量,或所有的
  Handler_* 变量。如果使用 innotop,在 Comand Summary 模式下查看更简单,也可以通过 mysqladmin extended -r -i60 | grep Handler_ 的
  命令完成。

3.线程和连接统计
	这些变量用来追踪 尝试的连接,退出的连接,网络流量和线程统计。
	Connections, Max_used_connections, THreads_connected
	Aborted_clients, Aborted_connects
	Bytes_received, Bytes_sent
	Slow_launch_threads, Threads_cached, Threads_created, Threads_running

	如果 Aborted_connects 不为0,可能意味着网络有问题或某人尝试连接但失败(可能用户制定了错误的密码,无效的数据库,或者某个监控系统正在打开tcp
  的3306端口来检测服务器是否存活)。如果这个值太高,可能有严重的副作用:导致mysql阻塞一个主机。

4.二进制日志状态
	Binlog_cache_use 和 Binlog_cache_disk_use 状态变量显示了在二进制日志缓存中有多少事务被存储过,以及多少事务因超过二进制日志缓存而必须存储
  到一个临时文件中。mysql5.5 中还包含了 Binlog_stmt_cache_use 和 Binlog_stmt_cache_disk_use ,显示了非事务语句相应的度量值。所谓的 '二进制
  日志缓存命中率' 往往对配置二进制日志缓存的大小没有多少参考意义。

5.命令计数器
	Com_* 变量统计了每种类型的sql或 C API 命令发起过的次数。例如,Com_select 统计了 select 语句的数量,Com_change_db 统计了一个连接的默认数据库
  被通过 use 语句或者 C API 调用的更改次数。Questions 变量统计总查询量和服务器收到的命令数。然后,它并不完全等于所有的 Com_* 变量的总和,这与查询
  缓存命中,关闭和退出的连接,以及其他因素可能有关。
    Com_admin_commands 状态变量可能非常大。它不仅技术管理命令,并且还包括对mysql实例的ping请求。这些请求通过 C API 发起,并且一般来自客户端代码。
  例如, $db->ping();
  	这些 Ping 是垃圾查询。它们往往不会对服务器产生许多负载,但仍然是个浪费,因为网络回路时间会增加应用的响应时间。我们曾看到ORM系统在每次查询之前 ping
  服务器,ping 服务器然后再查询是一个'跳跃之前看一下'设计模式的典型例子,它会产生竞争条件。也看到过每次查询之前更改默认的数据库抽象函数库,这也会产生大量
  的Com_change_db命令。最好消除这2个做法。

6.临时文件和表
	可以通过下面的命令查看mysql创建临时表和文件的计数:
	show global status like 'created_tmp%';
	这显示了关于隐式临时表和文件的统计---执行查询时内部创建的。

7.句柄操作
	句柄API是mysql和存储引擎之间的接口,Handler_* 变量用于统计句柄的操作,例如mysql请求一个存储引擎从索引中读取下一行的次数。可以通过下面的语句查看
  这些变量:show global status like 'Handler%';

8.MyISAM 键缓冲
	Key_* 变量包含度量值和关于MyISAM键缓冲的计数。可以通过下面命令:
	show global status like 'Key_%';
	
9.文件描述符
	如果你主要使用MyISAM存储引擎,那么 Open_* 变量揭示了 mysql 每隔多久会打开每个表的 .frm, .MYI, .MYD 文件。InnoDB 保持所有的数据在表空间文件中,
  因此如果你主要使用 InnoDB,那么这些变量并不精确。
    show global status like 'Open_%';

10.查询缓存
	通过查询 Qcache_* 状态变量可以检查查询缓存:
	show global status like 'Qcache_%';

11.SELECT 类型	
	Select_* 变量是特定类型的 select 查询的计数器。它们能帮助你了解使用各种查询计划的 select 查询比率。不幸的是,并没有关于其他查询类型的状态变量,
  例如 update 和 replace;然而,可以看一下 Handler_* 状态变量大致了解非 select 查询的相对数量。
  show global status like 'Select_%';
  	以我们的判断,Select_* 状态变量可以按花费递增的顺序如下排序:
  	1.Select_range
  		在第一个表上扫描一个索引区间的联接数目。
  	2.Select_scan
  		扫描整个第一张表的联接数目。如果第一个表中的每行都参与联接,这样计数并没有问题;如果你并不想要所有的行但又没有索引以查找到所需要的行,就比较糟糕了。
  	3.Select_full_range_join
  		使用在表n中的一个值来从表n+1 中通过参考索引的区间内获取行所做的联接数。这个值或多或少比 Select_scan 开销多些,具体取决于查询。
  	4.Select_range_check
  		在表n+1 中重新评估表n中的每一行的索引是否开销最小所做的联接数。这一般意味着在表n+1中对该联接而言并没有有用的索引。这个查询有非常高的额外开销。
  	5.Select_full_join
  		交叉联接或并没有条件匹配表中行的联接的数目。检测的行数是每个表中行数的乘积。这通常是个坏事。
  	最后2个变量一般并不会快速的增长,如果快速增长,则可能表明一个'糟糕'的查询引入了系统中。

12.排序
	当mysql不能使用一个索引来获取预先排序的行时,必须使用文件排序,这会增加 Sort_* 状态变量。除 Sort_merge_passes外,你可以只是增加mysql 会用来排序的
  索引以改变这些值。Sort_merge_passed 依赖 sort_buffer_size 服务器变量(不要与myisam_sort_buffer_size服务器变量混淆)。mysql使用排序缓存来容纳排序的
  行块。当完成排序后,它将这些排序后的行合并到结果集中,增加 Sort_merge_passes,并且用下一个待排序的行块填充缓存。然后,使用这个变量来指导排序缓存的大小并
  不是个好办法。
    show global status like 'Sort_%';
    当mysql从文件排序的结果中读取已经排好序的行并返回给客户端时,Sort_scan 和 Sort_range 变量会增长。不同点在于:前者是当查询计划导致 Select_scan 增加时
  增加,而后者是当 Select_range 增加时增加。二者的实现和开销完全一样;仅仅指示了导致排序的查询计划类型。

13.表锁
	Table_lock_immediate 和 Table_locks_waited 变量可以告诉你又多少锁被立即授权,有多少锁需要等待。但请注意,它们只是展示了服务器级别锁的统计,并不是存储引擎
  级别的锁统计。

14.InnoDB 相关
	Innodb_* 变量展示了 show engine innodb status 中包含的一些数据。这些变量按名字分组:Innodb_buffer_pool_*,Innodb_log_* 等等。
	这些变量存在于mysql5.5 或更新的版本中,它们有重要的副作用:它们会创建一个全局锁,然后在释放该锁之前遍历整个Innodb缓冲池。同时,另外一些线程也会遇到该锁而阻塞,
  直到它被释放。这歪曲了一些状态值,比如 Threads_running,因此,它们看起来比平时更高(可能高许多,取决于系统的负载有忙)。当运行 show engine innodb status 或通过
  information_schema 表访问这些统计时,有相同的副作用。
    因此,这些操作在这些版本的mysql中会更加昂贵---检查服务器状态太频繁可能会显著的增加负载。使用 show status like 也无济于事,因为它要获取所有的状态然后再进行过滤。

15.插件相关
	mysql5.1和更新的版本中支持可插拔的存储引擎,并在服务器内部对这些存储引擎提供了注册它们自己的状态和配置变量的机制。如果你在使用一个可插拔的存储引擎,也许会看到许多插件
  特有的变量。类似的变量总是以插件名开头。

16.show engine innodb status
	show engine innodb status
	show innodb status //老版本
	不像其他大部分show命令,它的输出就是单独的一个字符串,没有行和列。它会分为很多段,每一段对应了InnoDB存储引擎不同部分的信息。
	输出内容包含了一些平均值的统计信息,例如fsync()每秒调用次数。这些平均值是自上次输出结果生成以来的统计数。因此,如果你正在检查这些值,那么就要确保已经等待了30s左右的
  时间,使2次采样之间积累起足够长的统计时间并多次采样,检查计数器变化而弄清其行为。并不是所有的输出都会在一个时间点生成,因而不是所有显示出来的平均值会在同一时间间隔重新
  计算一遍。而且,innodb有一个内部复位间隔,而它是不可预知的,各个版本也不同。你应该检查一下输出,看看哪些平均值在这个时间段生成,因为每次采样的时间间隔不总是相同的。

    1.头部信息
=====================================
2019-09-01 16:07:29 7fda67186700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 3 seconds
	第一段是头部信息,它仅仅声明了输出的开始,其内容包括当前的日期和时间,以及自上次输出以来经过的时长。下来的第二行是当前日期和时间。第4行显示的是计算出这一平均值的
  时间间隔,即自上次输出以来的时间,或者是距离上次内部复位的时长。

	2.SEMAPHORES
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 17302
OS WAIT ARRAY INFO: signal count 30366
Mutex spin waits 1316797, rounds 1183725, OS waits 1645
RW-shared spins 26012, rounds 518136, OS waits 15432
RW-excl spins 297681, rounds 141195, OS waits 171
Spin rounds per wait: 0.90 mutex, 19.92 RW-shared, 0.47 RW-excl
	第4行给出了关于操作系统等待数组的信息,它是一个'插槽'数组.innodb在数组里为信号量保留了一些插槽,操作系统为这些信号量给线程发送信号,使线程可以继续运行,以完成
  它们等着做的事情。这一行还显示了innodb 使用了多少次操作系统的等待。保留技术(reservation count)显示了innodb分配插槽的频度,而信号技术(signal count)衡量的是线程
  通过数组得到信号的频度。操作系统的等待相对于空转等待(spin wait)要更昂贵一些。
    第5~12行显示的是当前正在等待互斥量的innodb线程。在这个例子中有2个线程正在等待,每一个都是以 '--Thread<数字> has waited...' 开始的。这一段应该是空的,除非服务器
  运行着高并发的工作负载,促使innodb采取让操作系统等待的措施。除非你对innodb源码很熟,否则这里看到的最有用的信息是发生线程等待的代码文件名。这就给了你一个提示:在innodb
  内部哪里才是热点。举例来说,如果看到许多线程都在一个名为 buf0buf.ic 的文件上等待着,那就意味着你的系统里存在缓冲池竞争。这个输出信息还显示了这些线程等待了多长时间,其中
  'waiters flags' 显示了有多少个等待者正在等待同一个互斥量。
    文本'wait is ending' 意味着这个互斥锁实际上已经被释放了,但操作系统还没把线程调度过来运行。
    你可能想知道innodb真正等待的是什么。innodb 使用了互斥量和信号量来保护代码的临界区,例如,限定每次只能有一个线程进入临界区,或者是当有活动的读时,就限制写入等。在innodb
  代码里有很多临界区,在合适的条件下,它们都可能出现在那里。常常能见到的一种情形就是获取缓冲池分页的访问权。
    在等待线程的列表之后,第13行和第14行显示了更多的事件计数器。在第13行显示的是跟互斥量相关的几个计数器,第14行用于显示读/写共享和排它锁的计数器。在每一种情形中,都能看到
  innodb 依靠操作系统等待的频度。
    innodb有着一个多阶等待策略。首先,它会尝试着对锁进行空等待。如果经过了一个预设的空转等待周期(设置 innodb_sync_spin_loops 配置变量指令)之后还没有成功,那就会退回到
  更昂贵更复杂的等待数组中。
    空转等待的成本相对比较低,但是它们要不停的检查一个资源是否被锁定,这种方式会消耗cpu周期。但是,这没那么糟糕,因为当处理器等待IO时,一般都会有一些空闲的cpu周期可用,
  即使没有空闲的cpu周期,空等也要比其他方式更加廉价一些。然后,当另外一条线程能做一些事情时,空转等待也还会独占处理器。
  	空转等待的替代方案就是让操作系统做上下文切换,这样,当这个线程在等待时,另外一个线程就可以运行了,然后,通过等待数组里的信号量发出信号,唤醒那个沉睡的线程。通过信号量
  来发送信号是比较有效率的,但是上下文切换就很昂贵,这很快就会积少成多:每秒钟几千次的切换会引发大量的系统开销。
    你可以通过改变系统变量 innodb_sync_spin_loops 的值,试着在空转等待与操作系统等待之间达成平衡。不要担心空转等待,除非你在每一秒里面会看到许多空转等待(大概是几十万
  这个水平)。这经常需要理解源代码或咨询专家才能解决。或者看一下,show engine innodb mutex。

    3.LATEST FOREIGN KEY ERROR
    	下一段即,latest foreign key error,一般不会出现,除非你的服务器上有外键错误。在源代码里面有许多地方会产生这样的输出,具体取决于错误的类型。有时问题在于
      事务在插入,更新或删除一条记录时要寻找到父行或子行。还有些时候是当innodb尝试增加或删除一个键,或修改一个已经存在的外键时,发现表之间类型不匹配。
        这部分输出对于调试与innodb往往不明确的外键错误相对应的准确原因非常有帮助。

    4.LATEST DETECTED DEADLOCK
    	跟上面一样,latest detected deadlock 部分也只有当服务器内部有死锁时才会出现。死锁信息同样在每次有新错误时都会重写。Percona Toolkit 中的 
      pt-deadlock-logger 工具可以保存这些信息供后续分析。
      	死锁在等待关系图里是一个循环,就是一个锁定了行的数据结构又在等待别的锁。这个循环可以任意的大。innodb 会立即检测到死锁,因为每当有事务等待行锁时,它都会去检测
      等待关系图里是否有循环。死锁的情况可能比较复杂,但是,这一部分只显示了最近2个死锁的情况,它们在各自的事务里执行的最后一条语句,以及它们在图里形成循环锁的信息。
      在这个循环里你看不到其他事务,也看不到在事务里早先可能真正获得了锁的语句。尽管如此,通常还是可以通过查看这些输出来确定到底是什么引起了死锁。
        在innodb里实际上有2种死锁。
        1.就是常见的一种,它在等待关系图里是一个真正的循环。
        2.另外一个就是在等待关系图里,因为代价昂贵而无法检查它是不是包含了循环。如果innodb要在关系图里检查超过100w个锁,或者在检查的过程中,innodb要重做200个以上的事务,
        它就会放弃,并宣布这是一个死锁。这些数值硬编码在innodb里面,无法配置(修改,重新编译)。当innodb的检查工作超过了这个极限后,它就会引发一个死锁,这时候你就会看到
        一条信息 'too deep or long search in the lock table waits-for graph'.

        innodb 不仅会打印出事务和事务持有及等待的锁,而且还有记录本身。
        当事务持有了其他事务需要的锁,同时又想获得其他事务持有的锁时,等待关系图上就会产生循环了。innodb不会显示所有持有和等待的锁。但是,它显示了足够的信息帮你确定:
      查询操作正在使用哪些索引。这对于你确定是否能避免死锁有着极大的价值。
        如果能使2个查询对同一个索引朝同一个方向进行扫描,就能降低死锁的数目。因为,查询在同一顺序上请求的锁的时候不会创建循环。

    5.TRANSACTIONS
------------
TRANSACTIONS
------------
Trx id counter 22043759
Purge done for trx's n:o < 21888087 undo n:o < 0 state: running but idle
History list length 2918
LIST OF TRANSACTIONS FOR EACH SESSION:

		第4行:当前事务id,这是一个事务变量,每创建一个新事务都会增加
		第5行:这是InnoDB清楚旧 mvcc 行时所用的事务id.将这个值和当前事务id进行比较,可以知道有多少老版本的数据未被清楚。这个数字多大才可以安全的取值没有
		硬性规定和速成的规定。如果数据没有做过任何更新,那么一个巨大的数字也不意味着有未清楚的数据,因为实际上所有事物在数据库里查看的都是同一个版本的数据。
		从另外一方面来说,如果有很多行被更新,那每一行就会有一个或者多个版本留在内存里。减少此类开销的最好办法是确保事物一完成就立刻提交它,不要让它长时间处于
		打开状态。因为一个打开的事务即使不做任何操作,也会影响到innodb清理旧版本的行数据。
		第6行:历史记录长度,即位于innodb数据文件的撤销空间里的页面的数目。如果事务执行了更新并提交,这个数字就会增加;而当清理进程移除旧版本数据时,它就会递减,
		清理进程也会更新第5行中的数值。
		第7行:锁结构数目。每个锁结构经常持有多个行锁,所以,它跟被锁定行的数目不一样。

		头部信息之后就是一个事务列表。当前版本的mysql还不支持嵌套事务,因此,在某个时间点,每个客户端连接能拥有的事务数目是有一个上限的,而每个事务只能属於单一连接。
	  在输出的信息里,每一个事务至少占2行内容。

---TRANSACTION 22043755, not started, process no 5388, OS thread id 123123
MySQL thread id 101577, OS thread handle 0x7fda96144700, query id 7661049 192.168.0.38 apollo_user	
		第1行以该事务的id和开始状态。这个事务是 'no started',意思是已经提交并且没有再发起影响事务的语句;可能刚好空闲。然后是一些进程和线程信息。第2行显示了
	  mysql 进程id,也和 show full processlist 中的id是一样的。紧随其后的是一个内部查询号和一些连接信息。

---TRANSACTION 22043755, ACTIVE 4 sec, process no 1234, OS thread id 123123, thread declared inside innodb 442
mysql tables in use 1,locked 0
MySQL thread id 8079, query id 728899 localhost baron Sending data
select sql_calc_found_rows * from b limit 5
Trx read view will not see trx with id >= 08099888, sees < 0 8098281
		本例中的第1行显示此事务已经活跃了4s。可能的状态有'no started','active','prepared'和'committed in memory' (一旦被提交到磁盘上,状态就会变为 'no started')。
	  尽管这个示例没有被提示,但是在其他条件下,你也许能看到关于事务当前正在做什么的信息。在源代码中有超过30个字符串常量可以显示在这里,例如'fetching rows',
	  'adding foreign keys' 等等。
	    第1行里的文本'thread declared inside InnoDB 442' 的意思是该线程正在innodb内核里做一些操作,并且还有442张'票'可以使用。换句话说,就是同样的sql查询可以重新
	  进入innodb内核442次。这个票是系统用来限制内核中线程并发操作的手段,以防止其在某些平台上运行失常。即使线程的状态是'inside InnoDB',它也不是在innodb里面完成所有
	  的工作。查询可能是在服务器一级做一些操作,而只是通过某个途径跟innodb内核互动一下。你也可能看到事务的状态是'sleeping before joining InnoDB queue'或者 
	  'waiting in InnoDB queue'。
	    接下来一行显示了当前语句里有多少表被使用和锁定。innodb一般不会锁定表,但对有些语句会锁定。如果mysql服务器高于innodb层次之上将表锁定,这里也是能够显示出来的。
	  如果事务已经锁定了几行数据,这里将会有一行信息显示出锁定结构的数目(再声明一次,这跟行锁是2回事)和堆的大小。
	    堆的大小指的是持有这些行锁而占用的内存大小.innodb是用一种特殊的位图表来实现行锁的,从理论上讲,它可将每一个锁定的行表示为一个比特。我们的测试显示,每一个锁通常
	  不超过4比特。
	    如果一个事务正在运行一个查询,那么接下来就会显示出查询的文本。
	    第5行显示了事务的读视图,它表明了因为版本关系而产生的对于事务可见和不可见两种类型的事务id的范围。在本例中,有2个数字之间有一个4个事务的间隙,这4个事务可能是不可见
	  的。innodb 在执行查询时,对于那些事务id正好在这个间隙的行,还会检查其可见性。
	    如果事务正在等待一个锁,那么在查询内容之后将可以看到这个锁的信息。不幸的是,输出信息并没有说出这个锁正在被哪个事务持有。
	    如果输出信息里有很多个事务,innodb可能会限制要打印出来的事务数目。

    6.FILE I/O
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
		第4~7行显示了IO辅助线程的状态。第8~10行显示的是每个辅助线程的挂起操作的数目,以及日志和缓冲池线程挂起的 fsync() 操作数目。简写'aio'的意思是
	  '异步IO'。第11行显示了读,写和fsync()调用执行的数目。在你的负载下这些绝对值会有所不同,因此更重要的是监控它们过去一段时间内是如何改变的。第12行
	  显示了头部显示的时间段内的每秒平均值。
	    在第8~9行显示的是挂起值是检查IO受限的应用的一个好办法。如果这些IO大部分有挂起操作,那么负载可能IO受限。
	    在windows下,可以通过 innodb_file_io_threads 配置变量来调整 IO 辅助线程数,因此可能会看到不止一个读线程和写线程。然后,在所有平台下至少会
	  看到4个线程。
	    1.Insert buffer thread
	    	负责插入缓冲合并(例如,记录从被插入缓冲合并到表空间中)
	    2.Log thread
	    	负责异步刷日志
	    3.Read thread
	    	执行预读操作以尝试预先读取innodb预感需要的数据
	    4.Write thread
	    	刷脏缓冲

    7.INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 2703, seg size 2705, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 34673, node heap has 2 buffer(s)
Hash table size 34673, node heap has 0 buffer(s)
Hash table size 34673, node heap has 0 buffer(s)

    	第4行显示了关于插入插入缓存大小,'free list'的长度和段大小的信息。文本 'for space 0' 像是指明了多个插入缓冲的可能性--每个表空间一个,
      但从未实现,并且这个文本在最新的mysql版本中被移除了。只有一个插入缓冲,因此第5行是多余的。第6行显示了有多少缓冲操作已经完成。合并与插入的
      比例很好的说明了缓冲使用效率如何。
        第7行显示的是自适应哈希索引的状态。第8行显示了在头部提及的时间内innodb完成了多少哈希索引操作。哈希索引查找与非哈希索引的查找的比例仅供
      参考。自适应索引无法配置。

    8.LOG
---
LOG
---
Log sequence number 6091114310
Log flushed up to   6091114310
Pages flushed up to 6091114310
Last checkpoint at  6091114301
0 pending log flushes, 0 pending chkp writes
46 log i/o's done, 0.00 log i/o's/second

      第4行显示了当前日志序号,第5行显示了日志已经刷到哪个位置。日志序号就是写到日志文件中的字节数,因此可用来计算日志缓冲中还有多少没有写入到
    日志文件中。在这个例子中,它有 9615 字节(13000620880 - 13000611265)。第6行显示了上一次检测点(一个监测点表示一个数据和日志文件都处于
    已知状态的时刻,并且能用于恢复)。如果上一个监测点落后日志序号太多,并且差异接近于该日志文件的大小,innodb会触发'疯狂刷',这对性能有影响。
    第7~8行显示了挂起的日志操作和统计,你可以将其与FILE IO 部分的值相比较,以了解你的IO有多少是由日志子系统引起,有多少是其他原因。

   9.BUFFER POLL AND MEMORY
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 137756672; in additional pool allocated 0
Total memory allocated by read views 88
Internal hash tables (constant factor + variable factor)
    Adaptive hash index 2217584 	(2213368 + 4216)
    Page hash           139112 (buffer pool 0 only)
    Dictionary cache    593780 	(554768 + 39012)
    File system         83536 	(82672 + 864)
    Lock system         333248 	(332872 + 376)
    Recovery system     0 	(0 + 0)
Dictionary memory allocated 39012
Buffer pool size        8191
Buffer pool size, bytes 134201344
Free buffers            8047
Database pages          144
Old database pages      0
Modified db pages       0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 144, created 0, written 0
		第4行显示了innodb分配的总内存,以及其中多个是额外的内存池分配。额外内存池仅分配了其中(一般很小)一部分的内存,由内部内存分配器分配。
	  现代innodb版本一般使用操作系统的内存分配器,但是老版本用自己的。因为之前有些操作系统并未提供一个非常好的实现。
	    第5~8行显示了缓冲池度量值,以页为单位。度量值有总的缓冲池大小,空闲页数,分配用来存储数据页的页数,以及'脏'数据页数。innodb 使用的是
	  缓冲池中的部分页来对锁,自适应哈希,以及其他系统结构做索引,因此池中的数据库页数永远不等于总的池大小。
	    第9~10行显示了挂起的读和写的数量(例如innodb需要为缓冲池而做的总的逻辑读和写)。这些值并不与FILE IO 部分的值相匹配,因为innodb可能合并
	  许多的逻辑 操作到一个物理IO操作中。LRU 代表'最近使用到的';它是通过冲刷缓冲中不经常使用的页来释放空间以供给经常使用的页的一种办法。冲刷
	  列表存放由检查点处理需要冲刷的旧页,并且单页的写是独立的页面写,不会被合并。
	    输出的第8行显示缓冲池包含37491个脏页,这是某些时刻(它们已经在内存中被修改但尚未写到磁盘上)需要被刷到磁盘上。然后,第10行显示当前没有安排
	  冲刷。这不是一个问题,innodb会在需要的时候刷。如果在innodb的状态输出中到处可见大量挂起的IO操作,这往往表明服务器有严重问题。
	    第11行显示了innodb被读取,创建和写入多少页。读/写页的值指的是从磁盘读到缓冲池中的数据,或反过来说。创建页的值是指innodb在缓冲池中分配但
	  没有从数据文件中读取内容的页,因为它并不关心内容是什么。
	    第13行报告了缓冲池的命中率,它用来衡量innodb在缓冲池中查找所需页的比例。它度量自上次innodb状态输出后的命中率,因此,如果服务器自那以后
	  一直很安静,你会看到'no buffer pool page gets since the last printout'。它对度量缓冲池的大小并没有用处。

   10.ROW OPERATIONS
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
0 transactions active inside InnoDB
0 out of 1000 descriptors used
---OLDEST VIEW---
Normal read view
Read view low limit trx n:o D00
Read view up limit trx id D00
Read view low limit trx id D00
Read view individually stored trx ids:
-----------------
Main thread process no. 1612, id 140456879916800, state: waiting for server activity
Number of rows inserted 0, updated 0, deleted 0, read 0
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s

	第4行显示了innodb内核内有多少线程。队列中的查询是innodb为限制并发执行的线程量而不允许进入内核的线程。查询同样在进入队列之前会休眠等待。
	第5行显示了有多少打开的innodb读视图。读视图是包含事务开始点的数据库内容的mvcc'快照'。你可以看看某特定事务是否在 transactions 部分有
  读视图。
    第6行显示了内核的主线程状态。可能的状态值如下:
    1.doing background drop tables
    2.doing insert buffer merge
    3.flushing buffer pool pages
    4.flushing log
    5.making checkpoint
    6.purging
    7.reserving kernel mutex
    8.sleeping
    9.suspending
    10.waiting for buffer pool flush to end
    11.waiting for server activity
    大部分服务器上应该会经常看到 'sleeping' ,如果生成多个快照而一再查看到不同的状态,例如'flushing buffer pool pages',则应该怀疑相关的活动
   有问题---例如,'疯狂刷'问题,可能由某个冲刷算法差劲的innodb版本引起,或由糟糕的配置导致的,例如太小的事务日志文件。
     第7~8行显示了多少行被插入,更新,删除和读取,以及它们的每秒均值。如果你想查看innodb有多少工作正在进行,那么它们是很好的参考值。
     show engine innodb status 输出在第9~13行结束,如果看不到这个文本,那可能是有一个很大的死锁截断了输出。


17.SHOW PROCESSLIST
	进程列表是当前连接到mysql的连接或现场的清单。show processlist 列出了这些线程,以及每个线程的状态信息。
MariaDB [(none)]> show full processlist \G
*************************** 1. row ***************************
      Id: 2
    User: system user
    Host:
      db: NULL
 Command: Qeury
    Time: 3792
   State: Sending data
    Info: NULL
Progress: 0.000
*************************** 2. row ***************************
      Id: 5
    User: root
    Host: localhost
      db: NULL
 Command: Killed
    Time: 0
   State: end
    Info: show full processlist
Progress: 0.000
	
	也可以从 information_schema 中的表来获取这个信息。上面例子中,第一个进程正在运行查询并发送数据,而第二个进程已经被杀死,这可能是由于这需要非常长
  的一段时间来完成,于是某人深思熟虑后通过kill命令终结它。线程有可能在kill状态停留一段时间,因为kill命令有可能不立即执行完成,比如它可能需要一些时间
  来回滚事务。
    show full processlist (增加了full关键字)将显示每个查询的全文,否则最多显示100个字符。

18.SHOW ENGINE INNODB MUTEX
	SHOW ENGINE INNODB MUTEX 返回innodb互斥体的详细信息,主要对洞悉可扩展性和并发性问题有帮助。每个互斥体都保护着代码中的一个临界区。
	基于等待的数量,可以使用这个输出帮助确定innodb那一块是瓶颈。只要有互斥体,就会有潜在的竞争。该命令可能输出非常多,需要一些脚本进行聚合分析。
	有3种策略可以消除互斥相关的瓶颈:尽量避开innodb的弱点,限制并发,或者在cpu密集型的空转等待和资源密集型密集型的操作系统等待之前做平衡。

19.复制状态
	在主库上执行 show master status 可以显示主库的复制状态和配置。
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000018 |      245 |              |                  |
+------------------+----------+--------------+------------------+

	输出包含了主库当前的二进制日志位置。通过show binary logs 可以获取二进制日志列表。
MariaDB [(none)]> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       584 |
| mysql-bin.000002 |       245 |
| mysql-bin.000003 |       245 |
| mysql-bin.000004 |       245 |
| mysql-bin.000005 |       288 |
	

MariaDB [(none)]> show binlog events\G
*************************** 1. row ***************************
   Log_name: mysql-bin.000001
        Pos: 4
 Event_type: Format_desc
  Server_id: 10
End_log_pos: 245
       Info: Server ver: 5.5.60-MariaDB, Binlog ver: 4
*************************** 2. row ***************************
   Log_name: mysql-bin.000001
        Pos: 245
 Event_type: Query
  Server_id: 10
End_log_pos: 397
       Info: use `test`; create table a (
id int(11) not null auto_increment,
name varchar(11),
primary key(`id`))
	要查看这些二进制日志中的事件,可以使用 show binlog events

	show slave status;
	Master_Log_File/Read_Master_Log_Pos
	io线程读主库二进制日志的位置

	Relay_Log_File/Relay_Log_Pos
	sql线程执行中继日志的位置

	Relay_Master_Log_File/Exec_Master_Log_Pos	
	sql线程执行的映射到主库二进制日志的位置。这与 Relay_Log_File/Relay_Log_Pos 有着相同的逻辑位置,但是主库的二进制日志而非复制的中继日志。换句话说,
  如果你看一下日志中的这2个位置,你会发现有相同的日志事件。

20.INFORMATION_SCHEMA
	INFORMATION_SCHEMA 库是一个sql标准中定义的系统视图的集合。mysql实现了许多标准中的视图,并且增加了一些其他的视图。在mysql5.1中,其中许多的视图与
  mysql的 show 命令对应,例如show full processlist 和 show status。然后,也有一些视图没有对应的show 命令。
    INFORMATION_SCHEMA 视图的美在于能够以标准的sql来进行查询。这比show 命令更灵活,因为show命令产生的结果不能聚合,联接或者进行其他标准的sql操作。
  在系统视图层拥有所有可获得的数据使得写感兴趣和有用的查询变得可行。
    MySQL Forge 是一个查询和分析针对这些视图的查询的好地方。
    最大的缺点是视图与相应的show命令相比,有时非常慢。它们一般会取所有的数据,存在临时表中,然后使查询可以获取临时表。当服务器上数据量大或者表多时,
  查询INFORMATION_SCHEMA 表会导致非常高的负载,并且会导致服务器对其他用户而言停转或者不可响应,因此在一个高负载且数据量大的生产服务器上使用时要小心。
  查询时会有危险的表主要是那些包含下列元素的表:TABLES,COLUMNS,REFERNTIAL_CONSTRAINTS,KEY_COLUMN_USAGE.对这些表的查询会导致mysql向存储引擎请求
  获取类似服务器上表的索引统计等数据,而这些在innodb里是非常繁重的。
    这些视图不可更新。尽管你可以从中检索服务器设置,但不能更新影响服务器的配置,因此,仍然需要对配置使用 show 和 set 命令。

21.InnoDB 表
	innodb 插件创建了许多 INFORMATION_SCHEMA 表。
	
	1.INNODB_CMP 和 INNODB_CMP_RESET
		这些表显示了innodb中以新文件格式 Barracuda 压缩的数据的相关信息。第二个表显示的信息和第一个表相同,但具有重置所包含数据的副作用,好像使用 FLUSH
	  命令那样。

	2.INNODB_CMPMEM 和 INNODB_CMPMEM_RESET
		这些表显示了用于innodb压缩数据的缓冲池中页的信息。第二个表是个重置表。

	3.INNODB_TRX 和 INNODB_LOCKS
		这些表显示了事务,拥有和等待锁的事务。它们对于诊断锁等待问题和长时间运行的事务非常重要。

	除了这些表,mysql5.5还增加了 INNODB_LOCK_WAITS,它可以帮助更容易的诊断更多类型的锁等待问题。

22.Performance Schema
	Performance Schema 是mysql增强仪表的心的汇总处。默认情况下,Performance Schema 是禁用的,你必须打开并且使其在一个想要手机的特定的仪表点(消费者)启用。
	在mysql5.5 中,Performance Schema 包含了指示条件变量,互斥体,读/写锁和文件IO实例的表。还有指示实例上的等待信息的表,而这些经常是你在查询时首先感兴趣的,
  以及与其实例表的联接。

总结:
	mysql暴露服务器内部信息的首要方式是 show 命令,但这在改变。在mysql5.1中引入的可插拔的 INFORMATION_SCHEMA 表允许innodb插件增加一些非常有意义的仪表.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章