-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy path39讲自增主键为什么不是连续的.html
384 lines (328 loc) · 50.9 KB
/
39讲自增主键为什么不是连续的.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
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport"
content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="format-detection" content="telephone=no">
<style type="text/css">
#watermark {
position: relative;
overflow: hidden;
}
#watermark .x {
position: absolute;
top: 800;
left: 400;
color: #3300ff;
font-size: 50px;
pointer-events: none;
opacity:0.3;
filter:Alpha(opacity=50);
}
</style>
<style type="text/css">
html{color:#333;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;text-rendering:optimizelegibility;font-family:Helvetica Neue,PingFang SC,Verdana,Microsoft Yahei,Hiragino Sans GB,Microsoft Sans Serif,WenQuanYi Micro Hei,sans-serif}html.borderbox *,html.borderbox :after,html.borderbox :before{box-sizing:border-box}article,aside,blockquote,body,button,code,dd,details,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hr,input,legend,li,menu,nav,ol,p,pre,section,td,textarea,th,ul{margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,menu,nav,section{display:block}audio,canvas,video{display:inline-block}body,button,input,select,textarea{font:300 1em/1.8 PingFang SC,Lantinghei SC,Microsoft Yahei,Hiragino Sans GB,Microsoft Sans Serif,WenQuanYi Micro Hei,Helvetica,sans-serif}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}blockquote{position:relative;color:#999;font-weight:400;border-left:1px solid #1abc9c;padding-left:1em;margin:1em 3em 1em 2em}@media only screen and (max-width:640px){blockquote{margin:1em 0}}abbr,acronym{border-bottom:1px dotted;font-variant:normal}abbr{cursor:help}del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:400}ol,ul{list-style:none}caption,th{text-align:left}q:after,q:before{content:""}sub,sup{font-size:75%;line-height:0;position:relative}:root sub,:root sup{vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}a{color:#1abc9c}a:hover{text-decoration:underline}.typo a{border-bottom:1px solid #1abc9c}.typo a:hover{border-bottom-color:#555;color:#555}.typo a:hover,a,ins{text-decoration:none}.typo-u,u{text-decoration:underline}mark{background:#fffdd1;border-bottom:1px solid #ffedce;padding:2px;margin:0 5px}code,pre,pre tt{font-family:Courier,Courier New,monospace}pre{background:hsla(0,0%,97%,.7);border:1px solid #ddd;padding:1em 1.5em;display:block;-webkit-overflow-scrolling:touch}hr{border:none;border-bottom:1px solid #cfcfcf;margin-bottom:.8em;height:10px}.typo-small,figcaption,small{font-size:.9em;color:#888}b,strong{font-weight:700;color:#000}[draggable]{cursor:move}.clearfix:after,.clearfix:before{content:"";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}.textwrap,.textwrap td,.textwrap th{word-wrap:break-word;word-break:break-all}.textwrap-table{table-layout:fixed}.serif{font-family:Palatino,Optima,Georgia,serif}.typo-dl,.typo-form,.typo-hr,.typo-ol,.typo-p,.typo-pre,.typo-table,.typo-ul,.typo dl,.typo form,.typo hr,.typo ol,.typo p,.typo pre,.typo table,.typo ul,blockquote{margin-bottom:1rem}h1,h2,h3,h4,h5,h6{font-family:PingFang SC,Helvetica Neue,Verdana,Microsoft Yahei,Hiragino Sans GB,Microsoft Sans Serif,WenQuanYi Micro Hei,sans-serif;color:#000;line-height:1.35}.typo-h1,.typo-h2,.typo-h3,.typo-h4,.typo-h5,.typo-h6,.typo h1,.typo h2,.typo h3,.typo h4,.typo h5,.typo h6{margin-top:1.2em;margin-bottom:.6em;line-height:1.35}.typo-h1,.typo h1{font-size:2em}.typo-h2,.typo h2{font-size:1.8em}.typo-h3,.typo h3{font-size:1.6em}.typo-h4,.typo h4{font-size:1.4em}.typo-h5,.typo-h6,.typo h5,.typo h6{font-size:1.2em}.typo-ul,.typo ul{margin-left:1.3em;list-style:disc}.typo-ol,.typo ol{list-style:decimal;margin-left:1.9em}.typo-ol ol,.typo-ol ul,.typo-ul ol,.typo-ul ul,.typo li ol,.typo li ul{margin-bottom:.8em;margin-left:2em}.typo-ol ul,.typo-ul ul,.typo li ul{list-style:circle}.typo-table td,.typo-table th,.typo table caption,.typo table td,.typo table th{border:1px solid #ddd;padding:.5em 1em;color:#666}.typo-table th,.typo table th{background:#fbfbfb}.typo-table thead th,.typo table thead th{background:hsla(0,0%,95%,.7)}.typo table caption{border-bottom:none}.typo-input,.typo-textarea{-webkit-appearance:none;border-radius:0}.typo-em,.typo em,caption,legend{color:#000;font-weight:inherit}.typo-em{position:relative}.typo-em:after{position:absolute;top:.65em;left:0;width:100%;overflow:hidden;white-space:nowrap;content:"\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB"}.typo img{max-width:100%}.common-content{font-weight:400;color:#353535;line-height:1.75rem;white-space:normal;word-break:normal;font-size:1rem}.common-content img{display:block;max-width:100%;background-color:#eee}.common-content audio,.common-content video{width:100%;background-color:#eee}.common-content center,.common-content font{margin-top:1rem;display:inline-block}.common-content center{width:100%}.common-content pre{margin-top:1rem;padding-left:0;padding-right:0;position:relative;overflow:hidden}.common-content pre code{font-size:.8rem;font-family:Consolas,Liberation Mono,Menlo,monospace,Courier;display:block;width:100%;box-sizing:border-box;padding-left:1rem;padding-right:1rem;overflow-x:auto}.common-content hr{border:none;margin-top:1.5rem;margin-bottom:1.5rem;border-top:1px solid #f5f5f5;height:1px;background:none}.common-content b,.common-content h1,.common-content h2,.common-content h3,.common-content h4,.common-content h5,.common-content strong{font-weight:700}.common-content h1,.common-content h2{font-size:1.125rem;margin-bottom:.45rem}.common-content h3,.common-content h4,.common-content h5{font-size:1rem;margin-bottom:.45rem}.common-content p{font-weight:400;color:#353535;margin-top:.15rem}.common-content .orange{color:#ff5a05}.common-content .reference{font-size:1rem;color:#888}.custom-rich-content h1{margin-top:0;font-weight:400;font-size:15.25px;border-bottom:1px solid #eee;line-height:2.8}.custom-rich-content li,.custom-rich-content p{font-size:14px;color:#888;line-height:1.6}table.hljs-ln{margin-bottom:0;border-spacing:0;border-collapse:collapse}table.hljs-ln,table.hljs-ln tbody,table.hljs-ln td,table.hljs-ln tr{box-sizing:border-box}table.hljs-ln td{padding:0;border:0}table.hljs-ln td.hljs-ln-numbers{min-width:15px;color:rgba(27,31,35,.3);text-align:right;white-space:nowrap;cursor:pointer;user-select:none}table.hljs-ln td.hljs-ln-code,table.hljs-ln td.hljs-ln-numbers{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px;line-height:20px;vertical-align:top}table.hljs-ln td.hljs-ln-code{position:relative;padding-right:10px;padding-left:10px;overflow:visible;color:#24292e;word-wrap:normal;white-space:pre}video::-webkit-media-controls{overflow:hidden!important}video::-webkit-media-controls-enclosure{width:calc(100% + 32px);margin-left:auto}.button-cancel{color:#888;border:1px solid #888;border-radius:3px;margin-right:12px}.button-cancel,.button-primary{-ms-flex-positive:1;flex-grow:1;height:35px;display:inline-block;font-size:15px;text-align:center;line-height:36px}.button-primary{color:#fff;background-color:#ff5a05;border-radius:3px}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.eot);src:url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.eot#iefix) format("embedded-opentype"),url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.woff) format("woff"),url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.ttf) format("truetype"),url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.svg#iconfont) format("svg")}@font-face{font-family:player-font;src:url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.eot);src:url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.eot#iefix) format("embedded-opentype"),url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.woff) format("woff"),url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.ttf) format("truetype"),url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.svg#player-font) format("svg")}.iconfont{font-family:iconfont!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-webkit-text-stroke-width:.2px;-moz-osx-font-smoothing:grayscale}html{background:#fff;min-height:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{width:100%}body.fixed{overflow:hidden;position:fixed;width:100vw;height:100vh}i{font-style:normal}a{word-wrap:break-word;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:hover{text-decoration:none}.fade-enter-active,.fade-leave-active{transition:opacity .3s}.fade-enter,.fade-leave-to{opacity:0}.MathJax,.MathJax_CHTML,.MathJax_MathContainer,.MathJax_MathML,.MathJax_PHTML,.MathJax_PlainSource,.MathJax_SVG{outline:0}.ios-app-switch .js-audit{display:none}._loading_wrap_{position:fixed;width:100vw;height:100vh;top:50%;left:50%;transform:translate(-50%,-50%);z-index:999}._loading_div_class_,._loading_wrap_{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}._loading_div_class_{word-wrap:break-word;padding:.5rem .75rem;text-align:center;z-index:9999;font-size:.6rem;max-width:60%;color:#fff;border-radius:.25rem;-ms-flex-direction:column;flex-direction:column}._loading_div_class_ .message{color:#353535;font-size:16px;line-height:3}.spinner{animation:circle-rotator 1.4s linear infinite}.spinner *{line-height:0;box-sizing:border-box}@keyframes circle-rotator{0%{transform:rotate(0deg)}to{transform:rotate(270deg)}}.path{stroke-dasharray:187;stroke-dashoffset:0;transform-origin:center;animation:circle-dash 1.4s ease-in-out infinite,circle-colors 5.6s ease-in-out infinite}@keyframes circle-colors{0%{stroke:#ff5a05}to{stroke:#ff5a05}}@keyframes circle-dash{0%{stroke-dashoffset:187}50%{stroke-dashoffset:46.75;transform:rotate(135deg)}to{stroke-dashoffset:187;transform:rotate(450deg)}}.confirm-box-wrapper,.confirm-box-wrapper .mask{position:absolute;top:0;left:0;right:0;bottom:0}.confirm-box-wrapper .mask{background:rgba(0,0,0,.6)}.confirm-box-wrapper .confirm-box{position:fixed;top:50%;left:50%;width:267px;background:#fff;transform:translate(-50%,-50%);border-radius:7px}.confirm-box-wrapper .confirm-box .head{margin:0 18px;font-size:18px;text-align:center;line-height:65px;border-bottom:1px solid #d9d9d9}.confirm-box-wrapper .confirm-box .body{padding:18px;padding-bottom:0;color:#353535;font-size:12.5px;max-height:150px;overflow:auto}.confirm-box-wrapper .confirm-box .foot{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;padding:18px}.confirm-box-wrapper .confirm-box .foot .button-cancel{border:1px solid #d9d9d9}.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:teal}.hljs-doctag,.hljs-string{color:#d14}.hljs-section,.hljs-selector-id,.hljs-title{color:#900;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-link,.hljs-regexp{color:#009926}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
</style>
<style type="text/css">
.button-cancel[data-v-87ffcada]{color:#888;border:1px solid #888;border-radius:3px;margin-right:12px}.button-cancel[data-v-87ffcada],.button-primary[data-v-87ffcada]{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;height:35px;display:inline-block;font-size:15px;text-align:center;line-height:36px}.button-primary[data-v-87ffcada]{color:#fff;background-color:#ff5a05;border-radius:3px}.pd[data-v-87ffcada]{padding-left:1.375rem;padding-right:1.375rem}.article[data-v-87ffcada]{max-width:70rem;margin:0 auto}.article .article-unavailable[data-v-87ffcada]{color:#fa8919;font-size:15px;font-weight:600;line-height:24px;border-radius:5px;padding:12px;background-color:#f6f7fb;margin-top:20px}.article .article-unavailable .iconfont[data-v-87ffcada]{font-size:12px}.article .main[data-v-87ffcada]{padding:1.25rem 0;margin-bottom:52px}.article-title[data-v-87ffcada]{color:#353535;font-weight:400;line-height:1.65rem;font-size:1.34375rem}.article-info[data-v-87ffcada]{color:#888;font-size:.9375rem;margin-top:1.0625rem}.article-content[data-v-87ffcada]{margin-top:1.0625rem}.article-content.android video[data-v-87ffcada]::-webkit-media-controls-fullscreen-button{display:none}.copyright[data-v-87ffcada]{color:#b2b2b2;padding-bottom:20px;margin-top:20px;font-size:13px}.audio-player[data-v-87ffcada]{width:100%;margin:20px 0}.to-comment[data-v-87ffcada]{overflow:hidden;padding-top:10px;margin-bottom:-30px}.to-comment a.button-primary[data-v-87ffcada]{float:right;height:20px;font-size:12px;line-height:20px;padding:4px 8px;cursor:pointer}.article-comments[data-v-87ffcada]{margin-top:2rem}.article-comments h2[data-v-87ffcada]{text-align:center;color:#888;position:relative;z-index:1;margin-bottom:1rem}.article-comments h2[data-v-87ffcada]:before{border-top:1px dotted #888;content:"";position:absolute;top:56%;left:0;width:100%;z-index:-1}.article-comments h2 span[data-v-87ffcada]{font-size:15.25px;font-weight:400;padding:0 1rem;background:#fff;display:inline-block}.article-sub-bottom[data-v-87ffcada]{z-index:10;cursor:pointer}.switch-btns[data-v-87ffcada]{height:76px;cursor:pointer;padding-top:24px;padding-bottom:24px;border-bottom:10px solid #f6f7fb;position:relative}.switch-btns[data-v-87ffcada]:before{content:" ";height:1px;background:#e8e8e8;position:absolute;top:0;left:0;-webkit-box-sizing:border-box;box-sizing:border-box;left:1.375rem;right:1.375rem}.switch-btns .btn[data-v-87ffcada]{height:38px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.switch-btns .btn .tag[data-v-87ffcada]{-webkit-box-flex:0;-ms-flex:0 0 62px;flex:0 0 62px;text-align:center;color:#888;font-size:14px;border-radius:10px;height:22px;line-height:22px;background:#f6f7fb;font-weight:400}.switch-btns .btn .txt[data-v-87ffcada]{margin-left:10px;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;color:#888;font-size:15px;height:22px;line-height:22px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:400}@media (max-width:769px){.article .breadcrumb[data-v-87ffcada]{padding-top:10px;padding-bottom:10px}}
</style>
<style type="text/css">
.comment-item{list-style-position:inside;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;margin-bottom:1rem}.comment-item a{border-bottom:none}.comment-item .avatar{width:2.625rem;height:2.625rem;-ms-flex-negative:0;flex-shrink:0;border-radius:50%}.comment-item .info{margin-left:.5rem;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.comment-item .info .hd{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.comment-item .info .hd .username{color:#888;font-size:15.25px;font-weight:400;line-height:1.2}.comment-item .info .hd .control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.comment-item .info .hd .control .btn-share{color:#888;font-size:.75rem;margin-right:1rem}.comment-item .info .hd .control .btn-praise{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:15.25px;text-decoration:none}.comment-item .info .hd .control .btn-praise i{color:#888;display:inline-block;font-size:.75rem;margin-right:.3rem;margin-top:-.01rem}.comment-item .info .hd .control .btn-praise i.on,.comment-item .info .hd .control .btn-praise span{color:#ff5a05}.comment-item .info .bd{color:#353535;font-size:15.25px;font-weight:400;white-space:normal;word-break:break-all;line-height:1.6}.comment-item .info .time{color:#888;font-size:9px;line-height:1}.comment-item .info .reply .reply-hd{font-size:15.25px}.comment-item .info .reply .reply-hd span{margin-left:-12px;color:#888;font-weight:400}.comment-item .info .reply .reply-hd i{color:#ff5a05;font-size:15.25px}.comment-item .info .reply .reply-content{color:#353535;font-size:15.25px;font-weight:400;white-space:normal;word-break:break-all}.comment-item .info .reply .reply-time{color:#888;font-size:9px}
</style>
</head>
<body>
<div id="app">
<div data-v-87ffcada="" class="article" id="watermark">
<div data-v-87ffcada="" class="main main-app">
<h1 data-v-87ffcada="" class="article-title pd">
39讲自增主键为什么不是连续的
</h1>
<div data-v-87ffcada="" class="article-content typo common-content pd"><img data-v-87ffcada=""
src="https://static001.geekbang.org/resource/image/18/30/18938982e22dc8ff03c9449aa464e830.jpg">
<div>
<audio controls="controls" height="100" width="100">
<source src="39讲自增主键为什么不是连续的.mp3" type="audio/mp3" />
<embed height="100" width="100" src="39讲自增主键为什么不是连续的.mp3" />
</audio>
</div>
<div data-v-87ffcada="" id="article-content" class="">
<div class="text">
<p>在<a href="https://time.geekbang.org/column/article/69236">第4篇文章</a>中,我们提到过自增主键,由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧凑。</p><p>之前我见过有的业务设计依赖于自增主键的连续性,也就是说,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不能保证连续递增。</p><p>今天这篇文章,我们就来说说这个问题,看看什么情况下自增主键会出现 “空洞”?</p><p>为了便于说明,我们创建一个表t,其中id是自增主键字段、c是唯一索引。</p><pre><code>CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `c` (`c`)
) ENGINE=InnoDB;
</code></pre><h1>自增值保存在哪儿?</h1><p>在这个空表t里面执行insert into t values(null, 1, 1);插入一行数据,再执行show create table命令,就可以看到如下图所示的结果:</p><p><img src="https://static001.geekbang.org/resource/image/cb/ff/cb2637cada0201b18650f56875e94fff.png" alt=""></p><center><span class="reference">图1 自动生成的AUTO_INCREMENT值</span></center><p>可以看到,表定义里面出现了一个AUTO_INCREMENT=2,表示下一次插入数据时,如果需要自动生成自增值,会生成id=2。</p><p>其实,这个输出结果容易引起这样的误解:自增值是保存在表结构定义里的。实际上,<strong>表的结构定义存放在后缀名为.frm的文件中,但是并不会保存自增值。</strong></p><p>不同的引擎对于自增值的保存策略不同。</p><ul>
<li>MyISAM引擎的自增值保存在数据文件中。</li>
<li>InnoDB引擎的自增值,其实是保存在了内存里,并且到了MySQL 8.0版本后,才有了“自增值持久化”的能力,也就是才实现了“如果发生重启,表的自增值可以恢复为MySQL重启前的值”,具体情况是:
<ul>
<li>在MySQL 5.7及之前的版本,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值max(id),然后将max(id)+1作为这个表当前的自增值。<br>
举例来说,如果一个表当前数据行里最大的id是10,AUTO_INCREMENT=11。这时候,我们删除id=10的行,AUTO_INCREMENT还是11。但如果马上重启实例,重启后这个表的AUTO_INCREMENT就会变成10。<br>
也就是说,MySQL重启可能会修改一个表的AUTO_INCREMENT的值。</li>
<li>在MySQL 8.0版本,将自增值的变更记录在了redo log中,重启的时候依靠redo log恢复重启之前的值。</li>
</ul>
</li>
</ul><!-- [[[read_end]]] --><p>理解了MySQL对自增值的保存策略以后,我们再看看自增值修改机制。</p><h1>自增值修改机制</h1><p>在MySQL里面,如果字段id被定义为AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:</p><ol>
<li>
<p>如果插入数据时id字段指定为0、null 或未指定值,那么就把这个表当前的 AUTO_INCREMENT值填到自增字段;</p>
</li>
<li>
<p>如果插入数据时id字段指定了具体的值,就直接使用语句里指定的值。</p>
</li>
</ol><p>根据要插入的值和当前自增值的大小关系,自增值的变更结果也会有所不同。假设,某次要插入的值是X,当前的自增值是Y。</p><ol>
<li>
<p>如果X<Y,那么这个表的自增值不变;</p>
</li>
<li>
<p>如果X≥Y,就需要把当前自增值修改为新的自增值。</p>
</li>
</ol><p><strong>新的自增值生成算法是</strong>:从auto_increment_offset开始,以auto_increment_increment为步长,持续叠加,直到找到第一个大于X的值,作为新的自增值。</p><p>其中,auto_increment_offset 和 auto_increment_increment是两个系统参数,分别用来表示自增的初始值和步长,默认值都是1。</p><blockquote>
<p>备注:在一些场景下,使用的就不全是默认值。比如,双M的主备结构里要求双写的时候,我们就可能会设置成auto_increment_increment=2,让一个库的自增id都是奇数,另一个库的自增id都是偶数,避免两个库生成的主键发生冲突。</p>
</blockquote><p>当auto_increment_offset和auto_increment_increment都是1的时候,新的自增值生成逻辑很简单,就是:</p><ol>
<li>
<p>如果准备插入的值>=当前自增值,新的自增值就是“准备插入的值+1”;</p>
</li>
<li>
<p>否则,自增值不变。</p>
</li>
</ol><p>这就引入了我们文章开头提到的问题,在这两个参数都设置为1的时候,自增主键id却不能保证是连续的,这是什么原因呢?</p><h1>自增值的修改时机</h1><p>要回答这个问题,我们就要看一下自增值的修改时机。</p><p>假设,表t里面已经有了(1,1,1)这条记录,这时我再执行一条插入数据命令:</p><pre><code>insert into t values(null, 1, 1);
</code></pre><p>这个语句的执行流程就是:</p><ol>
<li>
<p>执行器调用InnoDB引擎接口写入一行,传入的这一行的值是(0,1,1);</p>
</li>
<li>
<p>InnoDB发现用户没有指定自增id的值,获取表t当前的自增值2;</p>
</li>
<li>
<p>将传入的行的值改成(2,1,1);</p>
</li>
<li>
<p>将表的自增值改成3;</p>
</li>
<li>
<p>继续执行插入数据操作,由于已经存在c=1的记录,所以报Duplicate key error,语句返回。</p>
</li>
</ol><p>对应的执行流程图如下:</p><p><img src="https://static001.geekbang.org/resource/image/f1/d3/f16d89a6e7ad6e2cde13b32bb2292dd3.jpg" alt=""></p><center><span class="reference">图2 insert(null, 1,1)唯一键冲突</span></center><p>可以看到,这个表的自增值改成3,是在真正执行插入数据的操作之前。这个语句真正执行的时候,因为碰到唯一键c冲突,所以id=2这一行并没有插入成功,但也没有将自增值再改回去。</p><p>所以,在这之后,再插入新的数据行时,拿到的自增id就是3。也就是说,出现了自增主键不连续的情况。</p><p>如图3所示就是完整的演示结果。</p><p><img src="https://static001.geekbang.org/resource/image/77/26/77b87820b649692a555f19b562d5d926.png" alt=""></p><center><span class="reference">图3 一个自增主键id不连续的复现步骤</span></center><p>可以看到,这个操作序列复现了一个自增主键id不连续的现场(没有id=2的行)。可见,<strong>唯一键冲突是导致自增主键id不连续的第一种原因。</strong></p><p>同样地,事务<strong>回滚也会产生类似的现象,这就是第二种原因。</strong></p><p>下面这个语句序列就可以构造不连续的自增id,你可以自己验证一下。</p><pre><code>insert into t values(null,1,1);
begin;
insert into t values(null,2,2);
rollback;
insert into t values(null,2,2);
//插入的行是(3,2,2)
</code></pre><p>你可能会问,为什么在出现唯一键冲突或者回滚的时候,MySQL没有把表t的自增值改回去呢?如果把表t的当前自增值从3改回2,再插入新数据的时候,不就可以生成id=2的一行数据了吗?</p><p>其实,MySQL这么设计是为了提升性能。接下来,我就跟你分析一下这个设计思路,看看<strong>自增值为什么不能回退。</strong></p><p>假设有两个并行执行的事务,在申请自增值的时候,为了避免两个事务申请到相同的自增id,肯定要加锁,然后顺序申请。</p><ol>
<li>
<p>假设事务A申请到了id=2, 事务B申请到id=3,那么这时候表t的自增值是4,之后继续执行。</p>
</li>
<li>
<p>事务B正确提交了,但事务A出现了唯一键冲突。</p>
</li>
<li>
<p>如果允许事务A把自增id回退,也就是把表t的当前自增值改回2,那么就会出现这样的情况:表里面已经有id=3的行,而当前的自增id值是2。</p>
</li>
<li>
<p>接下来,继续执行的其他事务就会申请到id=2,然后再申请到id=3。这时,就会出现插入语句报错“主键冲突”。</p>
</li>
</ol><p>而为了解决这个主键冲突,有两种方法:</p><ol>
<li>
<p>每次申请id之前,先判断表里面是否已经存在这个id。如果存在,就跳过这个id。但是,这个方法的成本很高。因为,本来申请id是一个很快的操作,现在还要再去主键索引树上判断id是否存在。</p>
</li>
<li>
<p>把自增id的锁范围扩大,必须等到一个事务执行完成并提交,下一个事务才能再申请自增id。这个方法的问题,就是锁的粒度太大,系统并发能力大大下降。</p>
</li>
</ol><p>可见,这两个方法都会导致性能问题。造成这些麻烦的罪魁祸首,就是我们假设的这个“允许自增id回退”的前提导致的。</p><p>因此,InnoDB放弃了这个设计,语句执行失败也不回退自增id。也正是因为这样,所以才只保证了自增id是递增的,但不保证是连续的。</p><h1>自增锁的优化</h1><p>可以看到,自增id锁并不是一个事务锁,而是每次申请完就马上释放,以便允许别的事务再申请。其实,在MySQL 5.1版本之前,并不是这样的。</p><p>接下来,我会先给你介绍下自增锁设计的历史,这样有助于你分析接下来的一个问题。</p><p>在MySQL 5.0版本的时候,自增锁的范围是语句级别。也就是说,如果一个语句申请了一个表自增锁,这个锁会等语句执行结束以后才释放。显然,这样设计会影响并发度。</p><p>MySQL 5.1.22版本引入了一个新策略,新增参数innodb_autoinc_lock_mode,默认值是1。</p><ol>
<li>
<p>这个参数的值被设置为0时,表示采用之前MySQL 5.0版本的策略,即语句执行结束后才释放锁;</p>
</li>
<li>
<p>这个参数的值被设置为1时:</p>
<ul>
<li>普通insert语句,自增锁在申请之后就马上释放;</li>
<li>类似insert … select这样的批量插入数据的语句,自增锁还是要等语句结束后才被释放;</li>
</ul>
</li>
<li>
<p>这个参数的值被设置为2时,所有的申请自增主键的动作都是申请后就释放锁。</p>
</li>
</ol><p>你一定有两个疑问:<strong>为什么默认设置下,insert … select 要使用语句级的锁?为什么这个参数的默认值不是2?</strong></p><p>答案是,这么设计还是为了数据的一致性。</p><p>我们一起来看一下这个场景:</p><p><img src="https://static001.geekbang.org/resource/image/e0/df/e0a69e151277de54a8262657e4ec89df.png" alt=""></p><center><span class="reference">图4 批量插入数据的自增锁</span></center><p>在这个例子里,我往表t1中插入了4行数据,然后创建了一个相同结构的表t2,然后两个session同时执行向表t2中插入数据的操作。</p><p>你可以设想一下,如果session B是申请了自增值以后马上就释放自增锁,那么就可能出现这样的情况:</p><ul>
<li>session B先插入了两个记录,(1,1,1)、(2,2,2);</li>
<li>然后,session A来申请自增id得到id=3,插入了(3,5,5);</li>
<li>之后,session B继续执行,插入两条记录(4,3,3)、 (5,4,4)。</li>
</ul><p>你可能会说,这也没关系吧,毕竟session B的语义本身就没有要求表t2的所有行的数据都跟session A相同。</p><p>是的,从数据逻辑上看是对的。但是,如果我们现在的binlog_format=statement,你可以设想下,binlog会怎么记录呢?</p><p>由于两个session是同时执行插入数据命令的,所以binlog里面对表t2的更新日志只有两种情况:要么先记session A的,要么先记session B的。</p><p>但不论是哪一种,这个binlog拿去从库执行,或者用来恢复临时实例,备库和临时实例里面,session B这个语句执行出来,生成的结果里面,id都是连续的。这时,这个库就发生了数据不一致。</p><p>你可以分析一下,出现这个问题的原因是什么?</p><p>其实,这是因为原库session B的insert语句,生成的id不连续。这个不连续的id,用statement格式的binlog来串行执行,是执行不出来的。</p><p>而要解决这个问题,有两种思路:</p><ol>
<li>
<p>一种思路是,让原库的批量插入数据语句,固定生成连续的id值。所以,自增锁直到语句执行结束才释放,就是为了达到这个目的。</p>
</li>
<li>
<p>另一种思路是,在binlog里面把插入数据的操作都如实记录进来,到备库执行的时候,不再依赖于自增主键去生成。这种情况,其实就是innodb_autoinc_lock_mode设置为2,同时binlog_format设置为row。</p>
</li>
</ol><p>因此,<strong>在生产上,尤其是有insert … select这种批量插入数据的场景时,从并发插入数据性能的角度考虑,我建议你这样设置:innodb_autoinc_lock_mode=2 ,并且 binlog_format=row</strong>.这样做,既能提升并发性,又不会出现数据一致性问题。</p><p>需要注意的是,我这里说的<strong>批量插入数据,包含的语句类型是insert … select、replace … select和load data语句。</strong></p><p>但是,在普通的insert语句里面包含多个value值的情况下,即使innodb_autoinc_lock_mode设置为1,也不会等语句执行完成才释放锁。因为这类语句在申请自增id的时候,是可以精确计算出需要多少个id的,然后一次性申请,申请完成后锁就可以释放了。</p><p>也就是说,批量插入数据的语句,之所以需要这么设置,是因为“不知道要预先申请多少个id”。</p><p>既然预先不知道要申请多少个自增id,那么一种直接的想法就是需要一个时申请一个。但如果一个select … insert语句要插入10万行数据,按照这个逻辑的话就要申请10万次。显然,这种申请自增id的策略,在大批量插入数据的情况下,不但速度慢,还会影响并发插入的性能。</p><p>因此,对于批量插入数据的语句,MySQL有一个批量申请自增id的策略:</p><ol>
<li>
<p>语句执行过程中,第一次申请自增id,会分配1个;</p>
</li>
<li>
<p>1个用完以后,这个语句第二次申请自增id,会分配2个;</p>
</li>
<li>
<p>2个用完以后,还是这个语句,第三次申请自增id,会分配4个;</p>
</li>
<li>
<p>依此类推,同一个语句去申请自增id,每次申请到的自增id个数都是上一次的两倍。</p>
</li>
</ol><p>举个例子,我们一起看看下面的这个语句序列:</p><pre><code>insert into t values(null, 1,1);
insert into t values(null, 2,2);
insert into t values(null, 3,3);
insert into t values(null, 4,4);
create table t2 like t;
insert into t2(c,d) select c,d from t;
insert into t2 values(null, 5,5);
</code></pre><p>insert…select,实际上往表t2中插入了4行数据。但是,这四行数据是分三次申请的自增id,第一次申请到了id=1,第二次被分配了id=2和id=3, 第三次被分配到id=4到id=7。</p><p>由于这条语句实际只用上了4个id,所以id=5到id=7就被浪费掉了。之后,再执行insert into t2 values(null, 5,5),实际上插入的数据就是(8,5,5)。</p><p><strong>这是主键id出现自增id不连续的第三种原因。</strong></p><h1>小结</h1><p>今天,我们从“自增主键为什么会出现不连续的值”这个问题开始,首先讨论了自增值的存储。</p><p>在MyISAM引擎里面,自增值是被写在数据文件上的。而在InnoDB中,自增值是被记录在内存的。MySQL直到8.0版本,才给InnoDB表的自增值加上了持久化的能力,确保重启前后一个表的自增值不变。</p><p>然后,我和你分享了在一个语句执行过程中,自增值改变的时机,分析了为什么MySQL在事务回滚的时候不能回收自增id。</p><p>MySQL 5.1.22版本开始引入的参数innodb_autoinc_lock_mode,控制了自增值申请时的锁范围。从并发性能的角度考虑,我建议你将其设置为2,同时将binlog_format设置为row。我在前面的文章中其实多次提到,binlog_format设置为row,是很有必要的。今天的例子给这个结论多了一个理由。</p><p>最后,我给你留一个思考题吧。</p><p>在最后一个例子中,执行insert into t2(c,d) select c,d from t;这个语句的时候,如果隔离级别是可重复读(repeatable read),binlog_format=statement。这个语句会对表t的所有记录和间隙加锁。</p><p>你觉得为什么需要这么做呢?</p><p>你可以把你的思考和分析写在评论区,我会在下一篇文章和你讨论这个问题。感谢你的收听,也欢迎你把这篇文章分享给更多的朋友一起阅读。</p><h1>上期问题时间</h1><p>上期的问题是,如果你维护的MySQL系统里有内存表,怎么避免内存表突然丢数据,然后导致主备同步停止的情况。</p><p>我们假设的是主库暂时不能修改引擎,那么就把备库的内存表引擎先都改成InnoDB。对于每个内存表,执行</p><pre><code>set sql_log_bin=off;
alter table tbl_name engine=innodb;
</code></pre><p>这样就能避免备库重启的时候,数据丢失的问题。</p><p>由于主库重启后,会往binlog里面写“delete from tbl_name”,这个命令传到备库,备库的同名的表数据也会被清空。</p><p>因此,就不会出现主备同步停止的问题。</p><p>如果由于主库异常重启,触发了HA,这时候我们之前修改过引擎的备库变成了主库。而原来的主库变成了新备库,在新备库上把所有的内存表(这时候表里没数据)都改成InnoDB表。</p><p>所以,如果我们不能直接修改主库上的表引擎,可以配置一个自动巡检的工具,在备库上发现内存表就把引擎改了。</p><p>同时,跟业务开发同学约定好建表规则,避免创建新的内存表。</p><p>评论区留言点赞板:</p><blockquote>
<p>大家在春节期间还坚持看专栏,并且深入地思考和回复,给大家点赞。<br>
@长杰 同学提到的将数据保存到InnoDB表用来持久化,也是一个方法。不过,我还是建议釜底抽薪,直接修改备库的内存表的引擎。<br>
@老杨同志 提到的是主库异常重启的场景,这时候是不会报主备不一致的,因为主库重启的时候写了delete from tbl_name,主备的内存表都清空了。</p>
</blockquote><p><img src="https://static001.geekbang.org/resource/image/09/77/09c1073f99cf71d2fb162a716b5fa577.jpg" alt=""></p>
</div>
</div>
</div>
<div data-v-87ffcada="" class="article-comments pd"><h2 data-v-87ffcada=""><span
data-v-87ffcada="">精选留言</span></h2>
<ul data-v-87ffcada="">
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/14/05/d4/e06bf86d.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">长杰</span>
</div>
<div class="bd">在最后一个例子中,执行 insert into t2(c,d) select c,d from t; 这个语句的时候,如果隔离级别是可重复读(repeatable read),binlog_format=statement。这个语句会对表 t 的所有记录和间隙加锁。<br>你觉得为什么需要这么做呢?<br>假如原库不对t表所有记录和间隙加锁,如果有其他事物新增数据并先与这个批量操作提交,由于事物的隔离级别是可重复读,t2是看不到新增的数据的。但是记录的binlog是statement格式,备库或基于binlog恢复的临时库,t2会看到新增的数据,出现数据不一致的情况。 <br></div>
<span class="time">2019-02-11 15:57</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">👍 这是一个典型的场景</p>
<p class="reply-time">2019-02-11 18:04</p>
</div>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/11/40/5e/b8fada94.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">Ryoma</span>
</div>
<div class="bd">在8.0.3版本后,innodb_autoinc_lock_mode默认值已是2,在binlog_format默认值为row的前提下,想来也是为了增加并发。 <br><br>https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_autoinc_lock_mode <br></div>
<span class="time">2019-02-14 22:21</span>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/11/ec/fd/bad2abf5.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">帽子掉了</span>
</div>
<div class="bd">老师您好,我有一个时序问题,想请教一下。<br>从这篇文章的介绍来看,获取自增id和写binlog是有先后顺序的。<br>那么在binlog为statement的情况下。<br>语句A先获取id=1,然后B获取id=2,接着B提交,写binlog,再A写binlog。<br>这个时候如果binlog重放,是不是会发生B的id为1,而A的id为2的不一致的情况? <br></div>
<span class="time">2019-02-13 20:49</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">好问题,不会<br>因为binlog在记录这种带自增值的语句之前,会在前面多一句,用于指定“接下来这个语句要需要的 自增ID值是多少”,而这个值,是在主库上这一行插入成功后对应的自增值,所以是一致的</p>
<p class="reply-time">2019-02-14 14:58</p>
</div>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/11/8a/3e/30c05bce.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">aliang</span>
</div>
<div class="bd">老师,我们这边有的开发不喜欢用mysql自带的主键自增功能,而是在程序中控制主键(时间+业务+机器+序列,bigint类型,实际长度有17位,其中序列保存在内存中,每次递增,主键值不连续)。理由是<br>(1)通过这样的主键可以直接定位数据,减少索引(2)如果自增,必须先存数据得到主键才可继续下面的程序,如果自己计算主键,可以在入库前进行异步处理<br>(3)a表要insert得到主键,然后处理b表,然后根据条件还要update a表。如果程序自己控制,就不用先insert a表,数据可以在内存中,直到最后一次提交。(对于a表,本来是insert+update,最后只是一条insert,少一次数据库操作)<br>我想请问的是:<br>(1)针对理由1,是否可以用组合索引替代?<br>(2)针对理由2,是否mysql自身的主键自增分配逻辑就已经能实现了?<br>(3)针对理由3,主键更长意味着更大的索引(主键索引和普通索引),你觉得怎样做会更好呢 <br></div>
<span class="time">2019-02-12 16:34</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">“(时间+业务+机器+序列,bigint类型,实际长度有17位,其中序列保存在内存中,每次递增,主键值不连续)。” ----bigint就是8位,这个你需要确定一下。如果是8位的还好,如果是17位的字符串,就比较耗费空间;<br><br>(1)如果“序列”是递增的,还是不能直接用来体现业务逻辑吧? 创建有业务意义的字段索引估计还是省不了的 ?<br>(2)mysql确实做不到“插入之前就先算好接下来的id是多少”,一般都是insert执行完成后,再执行select last_insert_id<br> (3) 先insert a再update b再update a,确实看上去比较奇怪,不过感觉这个逻辑应该是可以优化的,不应该作为“主键选择”的一个依据。你可否脱敏一下,把模拟的表结构和业务逻辑说下,看看是不是可以优化的。<br><br>总之,按照你说的“时间+业务+机器+序列”这种模式,有点像用uuid,主要的问题还是,如果这个表的索引多,占用的空间比较大</p>
<p class="reply-time">2019-02-12 21:45</p>
</div>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/13/df/90/68408c1b.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">郭烊千玺</span>
</div>
<div class="bd">请教老师个额外话题 select concat(truncate(sum(data_length)/1024/1024,2),'MB') as data_size,<br>concat(truncate(sum(max_data_length)/1024/1024,2),'MB') as max_data_size,<br>concat(truncate(sum(data_free)/1024/1024,2),'MB') as data_free,<br>concat(truncate(sum(index_length)/1024/1024,2),'MB') as index_size<br>from information_schema.tables where TABLE_SCHEMA = 'databasename'; 网上广为流传的这个统计的表大小的方法准确吗 mysql内部是怎么统计的?并且data_free这个mydql内部又是怎么统计的 是采样8个页来评估整表吗 并且实验总感觉这样统计不准啊 到底靠谱吗 求赐教求赐教啊 困惑好久了 <br></div>
<span class="time">2019-02-12 15:17</span>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="http://thirdwx.qlogo.cn/mmopen/vi_32/Nr8o80t7TVwlXk7eoFYQpknWiayM5NbWKSf4DicTmYxGSoKoUwNurxjvDflgpZu6I9ChWdNr14gbABgq1ibP2cvWg/132" class="avatar">
<div class="info">
<div class="hd"><span class="username">悟空</span>
</div>
<div class="bd">赶上了进度,把春节期间的补回来了 <br></div>
<span class="time">2019-02-12 11:49</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">👍</p>
<p class="reply-time">2019-02-12 21:26</p>
</div>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/10/f7/b1/b05a2156.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">we</span>
</div>
<div class="bd">insert into t values(null,1,1);<br>begin;<br>insert into t values(null,2,2);<br>rolllack;<br>insert into t values(null,2,2);<br>// 插入的行是 (3,2,2)<br><br>老师 里面是 rollback 吧 <br></div>
<span class="time">2019-02-12 10:09</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">是的,我手残了。。<br><br>多谢指出,发起勘误了哈<br></p>
<p class="reply-time">2019-02-12 21:33</p>
</div>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/11/5b/fc/5c24080b.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">牛在天上飞</span>
</div>
<div class="bd">老师,请问产生大量的event事件会对mysql服务器有什么影响?主要是哪几个方面的影响? <br></div>
<span class="time">2019-02-12 09:00</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">也没啥,主要就是不好管理。。<br>毕竟event是写在MySQL里的,写程序的同学不一定会记得。<br>比较建议将这类逻辑写在应用程序里面</p>
<p class="reply-time">2019-02-12 21:31</p>
</div>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/11/8a/3e/30c05bce.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">aliang</span>
</div>
<div class="bd">老师,执行SELECT `ID`, `USER`, `HOST`, `DB`, `COMMAND`, `TIME`, `STATE`, LEFT(`INFO`, 51200) AS `Info` FROM `information_schema`.`PROCESSLIST`;后不时有COMMAND为killed但info为null的进程,请问是怎么回事呢 <br></div>
<span class="time">2019-02-11 16:30</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">就表示还在“killed”状态,看一下32篇哈</p>
<p class="reply-time">2019-02-11 18:07</p>
</div>
</div>
</li>
<li data-v-87ffcada="" class="comment-item"><img
src="https://static001.geekbang.org/account/avatar/00/11/15/69/fc60d1f4.jpg" class="avatar">
<div class="info">
<div class="hd"><span class="username">陈华应</span>
</div>
<div class="bd">防止insert语句执行过程中,原表有新增数据,进而导致的插入新表的数据比原表少 <br></div>
<span class="time">2019-02-11 11:29</span>
<div class="reply">
<div class="reply-hd"><span>作者回复</span></div>
<p class="reply-content">确实是考虑并发 , 不过并不会有这个现象哦,因为一个语句执行期间还是有一致性视图的。<br><br>把binlog加进去考虑下哈<br></p>
<p class="reply-time">2019-02-11 16:22</p>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</body>
</html>