-
Notifications
You must be signed in to change notification settings - Fork 683
/
Copy pathMySQL 日志详解.md.html
1123 lines (1025 loc) · 70.1 KB
/
MySQL 日志详解.md.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>MySQL 日志详解.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/文章/AQS 万字图文全面解析.md.html">AQS 万字图文全面解析.md.html</a>
</li>
<li>
<a href="/文章/Docker 镜像构建原理及源码分析.md.html">Docker 镜像构建原理及源码分析.md.html</a>
</li>
<li>
<a href="/文章/ElasticSearch 小白从入门到精通.md.html">ElasticSearch 小白从入门到精通.md.html</a>
</li>
<li>
<a href="/文章/JVM CPU Profiler技术原理及源码深度解析.md.html">JVM CPU Profiler技术原理及源码深度解析.md.html</a>
</li>
<li>
<a href="/文章/JVM 垃圾收集器.md.html">JVM 垃圾收集器.md.html</a>
</li>
<li>
<a href="/文章/JVM 面试的 30 个知识点.md.html">JVM 面试的 30 个知识点.md.html</a>
</li>
<li>
<a href="/文章/Java IO 体系、线程模型大总结.md.html">Java IO 体系、线程模型大总结.md.html</a>
</li>
<li>
<a href="/文章/Java NIO浅析.md.html">Java NIO浅析.md.html</a>
</li>
<li>
<a href="/文章/Java 面试题集锦(网络篇).md.html">Java 面试题集锦(网络篇).md.html</a>
</li>
<li>
<a href="/文章/Java-直接内存 DirectMemory 详解.md.html">Java-直接内存 DirectMemory 详解.md.html</a>
</li>
<li>
<a href="/文章/Java中9种常见的CMS GC问题分析与解决(上).md.html">Java中9种常见的CMS GC问题分析与解决(上).md.html</a>
</li>
<li>
<a href="/文章/Java中9种常见的CMS GC问题分析与解决(下).md.html">Java中9种常见的CMS GC问题分析与解决(下).md.html</a>
</li>
<li>
<a href="/文章/Java中的SPI.md.html">Java中的SPI.md.html</a>
</li>
<li>
<a href="/文章/Java中的ThreadLocal.md.html">Java中的ThreadLocal.md.html</a>
</li>
<li>
<a href="/文章/Java线程池实现原理及其在美团业务中的实践.md.html">Java线程池实现原理及其在美团业务中的实践.md.html</a>
</li>
<li>
<a href="/文章/Java魔法类:Unsafe应用解析.md.html">Java魔法类:Unsafe应用解析.md.html</a>
</li>
<li>
<a href="/文章/Kafka 源码阅读笔记.md.html">Kafka 源码阅读笔记.md.html</a>
</li>
<li>
<a href="/文章/Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理.md.html">Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB Buffer Pool.md.html">MySQL · 引擎特性 · InnoDB Buffer Pool.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB IO子系统.md.html">MySQL · 引擎特性 · InnoDB IO子系统.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 事务系统.md.html">MySQL · 引擎特性 · InnoDB 事务系统.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 同步机制.md.html">MySQL · 引擎特性 · InnoDB 同步机制.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 数据页解析.md.html">MySQL · 引擎特性 · InnoDB 数据页解析.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB崩溃恢复.md.html">MySQL · 引擎特性 · InnoDB崩溃恢复.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · 临时表那些事儿.md.html">MySQL · 引擎特性 · 临时表那些事儿.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制 半同步复制.md.html">MySQL 主从复制 半同步复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制 基于GTID复制.md.html">MySQL 主从复制 基于GTID复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制.md.html">MySQL 主从复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 事务日志(redo log和undo log).md.html">MySQL 事务日志(redo log和undo log).md.html</a>
</li>
<li>
<a href="/文章/MySQL 亿级别数据迁移实战代码分享.md.html">MySQL 亿级别数据迁移实战代码分享.md.html</a>
</li>
<li>
<a href="/文章/MySQL 从一条数据说起-InnoDB行存储数据结构.md.html">MySQL 从一条数据说起-InnoDB行存储数据结构.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:事务和锁的面纱.md.html">MySQL 地基基础:事务和锁的面纱.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:数据字典.md.html">MySQL 地基基础:数据字典.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:数据库字符集.md.html">MySQL 地基基础:数据库字符集.md.html</a>
</li>
<li>
<a href="/文章/MySQL 性能优化:碎片整理.md.html">MySQL 性能优化:碎片整理.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:一个 ALTER TALBE 执行了很久,你慌不慌?.md.html">MySQL 故障诊断:一个 ALTER TALBE 执行了很久,你慌不慌?.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:如何在日志中轻松定位大事务.md.html">MySQL 故障诊断:如何在日志中轻松定位大事务.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:教你快速定位加锁的 SQL.md.html">MySQL 故障诊断:教你快速定位加锁的 SQL.md.html</a>
</li>
<li>
<a class="current-tab" href="/文章/MySQL 日志详解.md.html">MySQL 日志详解.md.html</a>
</li>
<li>
<a href="/文章/MySQL 的半同步是什么?.md.html">MySQL 的半同步是什么?.md.html</a>
</li>
<li>
<a href="/文章/MySQL中的事务和MVCC.md.html">MySQL中的事务和MVCC.md.html</a>
</li>
<li>
<a href="/文章/MySQL事务_事务隔离级别详解.md.html">MySQL事务_事务隔离级别详解.md.html</a>
</li>
<li>
<a href="/文章/MySQL优化:优化 select count().md.html">MySQL优化:优化 select count().md.html</a>
</li>
<li>
<a href="/文章/MySQL共享锁、排他锁、悲观锁、乐观锁.md.html">MySQL共享锁、排他锁、悲观锁、乐观锁.md.html</a>
</li>
<li>
<a href="/文章/MySQL的MVCC(多版本并发控制).md.html">MySQL的MVCC(多版本并发控制).md.html</a>
</li>
<li>
<a href="/文章/QingStor 对象存储架构设计及最佳实践.md.html">QingStor 对象存储架构设计及最佳实践.md.html</a>
</li>
<li>
<a href="/文章/RocketMQ 面试题集锦.md.html">RocketMQ 面试题集锦.md.html</a>
</li>
<li>
<a href="/文章/SnowFlake 雪花算法生成分布式 ID.md.html">SnowFlake 雪花算法生成分布式 ID.md.html</a>
</li>
<li>
<a href="/文章/Spring Boot 2.x 结合 k8s 实现分布式微服务架构.md.html">Spring Boot 2.x 结合 k8s 实现分布式微服务架构.md.html</a>
</li>
<li>
<a href="/文章/Spring Boot 教程:如何开发一个 starter.md.html">Spring Boot 教程:如何开发一个 starter.md.html</a>
</li>
<li>
<a href="/文章/Spring MVC 原理.md.html">Spring MVC 原理.md.html</a>
</li>
<li>
<a href="/文章/Spring MyBatis和Spring整合的奥秘.md.html">Spring MyBatis和Spring整合的奥秘.md.html</a>
</li>
<li>
<a href="/文章/Spring 帮助你更好的理解Spring循环依赖.md.html">Spring 帮助你更好的理解Spring循环依赖.md.html</a>
</li>
<li>
<a href="/文章/Spring 循环依赖及解决方式.md.html">Spring 循环依赖及解决方式.md.html</a>
</li>
<li>
<a href="/文章/Spring中眼花缭乱的BeanDefinition.md.html">Spring中眼花缭乱的BeanDefinition.md.html</a>
</li>
<li>
<a href="/文章/Vert.x 基础入门.md.html">Vert.x 基础入门.md.html</a>
</li>
<li>
<a href="/文章/eBay 的 Elasticsearch 性能调优实践.md.html">eBay 的 Elasticsearch 性能调优实践.md.html</a>
</li>
<li>
<a href="/文章/不可不说的Java“锁”事.md.html">不可不说的Java“锁”事.md.html</a>
</li>
<li>
<a href="/文章/互联网并发限流实战.md.html">互联网并发限流实战.md.html</a>
</li>
<li>
<a href="/文章/从ReentrantLock的实现看AQS的原理及应用.md.html">从ReentrantLock的实现看AQS的原理及应用.md.html</a>
</li>
<li>
<a href="/文章/从SpringCloud开始,聊微服务架构.md.html">从SpringCloud开始,聊微服务架构.md.html</a>
</li>
<li>
<a href="/文章/全面了解 JDK 线程池实现原理.md.html">全面了解 JDK 线程池实现原理.md.html</a>
</li>
<li>
<a href="/文章/分布式一致性理论与算法.md.html">分布式一致性理论与算法.md.html</a>
</li>
<li>
<a href="/文章/分布式一致性算法 Raft.md.html">分布式一致性算法 Raft.md.html</a>
</li>
<li>
<a href="/文章/分布式唯一 ID 解析.md.html">分布式唯一 ID 解析.md.html</a>
</li>
<li>
<a href="/文章/分布式链路追踪:集群管理设计.md.html">分布式链路追踪:集群管理设计.md.html</a>
</li>
<li>
<a href="/文章/动态代理种类及原理,你知道多少?.md.html">动态代理种类及原理,你知道多少?.md.html</a>
</li>
<li>
<a href="/文章/响应式架构与 RxJava 在有赞零售的实践.md.html">响应式架构与 RxJava 在有赞零售的实践.md.html</a>
</li>
<li>
<a href="/文章/大数据算法——布隆过滤器.md.html">大数据算法——布隆过滤器.md.html</a>
</li>
<li>
<a href="/文章/如何优雅地记录操作日志?.md.html">如何优雅地记录操作日志?.md.html</a>
</li>
<li>
<a href="/文章/如何设计一个亿级消息量的 IM 系统.md.html">如何设计一个亿级消息量的 IM 系统.md.html</a>
</li>
<li>
<a href="/文章/异步网络模型.md.html">异步网络模型.md.html</a>
</li>
<li>
<a href="/文章/当我们在讨论CQRS时,我们在讨论些神马?.md.html">当我们在讨论CQRS时,我们在讨论些神马?.md.html</a>
</li>
<li>
<a href="/文章/彻底理解 MySQL 的索引机制.md.html">彻底理解 MySQL 的索引机制.md.html</a>
</li>
<li>
<a href="/文章/最全的 116 道 Redis 面试题解答.md.html">最全的 116 道 Redis 面试题解答.md.html</a>
</li>
<li>
<a href="/文章/有赞权限系统(SAM).md.html">有赞权限系统(SAM).md.html</a>
</li>
<li>
<a href="/文章/有赞零售中台建设方法的探索与实践.md.html">有赞零售中台建设方法的探索与实践.md.html</a>
</li>
<li>
<a href="/文章/服务注册与发现原理剖析(Eureka、Zookeeper、Nacos).md.html">服务注册与发现原理剖析(Eureka、Zookeeper、Nacos).md.html</a>
</li>
<li>
<a href="/文章/深入浅出Cache.md.html">深入浅出Cache.md.html</a>
</li>
<li>
<a href="/文章/深入理解 MySQL 底层实现.md.html">深入理解 MySQL 底层实现.md.html</a>
</li>
<li>
<a href="/文章/漫画讲解 git rebase VS git merge.md.html">漫画讲解 git rebase VS git merge.md.html</a>
</li>
<li>
<a href="/文章/生成浏览器唯一稳定 ID 的探索.md.html">生成浏览器唯一稳定 ID 的探索.md.html</a>
</li>
<li>
<a href="/文章/缓存 如何保证缓存与数据库的双写一致性?.md.html">缓存 如何保证缓存与数据库的双写一致性?.md.html</a>
</li>
<li>
<a href="/文章/网易严选怎么做全链路监控的?.md.html">网易严选怎么做全链路监控的?.md.html</a>
</li>
<li>
<a href="/文章/美团万亿级 KV 存储架构与实践.md.html">美团万亿级 KV 存储架构与实践.md.html</a>
</li>
<li>
<a href="/文章/美团点评Kubernetes集群管理实践.md.html">美团点评Kubernetes集群管理实践.md.html</a>
</li>
<li>
<a href="/文章/美团百亿规模API网关服务Shepherd的设计与实现.md.html">美团百亿规模API网关服务Shepherd的设计与实现.md.html</a>
</li>
<li>
<a href="/文章/解读《阿里巴巴 Java 开发手册》背后的思考.md.html">解读《阿里巴巴 Java 开发手册》背后的思考.md.html</a>
</li>
<li>
<a href="/文章/认识 MySQL 和 Redis 的数据一致性问题.md.html">认识 MySQL 和 Redis 的数据一致性问题.md.html</a>
</li>
<li>
<a href="/文章/进阶:Dockerfile 高阶使用指南及镜像优化.md.html">进阶:Dockerfile 高阶使用指南及镜像优化.md.html</a>
</li>
<li>
<a href="/文章/铁总在用的高性能分布式缓存计算框架 Geode.md.html">铁总在用的高性能分布式缓存计算框架 Geode.md.html</a>
</li>
<li>
<a href="/文章/阿里云PolarDB及其共享存储PolarFS技术实现分析(上).md.html">阿里云PolarDB及其共享存储PolarFS技术实现分析(上).md.html</a>
</li>
<li>
<a href="/文章/阿里云PolarDB及其共享存储PolarFS技术实现分析(下).md.html">阿里云PolarDB及其共享存储PolarFS技术实现分析(下).md.html</a>
</li>
<li>
<a href="/文章/面试最常被问的 Java 后端题.md.html">面试最常被问的 Java 后端题.md.html</a>
</li>
<li>
<a href="/文章/领域驱动设计在互联网业务开发中的实践.md.html">领域驱动设计在互联网业务开发中的实践.md.html</a>
</li>
<li>
<a href="/文章/领域驱动设计的菱形对称架构.md.html">领域驱动设计的菱形对称架构.md.html</a>
</li>
<li>
<a href="/文章/高效构建 Docker 镜像的最佳实践.md.html">高效构建 Docker 镜像的最佳实践.md.html</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>MySQL 日志详解</h1>
<p>官方手册:<a href="https://dev.mysql.com/doc/refman/5.7/en/server-logs.html">https://dev.mysql.com/doc/refman/5.7/en/server-logs.html</a></p>
<p>不管是哪个数据库产品,一定会有日志文件。在MariaDB/MySQL中,主要有5种日志文件:
1.错误日志(error log):记录mysql服务的启停时正确和错误的信息,还记录启动、停止、运行过程中的错误信息。
2.查询日志(general log):记录建立的客户端连接和执行的语句。
3.二进制日志(bin log):记录所有更改数据的语句,可用于数据复制。
4.慢查询日志(slow log):记录所有执行时间超过long_query_time的所有查询或不使用索引的查询。
5.中继日志(relay log):主从复制时使用的日志。</p>
<p>除了这5种日志,在需要的时候还会创建DDL日志。本文暂先讨论错误日志、一般查询日志、慢查询日志和二进制日志,中继日志和主从复制有关,将在复制的章节中介绍。下一篇文章将介绍innodb事务日志,见:<a href="https://www.cnblogs.com/f-ck-need-u/p/9010872.html">MySQL的事务日志</a>。</p>
<h1>1.日志刷新操作</h1>
<p>以下操作会刷新日志文件,刷新日志文件时会关闭旧的日志文件并重新打开日志文件。对于有些日志类型,如二进制日志,刷新日志会滚动日志文件,而不仅仅是关闭并重新打开。</p>
<pre><code>mysql> FLUSH LOGS;
shell> mysqladmin flush-logs
shell> mysqladmin refresh
</code></pre>
<h1>2.错误日志</h1>
<p>错误日志是最重要的日志之一,它记录了MariaDB/MySQL服务启动和停止正确和错误的信息,还记录了mysqld实例运行过程中发生的错误事件信息。</p>
<p>可以使用" --log-error=[file_name] "来指定mysqld记录的错误日志文件,如果没有指定file_name,则默认的错误日志文件为datadir目录下的 <code>hostname</code>.err ,hostname表示当前的主机名。</p>
<p>也可以在MariaDB/MySQL配置文件中的mysqld配置部分,使用log-error指定错误日志的路径。</p>
<p>如果不知道错误日志的位置,可以查看变量log_error来查看。</p>
<pre><code>mysql> show variables like 'log_error';
+---------------+----------------------------------------+
| Variable_name | Value |
+---------------+----------------------------------------+
| log_error | /var/lib/mysql/node1.longshuai.com.err |
+---------------+----------------------------------------+
</code></pre>
<p>在MySQL 5.5.7之前,刷新日志操作(如flush logs)会备份旧的错误日志(以_old结尾),并创建一个新的错误日志文件并打开,在MySQL 5.5.7之后,执行刷新日志的操作时,错误日志会关闭并重新打开,如果错误日志不存在,则会先创建。</p>
<p>在MariaDB/MySQL正在运行状态下删除错误日志后,不会自动创建错误日志,只有在刷新日志的时候才会创建一个新的错误日志文件。</p>
<p>以下是MySQL 5.6.35启动的日志信息。</p>
<pre><code>2017-03-29 01:15:14 2362 [Note] Plugin 'FEDERATED' is disabled.
2017-03-29 01:15:14 2362 [Note] InnoDB: Using atomics to ref count buffer pool pages
2017-03-29 01:15:14 2362 [Note] InnoDB: The InnoDB memory heap is disabled
2017-03-29 01:15:14 2362 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2017-03-29 01:15:14 2362 [Note] InnoDB: Memory barrier is not used
2017-03-29 01:15:14 2362 [Note] InnoDB: Compressed tables use zlib 1.2.3
2017-03-29 01:15:14 2362 [Note] InnoDB: Using Linux native AIO
2017-03-29 01:15:14 2362 [Note] InnoDB: Using CPU crc32 instructions
2017-03-29 01:15:14 2362 [Note] InnoDB: Initializing buffer pool, size = 128.0M
2017-03-29 01:15:14 2362 [Note] InnoDB: Completed initialization of buffer pool
2017-03-29 01:15:14 2362 [Note] InnoDB: Highest supported file format is Barracuda.
2017-03-29 01:15:14 2362 [Note] InnoDB: 128 rollback segment(s) are active.
2017-03-29 01:15:14 2362 [Note] InnoDB: Waiting for purge to start
2017-03-29 01:15:14 2362 [Note] InnoDB: 5.6.35 started; log sequence number 3911610
2017-03-29 01:15:14 2362 [Note] Server hostname (bind-address): '*'; port: 3306
2017-03-29 01:15:14 2362 [Note] IPv6 is available.
2017-03-29 01:15:14 2362 [Note] - '::' resolves to '::';
2017-03-29 01:15:14 2362 [Note] Server socket created on IP: '::'.
2017-03-29 01:15:14 2362 [Warning] 'proxies_priv' entry '@ <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="72001d1d06320a07170a1b5c1e1d1c15011a07131b5c111d1f">[email protected]</a>' ignored in --skip-name-resolve mode.
2017-03-29 01:15:14 2362 [Note] Event Scheduler: Loaded 0 events
2017-03-29 01:15:14 2362 [Note] /usr/local/mysql/bin/mysqld: ready for connections.
Version: '5.6.35' socket: '/mydata/data/mysql.sock' port: 3306 MySQL Community Server (GPL)
</code></pre>
<h1>3.一般查询日志</h1>
<p>查询日志分为一般查询日志和慢查询日志,它们是通过查询是否超出变量 long_query_time 指定时间的值来判定的。在超时时间内完成的查询是一般查询,可以将其记录到一般查询日志中,<strong>但是建议关闭这种日志(默认是关闭的)</strong>,超出时间的查询是慢查询,可以将其记录到慢查询日志中。</p>
<p>使用" --general_log={0|1} "来决定是否启用一般查询日志,使用" --general_log_file=file_name "来指定查询日志的路径。不给定路径时默认的文件名以 <code>hostname</code>.log 命名。</p>
<p>和查询日志有关的变量有:</p>
<pre><code>`long_query_time = 10 ``# 指定慢查询超时时长,超出此时长的属于慢查询,会记录到慢查询日志中``log_output={TABLE|FILE|NONE} ``# 定义一般查询日志和慢查询日志的输出格式,不指定时默认为file`
</code></pre>
<p>TABLE表示记录日志到表中,FILE表示记录日志到文件中,NONE表示不记录日志。只要这里指定为NONE,即使开启了一般查询日志和慢查询日志,也都不会有任何记录。</p>
<p>和一般查询日志相关的变量有:</p>
<pre><code>`general_log=off ``# 是否启用一般查询日志,为全局变量,必须在global上修改。``sql_log_off=off ``# 在session级别控制是否启用一般查询日志,默认为off,即启用``general_log_file=``/mydata/data/hostname``.log ``# 默认是库文件路径下主机名加上.log`
</code></pre>
<p>在MySQL 5.6以前的版本还有一个"log"变量也是决定是否开启一般查询日志的。在5.6版本开始已经废弃了该选项。</p>
<p>默认没有开启一般查询日志,也不建议开启一般查询日志。此处打开该类型的日志,看看是如何记录一般查询日志的。</p>
<p>首先开启一般查询日志。</p>
<pre><code>mysql> set @@global.general_log=1;
[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7705181803370f02120f1e">[email protected]</a> data]# ll *.log
-rw-rw---- 1 mysql mysql 5423 Mar 20 16:29 mysqld.log
-rw-rw---- 1 mysql mysql 262 Mar 29 09:31 xuexi.log
</code></pre>
<p>执行几个语句。</p>
<pre><code>mysql> select host,user from mysql.user;
mysql> show variables like "%error%";
mysql> insert into ttt values(233);
mysql> create table tt(id int);
mysql> set @a:=3;
</code></pre>
<p>查看一般查询日志的内容。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e795888893a79f92829f8e">[email protected]</a> data]# cat xuexi.log
/usr/local/mysql/bin/mysqld, Version: 5.6.35-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306 Unix socket: /mydata/data/mysql.sock
Time Id Command Argument
180421 20:04:41 13 Query select user,host from mysql.user
180421 20:06:06 13 Query show variables like "%error%"
180421 20:07:28 13 Query insert into ttt values(233)
180421 20:11:47 13 Query create table tt(id int)
180421 20:12:29 13 Query set @a:=3
</code></pre>
<p>由此可知,一般查询日志查询的不止是select语句,几乎所有的语句都会记录。</p>
<h1>4.慢查询日志</h1>
<p>查询超出变量 long_query_time 指定时间值的为慢查询。但是查询获取锁(包括锁等待)的时间不计入查询时间内。</p>
<p>mysql记录慢查询日志是在查询执行完毕且已经完全释放锁之后才记录的,因此慢查询日志记录的顺序和执行的SQL查询语句顺序可能会不一致(例如语句1先执行,查询速度慢,语句2后执行,但查询速度快,则语句2先记录)。</p>
<p>注意,MySQL 5.1之后就支持微秒级的慢查询超时时长,对于DBA来说,一个查询运行0.5秒和运行0.05秒是非常不同的,前者可能索引使用错误或者走了表扫描,后者可能索引使用正确。</p>
<p>另外,指定的慢查询超时时长表示的是超出这个时间的才算是慢查询,等于这个时间的不会记录。</p>
<p>和慢查询有关的变量:</p>
<pre><code>`long_query_time=10 ``# 指定慢查询超时时长(默认10秒),超出此时长的属于慢查询``log_output={TABLE|FILE|NONE} ``# 定义一般查询日志和慢查询日志的输出格式,默认为file``log_slow_queries={``yes``|no} ``# 是否启用慢查询日志,默认不启用``slow_query_log={1|ON|0|OFF} ``# 也是是否启用慢查询日志,此变量和log_slow_queries修改一个另一个同时变化``slow_query_log_file=``/mydata/data/hostname-slow``.log ``#默认路径为库文件目录下主机名加上-slow.log``log_queries_not_using_indexes=OFF ``# 查询没有使用索引的时候是否也记入慢查询日志`
</code></pre>
<p>现在启用慢查询日志。</p>
<pre><code>mysql> set @@global.slow_query_log=on;
</code></pre>
<p>因为默认超时时长为10秒,所以进行一个10秒的查询。</p>
<pre><code>mysql> select sleep(10);
</code></pre>
<p>查看慢查询日志文件。这里看到虽然sleep了10秒,但是最后查询时间超出了847微秒,因此这里也记录了该查询。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4b3924243f0b333e2e3322">[email protected]</a> data]# cat xuexi-slow.log
/usr/local/mysql/bin/mysqld, Version: 5.6.35-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306 Unix socket: /mydata/data/mysql.sock
Time Id Command Argument
# Time: 170329 9:55:58
# <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="104563756250587f6364">[email protected]</a>: root[root] @ localhost [] Id: 1
# Query_time: 10.000847 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test;
SET timestamp=1490752558;
select sleep(10);
</code></pre>
<p>随着时间的推移,慢查询日志文件中的记录可能会变得非常多,这对于分析查询来说是非常困难的。好在提供了一个专门归类慢查询日志的工具mysqldumpslow。</p>
<pre><code>`[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="53213c3c27132b26362b3a">[email protected]</a> data]``# mysqldumpslow --help`` ``-d debug `` ``-``v` `verbose:显示详细信息`` ``-t NUM just show the ``top` `n queries:仅显示前n条查询`` ``-a don``'t abstract all numbers to N and strings to '``S':归类时不要使用N替换数字,S替换字符串`` ``-g PATTERN ``grep``: only consider stmts that include this string:通过``grep``来筛选``select``语句。`
</code></pre>
<p>该工具归类的时候,默认会将<strong>同文本但变量值不同的查询语句视为同一类,并使用N代替其中的数值变量,使用S代替其中的字符串变量</strong>。可以使用-a来禁用这种替换。如:</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="55273a3a21152d20302d3c">[email protected]</a> data]# mysqldumpslow xuexi-slow.log
Reading mysql slow query log from xuexi-slow.log
Count: 1 Time=10.00s (10s) Lock=0.00s (0s) Rows=1.0 (1), root[root]@localhost
select sleep(N)
[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6d1f0202192d1518081504">[email protected]</a> data]# mysqldumpslow -a xuexi-slow.log
Reading mysql slow query log from xuexi-slow.log
Count: 1 Time=10.00s (10s) Lock=0.00s (0s) Rows=1.0 (1), root[root]@localhost
select sleep(10)
</code></pre>
<p>显然,这里归类后的结果只是精确到0.01秒的,如果想要显示及其精确的秒数,则使用-d选项启用调试功能。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a5d7cacad1e5ddd0c0ddcc">[email protected]</a> data]# mysqldumpslow -d xuexi-slow.log
Reading mysql slow query log from xuexi-slow.log
[[/usr/local/mysql/bin/mysqld, Version: 5.6.35-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306 Unix socket: /mydata/data/mysql.sock
Time Id Command Argument
# Time: 170329 9:55:58
# <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="80d5f3e5f2c0c8eff3f4">[email protected]</a>: root[root] @ localhost [] Id: 1
# Query_time: 10.000847 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test;
SET timestamp=1490752558;
select sleep(10);
]]
<<>>
<<# Time: 170329 9:55:58
# <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="85d0f6e0f7c5cdeaf6f1">[email protected]</a>: root[root] @ localhost [] Id: 1
# Query_time: 10.000847 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test;
SET timestamp=1490752558;
select sleep(10);
>> at /usr/local/mysql/bin/mysqldumpslow line 97, <> chunk 1.
[[# Time: 170329 9:55:58
# <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="287d5b4d5a6860475b5c">[email protected]</a>: root[root] @ localhost [] Id: 1
# Query_time: 10.000847 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test;
SET timestamp=1490752558;
select sleep(10);
]]
{{ select sleep(N)}}
Count: 1 Time=10.00s (10s) Lock=0.00s (0s) Rows=1.0 (1), root[root]@localhost
select sleep(N)
</code></pre>
<p>慢查询在SQL语句调优的时候非常有用,应该将它启用起来,且应该让慢查询阈值尽量小,例如1秒甚至低于1秒。就像一天执行上千次的1秒语句,和一天执行几次的20秒语句,显然更值得去优化这个1秒的语句。</p>
<h1>5.二进制日志</h1>
<h2>5.1 二进制日志文件</h2>
<p>二进制日志包含了<strong>引起或可能引起数据库改变</strong>(如delete语句但没有匹配行)的事件信息,但绝不会包括select和show这样的查询语句。语句以"事件"的形式保存,所以包含了时间、事件开始和结束位置等信息。</p>
<p>二进制日志是<strong>以事件形式记录的,不是事务日志****(****但可能是基于事务来记录二进制日志)</strong>,不代表它只记录innodb日志,myisam表也一样有二进制日志。</p>
<p>对于事务表的操作,二进制日志<strong>只在事务提交的时候一次性写入****(<strong><strong>基于事务的innodb</strong></strong>二进制日志),提交前的每个二进制日志记录都先cache,提交时写入</strong>。</p>
<p>所以,对于事务表来说,一个事务中可能包含多条二进制日志事件,它们会在提交时一次性写入。而对于非事务表的操作,每次执行完语句就直接写入。</p>
<p>MariaDB/MySQL默认没有启动二进制日志,要启用二进制日志使用 --log-bin=[on|off|file_name] 选项指定,如果没有给定file_name,则默认为datadir下的主机名加"-bin",并在后面跟上一串数字表示日志序列号,如果给定的日志文件中包含了后缀(logname.suffix)将忽略后缀部分。</p>
<p><img src="assets/733013-20180507084125816-1681048114.png" alt="img" /></p>
<p>或者在配置文件中的[mysqld]部分设置log-bin也可以。注意:对于mysql 5.7,直接启动binlog可能会导致mysql服务启动失败,这时需要在配置文件中的mysqld为mysql实例分配server_id。</p>
<pre><code>`[mysqld]``# server_id=1234``log-bin=[on|filename]`
</code></pre>
<p>mysqld还<strong>创建一个二进制日志索引文件</strong>,当二进制日志文件滚动的时候会向该文件中写入对应的信息。所以该文件包含所有使用的二进制日志文件的文件名。默认情况下该文件与二进制日志文件的文件名相同,扩展名为'.index'。要指定该文件的文件名使用 --log-bin-index[=file_name] 选项。当mysqld在运行时不应手动编辑该文件,免得mysqld变得混乱。</p>
<p>当重启mysql服务或刷新日志或者达到日志最大值时,将滚动二进制日志文件,滚动日志时只修改日志文件名的数字序列部分。</p>
<p>二进制日志文件的最大值通过变量 max_binlog_size 设置(默认值为1G)。但由于二进制日志可能是基于事务来记录的(如innodb表类型),而事务是绝对不可能也不应该跨文件记录的,如果正好二进制日志文件达到了最大值但事务还没有提交则不会滚动日志,而是继续增大日志,所以 max_binlog_size 指定的值和实际的二进制日志大小不一定相等。</p>
<p>因为二进制日志文件增长迅速,但官方说明因此而损耗的性能小于1%,且二进制目的是为了恢复定点数据库和主从复制,所以出于安全和功能考虑,<strong>极不建议将二进制日志和<strong><strong>datadir</strong></strong>放在同一磁盘上</strong>。</p>
<h2>5.2 查看二进制日志</h2>
<p>MySQL中查看二进制日志的方法主要有几种。</p>
<p>1.使用mysqlbinlog工具。</p>
<p>2.使用show显示对应的信息。</p>
<pre><code>`SHOW {BINARY | MASTER} LOGS ``# 查看使用了哪些日志文件``SHOW BINLOG EVENTS [IN ``'log_name'``] [FROM pos] ``# 查看日志中进行了哪些操作``SHOW MASTER STATUS ``# 显式主服务器中的二进制日志信息`
</code></pre>
<h3>5.2.1 mysqlbinlog</h3>
<p>二进制日志可以使用mysqlbinlog命令查看。</p>
<pre><code>`mysqlbinlog [option] log-file1 log-file2...`
</code></pre>
<p>以下是常用的几个选项:</p>
<pre><code>`-d,--database=name:只查看指定数据库的日志操作``-o,--offset=``#:忽略掉日志中的前n个操作命令``-r,--result-``file``=name:将输出的日志信息输出到指定的文件中,使用重定向也一样可以。``-s,--short-form:显示简单格式的日志,只记录一些普通的语句,会省略掉一些额外的信息如位置信息和时间信息以及基于行的日志。可以用来调试,生产环境千万不可使用``--``set``-charset=char_name:在输出日志信息到文件中时,在文件第一行加上``set` `names char_name``--start-datetime,--stop-datetime:指定输出开始时间和结束时间内的所有日志信息``--start-position=``#,--stop-position=#:指定输出开始位置和结束位置内的所有日志信息``-``v``,-vv:显示更详细信息,基于row的日志默认不会显示出来,此时使用-``v``或-vv可以查看`
</code></pre>
<p>在进行测试之前,先对日志进行一次刷新,以方便解释二进制日志的信息。</p>
<pre><code>shell> mysqladmin -uroot -p refresh
</code></pre>
<p>假设现在的日志文件是mysql-bin.000001,里面暂时只有一些初始信息,没有记录任何操作过的记录。</p>
<p>下面是每个二进制日志文件的初始信息。可以看到记录了时间和位置信息(at 4)。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bfcdd0d0cbffc7cadac7d6">[email protected]</a> data]# mysqlbinlog mysql-bin.000001
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="eca3a0a8b3afa3a1bca0a9b8a5a3a2b3b8b5bca9d1ac">[email protected]</a>@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#170329 2:18:10 server id 1 end_log_pos 120 CRC32 0x40f62523 Start: binlog v 4, server v 5.6.35-log created 170329 2:18:10 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
4qjaWA8BAAAAdAAAAHgAAAABAAQANS42LjM1LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADiqNpYEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAASMl
9kA=
'/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e2d21233e222b3a272120313a373e2b532e21222a">[email protected]</a>_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
</code></pre>
<p>现在在数据库中执行下面的操作:</p>
<pre><code>use test;
create table student(studentid int not null primary key,name varchar(30) not null,gender enum('female','mail'));
alter table student change gender gender enum('female','male');
insert into student values(1,'malongshuai','male'),(2,'gaoxiaofang','female');
</code></pre>
<p>再查看二进制日志信息。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f98b96968db9818c9c8190">[email protected]</a> data]# mysqlbinlog mysql-bin.000001
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b2fdfef6edf1fdffe2fef7e6fbfdfcede6ebe2f78ff2">[email protected]</a>@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#170329 2:18:10 server id 1 end_log_pos 120 CRC32 0x40f62523 Start: binlog v 4, server v 5.6.35-log created 170329 2:18:10 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
4qjaWA8BAAAAdAAAAHgAAAABAAQANS42LjM1LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADiqNpYEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAASMl
9kA=
'/*!*/;
# at 120
#170329 5:20:00 server id 1 end_log_pos 305 CRC32 0xbac43912 Query thread_id=1 exec_time=0 error_code=0
use `test`/*!*/;
SET TIMESTAMP=1490736000/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table student(studentid int not null primary key,name varchar(30) not null,gender enum('female','mail'))
/*!*/;
# at 305
#170329 5:21:21 server id 1 end_log_pos 441 CRC32 0xde67f702 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490736081/*!*/;
alter table student change gender gender enum('female','male')
/*!*/;
# at 441
#170329 5:21:33 server id 1 end_log_pos 520 CRC32 0x05a9c5a1 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490736093/*!*/;
BEGIN
/*!*/;
# at 520
#170329 5:21:33 server id 1 end_log_pos 671 CRC32 0xad9e7dc8 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490736093/*!*/;
insert into student values(1,'malongshuai','male'),(2,'gaoxiaofang','female')
/*!*/;
# at 671
#170329 5:21:33 server id 1 end_log_pos 702 CRC32 0xb69b0f7d Xid = 32
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="14575b59445851405d5b5a4b404d445129545b5850">[email protected]</a>_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
</code></pre>
<p>将上述信息整理为下图:其中timestamp记录的是从1970-01-01到现在的总秒数时间戳,可以使用 date -d '@1490736093' 转换。</p>
<p><img src="assets/733013-20180507085958196.png" alt="img" /></p>
<ul>
<li>位置0-120记录的是二进制日志的一些固定信息。</li>
<li>位置120-305记录的是use和create table语句,语句的记录时间为5:20:00。但注意,这里的use不是执行的use语句,而是MySQL发现要操作的数据库为test,而自动进行的操作并记录下来。人为的use语句是不会记录的。</li>
<li>位置305-441记录的是alter table语句,语句的记录时间为5:20:21。</li>
<li>位置441-702记录的是insert操作,因为该操作是DML语句,因此记录了事务的开始BEGIN和提交COMMIT。
<ul>
<li>begin的起止位置为441-520;</li>
<li>insert into语句的起止位置为520-671,记录的时间和自动开启事务的begin时间是一样的;</li>
<li>commit的起止位置为671-702。</li>
</ul>
</li>
</ul>
<p>使用-r命令将日志文件导入到指定文件中,使用重定向也可以实现同样的结果。并使用-s查看简化的日志文件。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a9dbc6c6dde9d1dcccd1c0">[email protected]</a> data]# mysqlbinlog mysql-bin.000001 -r /tmp/binlog.000001
[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fb8994948fbb838e9e8392">[email protected]</a> data]# mysqlbinlog mysql-bin.000001 -s>/tmp/binlog.sample
</code></pre>
<p>比较这两个文件,看看简化的日志文件简化了哪些东西。</p>
<p><img src="assets/733013-20180507090446176-118990478.png" alt="img" /></p>
<p>从上图中可以看出,使用-s后,少了基于行的日志信息,也少了记录的位置和时间信息。</p>
<p>使用-o可以忽略前N个条目,例如上面的操作涉及了6个操作。忽略掉前3个后的日志显示如下:可以看到直接从位置441开始显示了。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="71031e1e05310904140918">[email protected]</a> data]# mysqlbinlog mysql-bin.000001 -o 3
...前面固定部分省略...
'/*!*/;
# at 441
#170329 5:21:33 server id 1 end_log_pos 520 CRC32 0x05a9c5a1 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490736093/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 520
#170329 5:21:33 server id 1 end_log_pos 671 CRC32 0xad9e7dc8 Query thread_id=1 exec_time=0 error_code=0
use `test`/*!*/;
SET TIMESTAMP=1490736093/*!*/;
insert into student values(1,'malongshuai','male'),(2,'gaoxiaofang','female')
/*!*/;
# at 671
#170329 5:21:33 server id 1 end_log_pos 702 CRC32 0xb69b0f7d Xid = 32
COMMIT/*!*/;
DELIMITER ;
...后面固定部分省略...
</code></pre>
<p>使用-d可以只显示指定数据库相关的操作。例如先切换到其他数据库进行一番操作,然后再使用-d查看日志。</p>
<pre><code>mysql> use mysql;
mysql> create table mytest(id int);
[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cebca1a1ba8eb6bbabb6a7">[email protected]</a> data]# mysqlbinlog mysql-bin.000001 -d mysql
...前固定部分省略...'/*!*/;
# at 120
# at 305
# at 441
#170329 5:21:33 server id 1 end_log_pos 520 CRC32 0x05a9c5a1 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490736093/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 520
# at 671
#170329 5:21:33 server id 1 end_log_pos 702 CRC32 0xb69b0f7d Xid = 32
COMMIT/*!*/;
# at 702
#170329 6:27:12 server id 1 end_log_pos 805 CRC32 0x491529ff Query thread_id=1 exec_time=0 error_code=0
use `mysql`/*!*/;
SET TIMESTAMP=1490740032/*!*/;
create table mytest(id int)
/*!*/;
DELIMITER ;
...后面固定部分省略...
</code></pre>
<p>可以看到,除了指定的mysql数据库的信息输出了,还非常简化的输出了其他数据库的信息。</p>
<p>mysqlbinlog最有用的两个选项就是指定时间和位置来输出日志。</p>
<p>指定时间时,将输出指定时间范围内的日志。指定的时间可以不和日志中记录的日志相同。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fb8994948fbb838e9e8392">[email protected]</a> data]# mysqlbinlog mysql-bin.000001 --start-datetime='2017-03-28 00:00:01' --stop-datetime='2017-03-29 05:21:23'
...前面固定部分省略...
'/*!*/;
# at 120
#170329 5:20:00 server id 1 end_log_pos 305 CRC32 0xbac43912 Query thread_id=1 exec_time=0 error_code=0
use `test`/*!*/;
SET TIMESTAMP=1490736000/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table student(studentid int not null primary key,name varchar(30) not null,gender enum('female','mail'))
/*!*/;
# at 305
#170329 5:21:21 server id 1 end_log_pos 441 CRC32 0xde67f702 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490736081/*!*/;
alter table student change gender gender enum('female','male')
/*!*/;
DELIMITER ;
...后面固定部分省略...
</code></pre>
<p>同理指定位置也一样,但是指定位置时有个要求是如果指定起始位置,则必须指定日志文件中明确的起始位置。例如,日志文件中有位置120、305、441,可以指定起始和结束位置为120、500,但是不可以指定起止位置为150、500,因为日志文件中不存在150这个位置。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5c2e3333281c2429392435">[email protected]</a> data]# mysqlbinlog mysql-bin.000001 --start-position=150 --stop-position=441
...前面固定部分省略...
'/*!*/;
ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 4202496, event_type: 0
...后面固定部分省略...
[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="94e6fbfbe0d4ece1f1ecfd">[email protected]</a> data]# mysqlbinlog mysql-bin.000001 --start-position=305 --stop-position=500
...前面固定部分省略...
'/*!*/;
# at 305
#170329 5:21:21 server id 1 end_log_pos 441 CRC32 0xde67f702 Query thread_id=1 exec_time=0 error_code=0
use `test`/*!*/;
SET TIMESTAMP=1490736081/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
alter table student change gender gender enum('female','male')
/*!*/;
# at 441
#170329 5:21:33 server id 1 end_log_pos 520 CRC32 0x05a9c5a1 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490736093/*!*/;
BEGIN
/*!*/;
DELIMITER ;
...后面固定部分省略...
</code></pre>
<h3>5.2.2 show binary logs</h3>
<p>该语句用于查看当前使用了哪些二进制日志文件。</p>
<p>可以通过查看二进制的index文件来查看当前正在使用哪些二进制日志。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="aad8c5c5deead2dfcfd2c3">[email protected]</a> data]# cat mysql-bin.index
./mysql-bin.000003
./mysql-bin.000004
./mysql-bin.000005
./mysql-bin.000006
</code></pre>
<p>也可以在mysql环境中使用 show {binary | master} logs 来查看。binary和master是同义词。</p>
<pre><code>mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000003 | 167 |
| mysql-bin.000004 | 785 |
| mysql-bin.000005 | 1153 |
| mysql-bin.000006 | 602 |
+------------------+-----------
</code></pre>
<h3>5.2.3 show binlog events</h3>
<p><strong>该语句用于查看日志中进行了哪些操作。</strong></p>
<pre><code>mysql> show binlog events in 'mysql-bin.000005';
</code></pre>
<p><img src="assets/733013-20180507091129596-1182363918.png" alt="img" /></p>
<p>可以指定起始位置。同样,起始位置必须指定正确,不能指定不存在的位置。</p>
<pre><code>mysql> show binlog events in 'mysql-bin.000005' from 961;
+------------------+------+------------+-----------+-------------+--------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+------------+-----------+-------------+--------------------------------+
| mysql-bin.000005 | 961 | Table_map | 1 | 1019 | table_id: 98 (test.student) |
| mysql-bin.000005 | 1019 | Write_rows | 1 | 1075 | table_id: 98 flags: STMT_END_F |
| mysql-bin.000005 | 1075 | Xid | 1 | 1106 | COMMIT /* xid=129 */ |
| mysql-bin.000005 | 1106 | Rotate | 1 | 1153 | mysql-bin.000006;pos=4 |
+------------------+------+------------+-----------+-------------+--------------------------------+
</code></pre>
<h3>5.2.4 show master status</h3>
<p>该语句用于显示主服务器中的二进制日志信息。如果是主从结构,它只会显示主从结构中主服务器的二进制日志信息。</p>
<pre><code>mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 | 602 | | | |
+------------------+----------+--------------+------------------+-------------------+
</code></pre>
<p>可以查看到当前正在使用的日志及下一事件记录的开始位置,还能查看到哪些数据库需要记录二进制日志,哪些数据库不记录二进制日志。</p>
<h2>5.3 删除二进制日志</h2>
<p>删除二进制日志有几种方法。不管哪种方法,都会将删除后的信息同步到二进制index文件中。</p>
<p><strong>1.reset master<strong><strong>将会删除所有日志,并让日志文件重新从000001</strong></strong>开始。</strong></p>
<pre><code>mysql> reset master;
</code></pre>
<p><strong>2.PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }</strong></p>
<p>purge master logs to "binlog_name.00000X" 将会清空00000X之前的所有日志文件。例如删除000006之前的日志文件。</p>
<pre><code>mysql> purge master logs to "mysql-bin.000006";
mysql> purge binary logs to "mysql-bin.000006";
</code></pre>
<p>master和binary是同义词</p>
<p>purge master logs before 'yyyy-mm-dd hh:mi:ss' 将会删除指定日期之前的所有日志。但是若指定的时间处在正在使用中的日志文件中,将无法进行purge。</p>
<pre><code>mysql> purge master logs before '2017-03-29 07:36:40';
mysql> show warnings;
+---------+------+---------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------------------------+
| Warning | 1868 | file ./mysql-bin.000003 was not purged because it is the active log file. |
+---------+------+---------------------------------------------------------------------------+
</code></pre>
<p><strong>3.<strong><strong>使用--expire_logs_days=N</strong></strong>选项指定过了多少天日志自动过期清空。</strong></p>
<h2>5.4 二进制日志的记录格式</h2>
<p>在MySQL 5.1之前,MySQL只有一种基于语句statement形式的日志记录格式。即将所有的相关操作记录为SQL语句形式。但是这样的记录方式对某些特殊信息无法同步记录,例如uuid,now()等这样动态变化的值。</p>
<p>从MySQL 5.1开始,MySQL支持statement、row、mixed三种形式的记录方式。row形式是基于行来记录,也就是将相关行的每一列的值都在日志中保存下来,这样的结果会导致日志文件变得非常大,但是保证了动态值的确定性。还有一种mixed形式,表示如何记录日志由MySQL自己来决定。</p>
<p>日志的记录格式由变量 binlog_format 来指定。其值有:row,statement,mixed。innodb引擎的创始人之一在博客上推荐使用row格式。</p>
<p>下面将记录格式改为row。</p>
<pre><code>mysql> alter table student add birthday datetime default now();
mysql> flush logs;
mysql> set binlog_format='row';
mysql> insert into student values(7,'xiaowoniu','female',now());
</code></pre>
<p>查看产生的日志。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3f4d50504b7f474a5a4756">[email protected]</a> data]# mysqlbinlog mysql-bin.000005
...前面固定部分省略...
'/*!*/;
# at 120
#170329 8:06:24 server id 1 end_log_pos 200 CRC32 0x0ac02649 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1490745984/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1075838976/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
SET @@session.time_zone='SYSTEM'/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at 200
#170329 8:06:24 server id 1 end_log_pos 258 CRC32 0xb8cdfd09 Table_map: `test`.`student` mapped to number 94
# at 258
#170329 8:06:24 server id 1 end_log_pos 314 CRC32 0x8ce6f72c Write_rows: table id 94 flags: STMT_END_F
BINLOG '
gPraWBMBAAAAOgAAAAIBAAAAAF4AAAAAAAEABHRlc3QAB3N0dWRlbnQABAMP/hIFHgD3AQAMCf3N
uA==
gPraWB4BAAAAOAAAADoBAAAAAF4AAAAAAAEAAgAE//AHAAAACXhpYW93b25pdQGZnDqBmCz35ow=
'/*!*/;